@zenera/cli 1.1.22 → 1.1.24

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.
Files changed (73) hide show
  1. package/README.md +72 -2
  2. package/dist/archive.d.ts +139 -0
  3. package/dist/archive.js +376 -0
  4. package/dist/ask.d.ts +51 -0
  5. package/dist/ask.js +143 -0
  6. package/dist/batch.d.ts +77 -0
  7. package/dist/batch.js +338 -0
  8. package/dist/command.d.ts +6 -0
  9. package/dist/commands/export.d.ts +3 -0
  10. package/dist/commands/export.js +255 -0
  11. package/dist/commands/import.d.ts +3 -0
  12. package/dist/commands/import.js +173 -0
  13. package/dist/commands/index.d.ts +5 -1
  14. package/dist/commands/index.js +13 -1
  15. package/dist/commands/inspect.d.ts +11 -0
  16. package/dist/commands/inspect.js +388 -89
  17. package/dist/commands/list.js +128 -19
  18. package/dist/commands/memory.js +453 -16
  19. package/dist/commands/models.js +14 -2
  20. package/dist/commands/run.js +139 -34
  21. package/dist/commands/sandbox.js +72 -1
  22. package/dist/engine.d.ts +19 -0
  23. package/dist/engine.js +60 -8
  24. package/dist/liveness.js +6 -3
  25. package/dist/main.js +5 -2
  26. package/dist/podman.d.ts +16 -0
  27. package/dist/podman.js +115 -2
  28. package/dist/progress.d.ts +33 -0
  29. package/dist/progress.js +402 -0
  30. package/dist/request.d.ts +45 -0
  31. package/dist/request.js +300 -0
  32. package/dist/sandbox.js +10 -0
  33. package/dist/scaffold.d.ts +8 -0
  34. package/dist/scaffold.js +4 -1
  35. package/dist/session.d.ts +26 -1
  36. package/dist/session.js +42 -3
  37. package/dist/term.d.ts +3 -0
  38. package/dist/term.js +17 -1
  39. package/dist/trace.d.ts +84 -0
  40. package/dist/trace.js +686 -0
  41. package/dist/validate.js +93 -4
  42. package/package.json +12 -6
  43. package/templates/editor/.github/copilot-instructions.md +11 -6
  44. package/templates/editor/.github/prompts/finetune.prompt.md +251 -0
  45. package/templates/editor/.github/prompts/spec-sync-project.prompt.md +25 -2
  46. package/templates/editor/.github/skills/zen-cli/SKILL.md +14 -3
  47. package/templates/editor/.github/skills/zen-cli/references/check.md +13 -5
  48. package/templates/editor/.github/skills/zen-cli/references/export.md +107 -0
  49. package/templates/editor/.github/skills/zen-cli/references/inspect.md +262 -21
  50. package/templates/editor/.github/skills/zen-cli/references/memory.md +123 -15
  51. package/templates/editor/.github/skills/zen-cli/references/models.md +1 -1
  52. package/templates/editor/.github/skills/zen-cli/references/projects.md +12 -5
  53. package/templates/editor/.github/skills/zen-cli/references/rag.md +6 -0
  54. package/templates/editor/.github/skills/zen-cli/references/run.md +201 -4
  55. package/templates/editor/.github/skills/zen-finetune/SKILL.md +1000 -0
  56. package/templates/editor/.github/skills/zen-finetune/scripts/collect.sh +432 -0
  57. package/templates/editor/.github/skills/zen-finetune/scripts/sample.sh +199 -0
  58. package/templates/editor/.github/skills/zen-inspect/SKILL.md +396 -0
  59. package/templates/editor/.github/skills/zen-memory/SKILL.md +74 -28
  60. package/templates/editor/.github/skills/zen-memory-warmup/SKILL.md +370 -408
  61. package/templates/editor/.github/skills/zen-sandbox/SKILL.md +19 -0
  62. package/templates/editor/.github/skills/zen-sandbox-capacity/SKILL.md +334 -0
  63. package/templates/editor/.github/skills/zen-sandbox-capacity/references/loadtest.md +181 -0
  64. package/templates/editor/.github/skills/zen-sandbox-capacity/scripts/preflight_sandbox.sh +457 -0
  65. package/templates/editor/.github/skills/zen-spec-sync/SKILL.md +6 -5
  66. package/templates/editor/.vscode/agents.schema.json +1 -1
  67. package/templates/editor/.vscode/settings.json +1 -0
  68. package/templates/project/SPECIFICATION.md.tmpl +2 -0
  69. package/templates/project/agents/files-instructions.md +13 -0
  70. package/templates/project/agents/fork-instructions.md +27 -0
  71. package/templates/project/agents/memory-instructions.md +80 -7
  72. package/templates/project/gitignore +3 -0
  73. package/templates/project/scripts/_setup.sh +49 -7
