@0xgeorgemathew/zcode 0.3.2 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +184 -138
- package/bin/zcode.js +181 -140
- package/lib/appserver.js +190 -135
- package/lib/bootstrap.js +39 -60
- package/lib/checks.js +103 -0
- package/lib/commands/doctor.js +43 -64
- package/lib/commands/exec.js +327 -0
- package/lib/commands/login.js +2 -9
- package/lib/commands/mcp-list.js +6 -14
- package/lib/commands/sessions.js +181 -0
- package/lib/contract.js +301 -0
- package/lib/executor.js +617 -0
- package/lib/install-skills.js +54 -0
- package/lib/isolation.js +233 -223
- package/lib/key.js +1 -10
- package/lib/store.js +276 -0
- package/lib/ui.js +200 -71
- package/lib/workspace.js +336 -0
- package/package.json +22 -7
- package/skills/README.md +34 -0
- package/skills/claude-code/zcode/SKILL.md +112 -0
- package/skills/codex/zcode/SKILL.md +114 -0
- package/skills/codex/zcode/agents/openai.yaml +4 -0
- package/lib/commands/agent.js +0 -203
- package/lib/commands/run.js +0 -126
- package/lib/overlay.js +0 -138
package/README.md
CHANGED
|
@@ -1,225 +1,268 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/0xgeorgemathew/zcode/main/docs/assets/hero.svg" alt="A zcode work order: the contract on the left, the handback with changed files, a passing check and a COMPLETED stamp on the right" width="960">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@0xgeorgemathew/zcode"><img src="https://img.shields.io/npm/v/@0xgeorgemathew/zcode.svg?color=1C3F95&label=npm" alt="npm version"></a>
|
|
7
|
+
<img src="https://img.shields.io/badge/node-%E2%89%A520-1C3F95" alt="node 20 or later">
|
|
8
|
+
<img src="https://img.shields.io/badge/dependencies-0-1C3F95" alt="zero dependencies">
|
|
9
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-1C3F95" alt="MIT license"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
zcode is a command-line executor for orchestrator agents. Claude Code, Codex, or any agent with a shell hands it a task contract. zcode implements the task with GLM-5.3-Flash, runs your checks itself, and returns a handback that lists the changed files, the check results, and anything it could not verify.
|
|
13
|
+
|
|
14
|
+
The orchestrator keeps product decisions, design direction, and coordination. zcode works only inside the scope it is given.
|
|
15
|
+
|
|
16
|
+
<table>
|
|
17
|
+
<tr><td><b>Contract in</b></td><td>Objective, scope, constraints, binding design decisions, acceptance criteria, owned paths and checks. Only the objective is required.</td></tr>
|
|
18
|
+
<tr><td><b>Checks run by zcode</b></td><td>zcode runs each <code>--check</code> after the work. A failing check sends its output back to the model for up to 2 repair turns.</td></tr>
|
|
19
|
+
<tr><td><b>Status from evidence</b></td><td><code>completed</code> requires passing checks and no edits outside <code>--owns</code>. The model's own report is kept as a claim.</td></tr>
|
|
20
|
+
<tr><td><b>Sessions</b></td><td>Stable ids, <code>--detach</code>, <code>status</code>, <code>wait</code>, <code>resume</code>, <code>cancel</code>. A session whose process died shows as interrupted and can be resumed.</td></tr>
|
|
21
|
+
<tr><td><b>Parallel work</b></td><td>Two sessions with overlapping <code>--owns</code> in one repo are refused with exit 7.</td></tr>
|
|
22
|
+
<tr><td><b>Output</b></td><td>One <code>zcode.result/1</code> JSON line with <code>--json</code>. No colour codes when stdout is not a terminal.</td></tr>
|
|
23
|
+
</table>
|
|
18
24
|
|
|
19
25
|
|
|
20
26
|
|
|
21
|
-
##
|
|
27
|
+
## Quick start
|
|
22
28
|
|
|
23
29
|
```sh
|
|
24
30
|
npm install -g @0xgeorgemathew/zcode
|
|
31
|
+
echo "$ZAI_API_KEY" | zcode login # stores your Z.AI key with mode 600; zcode never prints it
|
|
32
|
+
zcode doctor # checks the engine, isolation and key
|
|
33
|
+
|
|
34
|
+
zcode task --check "npm test" "Fix the off-by-one in src/paginate.ts"
|
|
25
35
|
```
|
|
26
36
|
|
|
27
|
-
|
|
37
|
+
The CLI needs node 20 or later. The engine child runs best on node 26. zcode also needs the ZCode engine, which today ships inside the ZCode desktop app; zcode finds it automatically.
|
|
38
|
+
|
|
39
|
+
Installing the package also installs the Claude Code skill to `~/.claude/skills/zcode` and the Codex skill to `${CODEX_HOME:-~/.codex}/skills/zcode`. These skills teach the orchestrator how to delegate to zcode. Set `ZCODE_SKIP_SKILLS=1` to skip this step. Details are in [`skills/`](skills/README.md).
|
|
28
40
|
|
|
29
41
|
|
|
30
42
|
|
|
31
|
-
##
|
|
43
|
+
## Models and effort
|
|
32
44
|
|
|
33
|
-
|
|
34
|
-
echo "$ZAI_API_KEY" | zcode login # store your Z.AI key (mode 600, never printed)
|
|
35
|
-
zcode doctor # check engine, isolation, key
|
|
36
|
-
zcode "Explain this repo in two sentences"
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
Every command runs on GLM-5.3-Flash at effort `max` unless you pass a flag.
|
|
40
46
|
|
|
41
|
-
|
|
47
|
+
| setting | flag | values | default |
|
|
48
|
+
|---|---|---|---|
|
|
49
|
+
| model | `--model` | `glm-5.3-flash` (aliases `flash`, `5.3-flash`, `53f`), `glm-5.3` (aliases `5.3`, `53`) | `glm-5.3-flash` |
|
|
50
|
+
| effort | `--effort` | `low`, `medium`, `high`, `xhigh`, `max` | `max` |
|
|
42
51
|
|
|
43
52
|
```sh
|
|
44
|
-
zcode
|
|
45
|
-
zcode --
|
|
46
|
-
zcode --
|
|
47
|
-
|
|
53
|
+
zcode task "..." # GLM-5.3-Flash, effort max
|
|
54
|
+
zcode task --effort high "..." # Flash with less reasoning
|
|
55
|
+
zcode task --model glm-5.3 "..." # GLM-5.3, effort max
|
|
56
|
+
zcode task --model glm-5.3 --effort medium "..." # GLM-5.3, effort medium
|
|
48
57
|
```
|
|
49
58
|
|
|
50
|
-
|
|
59
|
+
A task contract can set `"model"` and `"effort"`. Flags override the contract. A resumed session keeps its original model and effort unless you pass the flags again.
|
|
51
60
|
|
|
52
61
|
|
|
53
62
|
|
|
54
|
-
##
|
|
63
|
+
## Hand off a task
|
|
55
64
|
|
|
56
|
-
|
|
65
|
+
```sh
|
|
66
|
+
zcode task --cwd ./site --id page-1 \
|
|
67
|
+
--owns src/pages/pricing/ \
|
|
68
|
+
--check "npm run build" --check "npm test -- pricing" \
|
|
69
|
+
--accept "Three plan cards, the middle one highlighted" \
|
|
70
|
+
--context @design/pricing.md \
|
|
71
|
+
"Implement the pricing page from the supplied design notes"
|
|
72
|
+
```
|
|
57
73
|
|
|
58
|
-
|
|
59
|
-
- **stderr** is the live feed, all dimmed so it visually recedes: thinking as `│ ` quote lines, tool calls as `→ started` / `✓ ok` / `✗ error`, then one status line with model, effort, tool count, duration, and the session id.
|
|
74
|
+
zcode turns this into an execution contract and runs a fresh engine session in yolo mode, with `--cwd` as the blast radius. The model may split the work across subagents. When it finishes, **zcode runs the checks itself**. If a check fails, zcode feeds the failure output back for a bounded number of repair turns (`--max-repairs`, default 2), then reports:
|
|
60
75
|
|
|
61
76
|
```text
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
77
|
+
✓ completed page-1 142.3s
|
|
78
|
+
Pricing page with three plan cards; middle card highlighted per design notes.
|
|
79
|
+
changed 3 files
|
|
80
|
+
A src/pages/pricing/index.tsx
|
|
81
|
+
A src/pages/pricing/PlanCard.tsx
|
|
82
|
+
M src/pages/pricing/styles.css
|
|
83
|
+
checks 2/2 passed · 1 repair turn
|
|
84
|
+
✓ npm run build
|
|
85
|
+
✓ npm test -- pricing
|
|
86
|
+
not verified
|
|
87
|
+
- prose acceptance criteria are confirmed only by the executor's own report
|
|
68
88
|
```
|
|
69
89
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
90
|
+
That block is the format of the summary printed to stdout. The live feed (session header, phases, tools, subagents, check results) goes to stderr. With `--json` you get the same data as one machine-readable result line.
|
|
73
91
|
|
|
74
|
-
|
|
92
|
+
For small work, the objective alone is enough: `zcode task "Fix the typo in the README heading"`.
|
|
75
93
|
|
|
76
|
-
|
|
94
|
+
### The contract
|
|
77
95
|
|
|
78
|
-
|
|
79
|
-
SID=$(zcode --json "Remember the secret word BANANA. Reply with exactly: OK" | tail -1 | jq -r .sessionId)
|
|
96
|
+
Flags cover the common fields. For richer handoffs, pass `--task contract.json`, `--task brief.md`, or `--task -` to read stdin. Only `objective` is required; unknown keys are rejected so a typo never silently drops a requirement.
|
|
80
97
|
|
|
81
|
-
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"objective": "Implement page 2 (Team) per the design spec",
|
|
101
|
+
"scope": ["Team page route and its components"],
|
|
102
|
+
"constraints": ["No new dependencies", "Keep existing routing untouched"],
|
|
103
|
+
"design": ["Grid of 3 columns ≥1024px, 1 column below", "Use tokens from src/theme.ts only"],
|
|
104
|
+
"acceptance": ["Every member card shows name, role, avatar"],
|
|
105
|
+
"checks": ["npm run build", "npm test -- team"],
|
|
106
|
+
"files": ["src/theme.ts", "src/pages/home/index.tsx"],
|
|
107
|
+
"references": ["design/team.png described in design/team.md"],
|
|
108
|
+
"context": ["Copy lives in content/team.json"],
|
|
109
|
+
"owns": ["src/pages/team/**", "content/team.json"],
|
|
110
|
+
"limits": { "timeoutMs": 1800000, "maxRepairs": 2, "checkTimeoutMs": 300000 },
|
|
111
|
+
"model": "glm-5.3",
|
|
112
|
+
"effort": "high"
|
|
113
|
+
}
|
|
82
114
|
```
|
|
83
115
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
116
|
+
`design` entries are presented to the model as binding decisions it must implement, not revisit. If the model hits a consequential product or design question the contract does not answer, it reports `blocked` with its questions instead of guessing.
|
|
87
117
|
|
|
88
|
-
|
|
118
|
+
### Status: what a result means
|
|
89
119
|
|
|
90
|
-
|
|
120
|
+
| status | meaning | exit |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| `completed` | zcode's own checks ran and passed, the executor reports done, no unmet criteria, nothing changed outside `--owns` | 0 |
|
|
123
|
+
| `unverified` | executor reports done, but no checks were declared (or no usable handback), so completion is self-reported | 9 |
|
|
124
|
+
| `partial` | work remains: executor says partial, a criterion is unmet, or files changed outside the owned scope | 8 |
|
|
125
|
+
| `blocked` | needs the orchestrator: `questions` lists what is missing | 10 |
|
|
126
|
+
| `failed` | checks still failing after the repair budget (`error.kind: checks_failed`, exit 8), engine/turn error (5), or timeout (124) | 5 / 8 / 124 |
|
|
127
|
+
| `cancelled` | stopped by `zcode cancel`, Ctrl-C, or SIGTERM | 130 |
|
|
91
128
|
|
|
92
|
-
|
|
93
|
-
WORK=$(mktemp -d)
|
|
94
|
-
zcode agent --cwd "$WORK" \
|
|
95
|
-
"Use the Agent tool to create hello.txt containing exactly HELLO-SUBAGENT, then report the agent id."
|
|
96
|
-
cat "$WORK/hello.txt" # HELLO-SUBAGENT
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
Use `--cwd` to declare where the subagent may work. `--profile` picks the subagent profile (default `general-purpose`; your own `~/.zcode/agents/*.md` profiles resolve too). With `--json`, the final line carries the engine-reported evidence:
|
|
100
|
-
|
|
101
|
-
```json
|
|
102
|
-
"subagents": [{
|
|
103
|
-
"agentId": "agent_8f5144b0-…",
|
|
104
|
-
"childSessionId": "sess_subagent_agent_8f5144b0-…",
|
|
105
|
-
"profileId": "general-purpose",
|
|
106
|
-
"status": "success",
|
|
107
|
-
"summary": "…the subagent's own report…",
|
|
108
|
-
"durationMs": 59765
|
|
109
|
-
}]
|
|
110
|
-
```
|
|
129
|
+
A model claiming success is never enough on its own. A subagent ending `success` only means it returned. The handback block the model writes is reported as `handback` (a claim), and the status is derived from what zcode observed. `notVerified` lists anything zcode could not check itself.
|
|
111
130
|
|
|
112
131
|
|
|
113
132
|
|
|
114
|
-
##
|
|
133
|
+
## Sessions
|
|
115
134
|
|
|
116
|
-
|
|
135
|
+
Every invocation gets a session: `--id page-1`, or a generated `zc-xxxxxxxx`. Each session has its own engine HOME (`~/.zcode-cli/sessions/<id>/home`), so conversation state, engine database, MCP servers, and skills never leak between sessions. An existing id is never re-run, so retrying a start you lost track of fails fast instead of doing the work twice. Use `status` to check on it, or `resume` to continue it.
|
|
117
136
|
|
|
118
137
|
```sh
|
|
119
|
-
zcode --
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
zcode --
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
zcode
|
|
126
|
-
zcode --mcp-inherit … # also load the desktop's enabled servers
|
|
138
|
+
zcode task --detach --id page-1 --owns src/pages/home/ --check "npm run build" "Build page 1"
|
|
139
|
+
zcode task --detach --id page-2 --owns src/pages/team/ --check "npm run build" "Build page 2"
|
|
140
|
+
zcode status # all sessions: id, state/status, kind, updated, label
|
|
141
|
+
zcode status page-1 --json # one session: state, phase, activity, recent events, result
|
|
142
|
+
zcode wait page-1 page-2 # block until both finish; print each handback
|
|
143
|
+
zcode resume page-2 "Use the 2-column variant below 1024px." # answer / follow up / retry
|
|
144
|
+
zcode cancel page-1 # stop the turn and any running check; recorded as cancelled
|
|
127
145
|
```
|
|
128
146
|
|
|
129
|
-
|
|
147
|
+
- **Lifecycle.** A session is `queued`, then `running`, then `finished` with a status. If the process that owned a running session dies, the session shows as `interrupted`, which can be resumed.
|
|
148
|
+
- **Resume** sends your message into the same engine conversation. For task sessions, the model is told that earlier work is already applied to the workspace, and zcode re-runs the checks and repairs and produces a fresh handback. A resume with no message (task sessions) means "continue from where you stopped".
|
|
149
|
+
- **Never automatically re-sent.** zcode retries only engine start-up, which happens before anything reaches the model. A prompt that was delivered is never re-sent automatically. Continuing is always an explicit `resume`.
|
|
150
|
+
- **Detached sessions** write their NDJSON to `~/.zcode-cli/sessions/<id>/stdout.ndjson` and diagnostics to `stderr.log`. The handback lands in `result.json`. You never need to read these files: `status` and `wait` print everything.
|
|
130
151
|
|
|
131
|
-
|
|
152
|
+
### Concurrency and ownership
|
|
132
153
|
|
|
133
|
-
|
|
154
|
+
`--owns` declares what a session may change: a path owns its subtree, and globs are supported. Patterns are relative to `--cwd`. A session without `--owns` owns the whole workspace, which is right for a one-off task in its own checkout.
|
|
134
155
|
|
|
135
|
-
|
|
156
|
+
- Starting a session whose ownership **overlaps a running session in the same workspace** is refused with exit 7, unless `--allow-overlap` is passed. The workspace is the git toplevel, so sibling directories of one repo count as one workspace. Disjoint owners (`src/pages/home/` vs `src/pages/team/`) run side by side.
|
|
157
|
+
- After the work, zcode diffs the workspace and reports each changed file. Changes outside the session's ownership are listed in `scopeViolations`, and for task sessions they make the result `partial`. Files that fall in a concurrent session's ownership are attributed to that session, not counted against this one.
|
|
158
|
+
- For overlapping or risky parallel work, give each session its own git worktree via `--cwd`.
|
|
159
|
+
- `ZAI_CODE_MAX_ACTIVE` (default 8) is a soft machine-wide cap. Sessions beyond it wait in `queued`.
|
|
160
|
+
|
|
161
|
+
|
|
136
162
|
|
|
137
|
-
-
|
|
163
|
+
## One-shot turns and subagent dispatch
|
|
138
164
|
|
|
139
|
-
|
|
165
|
+
`zcode` with a prompt (or `zcode run`) is a plain turn. The answer streams to stdout, and thinking is mirrored to stderr as `│ ` lines.
|
|
140
166
|
|
|
141
167
|
```sh
|
|
142
|
-
zcode
|
|
168
|
+
zcode "What is 17*23? Reply with only the number."
|
|
169
|
+
zcode --model glm-5.3 --effort high "Draft a commit message for the staged diff"
|
|
170
|
+
echo "$PROMPT" | zcode
|
|
143
171
|
```
|
|
144
172
|
|
|
145
|
-
|
|
173
|
+
`zcode agent "<instructions>"` forces a dispatch through the engine's Agent tool. It is verified from `session/subagents`: exit 6 if no subagent ran or any ended in a status other than `success`. `--profile` picks the subagent profile (default `general-purpose`).
|
|
174
|
+
|
|
175
|
+
Inside `zcode task`, subagents are optional. The executor decides when to use them, gives each a bounded scope and file ownership, and must verify the integrated result.
|
|
146
176
|
|
|
147
177
|
|
|
148
178
|
|
|
149
179
|
## Machine interface
|
|
150
180
|
|
|
151
|
-
`--json
|
|
181
|
+
`--json`: stdout carries NDJSON events, then exactly one final `{"type":"result",…}` line. With `--quiet`, the result line is the only output. For task sessions, text/reasoning deltas are left out of the events unless you pass `--stream`, so an orchestrator reading the output pays only for lifecycle events.
|
|
152
182
|
|
|
153
183
|
```json
|
|
154
|
-
{"type":"result","ok":true,"
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
"
|
|
159
|
-
"durationMs":
|
|
184
|
+
{"type":"result","schema":"zcode.result/1","ok":true,"status":"completed","id":"page-1","kind":"task",
|
|
185
|
+
"summary":"…","response":"…executor report…","issues":[],"questions":[],"unresolved":[],"notVerified":[],
|
|
186
|
+
"changes":{"tracking":"git","files":[{"path":"src/pages/home/index.tsx","change":"added","owned":true}]},
|
|
187
|
+
"scopeViolations":[],"checks":[{"command":"npm run build","ok":true,"exitCode":0,"timedOut":false,"durationMs":8123,"output":"…tail…"}],
|
|
188
|
+
"checksPassed":true,"repairs":0,"handback":{"status":"done","summary":"…","changes":[],"checks":[],"criteria":[],"unresolved":[],"questions":[],"notes":""},
|
|
189
|
+
"subagents":[{"agentId":"agent_…","profileId":"general-purpose","status":"success","summary":"…","durationMs":59765}],
|
|
190
|
+
"error":null,"cwd":"/abs/site","workspaceRoot":"/abs/site","owns":["src/pages/home/"],"sessionId":"sess_…","resumed":false,"turns":1,
|
|
191
|
+
"model":"GLM-5.3-Flash","effort":"max","mode":"yolo","usage":{"inputTokens":19608,"outputTokens":3120},
|
|
192
|
+
"toolCalls":14,"durationMs":142301,"files":{"session":"…/sessions/page-1","result":"…/result.json","events":"…/events.ndjson"}}
|
|
160
193
|
```
|
|
161
194
|
|
|
162
|
-
`model` and `effort` are engine-reported
|
|
163
|
-
|
|
164
|
-
Event types on the way in:
|
|
195
|
+
`model` and `effort` are engine-reported (from the engine's `model_request_started` event), not echoes. `sessionId` is the engine's session id; `id` is the zcode session id you pass to `status`, `wait`, `resume`, and `cancel`. A run that fails still ends with a parseable result line.
|
|
165
196
|
|
|
166
197
|
| event | meaning |
|
|
167
198
|
|---|---|
|
|
168
|
-
| `{"type":"
|
|
169
|
-
| `{"type":"
|
|
170
|
-
| `{"type":"tool","name":"
|
|
171
|
-
| `{"type":"
|
|
172
|
-
| `{"type":"
|
|
173
|
-
| `{"type":"
|
|
199
|
+
| `{"type":"session","id","kind","cwd","owns","checks","model","effort","resumed"}` | which session is active, and its scope |
|
|
200
|
+
| `{"type":"phase","phase":"starting\|executing\|reporting\|checking\|repairing\|queued"}` | what is running |
|
|
201
|
+
| `{"type":"tool","name":"Edit","phase":"started"}` | tool lifecycle (`scheduled`, `started`, `result`, `error`) |
|
|
202
|
+
| `{"type":"subagent","phase":"started\|returned\|error"}` | subagent activity |
|
|
203
|
+
| `{"type":"check","phase":"finished","command","ok","exitCode","durationMs"}` | zcode-run verification |
|
|
204
|
+
| `{"type":"mcp","name","status"}` · `{"type":"retry",…}` · `{"type":"model_request_started",…}` | MCP settling, start-up retry, engine model evidence |
|
|
205
|
+
| `{"type":"stream","kind":"text_delta\|reasoning_delta","delta"}` | live text (run/agent; task with `--stream`) |
|
|
206
|
+
|
|
207
|
+
`zcode status <id> --json` returns `{"type":"status", state, status, phase, pid, live, activity, recent:[…], result?}`. `zcode wait --json` prints one result line per session as each finishes.
|
|
174
208
|
|
|
175
209
|
|
|
176
210
|
|
|
177
211
|
## Options
|
|
178
212
|
|
|
179
|
-
| option |
|
|
213
|
+
| option | applies to | default | notes |
|
|
180
214
|
|---|---|---|---|
|
|
181
|
-
| `--
|
|
182
|
-
| `--
|
|
183
|
-
| `--cwd` |
|
|
184
|
-
| `--
|
|
185
|
-
| `--
|
|
186
|
-
| `--
|
|
187
|
-
| `--
|
|
188
|
-
| `--
|
|
189
|
-
| `--
|
|
190
|
-
| `--
|
|
191
|
-
| `--
|
|
192
|
-
| `--
|
|
193
|
-
| `--
|
|
194
|
-
| `--
|
|
195
|
-
| `--
|
|
196
|
-
|
|
|
215
|
+
| `--id`, `--label` | run, task, agent | `zc-<random>` | session identity |
|
|
216
|
+
| `--detach` | run, task, agent, resume | off | background worker; prints the id |
|
|
217
|
+
| `--cwd` | run, task, agent | current dir | the workspace and blast radius |
|
|
218
|
+
| `--owns` | run, task, agent | whole workspace | repeatable path or glob |
|
|
219
|
+
| `--allow-overlap` | run, task, agent | off | start despite overlapping ownership |
|
|
220
|
+
| `--task` | task | | JSON contract, markdown brief, or `-` |
|
|
221
|
+
| `--accept`, `--check`, `--file`, `--context` | task | | repeatable; `--context @file` reads a file |
|
|
222
|
+
| `--max-repairs` | task, resume | `2` | repair turns after failing checks |
|
|
223
|
+
| `--check-timeout-ms` | task, resume | `300000` | per check; checks get `CI=1` when unset |
|
|
224
|
+
| `--model` | all turns | `glm-5.3-flash` | `glm-5.3` plus aliases `5.3`, `53`, `flash`, `5.3-flash`, `53f` |
|
|
225
|
+
| `--effort` | all turns | `max` | `low`, `medium`, `high`, `xhigh`, `max` |
|
|
226
|
+
| `--timeout-ms` | all turns; wait | run 600000, task 1800000 | the whole invocation incl. checks and repairs |
|
|
227
|
+
| `--session` | run | | 0.3 compat: continue by zcode id or engine `sess_` id |
|
|
228
|
+
| `--profile` | agent | `general-purpose` | subagent profile |
|
|
229
|
+
| `--mcp` / `--mcp-inherit` / `--mcp-list` | run, task, agent | hermetic | MCP servers (inline JSON or `@file`) |
|
|
230
|
+
| `--skills` / `--no-skills` | run, task, agent | desktop skills | add skills; or run with none |
|
|
231
|
+
| `--json`, `--quiet` | all | | see Machine interface |
|
|
232
|
+
| `--thinking` / `--no-thinking` | turns | run on, task off | mirror reasoning to stderr |
|
|
233
|
+
| `--stream`, `--include-reasoning` | turns | off | deltas in task events; full reasoning in the result |
|
|
234
|
+
|
|
235
|
+
Only `glm-5.3` and `glm-5.3-flash` are accepted; anything else exits 2 before any spawn. Effort levels `low`, `high`, and `max` have been observed live on Flash. `medium` and `xhigh` may be rejected server-side.
|
|
197
236
|
|
|
198
237
|
## Exit codes
|
|
199
238
|
|
|
200
239
|
| code | meaning |
|
|
201
240
|
|---|---|
|
|
202
|
-
| 0 |
|
|
241
|
+
| 0 | completed |
|
|
203
242
|
| 1 | unexpected internal error |
|
|
204
|
-
| 2 | usage error,
|
|
243
|
+
| 2 | usage error (bad flag, model, effort, contract, unknown or duplicate session id) |
|
|
205
244
|
| 3 | no API key (`zcode login` or `ZAI_API_KEY`) |
|
|
206
245
|
| 4 | engine or builtin provider config not found |
|
|
207
|
-
| 5 |
|
|
246
|
+
| 5 | failed: engine or turn error |
|
|
208
247
|
| 6 | `agent`: no subagent dispatched or none ended `success` |
|
|
248
|
+
| 7 | workspace conflict, or the session is already running |
|
|
249
|
+
| 8 | partial, or checks still failing after repairs |
|
|
250
|
+
| 9 | unverified |
|
|
251
|
+
| 10 | blocked |
|
|
209
252
|
| 124 | `--timeout-ms` exceeded |
|
|
210
|
-
| 130 |
|
|
253
|
+
| 130 | cancelled |
|
|
211
254
|
|
|
212
255
|
|
|
213
256
|
|
|
214
257
|
## Under the hood
|
|
215
258
|
|
|
216
|
-
**Key handling.** `ZAI_API_KEY` env var, or `zcode login
|
|
259
|
+
**Key handling.** The key comes from the `ZAI_API_KEY` env var, or from `zcode login`, which stores it at `~/.zcode-cli/credentials.json` (mode 600). It is never printed or logged. Engine messages and check output are scrubbed before they are stored or shown. The only files the key ever lands in are each session's scratch provider config, which the engine requires to register the provider.
|
|
217
260
|
|
|
218
|
-
**Isolation.** This package's
|
|
261
|
+
**Isolation.** This package's state lives under `~/.zcode-cli`, never under `~/.zcode`, which belongs to the desktop app. Each session's engine runs with `HOME` pointed at its own scratch directory. On every invocation zcode rewrites the scratch config from your live desktop config: provider rule with your key, agent profiles, skills, MCP servers. It never touches the engine's database there, so sessions stay resumable. The desktop's OAuth `credentials.json` is never copied, and the live `~/.zcode` is never written. The engine's ~30 MB plugin cache is shared between sessions through a symlink.
|
|
219
262
|
|
|
220
|
-
**Yolo mode.**
|
|
263
|
+
**Yolo mode.** Tool side effects are auto-approved, matching the engine's own headless default; `--cwd` is the blast radius. If a headless turn requests interactive input, the result is reported as `blocked` instead of hanging. The executor contract forbids commits, pushes, deploys, and other external side effects unless the task explicitly asks for them.
|
|
221
264
|
|
|
222
|
-
**
|
|
265
|
+
**Environment.** `ZAI_CODE_HOME` (state root), `ZAI_CODE_ENGINE` (engine bundle), `ZAI_CODE_NODE` (engine interpreter), `ZAI_CODE_BUILTIN_PROVIDER_CONFIG`, `ZAI_CODE_LIVE_DIR` (desktop config dir, default `~/.zcode`), `ZAI_CODE_MAX_ACTIVE`, `NO_COLOR`.
|
|
223
266
|
|
|
224
267
|
|
|
225
268
|
|
|
@@ -228,12 +271,15 @@ Event types on the way in:
|
|
|
228
271
|
Zero dependencies, plain CommonJS, no build step.
|
|
229
272
|
|
|
230
273
|
```sh
|
|
231
|
-
npm test #
|
|
232
|
-
npm run
|
|
274
|
+
npm test # unit suite: in-process, scripted fake engine, no CLI spawn, no API calls
|
|
275
|
+
npm run test:live # functional suite: spawns the CLI against the real engine and GLM API
|
|
276
|
+
npm run accept:flash # black-box acceptance runs (real API)
|
|
233
277
|
npm run accept:subagent
|
|
234
278
|
npm run accept:53
|
|
235
279
|
```
|
|
236
280
|
|
|
237
|
-
|
|
281
|
+
Live tests load the key from the repo `.env`, which is never committed or shipped. The design record and the wire-protocol facts pinned live are in `DESIGN.md` (§17 covers the 0.4 executor redesign) and `docs/BUILD-REPORT.md`.
|
|
282
|
+
|
|
283
|
+
## License
|
|
238
284
|
|
|
239
|
-
MIT
|
|
285
|
+
MIT. Source and issues: [github.com/0xgeorgemathew/zcode](https://github.com/0xgeorgemathew/zcode).
|