feat(cli): M8 — headless one-shot mode (-p / --print)#19
Merged
Conversation
Removes the "Headless mode is wired in M8" stub and ships the real thing.
· apps/cli/src/headless.ts (NEW, ~270 lines)
- Mirrors the REPL bootstrap (settings + creds + tools + memory + skills +
output style + MCP + hooks + sandbox + autoCompact) but runs a SINGLE
conversation turn, no readline.
- Three output formats:
· text — plain deltas + tool markers (default)
· json — single final JSON object on stdout
· stream-json — NDJSON, one event per line
- Approval callback returns `false` in headless (no human to ask);
users wanting auto-yes pass --mode dontAsk or --mode bypassPermissions.
- SIGINT/SIGTERM hook → AbortController → exit code 5.
- 5 stable exit codes: 0 ok / 1 generic / 2 bad-input / 3 api-or-auth /
4 max-turns / 5 aborted.
· apps/cli/src/cli.ts — replaces the stub branch with a real runHeadless()
call.
· apps/cli/src/parse-args.ts help text — documents the exit codes and what
each output-format means.
· apps/cli/src/headless.test.ts (NEW) — 2 tests proving early-exit paths
(returns 3 on missing creds + same behavior under --output-format json).
Live end-to-end coverage is via docs/m1-validation.md (real API).
· docs/BEHAVIOR_PARITY.md — `-p` headless and --output-format move from
🔄 M8 to ✅ / 🟡 (json-schema + include-partial-messages still parsed only).
Tests: core unchanged (308 pass); cli 41 → 43 (+2 headless). Total 351.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
oratis
added a commit
that referenced
this pull request
May 28, 2026
This session ("继续推进" from v2) added 5 PRs on top of #1-#16:
· #17 M3c-rest tools (TodoWrite + WebFetch + WebSearch)
· #18 M3.5 attack tests + security-model.md
· #19 M8 headless mode (-p / --print)
· #20 M5.2 plugin live wire-up
· #21 system-reminder injector
Test count: 313 → 387 (+74).
Scope completion estimate: 65-70% → 72-78%.
Major remaining items: M6 Mac Electron (still 0%), M7 file panel (depends
on M6), and the M3c-rest/M8/M5.2 leftovers itemized in the body.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Removes the "Headless mode is wired in M8" stub at
apps/cli/src/cli.ts:42and ships the real thing.apps/cli/src/headless.ts(NEW) — full bootstrap (settings, creds, tools, memory, skills, output style, MCP, hooks, sandbox, autoCompact) but runs a SINGLE turn instead of a readline loop. Three output formats:falsein headless (no human to ask). Use--mode dontAskor--mode bypassPermissions(trust-gated) for auto-approval.AbortController→ exit code 5.--help): 0 ok / 1 generic / 2 bad-input / 3 api-or-auth / 4 max-turns / 5 aborted.cli.tsreplaces the stub branch with a realrunHeadless()call.Test plan
pnpm -F deepcode-cli test— 43 passing (was 41; +2 inheadless.test.ts)pnpm -F deepcode-cli build— cleanHOME=/tmp/empty node apps/cli/dist/cli.js -p "hi"→ prints "No DeepSeek credentials.", exits 3 ✅--output-format json→ same exit 3 ✅docs/BEHAVIOR_PARITY.mdupdated —-pmoves to ✅, output-format to 🟡 (full pieces still pending json-schema)Notes
DeepSeekProviderfrom the host process is awkward without dep injection. Live end-to-end is exercised viadocs/m1-validation.mdagainst the real API.🤖 Generated with Claude Code