Skip to content

v1.18.4

Choose a tag to compare

@KentQi KentQi released this 01 Nov 05:02
· 11 commits to main since this release
440147b

1.18.4 — 2026-10-29

Clears the remaining P2/P3 backlog (the triage in docs/04-test/18-triage-p2-p3-v1.18.4.md): the guard-policy holes, the runtime/protocol rough edges, prompt/playbook consistency, and the test/packaging debt. No behaviour change in the happy path; the changes below are the ones a caller can observe.

  • Guard policy (security-adjacent). git branch -u<ref> (and -u <ref>, --set-upstream) is refused — it writes .git/config from a read-only review (P2-11). In fix mode the two guard files (scripts/pre-tool-hook.js, src/shell-guard.js) can no longer be written, so reviewing this package can't disarm every later run (SEC-15). Review mode now refuses to Read secret material inside the repo (.env*, id_rsa*, *.pem/*.key, credentials, .ssh/.aws/.gnupg, .netrc, .pgpass; .env.example-style templates stay readable) (SEC-23). A Bash payload whose command is not a string is denied instead of allowed (SEC-24), and NotebookEdit now reads notebook_path so fix mode can actually edit notebooks (SEC-25).
  • Loopback detection normalises the forms URL.hostname actually produces: [::1], localhost., zone ids and IPv4-mapped IPv6 — the local-gateway Bearer token can no longer be routed through an HTTP proxy by spelling the host differently (SEC-09).
  • Transcript recovery works on macOS again: isAllowedTranscriptPath compares realpaths (with the nearest existing ancestor for missing tails), so the /var vs /private/var spelling no longer makes a 429-killed subagent's recovered report silently vanish (R-7).
  • Process lifecycle: SIGTERM/SIGINT/SIGHUP exit with 143/130/129 instead of 0, so a host can tell a signal from a clean shutdown (R-21); a client that closes stdin now triggers the same shutdown path as transport.close() (measured before: a running review kept billing after stdin closed); transport.onclose runs the SDK's own cleanup first (P-12).
  • Cache/TTL honesty: npm-root probe failures expire after 60 s (was permanent), and --version/--help caches carry a 5-minute TTL, so an in-place upgrade is picked up without restarting the host (R-8/R-9).
  • Robustness: parseResultJson parses pretty-printed results, parseUnrecognizedModels handles nested JSON, looksLikeLaunchAck no longer discards a real report that starts with the ack sentence, the 2-hour sweep flag is set only after a successful readdir, and the dead agentResults map (which pinned every tool_result in memory) is gone (R-11/R-14/R-15/R-16/R-19).
  • Async contract: the first response is bounded by a 20 s soft preflight budget (probes that time out degrade with a warning instead of hanging the call), resolveClaudeCliForCall waits for the settled CLI probe, cancel:true without a jobId is an error, job retention is a 10-entry / 32 MiB budget (an evicted result polls as isError + status:"evicted"), and every job-shaped structuredContent carries {jobId, status, repoPath} (P-03/P-05/P-06/P-11/P-14/P-20).
  • Tool metadata: the four tools carry title + annotations (readOnlyHint for env/status) and register through registerTool when the SDK provides it, with a fallback for older SDKs (P-13).
  • Validation tightened: focus must be a single line (tabs/newlines/CR refused), outputLanguage is ≤20 chars with no sentence punctuation, and a PR reference whose owner/repo starts with - is refused (P2-7/P3-1/P3-3).
  • Prompt/playbook: one report contract (already in 1.18.3) is now also the SKILL.md text; the fleet is described as "5 briefs + 3/5 split finders" (3+5=8, 5+5=10) instead of "verbatim"; scope=auto order is PR > branch > working-dir > last commit everywhere; CONFIRMED=85-100 / PLAUSIBLE=75-84 / REFUTED=0 is documented, so the >= 75 filter and "keep CONFIRMED and PLAUSIBLE" select the same set; a stale skill that cannot be refreshed now degrades to the bundled fleet pipeline instead of running the old one silently (P2-2/P2-3/P2-8/P2-9/P2-10/P2-12/P2-13).
  • Packaging: files is narrowed to the runtime set (tarball 30 files/789 KB → 15 files/551 KB) and a new scripts/pack-test.mjs (38 checks) asserts the tarball contents and boots the packed server; scripts/lib/mcp-client.mjs replaces the six hand-rolled stdio clients in the free suites; init.mjs writes its config atomically (temp + fsync + rename) and no longer half-writes on failure.
  • Suites: shell-guard 260, audit-fixes 300, p0-regression 126, validation 23, pack 38, cross-cases 150/150, smoke PASS — npm test green (7 suites).
  • Upgrade note: the policy tables changed, so a running MCP host now refuses to start a review until it is restarted (the stale-policy self-test). focus/outputLanguage inputs that used to pass may now be rejected.