@0xgeorgemathew/zcode 0.3.1 → 0.4.0
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 +179 -130
- 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/isolation.js +253 -193
- package/lib/key.js +6 -9
- package/lib/store.js +276 -0
- package/lib/ui.js +200 -71
- package/lib/workspace.js +336 -0
- package/package.json +9 -5
- package/skills/README.md +32 -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,273 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# ⚡ zcode
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**The execution engine for orchestrator agents.**
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
$ zcode "What is 17*23? Reason carefully, then reply with only the number."
|
|
9
|
-
│ The user wants 17 * 23. Simple math. 17*23 = 17*20 + 17*3 = 340 + 51 = 391. Reply with only the number.
|
|
10
|
-
391
|
|
11
|
-
GLM-5.3-Flash · effort max · 0 tool calls · 9.1s · sess_03bf3114-44
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
That is a real transcript. Thinking streams as a dimmed quote block on stderr, the answer lands alone on stdout, and a status line closes the turn. What you pipe is exactly what the model answered.
|
|
7
|
+
Hand it a scoped task. It implements, verifies with *your* checks, and hands back proof.
|
|
15
8
|
|
|
16
|
-
[](https://www.npmjs.com/package/@0xgeorgemathew/zcode)
|
|
9
|
+
[](https://www.npmjs.com/package/@0xgeorgemathew/zcode)
|
|
10
|
+
[](package.json)
|
|
11
|
+
[](package.json)
|
|
17
12
|
[](LICENSE)
|
|
18
13
|
|
|
19
|
-
|
|
14
|
+
`GLM-5.3-Flash` · effort `max` by default · `GLM-5.3` on demand
|
|
20
15
|
|
|
21
|
-
|
|
16
|
+
</div>
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
npm install -g @0xgeorgemathew/zcode
|
|
25
|
-
```
|
|
18
|
+
|
|
26
19
|
|
|
27
|
-
|
|
20
|
+
Opus, Sonnet, GPT, or any agent with a shell delegates implementation to zcode. The orchestrator keeps product decisions, design direction, and coordination. zcode owns execution inside the scope it is given, and reports back what changed, what was checked, what failed, and what is still unverified.
|
|
21
|
+
|
|
22
|
+
| | |
|
|
23
|
+
|---|---|
|
|
24
|
+
| 🧾 **Contracts, not prompts** | objective, scope, constraints, binding design decisions, acceptance criteria, checks |
|
|
25
|
+
| ✅ **Evidence over claims** | zcode runs your checks itself and repairs failures in bounded turns; the model's report is only a claim |
|
|
26
|
+
| 🧵 **Real sessions** | stable ids, detach, `status`, `wait`, `resume`, `cancel`; interrupted sessions are resumable |
|
|
27
|
+
| 🧱 **Safe parallelism** | `--owns` leases per workspace; overlapping scopes are refused, out-of-scope edits are flagged |
|
|
28
|
+
| 🤖 **Machine-first output** | one stable `zcode.result/1` JSON line; clean, colour-free text when not on a TTY |
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
|
|
31
|
-
##
|
|
32
|
+
## Quick start
|
|
32
33
|
|
|
33
34
|
```sh
|
|
35
|
+
npm install -g @0xgeorgemathew/zcode
|
|
34
36
|
echo "$ZAI_API_KEY" | zcode login # store your Z.AI key (mode 600, never printed)
|
|
35
37
|
zcode doctor # check engine, isolation, key
|
|
36
|
-
zcode "Explain this repo in two sentences"
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
## Ask
|
|
42
38
|
|
|
43
|
-
|
|
44
|
-
zcode "Reply with exactly: OK" # GLM-5.3-Flash, effort max
|
|
45
|
-
zcode --model glm-5.3 "Reply with exactly: OK" # GLM-5.3
|
|
46
|
-
zcode --effort high "Draft a commit message" # low | medium | high | xhigh | max
|
|
47
|
-
echo "$PROMPT" | zcode # prompt via stdin
|
|
39
|
+
zcode task --check "npm test" "Fix the off-by-one in src/paginate.ts"
|
|
48
40
|
```
|
|
49
41
|
|
|
50
|
-
|
|
42
|
+
Needs node 20+ for the CLI (26 recommended for the engine child) and the ZCode engine on the machine. Today that is the copy bundled with the ZCode desktop app, which is resolved automatically.
|
|
43
|
+
|
|
44
|
+
Orchestrator skills for Claude Code and Codex ship in [`skills/`](skills/README.md).
|
|
51
45
|
|
|
52
46
|
|
|
53
47
|
|
|
54
|
-
##
|
|
48
|
+
## Models and effort
|
|
55
49
|
|
|
56
|
-
|
|
50
|
+
Every command runs on **GLM-5.3-Flash at effort `max`** unless you say otherwise.
|
|
57
51
|
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
| | flag | values | default |
|
|
53
|
+
|---|---|---|---|
|
|
54
|
+
| 🧠 model | `--model` | `glm-5.3-flash` (aliases `flash`, `5.3-flash`, `53f`) · `glm-5.3` (aliases `5.3`, `53`) | `glm-5.3-flash` |
|
|
55
|
+
| 🎚️ effort | `--effort` | `low` · `medium` · `high` · `xhigh` · `max` | `max` |
|
|
60
56
|
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
DONE
|
|
67
|
-
GLM-5.3-Flash · effort max · 1 tool call · 11.1s · sess_e9fc3633-3b
|
|
57
|
+
```sh
|
|
58
|
+
zcode task "…" # GLM-5.3-Flash, effort max
|
|
59
|
+
zcode task --effort high "…" # Flash, lighter reasoning
|
|
60
|
+
zcode task --model glm-5.3 "…" # full GLM-5.3, effort max
|
|
61
|
+
zcode task --model glm-5.3 --effort medium "…" # full GLM-5.3, medium effort
|
|
68
62
|
```
|
|
69
63
|
|
|
70
|
-
|
|
64
|
+
A task contract can also set `"model"` and `"effort"`; flags win over the contract. A resumed session keeps the model and effort it started with unless you pass the flags again.
|
|
71
65
|
|
|
72
66
|
|
|
73
67
|
|
|
74
|
-
##
|
|
75
|
-
|
|
76
|
-
Every result carries a `sessionId`. Sessions persist on disk, so a later invocation, in a new process, picks up the same thread:
|
|
68
|
+
## Hand off a task
|
|
77
69
|
|
|
78
70
|
```sh
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
71
|
+
zcode task --cwd ./site --id page-1 \
|
|
72
|
+
--owns src/pages/pricing/ \
|
|
73
|
+
--check "npm run build" --check "npm test -- pricing" \
|
|
74
|
+
--accept "Three plan cards, the middle one highlighted" \
|
|
75
|
+
--context @design/pricing.md \
|
|
76
|
+
"Implement the pricing page from the supplied design notes"
|
|
82
77
|
```
|
|
83
78
|
|
|
84
|
-
|
|
79
|
+
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:
|
|
85
80
|
|
|
86
|
-
|
|
81
|
+
```text
|
|
82
|
+
✓ completed page-1 142.3s
|
|
83
|
+
Pricing page with three plan cards; middle card highlighted per design notes.
|
|
84
|
+
changed 3 files
|
|
85
|
+
A src/pages/pricing/index.tsx
|
|
86
|
+
A src/pages/pricing/PlanCard.tsx
|
|
87
|
+
M src/pages/pricing/styles.css
|
|
88
|
+
checks 2/2 passed · 1 repair turn
|
|
89
|
+
✓ npm run build
|
|
90
|
+
✓ npm test -- pricing
|
|
91
|
+
not verified
|
|
92
|
+
- prose acceptance criteria are confirmed only by the executor's own report
|
|
93
|
+
```
|
|
87
94
|
|
|
88
|
-
|
|
95
|
+
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.
|
|
89
96
|
|
|
90
|
-
|
|
97
|
+
For small work, the objective alone is enough: `zcode task "Fix the typo in the README heading"`.
|
|
91
98
|
|
|
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
|
-
```
|
|
99
|
+
### The contract
|
|
98
100
|
|
|
99
|
-
|
|
101
|
+
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.
|
|
100
102
|
|
|
101
103
|
```json
|
|
102
|
-
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
|
|
104
|
+
{
|
|
105
|
+
"objective": "Implement page 2 (Team) per the design spec",
|
|
106
|
+
"scope": ["Team page route and its components"],
|
|
107
|
+
"constraints": ["No new dependencies", "Keep existing routing untouched"],
|
|
108
|
+
"design": ["Grid of 3 columns ≥1024px, 1 column below", "Use tokens from src/theme.ts only"],
|
|
109
|
+
"acceptance": ["Every member card shows name, role, avatar"],
|
|
110
|
+
"checks": ["npm run build", "npm test -- team"],
|
|
111
|
+
"files": ["src/theme.ts", "src/pages/home/index.tsx"],
|
|
112
|
+
"references": ["design/team.png described in design/team.md"],
|
|
113
|
+
"context": ["Copy lives in content/team.json"],
|
|
114
|
+
"owns": ["src/pages/team/**", "content/team.json"],
|
|
115
|
+
"limits": { "timeoutMs": 1800000, "maxRepairs": 2, "checkTimeoutMs": 300000 },
|
|
116
|
+
"model": "glm-5.3",
|
|
117
|
+
"effort": "high"
|
|
118
|
+
}
|
|
110
119
|
```
|
|
111
120
|
|
|
112
|
-
|
|
121
|
+
`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.
|
|
113
122
|
|
|
114
|
-
|
|
123
|
+
### Status: what a result means
|
|
115
124
|
|
|
116
|
-
|
|
125
|
+
| status | meaning | exit |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| `completed` | zcode's own checks ran and passed, the executor reports done, no unmet criteria, nothing changed outside `--owns` | 0 |
|
|
128
|
+
| `unverified` | executor reports done, but no checks were declared (or no usable handback), so completion is self-reported | 9 |
|
|
129
|
+
| `partial` | work remains: executor says partial, a criterion is unmet, or files changed outside the owned scope | 8 |
|
|
130
|
+
| `blocked` | needs the orchestrator: `questions` lists what is missing | 10 |
|
|
131
|
+
| `failed` | checks still failing after the repair budget (`error.kind: checks_failed`, exit 8), engine/turn error (5), or timeout (124) | 5 / 8 / 124 |
|
|
132
|
+
| `cancelled` | stopped by `zcode cancel`, Ctrl-C, or SIGTERM | 130 |
|
|
117
133
|
|
|
118
|
-
|
|
119
|
-
zcode --mcp '{"word-server":{"type":"stdio","command":"node","args":["srv.js"],"enabled":true}}' \
|
|
120
|
-
"Call get_magic_word and reply with exactly what it returns"
|
|
134
|
+
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.
|
|
121
135
|
|
|
122
|
-
|
|
123
|
-
"Look up the MCP spec section on tools"
|
|
136
|
+
|
|
124
137
|
|
|
125
|
-
|
|
126
|
-
|
|
138
|
+
## Sessions
|
|
139
|
+
|
|
140
|
+
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.
|
|
141
|
+
|
|
142
|
+
```sh
|
|
143
|
+
zcode task --detach --id page-1 --owns src/pages/home/ --check "npm run build" "Build page 1"
|
|
144
|
+
zcode task --detach --id page-2 --owns src/pages/team/ --check "npm run build" "Build page 2"
|
|
145
|
+
zcode status # all sessions: id, state/status, kind, updated, label
|
|
146
|
+
zcode status page-1 --json # one session: state, phase, activity, recent events, result
|
|
147
|
+
zcode wait page-1 page-2 # block until both finish; print each handback
|
|
148
|
+
zcode resume page-2 "Use the 2-column variant below 1024px." # answer / follow up / retry
|
|
149
|
+
zcode cancel page-1 # stop the turn and any running check; recorded as cancelled
|
|
127
150
|
```
|
|
128
151
|
|
|
129
|
-
|
|
152
|
+
- **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.
|
|
153
|
+
- **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".
|
|
154
|
+
- **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`.
|
|
155
|
+
- **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
156
|
|
|
131
|
-
|
|
157
|
+
### Concurrency and ownership
|
|
132
158
|
|
|
133
|
-
|
|
159
|
+
`--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
160
|
|
|
135
|
-
|
|
161
|
+
- 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.
|
|
162
|
+
- 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.
|
|
163
|
+
- For overlapping or risky parallel work, give each session its own git worktree via `--cwd`.
|
|
164
|
+
- `ZAI_CODE_MAX_ACTIVE` (default 8) is a soft machine-wide cap. Sessions beyond it wait in `queued`.
|
|
136
165
|
|
|
137
|
-
|
|
166
|
+
|
|
138
167
|
|
|
139
|
-
-
|
|
168
|
+
## One-shot turns and subagent dispatch
|
|
169
|
+
|
|
170
|
+
`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
171
|
|
|
141
172
|
```sh
|
|
142
|
-
zcode
|
|
173
|
+
zcode "What is 17*23? Reply with only the number."
|
|
174
|
+
zcode --model glm-5.3 --effort high "Draft a commit message for the staged diff"
|
|
175
|
+
echo "$PROMPT" | zcode
|
|
143
176
|
```
|
|
144
177
|
|
|
145
|
-
|
|
178
|
+
`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`).
|
|
179
|
+
|
|
180
|
+
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
181
|
|
|
147
182
|
|
|
148
183
|
|
|
149
184
|
## Machine interface
|
|
150
185
|
|
|
151
|
-
`--json
|
|
186
|
+
`--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
187
|
|
|
153
188
|
```json
|
|
154
|
-
{"type":"result","ok":true,"
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
"
|
|
159
|
-
"durationMs":
|
|
189
|
+
{"type":"result","schema":"zcode.result/1","ok":true,"status":"completed","id":"page-1","kind":"task",
|
|
190
|
+
"summary":"…","response":"…executor report…","issues":[],"questions":[],"unresolved":[],"notVerified":[],
|
|
191
|
+
"changes":{"tracking":"git","files":[{"path":"src/pages/home/index.tsx","change":"added","owned":true}]},
|
|
192
|
+
"scopeViolations":[],"checks":[{"command":"npm run build","ok":true,"exitCode":0,"timedOut":false,"durationMs":8123,"output":"…tail…"}],
|
|
193
|
+
"checksPassed":true,"repairs":0,"handback":{"status":"done","summary":"…","changes":[],"checks":[],"criteria":[],"unresolved":[],"questions":[],"notes":""},
|
|
194
|
+
"subagents":[{"agentId":"agent_…","profileId":"general-purpose","status":"success","summary":"…","durationMs":59765}],
|
|
195
|
+
"error":null,"cwd":"/abs/site","workspaceRoot":"/abs/site","owns":["src/pages/home/"],"sessionId":"sess_…","resumed":false,"turns":1,
|
|
196
|
+
"model":"GLM-5.3-Flash","effort":"max","mode":"yolo","usage":{"inputTokens":19608,"outputTokens":3120},
|
|
197
|
+
"toolCalls":14,"durationMs":142301,"files":{"session":"…/sessions/page-1","result":"…/result.json","events":"…/events.ndjson"}}
|
|
160
198
|
```
|
|
161
199
|
|
|
162
|
-
`model` and `effort` are engine-reported
|
|
163
|
-
|
|
164
|
-
Event types on the way in:
|
|
200
|
+
`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
201
|
|
|
166
202
|
| event | meaning |
|
|
167
203
|
|---|---|
|
|
168
|
-
| `{"type":"
|
|
169
|
-
| `{"type":"
|
|
170
|
-
| `{"type":"tool","name":"
|
|
171
|
-
| `{"type":"
|
|
172
|
-
| `{"type":"
|
|
173
|
-
| `{"type":"
|
|
204
|
+
| `{"type":"session","id","kind","cwd","owns","checks","model","effort","resumed"}` | which session is active, and its scope |
|
|
205
|
+
| `{"type":"phase","phase":"starting\|executing\|reporting\|checking\|repairing\|queued"}` | what is running |
|
|
206
|
+
| `{"type":"tool","name":"Edit","phase":"started"}` | tool lifecycle (`scheduled`, `started`, `result`, `error`) |
|
|
207
|
+
| `{"type":"subagent","phase":"started\|returned\|error"}` | subagent activity |
|
|
208
|
+
| `{"type":"check","phase":"finished","command","ok","exitCode","durationMs"}` | zcode-run verification |
|
|
209
|
+
| `{"type":"mcp","name","status"}` · `{"type":"retry",…}` · `{"type":"model_request_started",…}` | MCP settling, start-up retry, engine model evidence |
|
|
210
|
+
| `{"type":"stream","kind":"text_delta\|reasoning_delta","delta"}` | live text (run/agent; task with `--stream`) |
|
|
211
|
+
|
|
212
|
+
`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
213
|
|
|
175
214
|
|
|
176
215
|
|
|
177
216
|
## Options
|
|
178
217
|
|
|
179
|
-
| option |
|
|
218
|
+
| option | applies to | default | notes |
|
|
180
219
|
|---|---|---|---|
|
|
181
|
-
| `--
|
|
182
|
-
| `--
|
|
183
|
-
| `--cwd` |
|
|
184
|
-
| `--
|
|
185
|
-
| `--
|
|
186
|
-
| `--
|
|
187
|
-
| `--
|
|
188
|
-
| `--
|
|
189
|
-
| `--
|
|
190
|
-
| `--
|
|
191
|
-
| `--
|
|
192
|
-
| `--
|
|
193
|
-
| `--
|
|
194
|
-
| `--
|
|
195
|
-
| `--
|
|
196
|
-
|
|
|
220
|
+
| `--id`, `--label` | run, task, agent | `zc-<random>` | session identity |
|
|
221
|
+
| `--detach` | run, task, agent, resume | off | background worker; prints the id |
|
|
222
|
+
| `--cwd` | run, task, agent | current dir | the workspace and blast radius |
|
|
223
|
+
| `--owns` | run, task, agent | whole workspace | repeatable path or glob |
|
|
224
|
+
| `--allow-overlap` | run, task, agent | off | start despite overlapping ownership |
|
|
225
|
+
| `--task` | task | | JSON contract, markdown brief, or `-` |
|
|
226
|
+
| `--accept`, `--check`, `--file`, `--context` | task | | repeatable; `--context @file` reads a file |
|
|
227
|
+
| `--max-repairs` | task, resume | `2` | repair turns after failing checks |
|
|
228
|
+
| `--check-timeout-ms` | task, resume | `300000` | per check; checks get `CI=1` when unset |
|
|
229
|
+
| `--model` | all turns | `glm-5.3-flash` | `glm-5.3` plus aliases `5.3`, `53`, `flash`, `5.3-flash`, `53f` |
|
|
230
|
+
| `--effort` | all turns | `max` | `low`, `medium`, `high`, `xhigh`, `max` |
|
|
231
|
+
| `--timeout-ms` | all turns; wait | run 600000, task 1800000 | the whole invocation incl. checks and repairs |
|
|
232
|
+
| `--session` | run | | 0.3 compat: continue by zcode id or engine `sess_` id |
|
|
233
|
+
| `--profile` | agent | `general-purpose` | subagent profile |
|
|
234
|
+
| `--mcp` / `--mcp-inherit` / `--mcp-list` | run, task, agent | hermetic | MCP servers (inline JSON or `@file`) |
|
|
235
|
+
| `--skills` / `--no-skills` | run, task, agent | desktop skills | add skills; or run with none |
|
|
236
|
+
| `--json`, `--quiet` | all | | see Machine interface |
|
|
237
|
+
| `--thinking` / `--no-thinking` | turns | run on, task off | mirror reasoning to stderr |
|
|
238
|
+
| `--stream`, `--include-reasoning` | turns | off | deltas in task events; full reasoning in the result |
|
|
239
|
+
|
|
240
|
+
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
241
|
|
|
198
242
|
## Exit codes
|
|
199
243
|
|
|
200
244
|
| code | meaning |
|
|
201
245
|
|---|---|
|
|
202
|
-
| 0 |
|
|
246
|
+
| 0 | completed |
|
|
203
247
|
| 1 | unexpected internal error |
|
|
204
|
-
| 2 | usage error,
|
|
248
|
+
| 2 | usage error (bad flag, model, effort, contract, unknown or duplicate session id) |
|
|
205
249
|
| 3 | no API key (`zcode login` or `ZAI_API_KEY`) |
|
|
206
250
|
| 4 | engine or builtin provider config not found |
|
|
207
|
-
| 5 |
|
|
251
|
+
| 5 | failed: engine or turn error |
|
|
208
252
|
| 6 | `agent`: no subagent dispatched or none ended `success` |
|
|
253
|
+
| 7 | workspace conflict, or the session is already running |
|
|
254
|
+
| 8 | partial, or checks still failing after repairs |
|
|
255
|
+
| 9 | unverified |
|
|
256
|
+
| 10 | blocked |
|
|
209
257
|
| 124 | `--timeout-ms` exceeded |
|
|
210
|
-
| 130 |
|
|
258
|
+
| 130 | cancelled |
|
|
211
259
|
|
|
212
260
|
|
|
213
261
|
|
|
214
262
|
## Under the hood
|
|
215
263
|
|
|
216
|
-
**Key handling.** `ZAI_API_KEY` env var, or `zcode login
|
|
264
|
+
**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
265
|
|
|
218
|
-
**Isolation.**
|
|
266
|
+
**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
267
|
|
|
220
|
-
**Yolo mode.**
|
|
268
|
+
**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
269
|
|
|
222
|
-
**
|
|
270
|
+
**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
271
|
|
|
224
272
|
|
|
225
273
|
|
|
@@ -228,12 +276,13 @@ Event types on the way in:
|
|
|
228
276
|
Zero dependencies, plain CommonJS, no build step.
|
|
229
277
|
|
|
230
278
|
```sh
|
|
231
|
-
npm test #
|
|
232
|
-
npm run
|
|
279
|
+
npm test # unit suite: in-process, scripted fake engine, no CLI spawn, no API calls
|
|
280
|
+
npm run test:live # functional suite: spawns the CLI against the real engine and GLM API
|
|
281
|
+
npm run accept:flash # black-box acceptance runs (real API)
|
|
233
282
|
npm run accept:subagent
|
|
234
283
|
npm run accept:53
|
|
235
284
|
```
|
|
236
285
|
|
|
237
|
-
|
|
286
|
+
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`.
|
|
238
287
|
|
|
239
288
|
MIT license.
|