@@ -14,14 +14,18 @@ answers once on stdout and exits.
14
14
  | `--project <name\|dir>` | Which project. Inferred from the directory otherwise |
15
15
  | `--session <id>` | Continue a particular session |
16
16
  | `--new` | Start a new session rather than continuing one |
17
+ | `--input <file>` | Read the whole request from JSON; `-` is stdin |
17
18
  | `--workspace <dir>` | What the agent may read and write |
18
19
  | `--memory <dir>` | Where the agents remember into, instead of the project's |
20
+ | `--memory-read-only` | Recall from it; write nothing back |
19
21
  | `--model <ref>` | Override the default model for this run |
20
22
  | `--image <ref>` | Override the container image commands run in |
21
23
  | `--read-only` | Withhold every tool that can write |
22
24
  | `--plain` | Never open the TUI; a prompt is then required |
23
25
  | `--theme <dark\|light>` | Palette for the TUI; `auto` detects. `$ZENERA_THEME` |
24
26
  | `--out <file>` | Put the answer in this file instead of on stdout |
27
+ | `--batch-dir <dir>` | Where a batch's runs live. `<project>/batches/<stamp>` |
28
+ | `--concurrency <n>` | How many of a batch run at once. Default 16, most 32 |
25
29
  | `--yes` | Say yes to the workspace and install questions |
26
30
 
27
31
  Flags always beat the file: the repository states intent, the invocation
@@ -38,6 +42,7 @@ the file is the only place it lands.
38
42
  zen run "what changed?" > out.md answer in the file, progress on screen
39
43
  zen run "what changed?" > out.md 2>/dev/null ... and nothing on screen at all
40
44
  zen run --out out.md "what changed?" the same file, stdout left empty
45
+ zen run --json --out run.json "what changed?" the whole envelope, in a file
41
46
  ```
42
47
 
43
48
  There is no `--quiet`. Narration is on stderr already, so a redirect is enough;
@@ -46,7 +51,9 @@ There is no `--quiet`. Narration is on stderr already, so a redirect is enough;
46
51
  `--json` answers with the paths as well as the answer: the session and run
47
52
  directories, every file the run left behind, and every tree the agent could see,
48
53
  with the path it had on this machine beside the path it had inside the
49
- container.
54
+ container. `--out` takes that envelope off stdout the same way it takes the
55
+ prose — with `--json` the envelope _is_ the answer, so the file holds all of it
56
+ and stdout is left empty.
50
57
 
51
58
  ```json
52
59
  {
@@ -58,7 +65,8 @@ container.
58
65
  "output": ".../output.md",
59
66
  "state": ".../state.json",
60
67
  "meta": ".../meta.json",
61
- "report": ".../report.html"
68
+ "report": ".../report.html",
69
+ "graph": ".../graph.mmd"
62
70
  },
