Skip to content

feat(runtimes): add ZCode as a first-class dispatchable runtime - #990

Open
star-nebula wants to merge 4 commits into
builderz-labs:mainfrom
star-nebula:feat/zcode-runtime
Open

star-nebula wants to merge 4 commits into
builderz-labs:mainfrom
star-nebula:feat/zcode-runtime

Conversation

@star-nebula

Copy link
Copy Markdown

Summary

Adds ZCode as a sixth first-class runtime, with session inventory, transcripts, and task dispatch at parity with the existing runtimes.

  • Runtime registration and capability maps in src/lib/agent-runtimes.ts, so ZCode shows up in dispatch, the sessions list, terminal view, and settings like the built-in runtimes.
  • Session inventory reads ZCode's own state DB (~/.zcode/cli/db/db.sqlite) strictly read-only, excluding child/side-agent rows and archived sessions, mirroring the other runtime scanners. Title, working dir, latest model, message counts, and token usage are surfaced per session.
  • Transcripts are read from the same DB (message + part tables).
  • Dispatch goes through ZCode's headless JSON mode (--json --resume <sessionId> -p ...).
  • Includes a fix to runCommand found by dispatching a real message through the UI: it prepended node to any command that happens to be a node binary (matched on spawnCommand === process.execPath), so the ZCode bundle launch died parsing its own PE header (MZ ... SyntaxError). Node is now prepended only when the command is a .mjs entry script.

Testing

  • New suites: agent-runtimes-zcode, task-dispatch-zcode-runtime, continue-route-zcode, session-transcript-zcode, zcode-sessions, zcode-agent-sessions; the DB fixture is shaped from a real db.sqlite (pragma-derived columns, not guessed).
  • Full test suite green; typecheck and eslint clean; the api-parity check passes with the unchanged route surface (263 routes / 254 in openapi / 12 ignored).
  • Mutation probes: reverting the runCommand fix or the scanner's title handling each turns the corresponding new tests red.
  • Verified live on Windows 11 / Node 22 against a real ZCode install: the dashboard lists real sessions with titles/models/usage, and a dispatched message round-trips through zcode.cjs --json --resume ....

Notes

  • The scanner only opens ZCode's DB read-only and never writes to ZCode state; transcript/audit material passed onward stays within the existing audit-detail bounds.

ZCode was invisible to Mission Control even though it is the operator's
day-to-day GLM agent: the outbound runtime layer enumerates runtimes
through Record<RuntimeId, ...> maps, so adding an id forces every
capability surface (detection, auth, dispatch, resume, transcripts,
onboarding, install) to actually exist rather than half-exist.

Sessions are captured rather than pre-claimed because ZCode mints its own
sess_<uuid> ids, so the first successful dispatch owns the thread and a
divergent later id cannot hijack it. The capability manifest reports
tool_policy, budget_cap, pty and skills_inventory as false: ZCode 0.16.9
ships a denylist, no budget flag and no attachable PTY, and a claimed-true
capability would let the scheduler decide on behavior that is not there.
An untyped vi.fn inferred a zero-length parameter tuple, so the assertions on
the env we hand the CLI read as possibly-undefined and tsc refused the file.
The check itself is what caught it: an incremental typecheck reuses the
committed tsbuildinfo and skips the file.
…te DB

The first scanner treated ~/.zcode/cli/rollout/model-io-sess_*.jsonl as the
session inventory, but those files are raw model request/response captures for
only some sessions, and the filename regex never matched the real
`model-io-` prefix. The local session list therefore reported zero ZCode
sessions on a machine with ~100 of them.

ZCode's own SQLite DB (~/.zcode/cli/db/db.sqlite) is the authoritative
inventory and transcript source, which is also what the hermes and opencode
scanners already do. Scan it read-only with schema-drift guards, keep the
rollout capture as a transcript fallback, and expose workingDir so the UI can
show it.

Tests now build the real five-table schema instead of guessed rollout files.
…itles

The chat continue path sent runCommand a launch whose bin is the node binary
itself; the .mjs heuristic matched on "command === process.execPath" instead of
the command's extension, so node was handed its own executable as the entry
script and died parsing the PE header ("MZ"). Match on the extension.

Local ZCode sessions also showed bare ids because the scanner never read the
session table's title column; select it (blank becomes null) and map it into
the sessions payload like the other local runtimes.
@star-nebula
star-nebula requested a review from 0xNyk as a code owner October 4, 2026 01:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant