Rebasing onto 853 commits of main surfaced two things the earlier branch
had hidden.
main already owns a guard for the issue-#7253 bug class
(`remote-hook-service-registry-coverage.test.ts`). This branch had added a
second, near-identical one — a parallel implementation of a test that
already existed, which is what AGENTS.md's reuse rule is about. Deleted
ours and registered jcode in main's, which is the one that has kept pace
with every agent added since.
Also fixes a missing separator in the mobile icon map. `pnpm tc` does not
cover `mobile/`, so only the session-route closure suite caught it.
Co-authored-by: czzczz <chanzrz_zbf@foxmail.com>
Three fixes, all on paths this PR could not exercise locally.
The managed hook command was stored as a bare path. jcode tokenizes that
string shell-style before exec'ing it directly (parse_hook_command,
crates/jcode-terminal-launch/src/lib.rs): unquoted whitespace splits, and
every unquoted backslash is consumed as an escape. So on Windows
`C:\Users\me\.orca\agent-hooks\jcode-hook.cmd` reached exec as
`C:Usersme.orcaagent-hooksjcode-hook.cmd` and no hook fired at all, and a
POSIX home with a space split into two arguments. Store the path
single-quoted (verbatim, backslashes included), falling back to double
quotes for a path containing a single quote. Existing bare entries are
already repointed by the stale-key path, and getStatus accepts both forms
so the repair is not reported as a user-owned hook. The quoting helper was
previously dead code that only tests called; the three production sites
now use it. isJcodeManagedCommand also normalizes separators, since a
`/`-only needle never matched a Windows entry.
Commit-message generation feeds a staged patch to `jcode run` as the
prompt — attacker-influenced text — while jcode's default profile exposes
shell, read, write, and MCP. Pass `--tool-profile none`, which resolves to
an empty allowed-tool set in jcode's config (base_allowed_tools), matching
the read-only posture claude (plan) and codex (read-only) already take.
docs/reference/jcode-hook-events.md was never actually in this PR: the
repo ignores docs/** and tracks reference docs by allow-list only, so the
captured-payload evidence four source comments point at was silently
dropped. Allow-list it.
Co-authored-by: czzczz <chanzrz_zbf@foxmail.com>
The jcode prompt reader ran a synchronous bounded file scan plus a JSON
parse on every hook event. jcode blocks on pre_tool, so a turn that ran
four tools charged the user eight scans of latency it did not need — the
prompt cannot change inside a turn.
- Cache the journal read per pane, refreshed on the turn boundary that
can change it. The cache holds the whole evidence record, since
hasExplicitUserPrompt needs the transcript-evidence flag and not just
the text, and it joins the existing pane-scoped lifecycle (close,
rename, reset) rather than living in a module singleton.
- Key a journal prompt by its absolute byte offset instead of its
region-local line index. The backward scan windows the file from EOF,
so appending shifted every boundary and reminted the key for a prompt
that never moved; a repeated turn_end then slipped past the same-hash
dedupe as a second done event with duplicate telemetry.
- Pin the platform in the daemon pre-warm tests. The pre-warm is a no-op
off POSIX, so the dedupe and retry cases would have passed vacuously
on a Windows runner.
Co-authored-by: czzczz <chanzrz_zbf@foxmail.com>
- Windows posted no payload at all: the shared builder reads `payload@-` from
stdin, which the gate has already drained and observer hooks never receive, so
every Windows event was dropped. Write the env var to a temp file and pipe it.
- The daemon pre-warm never fired for daemon-host spawns, which is the default
local path; it now runs there too, and from the final env so the daemon gets the
hook port and token.
- A failed runtime-dir mkdir took down every local terminal, jcode or not.
- removeJcodeManagedHooks matched the raw line, so a user hook whose comment
mentioned the managed script was deleted; matching on Windows never worked.
- A managed entry left by a copied home or a platform switch is now repointed
instead of being reported as user-owned forever.
- The OSC colour skip only checked launchAgent, so a command- or telemetry-named
jcode pane still leaked the reply into its composer.
- `['hooks']` and a commented scalar are recognised, instead of appending a
second [hooks] table that makes jcode reject the whole config.
- A failed tool's error is marked as tool output rather than agent prose.
- The vault keeps a session's stored name, counts its tokens, and skips
background_task and [Scheduled task] turns.
Co-authored-by: czzczz <chanzrz_zbf@foxmail.com>
The bound was machine-speed sensitive and flaked on CI shard 3/8 at 1525ms. The
structural assertions (detached gate branch, foreground observer branch) and the
no-hang stdin drain cover the same contract without a timer.
Co-authored-by: czzczz <chanzrz_zbf@foxmail.com>
The absolute 1s bound was the flake CI shard 3/8 hit: it is tight enough to catch
a synchronous gate on an idle laptop and too tight on a loaded runner. Measuring
the same POST both ways on the same machine makes the claim a ratio, which is what
the test is actually about. Mutation-checked: a synchronous gate reads 6120ms
against a 1517ms observer.
Co-authored-by: czzczz <chanzrz_zbf@foxmail.com>
CI's anti-slop audit rejects Reflect.get: parse dynamic input into a named type
instead. Adds Windows script-shape tests too, since Windows is the platform this
change could not be exercised on directly.
Co-authored-by: czzczz <chanzrz_zbf@foxmail.com>
The jcode journal reader, the Claude transcript reader and the Command Code
transcript reader each carried their own copy of the same reverse chunked line
scan; they now share one tested helper. jcode's managed hook script drops its
hand-rolled curl for buildPosixAgentHookPostCommand, which also gains it the
raw-JSON transport and the --noproxy guard the bespoke copy was missing.
Co-authored-by: czzczz <chanzrz_zbf@foxmail.com>
Ports PR #10521 onto current main: agent catalog, managed hook service,
agent-status listener, session resume, AI Vault parser, per-pane daemon
isolation, and Source Control AI support.
Co-authored-by: Neil <neil@stably.ai>