63
71
  "mounts": [
64
72
  { "host": "...", "at": "/workspace", "readOnly": false },
@@ -76,11 +84,198 @@ container.
76
84
  `mounts` also lists the container's `$HOME` and, when keys are forwarded, the
77
85
  credential files mounted under `/run/zenera/keys`.
78
86
 
87
+ ## A request in a file
88
+
89
+ `--input <file.json>` is the whole invocation written down. It is the only way
90
+ to ask about a picture - a command line cannot carry one - and it is what makes
91
+ a run reproducible: a case is a file, so it can be checked in, diffed and re-run.
92
+
93
+ ```json
94
+ {
95
+ "project": "acme",
96
+ "input": [{ "text": "what is in this picture?" }, { "image": "./shot.png" }],
97
+ "workspace": "./ws",
98
+ "memory": "./mem"
99
+ }
100
+ ```
101
+
102
+ Only `input` is required, and it may be a plain string instead of an array. Each
103
+ part is a bare string, `{ "text": "…" }`, one of `{ "image" | "audio" | "video" |
104
+ "file": "…" }`, or the canonical `{ "type", "url", "mimeType" }` - the same shapes
105
+ the library's `Input` accepts, because the file is a JSON projection of it.
106
+
107
+ Three rules, and they are the whole of the format:
108
+
109
+ - **Paths are relative to the file**, not to the directory you ran from, so a
110
+ case travels with the images beside it. With `--input -` there is no file, so
111
+ they are relative to the cwd. A bare `project` is a registered name and is
112
+ left alone; one starting with `.` or `/` is a directory.
113
+ - **The file wins** over the same flag on the command line. A field it leaves
114
+ out falls through to the flag, then to the usual default. This is the one
115
+ place the rule above the options table is reversed - the file _is_ the
116
+ invocation, not a repository's standing intent.
117
+ - **A local media path is inlined** as a `data:` url, so the state a run resumes
118
+ from carries the picture rather than a path that meant something elsewhere.
119
+ `http(s):` and `data:` urls are passed through untouched. The bytes land in
120
+ `state.json` and are rewritten on every later turn of that session, so there
121
+ is a 20 MB ceiling and a warning well before it.
122
+
123
+ A request never opens the TUI and never asks about the workspace, exactly like a
124
+ prompt on the command line. Giving both a prompt and `--input` is an error.
125
+
126
+ ```
127
+ zen run --input case.json --json | jq -r .output
128
+ cat case.json | zen run --input - --json
129
+ zen run --input case.json --json --out result.json everything, in a file
130
+ zen run --input case.json --session 20260825-143012-a7f3 continue, don't start
131
+ ```
132
+
79
133
  `--plain` never opens the TUI. The TUI is the only thing that can ask for a
80
134
  prompt, so with `--plain` the prompt has to be there already - in the argument
81
135
  or on stdin - and `zen run --plain` with neither is an error instead of a
82
136
  window. Say it in a script that must not meet one.
83
137
 
138
+ ## Many at once - `zen run batch`
139
+
140
+ ```
141
+ zen run batch --input cases.json [--batch-dir <dir>] [--concurrency 16]
142
+ [--memory <dir>] [--memory-read-only] [--out <file>] [--json]
143
+ ```
144
+
145
+ The same file, pluralised. One project, many questions, sixteen at a time by
146
+ default:
147
+
148
+ ```json
149
+ {
150
+ "batch": [
151
+ { "id": "vat", "input": "what is the VAT threshold?" },
152
+ { "input": [{ "text": "what is this?" }, { "image": "./shot.png" }] },
153
+ { "id": "ws", "input": "read the notes", "workspace": "./cases/ws" }
154
+ ]
155
+ }
156
+ ```
157
+
158
+ An item takes `input`, an optional `id` and an optional `workspace`, and nothing
159
+ else. `project` and `memory` belong to the batch rather than to an item, so they
160
+ are flags: a file that names either is refused rather than half-honoured. An
161
+ `id` names a directory, so it has to be one - letters, digits, dot, dash and
162
+ underscore - and it defaults to the item's index. Two items may not share an
163
+ `id` or a `workspace`, because they run at the same time.
164
+
165
+ Everything refusable is refused before the first model call. A batch pays for a
166
+ mistake once per item.
167
+
168
+ ### What it leaves behind
169
+
170
+ ```
171
+ <batch-dir>/
172
+ README.md a live dashboard, rewritten every second
173
+ batch.json the index: every item, whether it worked, where it is
174
+ <id>/
175
+ workspace/ what that item could read and write
176
+ memory/ its own copy, in the copying mode only
177
+ output.json exactly what `zen run --json` prints for one run
178
+ ```
179
+
180
+ `README.md` is where the progress of a batch lives. Sixteen agents narrating at
181
+ once would be noise, so instead the file is rewritten once a second: a
182
+ fixed-height panel showing every worker - what it is running, the tail of what
183
+ it is thinking or writing, its turns and its tokens - over a `Tokens by model`
184
+ table, a table of the finished ones and a list of the ones still waiting. The
185
+ panel keeps its height while there is work left to start, so nothing jumps
186
+ between ticks. Watch it in an editor preview, or `watch -n1 cat "$DIR/README.md"`.
187
+ When the batch ends the same file is the report.
188
+
189
+ Tokens are reported **per model**: agents may each use a different one, so one
190
+ total belongs to none of them. Every model id gets a row with its calls and its
191
+ input, cached, output and thinking tokens, and the rows always add up to the
192
+ batch total. Tokens spent summarising, which no node attributes to a model, are
193
+ shown as `(compaction)`.
194
+
195
+ Each `output.json` is written the moment its item finishes, so a batch stopped
196
+ half way still has every answer it managed to get. `batch.json` is an index, not
197
+ a second copy - it points at the files:
198
+
199
+ ```json
200
+ {
201
+ "batch": {
202
+ "dir": "...",
203
+ "items": 3,
204
+ "ok": 2,
205
+ "failed": 1,
206
+ "concurrency": 16,
207
+ "memory": { "source": "...", "mode": "read-only" },
208
+ "usage": {
209
+ "inputTokens": 0,
210
+ "cachedInputTokens": 0,
211
+ "outputTokens": 0,
212
+ "reasoningTokens": 0
213
+ },
214
+ "models": [{ "model": "gemini-3-flash", "calls": 12, "usage": {} }],
215
+ "durationMs": 0
216
+ },
217
+ "batch_results": [
218
+ { "index": 0, "id": "vat", "ok": true, "input": "…", "output": ".../vat/output.json" },
219
+ {
220
+ "index": 1,
221
+ "id": "1",
222
+ "ok": false,
223
+ "input": "…",
224
+ "output": "...",
225
+ "error": { "message": "…" }
226
+ }
227
+ ]
228
+ }
229
+ ```
230
+
231
+ A failure is data. One item that cannot be answered costs one answer, not the
232
+ other ninety-nine; the exit code says how many failed, and it is set after
233
+ everything is written.
234
+
235
+ stdout is the batch directory and nothing else, so `ls "$(zen run batch --input
236
+ cases.json)"` works. `--json` prints the index there instead. Progress is in
237
+ `<batch-dir>/README.md` either way. `--out` puts the index in a second file as
238
+ well.
239
+
240
+ ### Memory, in two modes
241
+
242
+ A memory is a locked directory, so sixteen runs cannot hold one. Which leaves
243
+ two honest arrangements, and the flag picks between them:
244
+
245
+ | Mode | What happens |
246
+ | -------------------- | ------------------------------------------------------------------ |
247
+ | `--memory-read-only` | Every item recalls from the one graph. Nothing is written, no lock |
248
+ | default | Each item gets a copy under `<batch-dir>/<id>/memory` |
249
+
250
+ In the copying mode the project's own memory is never touched. Fold what the
251
+ items learned back in afterwards, having read it:
252
+
253
+ ```
254
+ zen memory merge <batch-dir>/*/memory
255
+ ```
256
+
257
+ An item that committed nothing leaves no `memory/` behind, so that line never
258
+ names a directory `merge` would refuse.
259
+
260
+ `--memory <dir>` names the source in both modes; without it the source is the
261
+ project's own memory, and a project with none runs the batch with none. A
262
+ source that does not exist yet is not an error in the copying mode: a project
263
+ declares its memory directory and the first run makes it, so every item simply
264
+ starts from an empty graph. That is how a cold project is warmed, and pointing
265
+ `--memory` at a directory that is not there is how you ask for it deliberately.
266
+ A batch refuses to start while another run holds that memory's lock.
267
+
268
+ `--memory-read-only` works on a single `zen run` too. It is how you ask a
269
+ question of what the agents know without changing what they know.
270
+
271
+ ### What means nothing in a batch
272
+
273
+ `--session`, `--new`, `--workspace`, `--plain` and `--theme` are refused by
274
+ name rather than ignored. Every item is a new session of its own, they cannot
275
+ share a workspace, and a batch never draws the TUI.
276
+
277
+ For a project or a prompt actually called "batch", say `--project batch`.
278
+
84
279
  ## Which word is the project
85
280
 
86
281
  The first positional is read as a project when it names one, and as the first
@@ -138,7 +333,7 @@ run history. Ids look like `20260825-143012-a7f3`.
138
333
  ```
139
334
  <project>/sessions/<id>/
140
335
  workspace/ what the agent sees, unless --workspace said otherwise
141
- runs/<run-id>/ input.md, output.md, state.json, report.html, meta.json
336
+ runs/<run-id>/ input.md, output.md, state.json, report.html, graph.mmd, meta.json
142
337
  .data/
143
338
  state.json the live, resumable state, rewritten after every run
144
339
  session.json when it was made, and the workspace it is rooted at
@@ -162,4 +357,6 @@ definition and is taken over.
162
357
  ## Afterwards
163
358
 
164
359
  Each run writes a `report.html` next to its state; the run prints a
165
- `file://` link to it. See [inspect.md](inspect.md).
360
+ `file://` link to it. It writes a `graph.mmd` beside it too - the same
361
+ trajectory as one Mermaid flowchart, which is what `zen inspect graph` prints.
362
+ See [inspect.md](inspect.md).