@zenera/cli 1.1.15 → 1.1.16
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 +183 -119
- package/dist/banner.d.ts +5 -1
- package/dist/banner.js +2 -2
- package/dist/command.d.ts +5 -0
- package/dist/main.js +10 -6
- package/package.json +2 -2
- package/templates/editor/.github/copilot-instructions.md +253 -218
- package/templates/editor/.github/prompts/new-agent.prompt.md +6 -6
- package/templates/editor/.github/prompts/new-skill.prompt.md +7 -7
- package/templates/editor/.github/prompts/review-project.prompt.md +1 -1
- package/templates/editor/.github/prompts/sync-with-spec.prompt.md +26 -26
- package/templates/editor/.github/skills/zen-cli/SKILL.md +62 -6
- package/templates/editor/.github/skills/zen-cli/references/check.md +3 -3
- package/templates/editor/.github/skills/zen-cli/references/faker.md +14 -14
- package/templates/editor/.github/skills/zen-cli/references/frame.md +6 -6
- package/templates/editor/.github/skills/zen-cli/references/inspect.md +3 -3
- package/templates/editor/.github/skills/zen-cli/references/keys.md +9 -9
- package/templates/editor/.github/skills/zen-cli/references/memory.md +11 -11
- package/templates/editor/.github/skills/zen-cli/references/models.md +8 -8
- package/templates/editor/.github/skills/zen-cli/references/projects.md +3 -3
- package/templates/editor/.github/skills/zen-cli/references/rag.md +191 -56
- package/templates/editor/.github/skills/zen-cli/references/run.md +3 -3
- package/templates/editor/.github/skills/zen-cli/references/sandbox.md +8 -8
- package/templates/editor/.github/skills/zen-memory/SKILL.md +50 -50
- package/templates/editor/.github/skills/zen-rag-docs/SKILL.md +71 -48
- package/templates/editor/.github/skills/zen-rag-schema/SKILL.md +67 -67
- package/templates/editor/.vscode/settings.json +5 -2
- package/templates/project/INSTRUCTIONS.md +1 -1
- package/templates/project/assets/README.md +1 -1
- package/templates/project/sandbox/Dockerfile.tmpl +3 -0
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<picture>
|
|
3
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/andreyryabov/ZeneraNeo/main/docs/imgs/banner-
|
|
4
|
-
<img src="https://raw.githubusercontent.com/andreyryabov/ZeneraNeo/main/docs/imgs/banner-
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/andreyryabov/ZeneraNeo/main/docs/imgs/banner-cli-dark.svg">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/andreyryabov/ZeneraNeo/main/docs/imgs/banner-cli-light.svg" alt="ZENERA CLI" width="720">
|
|
5
5
|
</picture>
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@zenera/cli)
|
|
@@ -12,23 +12,27 @@
|
|
|
12
12
|
|
|
13
13
|
# @zenera/cli
|
|
14
14
|
|
|
15
|
-
**`zen`
|
|
15
|
+
**`zen` - build specialist agents. Share them. Run them from the command line.**
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
`@zenera/cli` is the command-line package in the
|
|
18
|
+
[ZeneraNeo](https://github.com/andreyryabov/ZeneraNeo) toolkit. It creates,
|
|
19
|
+
runs, tests and improves the specialized agent systems defined by a project.
|
|
20
|
+
|
|
21
|
+
Not one general assistant that is passable at everything - a team built for the
|
|
18
22
|
work you actually keep doing, under a name you can type:
|
|
19
23
|
|
|
20
24
|
```sh
|
|
21
|
-
zen run accountant "Q3
|
|
22
|
-
zen run accountant "this MSA against our playbook
|
|
23
|
-
zen run analyst "why churn doubled in the EU accounts
|
|
25
|
+
zen run accountant "Q3 - match the receipts drawer to the ledger, then update the return"
|
|
26
|
+
zen run accountant "this MSA against our playbook - redlines, and what I must not sign"
|
|
27
|
+
zen run analyst "why churn doubled in the EU accounts - the exports are in this folder"
|
|
24
28
|
zen run analyst "what changed in EU battery regulation this year, with sources"
|
|
25
|
-
zen run devops "this week's advisories
|
|
26
|
-
zen run devops "the 03:12 outage
|
|
29
|
+
zen run devops "this week's advisories - which of them actually reach our code"
|
|
30
|
+
zen run devops "the 03:12 outage - timeline, contributing factors, owners"
|
|
27
31
|
```
|
|
28
32
|
|
|
29
33
|
Three agents there, six things asked of them: an agent you have built is not a
|
|
30
34
|
script with one job, it is a specialist you keep going back to. And it is work
|
|
31
|
-
that comes back
|
|
35
|
+
that comes back - every quarter, every sprint, every deal - which is exactly the
|
|
32
36
|
work nobody has shipped you a product for.
|
|
33
37
|
|
|
34
38
|
Once the agent exists it is a command: it works on the files you are standing
|
|
@@ -37,25 +41,25 @@ records every token it spent doing it.
|
|
|
37
41
|
|
|
38
42
|
Getting there is three beats:
|
|
39
43
|
|
|
40
|
-
1. **Describe it.** You write `SPECIFICATION.md`
|
|
44
|
+
1. **Describe it.** You write `SPECIFICATION.md` - what the system is for,
|
|
41
45
|
which specialists it needs, what each may reach for, what _done_ means. The
|
|
42
46
|
rest of the folder is built to implement it.
|
|
43
47
|
2. **Test it.** `zen check` validates the project and every file it names,
|
|
44
48
|
`zen run` exercises it for real, `zen inspect` opens the record of what it
|
|
45
49
|
actually did. When it comes out wrong you fix the specification, not the
|
|
46
50
|
prompts, and go round again.
|
|
47
|
-
3. **Share it.** It is a folder
|
|
51
|
+
3. **Share it.** It is a folder - commit it, review it in a pull request, send
|
|
48
52
|
it. One `zen init <dir>` on a project that arrived by clone registers it
|
|
49
53
|
without touching a thing, and it is their command now too.
|
|
50
54
|
|
|
51
55
|
> Part of [ZeneraNeo](https://github.com/andreyryabov/ZeneraNeo). This is an
|
|
52
|
-
> open-source side project for experimentation and chore work
|
|
56
|
+
> open-source side project for experimentation and chore work - **not** the
|
|
53
57
|
> official Zenera AI Platform. It carries no support or stability promises.
|
|
54
58
|
|
|
55
59
|
## What you build
|
|
56
60
|
|
|
57
61
|
Half a page of specification turns into a system like one of these. Nothing here
|
|
58
|
-
ships with the CLI
|
|
62
|
+
ships with the CLI - each is a folder somebody wrote, and could send you.
|
|
59
63
|
|
|
60
64
|
| Project | The team inside it |
|
|
61
65
|
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -63,37 +67,37 @@ ships with the CLI — each is a folder somebody wrote, and could send you.
|
|
|
63
67
|
| **analyst** | A planner that splits the question into branches; researchers that run in parallel over your files and the web; a statistician that writes and runs Python in the sandbox; an editor that joins it into one answer where every claim carries its source. |
|
|
64
68
|
| **devops** | A gatherer that pulls advisories, logs, alerts and deploys into one picture; a tracer that works out whether a vulnerable path is reachable at all, or which change actually broke it; an engineer that plans the fix, applies it a step at a time, and stops the moment a check fails. |
|
|
65
69
|
|
|
66
|
-
Build one, commit it, and it runs the same on anyone else's machine
|
|
70
|
+
Build one, commit it, and it runs the same on anyone else's machine - on
|
|
67
71
|
whichever models they prefer, and without carrying your keys.
|
|
68
72
|
|
|
69
73
|
## What makes it different
|
|
70
74
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
- **
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
- **A
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
- **
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
- **
|
|
91
|
-
|
|
92
|
-
|
|
75
|
+
Most tools give you one agent, or a framework and an empty file. This is a
|
|
76
|
+
factory: it designs the system for you, then keeps it honest.
|
|
77
|
+
|
|
78
|
+
- **You state the problem; a meta-agent designs the system.** Specialists,
|
|
79
|
+
prompts, tool grants, hand-offs, where it fans out - all of it drawn from what
|
|
80
|
+
you wrote, and checked before it ever runs.
|
|
81
|
+
- **A self-improving loop, not a one-off build.** Build, run, read the record,
|
|
82
|
+
change what was wrong, run again - and the system can drive that loop on
|
|
83
|
+
itself. Failures come back as findings with a cause and a fix, so the next
|
|
84
|
+
version is written rather than debugged.
|
|
85
|
+
- **It watches itself work.** Every run is recorded against the architecture it
|
|
86
|
+
declared - the agent nobody called, the skill that never fired, where the
|
|
87
|
+
tokens went. Nothing to instrument, nothing to sign up for.
|
|
88
|
+
- **Customisable all the way down.** Live in the specification and never look
|
|
89
|
+
lower. Or set the model, tools and memory of a single agent. Or take the
|
|
90
|
+
kernel itself and manage the trajectory turn by turn. No layer is sealed.
|
|
91
|
+
- **Your documents, searchable.** Hybrid retrieval over your files and your API
|
|
92
|
+
descriptions, plus a memory that is a graph rather than a bucket of rows - so
|
|
93
|
+
what an agent learned in March is still there in September.
|
|
94
|
+
- **Integrations it writes itself.** No MCP server to find, no connector to wait
|
|
95
|
+
for. If it has to reach your ERP, your database or a twenty-year-old SOAP
|
|
96
|
+
endpoint, it writes the call and runs it in a sandbox.
|
|
93
97
|
|
|
94
98
|
## Install
|
|
95
99
|
|
|
96
|
-
Node.js 24+. One command
|
|
100
|
+
Node.js 24+. One command - the OpenAI, Anthropic, Google and OpenRouter SDKs
|
|
97
101
|
all ship with the CLI, so any provider works out of the box.
|
|
98
102
|
|
|
99
103
|
```sh
|
|
@@ -108,19 +112,28 @@ npx @zenera/cli --help
|
|
|
108
112
|
|
|
109
113
|
## Quickstart
|
|
110
114
|
|
|
111
|
-
|
|
115
|
+
From nothing to a specialized agent system:
|
|
112
116
|
|
|
113
117
|
```sh
|
|
114
118
|
npm i -g @zenera/cli # every vendor SDK comes with it
|
|
115
119
|
zen key add openai # asks for the key without showing it; stored in ~/.zenera
|
|
116
120
|
zen init my-project # scaffolds a project and registers it
|
|
117
|
-
zen
|
|
121
|
+
zen open my-project # open the specification and project in your editor
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
In the editor, describe the job in `SPECIFICATION.md`, then send this in the
|
|
125
|
+
agent chat:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
/sync-with-spec
|
|
118
129
|
```
|
|
119
130
|
|
|
120
|
-
|
|
121
|
-
|
|
131
|
+
It creates the specialists, responsibilities, tool access and handoffs the job
|
|
132
|
+
needs. Back in the terminal, validate the generated system and run it against a
|
|
133
|
+
real workspace:
|
|
122
134
|
|
|
123
135
|
```sh
|
|
136
|
+
zen check my-project
|
|
124
137
|
cd ~/code/some-repo
|
|
125
138
|
zen run my-project "summarise this repo and write NOTES.md"
|
|
126
139
|
```
|
|
@@ -142,9 +155,8 @@ Giving a prompt on the command line skips every question: it starts a fresh
|
|
|
142
155
|
session and uses the current directory as the workspace, with write access.
|
|
143
156
|
`--session`, `--workspace` and `--read-only` override that.
|
|
144
157
|
|
|
145
|
-
To change what the system does,
|
|
146
|
-
`
|
|
147
|
-
send `/sync-with-spec` in the editor's chat. That is the next section.
|
|
158
|
+
To change what the system does, update `SPECIFICATION.md` and send
|
|
159
|
+
`/sync-with-spec` again. The next section explains that workflow in detail.
|
|
148
160
|
|
|
149
161
|
## You write the specification; a coding agent writes the system
|
|
150
162
|
|
|
@@ -152,7 +164,7 @@ send `/sync-with-spec` in the editor's chat. That is the next section.
|
|
|
152
164
|
implements it. Where the two disagree the specification wins, so a change to
|
|
153
165
|
what the system does starts there and not in `agents.yaml`.
|
|
154
166
|
|
|
155
|
-
The one `zen init` writes is not a heading list
|
|
167
|
+
The one `zen init` writes is not a heading list - it is a true specification of
|
|
156
168
|
the project just scaffolded, so you can read it against the files beside it
|
|
157
169
|
before changing a word:
|
|
158
170
|
|
|
@@ -166,7 +178,7 @@ nobody to hand work to, because there is no second job to hand on.
|
|
|
166
178
|
|
|
167
179
|
- The change asked for is in the workspace, or the question is answered from
|
|
168
180
|
what is actually in it.
|
|
169
|
-
- Everything the agent claims a command did, that command actually did
|
|
181
|
+
- Everything the agent claims a command did, that command actually did - it was
|
|
170
182
|
run, and its output was read.
|
|
171
183
|
- The reply names what changed, file by file, and says what it deliberately did
|
|
172
184
|
not do.
|
|
@@ -174,7 +186,7 @@ nobody to hand work to, because there is no second job to hand on.
|
|
|
174
186
|
|
|
175
187
|
### How you actually edit it
|
|
176
188
|
|
|
177
|
-
`SPECIFICATION.md` is ordinary Markdown, so any editor will do
|
|
189
|
+
`SPECIFICATION.md` is ordinary Markdown, so any editor will do - but the loop is
|
|
178
190
|
meant to be driven from a coding agent's chat, and `zen init` installs the
|
|
179
191
|
prompts that make each step a single command:
|
|
180
192
|
|
|
@@ -188,14 +200,14 @@ or IntelliJ it can find. `--editor <cmd>` names one outright.
|
|
|
188
200
|
|
|
189
201
|
In the window that opens:
|
|
190
202
|
|
|
191
|
-
1. **Edit `SPECIFICATION.md`**
|
|
203
|
+
1. **Edit `SPECIFICATION.md`** - what the system is for, which agents exist,
|
|
192
204
|
what each may reach for, and what _done_ means.
|
|
193
205
|
2. **Open the chat panel and send `/sync-with-spec`.** It reads the
|
|
194
206
|
specification and every file implementing it, works out the difference in
|
|
195
207
|
both directions, and changes the smallest thing that closes each gap.
|
|
196
208
|
3. **Read `SPECIFICATION-FEEDBACK.md`**, which it writes for anything it could
|
|
197
209
|
not do without guessing. Answer its questions by editing `SPECIFICATION.md`
|
|
198
|
-
|
|
210
|
+
- not by editing prompts - and send `/sync-with-spec` again.
|
|
199
211
|
|
|
200
212
|
Back in the terminal: `zen check`, then `zen run`.
|
|
201
213
|
|
|
@@ -204,40 +216,52 @@ Back in the terminal: `zen check`, then `zen run`.
|
|
|
204
216
|
|
|
205
217
|
They are prompt files under `.github/prompts/`, which VS Code and its forks
|
|
206
218
|
offer as chat slash-commands. Both `zen init` and `zen open` write them fresh,
|
|
207
|
-
so they never go stale
|
|
219
|
+
so they never go stale - and edits to them do not survive.
|
|
208
220
|
|
|
209
221
|
| In chat | Does |
|
|
210
222
|
| ----------------- | ----------------------------------------------------------- |
|
|
211
223
|
| `/sync-with-spec` | Makes every file match `SPECIFICATION.md`, both directions. |
|
|
212
224
|
| `/review-project` | Reads the project as a reviewer would, and reports. |
|
|
213
|
-
| `/new-agent` | Adds an agent
|
|
225
|
+
| `/new-agent` | Adds an agent - prompt, wiring and hand-offs. |
|
|
214
226
|
| `/new-skill` | Adds a skill under `agents/skills/`. |
|
|
215
227
|
|
|
216
228
|
In an editor that does not support prompt files, paste the contents of
|
|
217
|
-
`.github/prompts/sync-with-spec.prompt.md` into its chat instead
|
|
229
|
+
`.github/prompts/sync-with-spec.prompt.md` into its chat instead - it is only a
|
|
218
230
|
prompt. Alongside them, `.github/copilot-instructions.md` is the standing brief
|
|
219
231
|
that explains this runtime to whatever agent is reading, and
|
|
220
232
|
`.github/skills/zen-cli/` is the CLI's own reference for it.
|
|
221
233
|
|
|
222
234
|
</details>
|
|
223
235
|
|
|
224
|
-
### The loop
|
|
236
|
+
### The self-improving loop
|
|
225
237
|
|
|
226
238
|
```
|
|
227
|
-
edit SPECIFICATION.md → /sync-with-spec → zen check →
|
|
228
|
-
↑
|
|
229
|
-
|
|
239
|
+
edit SPECIFICATION.md → /sync-with-spec → zen check → zen run
|
|
240
|
+
↑ ↓
|
|
241
|
+
└───── refine the spec <-──── zen inspect <-───────┘
|
|
230
242
|
```
|
|
231
243
|
|
|
232
|
-
|
|
233
|
-
|
|
244
|
+
`zen inspect` makes the record visible: the run trace, timing and token
|
|
245
|
+
statistics, agent architecture, and memory used during the run.
|
|
246
|
+
|
|
247
|
+

|
|
248
|
+
|
|
249
|
+
Every step is a command, and everything each one reads or writes is a plain
|
|
250
|
+
file: the specification, the findings `zen check` prints with a code, a location
|
|
251
|
+
and a fix, the record `zen inspect` renders of what the run actually did. So the
|
|
252
|
+
loop does not need you standing in it. Hand the whole cycle to the agent in your
|
|
253
|
+
editor and it runs on the system it just built - test it, read the failure,
|
|
254
|
+
change the sentence in the specification that caused it, rebuild, run again.
|
|
255
|
+
"Fix my project" is one instruction. (The first time round, `scripts/_setup.sh`
|
|
256
|
+
prepares the container the tools run in.)
|
|
257
|
+
|
|
258
|
+
The last turn is the one that matters. When a run comes out wrong the fix is the
|
|
259
|
+
sentence that was missing from the specification, and the prompt edit follows
|
|
234
260
|
from that. Prompts patched directly drift away from the document meant to
|
|
235
261
|
describe them, and a project whose specification is no longer true is a project
|
|
236
262
|
with no specification.
|
|
237
263
|
|
|
238
|
-
|
|
239
|
-
read by a model as much as by a person — every finding carries a code, a
|
|
240
|
-
location and its fix — so "fix my project" is one instruction. Full guide:
|
|
264
|
+
Full guide:
|
|
241
265
|
[docs/specification.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/specification.md).
|
|
242
266
|
|
|
243
267
|
## A worked example
|
|
@@ -249,7 +273,7 @@ zen init repo-notes && cd repo-notes
|
|
|
249
273
|
zen open # opens this folder in your editor
|
|
250
274
|
```
|
|
251
275
|
|
|
252
|
-
Replace `SPECIFICATION.md` with what you want. This is the whole input
|
|
276
|
+
Replace `SPECIFICATION.md` with what you want. This is the whole input - no
|
|
253
277
|
YAML, no prompt files:
|
|
254
278
|
|
|
255
279
|
```markdown
|
|
@@ -261,9 +285,9 @@ Read a codebase and leave a short written note about it in the workspace.
|
|
|
261
285
|
|
|
262
286
|
## Agents
|
|
263
287
|
|
|
264
|
-
- `reader`
|
|
288
|
+
- `reader` - explores the workspace and forms a picture of it. May read files
|
|
265
289
|
and list directories, and nothing else. Hands off to `writer`.
|
|
266
|
-
- `writer`
|
|
290
|
+
- `writer` - turns that picture into `NOTES.md`. May write to the workspace.
|
|
267
291
|
|
|
268
292
|
## Done means
|
|
269
293
|
|
|
@@ -271,7 +295,7 @@ Read a codebase and leave a short written note about it in the workspace.
|
|
|
271
295
|
- Every claim in it comes from a file that was actually read.
|
|
272
296
|
```
|
|
273
297
|
|
|
274
|
-
Send `/sync-with-spec` in the editor's chat. It writes `agents.yaml`
|
|
298
|
+
Send `/sync-with-spec` in the editor's chat. It writes `agents.yaml` - who
|
|
275
299
|
exists, and what each may reach for:
|
|
276
300
|
|
|
277
301
|
```yaml
|
|
@@ -292,7 +316,7 @@ agents:
|
|
|
292
316
|
handoffs: [reader] # a hand-off does not return by itself; give it a way back
|
|
293
317
|
```
|
|
294
318
|
|
|
295
|
-
|
|
319
|
+
- and one prompt file per agent.
|
|
296
320
|
|
|
297
321
|
<details>
|
|
298
322
|
<summary>The prompt files it writes</summary>
|
|
@@ -320,15 +344,15 @@ lines. Then say where you put it and stop.
|
|
|
320
344
|
| Key | Is |
|
|
321
345
|
| ------------- | --------------------------------------------------------------------- |
|
|
322
346
|
| `name` | how everything else refers to this agent |
|
|
323
|
-
| `description` | what it is for
|
|
347
|
+
| `description` | what it is for - read by the _other_ agents when deciding to hand off |
|
|
324
348
|
| `system` | its own brief, in prose, at `agents/prompts/<name>.md` |
|
|
325
349
|
| `model` | this agent's model; the top-level one otherwise |
|
|
326
|
-
| `tools` | what it may reach for
|
|
350
|
+
| `tools` | what it may reach for - `workspace:*`, `sandbox:*`, a named tool |
|
|
327
351
|
| `handoffs` | who it may pass the work to |
|
|
328
352
|
| `skills` | knowledge pulled in mid-run instead of carried in every prompt |
|
|
329
353
|
|
|
330
354
|
The file is validated strictly at load: an unknown tool, a handoff to nobody, a
|
|
331
|
-
missing prompt file
|
|
355
|
+
missing prompt file - each fails immediately, naming the offending key, rather
|
|
332
356
|
than surfacing three turns into a run as a confused model. Full reference:
|
|
333
357
|
[docs/agents-yaml.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/agents-yaml.md).
|
|
334
358
|
|
|
@@ -345,21 +369,21 @@ zen inspect --project repo-notes --open # what it actually did
|
|
|
345
369
|
|
|
346
370
|
That is the end of it: `repo-notes` is now a command like any other, in any
|
|
347
371
|
directory, for as long as the folder exists. Commit the folder and whoever
|
|
348
|
-
clones it types `zen init repo-notes` once
|
|
349
|
-
project is registered, not rebuilt, and nothing in it is touched
|
|
372
|
+
clones it types `zen init repo-notes` once - a directory that is already a
|
|
373
|
+
project is registered, not rebuilt, and nothing in it is touched - and the name
|
|
350
374
|
is a command on their machine too.
|
|
351
375
|
|
|
352
376
|
## A project is a folder
|
|
353
377
|
|
|
354
|
-
Prompts, agent wiring, skills and tool selections are all files
|
|
355
|
-
YAML
|
|
378
|
+
Prompts, agent wiring, skills and tool selections are all files - Markdown and
|
|
379
|
+
YAML - rather than code buried inside an application. So the folder can be
|
|
356
380
|
committed, copied to another machine, reviewed in a pull request, and handed to
|
|
357
381
|
someone else who runs it with one command. Credentials live in `$HOME`, never in
|
|
358
382
|
the project, so there is no secret to strip before sharing it.
|
|
359
383
|
|
|
360
384
|
```
|
|
361
385
|
my-project/
|
|
362
|
-
SPECIFICATION.md what this is for
|
|
386
|
+
SPECIFICATION.md what this is for - the intent
|
|
363
387
|
INSTRUCTIONS.md house rules, prepended to every agent
|
|
364
388
|
agents.yaml who exists, what they may reach for
|
|
365
389
|
agents/
|
|
@@ -379,29 +403,50 @@ happened when it ran. Nothing here is tied to the machine it was written on,
|
|
|
379
403
|
which is the point of the CLI: it makes agentic systems shareable the way
|
|
380
404
|
repositories are shareable.
|
|
381
405
|
|
|
382
|
-
`zen init` also writes `.vscode/` and a `.github/` tree
|
|
406
|
+
`zen init` also writes `.vscode/` and a `.github/` tree - a standing brief that
|
|
383
407
|
explains this runtime to whatever coding agent you open the folder with, plus
|
|
384
408
|
the prompts and skills it needs to keep the project matching its specification.
|
|
385
409
|
|
|
386
410
|
## Concepts
|
|
387
411
|
|
|
388
|
-
- **Project**
|
|
412
|
+
- **Project** - a named directory holding a complete agent definition and the
|
|
389
413
|
sessions that have run against it. It is self-describing: `agents.yaml` is
|
|
390
414
|
what makes a directory a project, so moving or cloning it loses nothing.
|
|
391
|
-
- **Session**
|
|
415
|
+
- **Session** - a context that persists across runs: one workspace, one memory,
|
|
392
416
|
one store for large files, and a record of everything that happened, added to
|
|
393
417
|
as it goes. Resumable.
|
|
394
|
-
- **Run**
|
|
418
|
+
- **Run** - one prompt in, one answer out, inside a session. Recorded in full,
|
|
395
419
|
whether or not you were watching.
|
|
396
|
-
- **Workspace**
|
|
420
|
+
- **Workspace** - the directory the agents may read and write. A prompt given on
|
|
397
421
|
the command line uses the current directory; the TUI offers the session's own
|
|
398
422
|
empty folder instead, and asks before using anything outside it.
|
|
399
|
-
- **Keyring**
|
|
423
|
+
- **Keyring** - `~/.zenera/neo`, readable only by you. See
|
|
400
424
|
[Credentials](#credentials).
|
|
401
|
-
- **Cache**
|
|
425
|
+
- **Cache** - `~/.zenera/neo/cache`, one place for work already done: vectors,
|
|
402
426
|
parses, model listings, generated mocks. Shared by every project on the
|
|
403
427
|
machine, and never emptied by anything but you. See [Cache](#cache--work-you-have-already-paid-for).
|
|
404
428
|
|
|
429
|
+
## Sandbox commands
|
|
430
|
+
|
|
431
|
+
Agents use an isolated container when a project grants them command-line tools.
|
|
432
|
+
`zen run` prepares it automatically before the first command, but these commands
|
|
433
|
+
make setup, diagnostics and cleanup explicit - useful on a new machine or when
|
|
434
|
+
you want to validate a project's execution environment before a run.
|
|
435
|
+
|
|
436
|
+
```sh
|
|
437
|
+
zen sandbox status # engine, project image and active containers
|
|
438
|
+
zen sandbox up # prepare the execution environment for this project
|
|
439
|
+
zen sandbox pull # pull or build this project's image only
|
|
440
|
+
zen sandbox status --project my-app # inspect a named project from anywhere
|
|
441
|
+
zen sandbox disk # storage used by the engine and known projects
|
|
442
|
+
zen sandbox clean # remove containers created by zen
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
`status`, `up` and `pull` use the project in the current directory, or accept
|
|
446
|
+
`--project <name|dir>`. `--image <ref>` selects an image explicitly. `clean` and
|
|
447
|
+
`disk` are machine-wide operations, so use them when you mean to inspect or
|
|
448
|
+
remove resources beyond the current project.
|
|
449
|
+
|
|
405
450
|
## Commands
|
|
406
451
|
|
|
407
452
|
| Command | Does |
|
|
@@ -409,11 +454,11 @@ the prompts and skills it needs to keep the project matching its specification.
|
|
|
409
454
|
| `init` | Creates a project here, or in `<dir>`, and registers it. |
|
|
410
455
|
| `list` | Every known project: sessions, last run, whether one is live. |
|
|
411
456
|
| `open` | Opens a project in your editor. |
|
|
412
|
-
| `key` | The credential keyring
|
|
413
|
-
| `models` | What this machine can use
|
|
414
|
-
| `run` | Runs the project
|
|
457
|
+
| `key` | The credential keyring - add, check, switch, remove. |
|
|
458
|
+
| `models` | What this machine can use - list, search, test, pick. |
|
|
459
|
+
| `run` | Runs the project - the TUI on a terminal, a single answer otherwise. |
|
|
415
460
|
| `inspect` | Opens or rebuilds a run's `report.html`. |
|
|
416
|
-
| `memory` | What the agents remember
|
|
461
|
+
| `memory` | What the agents remember - size, listing, one node, or a whole page. |
|
|
417
462
|
| `check` | Validates the project and every file it names, and asks the models. |
|
|
418
463
|
| `sandbox` | Checks and prepares the container that command-line tools run in. |
|
|
419
464
|
| `cache` | What work has been kept, and getting rid of it. |
|
|
@@ -433,17 +478,36 @@ an installed one costs nothing until it is used.
|
|
|
433
478
|
| `faker` | `@zenera/faker` | A mock API from an openapi/swagger document. |
|
|
434
479
|
| `rag` | `@zenera/rag` | Search an openapi/swagger document as a graph. |
|
|
435
480
|
|
|
481
|
+
**`zen faker`** turns an OpenAPI or Swagger description into a working mock
|
|
482
|
+
server. It generates behavior for each route, checks the result against the
|
|
483
|
+
response contract, and reuses the generated implementation on later requests.
|
|
484
|
+
|
|
436
485
|
```sh
|
|
437
486
|
npm i -g @zenera/faker
|
|
438
487
|
zen faker serve api/openapi.yaml --port 8787 # a working mock, bodies written by a model
|
|
439
488
|
|
|
489
|
+
curl -s localhost:8787/users/12324
|
|
490
|
+
# { "user_id": 12324, "email": "brooke.hoffman@example.org", … }
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**`zen rag`** adds advanced retrieval for the knowledge an agent needs to work
|
|
494
|
+
from: documentation and API schemas. Document indexes support semantic,
|
|
495
|
+
full-text and hybrid search with passages returned alongside their source lines.
|
|
496
|
+
Schema indexes add graph-aware retrieval across operations, types, fields,
|
|
497
|
+
requests and responses, so an answer can include the connected API context
|
|
498
|
+
rather than an isolated match.
|
|
499
|
+
|
|
500
|
+
```sh
|
|
440
501
|
npm i -g @zenera/rag
|
|
441
502
|
zen rag schema index --embedding openai:text-embedding-3-small ./specs/*.yaml
|
|
442
503
|
zen rag schema search --output-property "user billing history" --format ts
|
|
504
|
+
|
|
505
|
+
zen rag docs index ./handbook --embedding openai:text-embedding-3-small
|
|
506
|
+
zen rag docs search "how does failover work when the primary is unreachable"
|
|
443
507
|
```
|
|
444
508
|
|
|
445
|
-
|
|
446
|
-
|
|
509
|
+
Use [@zenera/rag](https://github.com/andreyryabov/ZeneraNeo/blob/main/packages/rag/README.md)
|
|
510
|
+
for its complete retrieval capabilities and examples. Details:
|
|
447
511
|
[@zenera/faker](https://github.com/andreyryabov/ZeneraNeo/blob/main/packages/faker/README.md)
|
|
448
512
|
·
|
|
449
513
|
[@zenera/rag](https://github.com/andreyryabov/ZeneraNeo/blob/main/packages/rag/README.md).
|
|
@@ -455,7 +519,7 @@ The binary is installed under three names: `zen`, `zn` and `zenera`.
|
|
|
455
519
|
Global flags: `-h/--help`, `-v/--version`, `--json`, `-C <dir>`.
|
|
456
520
|
|
|
457
521
|
`stdout` carries the answer and `stderr` carries the narration, and `--json`
|
|
458
|
-
works on every command
|
|
522
|
+
works on every command - so `zen run … | jq` is a supported way to use this, not
|
|
459
523
|
an accident.
|
|
460
524
|
|
|
461
525
|
| Exit code | Meaning |
|
|
@@ -479,7 +543,7 @@ zen key add <provider> < key.txt # or pipe it in
|
|
|
479
543
|
|
|
480
544
|
The value is never passed as an argument. A command line is visible to anyone
|
|
481
545
|
listing running processes, is saved in your shell history and is captured in CI
|
|
482
|
-
logs
|
|
546
|
+
logs - so the hidden prompt and piping it in are the only two ways.
|
|
483
547
|
|
|
484
548
|
Entries live in `~/.zenera/neo/keys.json`, in a file only you can read. They are
|
|
485
549
|
copied into the environment just before a run, which has two consequences worth
|
|
@@ -490,14 +554,14 @@ checked out on a machine without `zen` still runs.
|
|
|
490
554
|
| ------------ | ------------------------------------- | -------------------------------- |
|
|
491
555
|
| `openai` | a secret | `OPENAI_API_KEY` |
|
|
492
556
|
| `anthropic` | a secret | `ANTHROPIC_API_KEY` |
|
|
493
|
-
| `google` | a secret
|
|
557
|
+
| `google` | a secret - AI Studio | `GEMINI_API_KEY` |
|
|
494
558
|
| `vertex` | a path to a service-account JSON file | `GOOGLE_APPLICATION_CREDENTIALS` |
|
|
495
559
|
| `openrouter` | a secret | `OPENROUTER_API_KEY` |
|
|
496
|
-
| `exa` | a secret
|
|
560
|
+
| `exa` | a secret - for the search tool | `EXA_API_KEY` |
|
|
497
561
|
|
|
498
562
|
`zen key add` verifies the credential against the provider before it finishes,
|
|
499
|
-
but stores it either way: a key that cannot be checked right now
|
|
500
|
-
behind a proxy
|
|
563
|
+
but stores it either way: a key that cannot be checked right now - offline,
|
|
564
|
+
behind a proxy - is not a key that is wrong. `--no-check` skips the call.
|
|
501
565
|
|
|
502
566
|
### Which key a model uses
|
|
503
567
|
|
|
@@ -533,12 +597,12 @@ been one does a short built-in list stand in.
|
|
|
533
597
|
`zen models test` separates three kinds of failure, because each calls for a
|
|
534
598
|
different action:
|
|
535
599
|
|
|
536
|
-
- **refused**
|
|
537
|
-
- **blocked**
|
|
600
|
+
- **refused** - the provider rejected the credential. Fix or replace the key.
|
|
601
|
+
- **blocked** - the credential was accepted and the account then said no: an API
|
|
538
602
|
switched off, an empty balance, a model this key was never granted. The key is
|
|
539
603
|
fine; the account needs changing, and the command that changes it is printed
|
|
540
604
|
with the error.
|
|
541
|
-
- **unknown**
|
|
605
|
+
- **unknown** - the question never arrived (offline, proxy, timeout). Nothing is
|
|
542
606
|
wrong with the key; try again.
|
|
543
607
|
|
|
544
608
|
```
|
|
@@ -559,11 +623,11 @@ zen rag schema index --embedding "$(zen models pick --embedding)" ./specs/*.yaml
|
|
|
559
623
|
|
|
560
624
|
### Setting up each provider
|
|
561
625
|
|
|
562
|
-
The shape is the same everywhere
|
|
626
|
+
The shape is the same everywhere - `zen key add <provider>`, then answer the
|
|
563
627
|
prompt. Open the one you need for its specifics.
|
|
564
628
|
|
|
565
629
|
<details>
|
|
566
|
-
<summary><strong>OpenAI</strong>
|
|
630
|
+
<summary><strong>OpenAI</strong> - one secret, exported as <code>OPENAI_API_KEY</code></summary>
|
|
567
631
|
|
|
568
632
|
```sh
|
|
569
633
|
zen key add openai
|
|
@@ -575,7 +639,7 @@ zen key add openai
|
|
|
575
639
|
</details>
|
|
576
640
|
|
|
577
641
|
<details>
|
|
578
|
-
<summary><strong>Anthropic</strong>
|
|
642
|
+
<summary><strong>Anthropic</strong> - one secret, exported as <code>ANTHROPIC_API_KEY</code></summary>
|
|
579
643
|
|
|
580
644
|
```sh
|
|
581
645
|
zen key add anthropic
|
|
@@ -585,7 +649,7 @@ zen run --model anthropic:claude-sonnet-4-5 "summarise this repo"
|
|
|
585
649
|
</details>
|
|
586
650
|
|
|
587
651
|
<details>
|
|
588
|
-
<summary><strong>OpenRouter</strong>
|
|
652
|
+
<summary><strong>OpenRouter</strong> - one secret, exported as <code>OPENROUTER_API_KEY</code></summary>
|
|
589
653
|
|
|
590
654
|
One credential for many vendors' models. The model id keeps its own vendor
|
|
591
655
|
prefix, after the `openrouter:` one:
|
|
@@ -599,7 +663,7 @@ zen run --model openrouter:anthropic/claude-haiku-4.5 "summarise this repo"
|
|
|
599
663
|
</details>
|
|
600
664
|
|
|
601
665
|
<details>
|
|
602
|
-
<summary><strong>Google AI Studio</strong>
|
|
666
|
+
<summary><strong>Google AI Studio</strong> - one secret, exported as <code>GEMINI_API_KEY</code></summary>
|
|
603
667
|
|
|
604
668
|
One key and nothing else to configure: the shortest way to a working Gemini
|
|
605
669
|
model.
|
|
@@ -610,7 +674,7 @@ zen check # google:gemini-3.5-flash now resolves
|
|
|
610
674
|
```
|
|
611
675
|
|
|
612
676
|
The same Gemini models are also served by Vertex AI, under a different
|
|
613
|
-
credential. Both can be configured at once
|
|
677
|
+
credential. Both can be configured at once - they are separate entries for
|
|
614
678
|
separate services, and the prefix on the model reference decides which is used:
|
|
615
679
|
|
|
616
680
|
```sh
|
|
@@ -621,12 +685,12 @@ zen run --model vertex:gemini-3.5-flash "summarise this repo"
|
|
|
621
685
|
</details>
|
|
622
686
|
|
|
623
687
|
<details>
|
|
624
|
-
<summary><strong>Vertex AI</strong>
|
|
688
|
+
<summary><strong>Vertex AI</strong> - a service-account file, or an express-mode key</summary>
|
|
625
689
|
|
|
626
690
|
Vertex accepts two kinds of credential, and you never declare which one you are
|
|
627
691
|
giving: if the value is a path to a file that exists it is treated as a
|
|
628
692
|
service-account key, otherwise as an API key. The name you give the entry has no
|
|
629
|
-
bearing on this
|
|
693
|
+
bearing on this - `vertex/express` is just an entry called `express`, exactly as
|
|
630
694
|
`vertex/prod` is one called `prod`, and either name can hold either kind.
|
|
631
695
|
|
|
632
696
|
**A service-account JSON file** is the usual one, and what production normally
|
|
@@ -638,7 +702,7 @@ zen key add vertex --gcp-location us-central1
|
|
|
638
702
|
# Paste the key, or a path to the file: /Users/you/keys/vertex-sa.json
|
|
639
703
|
```
|
|
640
704
|
|
|
641
|
-
The prompt is read by `zen`, not by your shell, so give a full path there
|
|
705
|
+
The prompt is read by `zen`, not by your shell, so give a full path there - `~`
|
|
642
706
|
is not expanded. In a script, pipe the path in instead:
|
|
643
707
|
|
|
644
708
|
```sh
|
|
@@ -657,7 +721,7 @@ moving or cleaning up the original later cannot break it.
|
|
|
657
721
|
- Which models a location serves varies per model and is not guessable. In one
|
|
658
722
|
project, `gemini-embedding-2` answered at `us` but 404'd at `us-central1`,
|
|
659
723
|
while `gemini-2.5-flash` did the opposite. New models often reach `global`,
|
|
660
|
-
`us` and `eu` first. `zen models test vertex:<model>` is what settles it
|
|
724
|
+
`us` and `eu` first. `zen models test vertex:<model>` is what settles it -
|
|
661
725
|
`zen key add` only establishes that the credential itself works.
|
|
662
726
|
- `--gcp-project <id>` is only needed when the `project_id` inside the file is
|
|
663
727
|
not the project you want to bill:
|
|
@@ -686,7 +750,7 @@ keyring, so it is always visible which credential a run will actually use.
|
|
|
686
750
|
</details>
|
|
687
751
|
|
|
688
752
|
<details>
|
|
689
|
-
<summary><strong>Exa</strong>
|
|
753
|
+
<summary><strong>Exa</strong> - one secret, exported as <code>EXA_API_KEY</code></summary>
|
|
690
754
|
|
|
691
755
|
Not a model provider: this is what backs the search tool an agent reaches for
|
|
692
756
|
when it has to look something up on the web.
|
|
@@ -706,7 +770,7 @@ Entries are named, so a provider can hold several, one of which is active:
|
|
|
706
770
|
zen key add openai/work # a second entry
|
|
707
771
|
zen key use openai/work # the one that runs will use
|
|
708
772
|
zen key ls --check # everything stored, and whether it still works
|
|
709
|
-
zen key show vertex/default # masked
|
|
773
|
+
zen key show vertex/default # masked - --reveal prints the secret
|
|
710
774
|
zen key env openai # shell exports, for other tools
|
|
711
775
|
zen key rm openai/work
|
|
712
776
|
```
|
|
@@ -722,12 +786,12 @@ zen key use vertex/dev # which one the next run uses
|
|
|
722
786
|
```
|
|
723
787
|
|
|
724
788
|
`zen key ls` marks the active entry with `*`, and anything it found outside the
|
|
725
|
-
keyring
|
|
789
|
+
keyring - in your environment, or in a `gcloud` login - with `~`, so it is always
|
|
726
790
|
clear where a working provider actually comes from.
|
|
727
791
|
|
|
728
792
|
</details>
|
|
729
793
|
|
|
730
|
-
## Cache
|
|
794
|
+
## Cache - work you have already paid for
|
|
731
795
|
|
|
732
796
|
Embedding a paragraph, parsing a document, asking a provider what it serves: all
|
|
733
797
|
of these are slow or costly, and all of them give the same answer every time. So
|
|
@@ -756,7 +820,7 @@ time.
|
|
|
756
820
|
## The library underneath
|
|
757
821
|
|
|
758
822
|
This is a shell over
|
|
759
|
-
[`@zenera/neo`](https://www.npmjs.com/package/@zenera/neo)
|
|
823
|
+
[`@zenera/neo`](https://www.npmjs.com/package/@zenera/neo) - agents, models,
|
|
760
824
|
tools, skills, memory and a running record of everything that happened. Use it
|
|
761
825
|
directly when you want the runtime inside your own application rather than on a
|
|
762
826
|
terminal:
|
|
@@ -765,19 +829,19 @@ terminal:
|
|
|
765
829
|
## Documentation
|
|
766
830
|
|
|
767
831
|
- [docs/specification.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/specification.md)
|
|
768
|
-
|
|
832
|
+
- writing the specification the project implements.
|
|
769
833
|
- [docs/projects.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/projects.md)
|
|
770
|
-
|
|
834
|
+
- what the project folder contains, file by file.
|
|
771
835
|
- [docs/agents-yaml.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/agents-yaml.md)
|
|
772
|
-
|
|
836
|
+
- every key in the configuration file.
|
|
773
837
|
- [docs/knowledge.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/knowledge.md)
|
|
774
|
-
|
|
838
|
+
- building a searchable document index.
|
|
775
839
|
- [docs/integrations.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/integrations.md)
|
|
776
|
-
|
|
840
|
+
- making an API description searchable and mockable.
|
|
777
841
|
- [docs/memory.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/memory.md)
|
|
778
|
-
|
|
842
|
+
- what agents keep between sessions.
|
|
779
843
|
|
|
780
844
|
## License
|
|
781
845
|
|
|
782
|
-
Early days and moving fast
|
|
846
|
+
Early days and moving fast - issues, questions and pull requests are welcome.
|
|
783
847
|
[MIT](LICENSE).
|