Skip to content

zcode-cli 3.8.1-23

Choose a tag to compare

@xhqing xhqing released this 04 Sep 06:38
· 25 commits to main since this release

Enable workspace-hook trust system in the TUI session factory

  • TUI session factory now enables the workspace-hook trust system: bootstrap passes workspaceHookTrustEnabled: true (TODO T1 completed) (scripts/sync-runtime.ts, scripts/check-runtime.ts, vendor/zcode.cjs, test/sync-runtime.test.ts, TODO.md, new TODO-archive.md).

    • Why: the runtime already ships a complete project-level trust system for workspace hooks (pending_trust -> trusted_persistent state machine, declaration sha256 + bundle digest binding, persistent trust store at ~/.zcode/security/workspace-hook-trust-v1.json, and the zcode hooks trust status/grant/revoke command family); the headless protocol path (--prompt) already sets workspaceHookTrustEnabled:!0; only zcode-cli's TUI session factory never passed it, so the runtime side was permanently false and project-level hooks were disabled as a whole (a CLI grant had no effect, and every session logged workspace_hook.feature_disabled). The consequence was that DayTradingAgent had to fall back to two security hooks under the user-level ~/.zcode/cli/config.json, and on 2026-09-04 that path was measured to be overwritten wholesale by a stale snapshot when the client saves settings -- the project-level single source is the stable state.
    • What changed: (1) sync-runtime.ts gains patchRuntimeWorkspaceHookTrust(runtime) -- it anchors on the unique anchor of the TUI session factory (...,onWorkflowEvent:b.onWorkflowEvent})) and injects ,workspaceHookTrustEnabled:!0; idempotent (returns the input unchanged when already patched) and throws with incompatible when the anchor is missing; wired into the installTuiBridge patch chain (between patchRuntimeHttpNoContent and patchRuntimeAgentAutoBackground). (2) The idempotent check chain in check-runtime.ts gained the matching line. (3) The patch was actually written into vendor/zcode.cjs (net +29 bytes, at offset ~12365683) and node --check passes. (4) New cases in test/sync-runtime.test.ts (injection assertion, idempotence, incompatible throw; the fixture cannot be executed with new Function, so these are pure string assertions).
    • End-to-end verification (tmp/smoke-hook-trust.ts, reproducible, gitignored): temporary HOME plus a project-level SessionStart hook through the whole flow -- before granting, a new session log contains no workspace_hook.feature_disabled (patch effective), config load logs config.project_hooks.pending_trust, and the hook is blocked by the trust gate (no marker file); after zcode hooks trust grant (CLI path, status becomes workspace_hooks_trusted_persistent) the hook actually runs in a new session (marker file appears) and the log still contains no feature_disabled. Two findings worth keeping: SessionStart hooks run on the first turn (the first user input triggers runSessionStartHooks("startup")), not at TUI startup, so a self-test must send a message; on macOS the /tmp -> /private/tmp symlink makes the workspaceIdentity recorded by the CLI differ from the one the TUI session resolves from cwd (the grant never reaches the session), so smoke sandboxes must live on a symlink-free path (under the project's tmp/). Real workspace paths are stable and unaffected.
    • Verification: bun test test/sync-runtime.test.ts 26 pass; full bun test 617 pass / 0 fail across 77 files; bun run check passes (zcode-cli 3.8.1-23 / zcode-runtime 0.16.3). Follow-up on the DayTradingAgent side (its TODO T140 2 and 3): rerun the credential probe in a new ZCode session (should still be blocked, now by the project-level hook), then withdraw the two user-level hooks and switch back to the project-level single source.
    • Follow-up closure: T1 is archived into the newly created TODO-archive.md; the same-origin risk (the client saving settings rewrites config.json wholesale from an in-memory stale snapshot, wiping external edits to the hooks section) is filed as TODO T2 (orange urgency).
  • Added the project-root TODO.md and registered T1 (session bootstrap should pass workspaceHookTrustEnabled: true) (new TODO.md).

    • Why: verification on the DayTradingAgent side (2026-09-03~04) found that zcode-cli never passes this parameter when constructing a session, so the project-level workspace hooks trust system already built into the runtime was disabled by the host capability switch (the CLI grant was in place and the trust store persisted -- only this switch was missing). Per the cross-project split, this work item was transferred from DayTradingAgent TODO T140 (1) and registered here.
    • What changed: created TODO.md (a four-level urgency section framework plus a numbered timestamp convention) and registered T1 (orange) -- task description, three vendor/zcode.cjs offset references (construction site ~11703354, bootstrap consumer ~11762913, !0 sample ~11922028), post-completion verification criteria (rerun the credential probe in a new DayTradingAgent session, no feature_disabled in the log, then withdraw the user-level fallback and switch to the project-level single source), and a note on the same-origin risk (measured on 2026-09-04: the client saving settings rewrites config.json wholesale from a stale snapshot, wiping external edits to the hooks section -- whether to file it separately was left undecided). This project had no TODO-archive.md yet (first item, nothing to archive); it was created along with the first archive.

Install

npm install -g https://github.com/xhqing/zcode-cli/releases/download/v3.8.1-23/zcode-cli-3.8.1-23.tgz