SIGN IN SIGN UP

feat: add --text flag and auto-save for deep research output (#68)

* feat: add --text flag and auto-save for deep research output

Add output schema support (auto vs text) to the research run command.
Default uses auto schema (structured JSON), --text switches to text
schema (markdown report). Results always save to files automatically
using the run ID as filename, or a custom path via -o.

- Auto schema: saves {base}.json with full structured response
- Text schema: saves {base}.json (metadata + basis) and {base}.md
  (markdown content)
- Executive summary always printed to stdout
- New _save_and_display_research replaces old dual-purpose output fn
- 62 tests covering schema selection, file output, and display

* feat(cli): refine research output — auto-save dir, --text-description, --force, robustness

Builds on the --text/auto-save base added earlier in this branch with a
round of UX, accuracy, and quality fixes from review:

- Default save path is now ./parallel-research/<run_id> instead of cwd, so
  invoking from $HOME (or anywhere) doesn't litter the directory. -o still
  takes precedence; trailing slash or an existing dir on -o appends <run_id>
  inside it.
- Refuse to overwrite existing output files; pass --force to clobber. Error
  lists each target with (exists)/(new) markers.
- KeyboardInterrupt handler prints "Resume with: parallel-cli research poll
  <run_id>" and exits 130, so a Ctrl-C mid-poll never loses the run_id.
- mkdir parents for -o paths into missing dirs; on OSError write failure,
  fall back to /tmp/<run_id>.{json,md} so a billed API call isn't lost.
- --text-description steers text-schema reports (rejects without --text).
- Suffix handling: only strip .json/.md from -o; preserve other extensions
  (.bak, .v2) so -o report.bak writes report.bak.json.
- Saver keys off the SDK's output.type discriminator instead of inferring
  from isinstance(content, str). Verified live: auto returns type="json",
  text returns type="text".
- Dedupe: extracted _exit_research_interrupted / _exit_research_timeout
  helpers shared by research_run and research_poll. Moved auto-cwd-isolation
  pytest fixture into tests/conftest.py so test_cli.py is covered too.

* chore(cli): replace `nonlocal` with list-as-box for Ctrl-C resume capture

Same effect, less foreign syntax: a single-element list captures the run_id
from the on_status callback so the KeyboardInterrupt handler can print a
'Resume with: parallel-cli research poll <run_id>' hint.
M
Matt H committed
cc2f470beb44b923788dceef188ee3197bba21c9
Parent: 66179f6
Committed by GitHub <noreply@github.com> on 5/6/2026, 1:17:17 AM