@zenera/cli 1.1.37 → 1.1.39
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 +158 -900
- package/dist/commands/index.js +6 -7
- package/dist/commands/sandbox.js +5 -5
- package/dist/external.js +1 -1
- package/dist/podman.js +3 -3
- package/dist/resources.d.ts +2 -2
- package/dist/resources.js +5 -5
- package/package.json +7 -7
- package/templates/editor/.github/skills/zen-cli/SKILL.md +3 -3
- package/templates/editor/.github/skills/zen-cli/references/frame.md +2 -2
- package/templates/editor/.github/skills/zen-cli/references/{faker.md → gym.md} +45 -40
- package/templates/editor/.github/skills/zen-cli/references/keys.md +2 -2
- package/templates/editor/.github/skills/zen-cli/references/models.md +1 -1
- package/templates/editor/.github/skills/zen-cli/references/rag.md +1 -1
- package/templates/editor/.vscode/agents.schema.json +1 -1
package/README.md
CHANGED
|
@@ -1,996 +1,254 @@
|
|
|
1
|
-
<div align="center">
|
|
1
|
+
<div align="center">
|
|
2
2
|
<img
|
|
3
|
-
src="https://raw.githubusercontent.com/
|
|
4
|
-
alt="Zenera
|
|
5
|
-
width="
|
|
3
|
+
src="https://raw.githubusercontent.com/zenera-ai/ZeneraNeo/main/docs/imgs/zenera-logo-with-media-queries.svg"
|
|
4
|
+
alt="Zenera"
|
|
5
|
+
width="24"
|
|
6
6
|
/>
|
|
7
7
|
<div>Powered By Zenera</div>
|
|
8
|
-
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
<br>
|
|
9
|
+
<img
|
|
10
|
+
src="https://raw.githubusercontent.com/zenera-ai/ZeneraNeo/main/docs/imgs/banner-cli-with-media-queries.svg"
|
|
11
|
+
alt="ZENERA CLI"
|
|
12
|
+
width="720"
|
|
13
|
+
/>
|
|
13
14
|
|
|
14
15
|
[](https://www.npmjs.com/package/@zenera/cli)
|
|
15
|
-
[](https://github.com/
|
|
16
|
+
[](https://github.com/zenera-ai/ZeneraNeo/blob/main/LICENSE)
|
|
16
17
|
[](https://nodejs.org)
|
|
17
|
-
[](https://github.com/zenera-ai/ZeneraNeo/actions/workflows/ci.yml)
|
|
18
19
|
|
|
19
|
-
[Install](#install) · [Quickstart](#quickstart) · [
|
|
20
|
+
[Why `zen`](#why-use-zen) · [Install](#install) · [Quickstart](#quickstart) · [Run](#run-it-your-way) · [Improve](#the-self-improving-loop) · [Evaluate](#evaluate-and-fine-tune) · [Share](#share-a-project) · [Commands](#commands-at-a-glance)
|
|
20
21
|
|
|
21
22
|
</div>
|
|
22
23
|
|
|
23
|
-
#
|
|
24
|
+
# `@zenera/cli`
|
|
25
|
+
|
|
26
|
+
**The CLI for [ZeneraNeo](https://github.com/zenera-ai/ZeneraNeo): build, run, and improve specialist AI agent systems from your terminal.**
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
The `zen` command is the everyday interface to ZeneraNeo. Describe a recurring
|
|
29
|
+
job, use the meta-agent to shape its agent system, run it against your files and
|
|
30
|
+
tools, then inspect what happened and improve it from evidence. Use the
|
|
31
|
+
interactive terminal app for hands-on work, or run commands non-interactively
|
|
32
|
+
in scripts and CI.
|
|
26
33
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
ZeneraNeo is built for work that benefits from focused specialists rather than
|
|
35
|
+
one general-purpose assistant: research and analysis, document and policy
|
|
36
|
+
review, operations, software delivery, and workflows that need to use your
|
|
37
|
+
existing knowledge. Agent runs can search project knowledge, use persistent
|
|
38
|
+
memory, and execute commands in a container. Their traces, outputs, timing, and
|
|
39
|
+
token usage are available to inspect.
|
|
32
40
|
|
|
33
|
-
> Part of [ZeneraNeo](https://github.com/
|
|
41
|
+
> Part of [ZeneraNeo](https://github.com/zenera-ai/ZeneraNeo). This is an
|
|
34
42
|
> open-source side project for experimentation and chore work - **not** the
|
|
35
43
|
> official Zenera AI Platform. It carries no support or stability promises.
|
|
36
44
|
|
|
37
45
|
<details>
|
|
38
46
|
<summary><strong>Contents</strong></summary>
|
|
39
47
|
|
|
40
|
-
- [
|
|
41
|
-
- [What you build](#what-you-build)
|
|
42
|
-
- [Why it is different](#why-it-is-different)
|
|
48
|
+
- [Why use `zen`?](#why-use-zen)
|
|
43
49
|
- [Install](#install)
|
|
44
50
|
- [Quickstart](#quickstart)
|
|
45
|
-
- [
|
|
46
|
-
- [How it works](#how-it-works)
|
|
47
|
-
- [The specification and the meta agent](#the-specification-and-the-meta-agent)
|
|
48
|
-
- [A worked example](#a-worked-example)
|
|
49
|
-
- [Anatomy of a project](#anatomy-of-a-project)
|
|
51
|
+
- [Run it your way](#run-it-your-way)
|
|
50
52
|
- [The self-improving loop](#the-self-improving-loop)
|
|
51
53
|
- [Evaluate and fine-tune](#evaluate-and-fine-tune)
|
|
52
54
|
- [Share a project](#share-a-project)
|
|
53
|
-
- [
|
|
54
|
-
|
|
55
|
-
- [Conventions and exit codes](#conventions-and-exit-codes)
|
|
56
|
-
- [The meta agent](#the-meta-agent)
|
|
57
|
-
- [Models and credentials](#models-and-credentials)
|
|
58
|
-
- [Sandbox](#sandbox)
|
|
59
|
-
- [Cache](#cache)
|
|
60
|
-
- [Ecosystem](#ecosystem)
|
|
61
|
-
- [Documentation](#documentation)
|
|
62
|
-
- [License](#license)
|
|
55
|
+
- [Commands at a glance](#commands-at-a-glance)
|
|
56
|
+
- [Learn more](#learn-more)
|
|
63
57
|
|
|
64
58
|
</details>
|
|
65
59
|
|
|
66
|
-
##
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
the
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
directory, runs real commands in a container, searches the web when it needs
|
|
86
|
-
to, and records every token it spends.
|
|
87
|
-
|
|
88
|
-
Getting there takes three steps:
|
|
89
|
-
|
|
90
|
-
1. **Describe it.** Write `SPECIFICATION.md`: what the system is for, which
|
|
91
|
-
specialists it needs, what each may use, and what _done_ means.
|
|
92
|
-
2. **Test it.** `zen check` validates the project, `zen run` exercises it,
|
|
93
|
-
`zen inspect` shows what it actually did. When the result is wrong, fix the
|
|
94
|
-
specification, not the prompts, and go round again.
|
|
95
|
-
3. **Share it.** A project is a folder: commit it, review it in a pull request,
|
|
96
|
-
send it. On the other end, one `zen init <dir>` registers it and it becomes
|
|
97
|
-
their command too.
|
|
98
|
-
|
|
99
|
-
## What you build
|
|
100
|
-
|
|
101
|
-
Half a page of specification becomes a system like one of these. None of them
|
|
102
|
-
ship with the CLI; each is a folder someone wrote and could send you.
|
|
103
|
-
|
|
104
|
-
| Project | The team inside it |
|
|
105
|
-
| :------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
106
|
-
| **accountant** | A **bookkeeper** reads and classifies every receipt, statement, invoice and agreement in the folder. A **reconciler** matches each against a ledger line or playbook position and lists what has no pair. A **preparer** fills the return or drafts the redlines. A **checker** rejects anything no document substantiates. |
|
|
107
|
-
| **analyst** | A **planner** splits the question into branches. **Researchers** work in parallel over your files and the web. A **statistician** writes and runs Python in the sandbox. An **editor** joins it into one answer where every claim carries its source. |
|
|
108
|
-
| **devops** | A **gatherer** pulls advisories, logs, alerts and deploys into one picture. A **tracer** works out whether a vulnerable path is reachable, or which change broke production. An **engineer** plans the fix, applies it step by step, and stops the moment a check fails. |
|
|
109
|
-
|
|
110
|
-
A committed project runs the same on anyone's machine, on whichever models they
|
|
111
|
-
prefer, without carrying your keys.
|
|
112
|
-
|
|
113
|
-
## Why it is different
|
|
114
|
-
|
|
115
|
-
Most tools give you one agent, or a framework and an empty file. `zen` is a
|
|
116
|
-
factory: it designs the system for you, then keeps it honest.
|
|
117
|
-
|
|
118
|
-
- **A meta-agent designs the system.** You state the problem; it derives the
|
|
119
|
-
specialists, prompts, tool grants, hand-offs and fan-out from what you wrote,
|
|
120
|
-
and validates them before anything runs.
|
|
121
|
-
- **Self-improvement, not a one-off build.** Build, run, read the record, fix
|
|
122
|
-
what was wrong, run again, and the meta-agent can drive that loop itself.
|
|
123
|
-
Failures come back as findings with a cause and a fix.
|
|
124
|
-
- **Agent fine-tuning on datasets and rubrics.** Cases built from your
|
|
125
|
-
specification are run, scored, analyzed and re-run until the system is both
|
|
126
|
-
correct and lean. It tunes prompts, skills and memory, not model weights.
|
|
127
|
-
- **Built-in observability.** Every run is recorded against the architecture it
|
|
128
|
-
declared: the agent nobody called, the skill that never fired, where the
|
|
129
|
-
tokens went. Nothing to instrument, nothing to sign up for.
|
|
130
|
-
- **Your knowledge, searchable.** Hybrid retrieval over your documents and API
|
|
131
|
-
descriptions, plus a graph memory, so what an agent learned in March is still
|
|
132
|
-
there in September.
|
|
133
|
-
- **Integrations it writes itself.** No MCP server to find, no connector to wait
|
|
134
|
-
for. To reach your ERP, your database or a twenty-year-old SOAP endpoint, it
|
|
135
|
-
writes the call and runs it in a sandbox.
|
|
136
|
-
- **Customisable all the way down.** Stay in the specification, tune a single
|
|
137
|
-
agent's model, tools and memory, or drive the kernel turn by turn. No layer is
|
|
138
|
-
sealed.
|
|
60
|
+
## Why use `zen`?
|
|
61
|
+
|
|
62
|
+
- **Turn a job description into a working system.** Describe the outcome and
|
|
63
|
+
constraints; the meta-agent can create and update the specialist agents,
|
|
64
|
+
instructions, skills, and hand-offs that implement them.
|
|
65
|
+
- **Keep improvement grounded in runs.** Validate the setup, inspect recorded
|
|
66
|
+
traces, evaluate against cases, and tune prompts, skills, and memory policies.
|
|
67
|
+
Fine-tuning here improves the agent system around the model; it does not
|
|
68
|
+
train model weights.
|
|
69
|
+
- **Work with your own material.** Run agents against a chosen workspace, use
|
|
70
|
+
document and API-schema retrieval through ZeneraNeo's RAG tools, and retain
|
|
71
|
+
useful knowledge in memory.
|
|
72
|
+
- **See what the system did.** Open a run report or inspect its graph and
|
|
73
|
+
individual steps, including tool calls and usage.
|
|
74
|
+
- **Use it interactively or automate it.** `zen run` offers a terminal UI when
|
|
75
|
+
you want one and one-shot, JSON, and batch modes for scripts and pipelines.
|
|
76
|
+
- **Choose your model provider.** The CLI supports OpenAI, Anthropic, Google,
|
|
77
|
+
Vertex AI, and OpenRouter, and provides commands to manage credentials and
|
|
78
|
+
test available models.
|
|
139
79
|
|
|
140
80
|
## Install
|
|
141
81
|
|
|
142
|
-
Requires Node.js 24
|
|
143
|
-
with the CLI, so any of those providers works out of the box.
|
|
82
|
+
Requires **Node.js 24 or newer**.
|
|
144
83
|
|
|
145
84
|
```sh
|
|
146
|
-
npm
|
|
85
|
+
npm install --global @zenera/cli
|
|
147
86
|
```
|
|
148
87
|
|
|
149
|
-
|
|
88
|
+
The CLI is available as `zen`, `zn`, and `zenera`. To try it without a global
|
|
89
|
+
install:
|
|
150
90
|
|
|
151
91
|
```sh
|
|
152
92
|
npx @zenera/cli --help
|
|
153
93
|
```
|
|
154
94
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
<summary><strong>Tab completion</strong> (zsh, bash, fish)</summary>
|
|
159
|
-
|
|
160
|
-
A global npm install sets up completion for commands, projects and stored
|
|
161
|
-
prompts automatically. It appends a guarded loader to your current shell's
|
|
162
|
-
startup file, once. **Open a new terminal** to activate it; the installer
|
|
163
|
-
cannot update the terminal where you ran npm.
|
|
164
|
-
|
|
165
|
-
Setup respects `ZDOTDIR` for zsh and `XDG_CONFIG_HOME` for fish. For Bash on
|
|
166
|
-
macOS it covers both login shells (the active `.bash_profile`, `.bash_login` or
|
|
167
|
-
`.profile`) and non-login shells (`.bashrc`). The loader does nothing once `zen`
|
|
168
|
-
is uninstalled.
|
|
169
|
-
|
|
170
|
-
Automatic setup is skipped for local installs and `npx`, under root/sudo, in
|
|
171
|
-
CI, on Windows, when `$SHELL` is missing or unsupported, and with
|
|
172
|
-
`--ignore-scripts`. To set it up by hand, or for another shell:
|
|
173
|
-
|
|
174
|
-
```sh
|
|
175
|
-
zen completion --install # the shell you are in; --yes to skip the question
|
|
176
|
-
zen completion fish --install # or name one
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
Or add `eval "$(zen completion zsh)"` to `~/.zshrc` yourself.
|
|
180
|
-
|
|
181
|
-
</details>
|
|
95
|
+
Agent command execution uses a container sandbox. Install and configure
|
|
96
|
+
[Podman](https://podman.io/) for workflows that run shell commands;
|
|
97
|
+
`zen sandbox` checks and prepares the local environment.
|
|
182
98
|
|
|
183
99
|
## Quickstart
|
|
184
100
|
|
|
185
|
-
|
|
101
|
+
Add a key for a supported provider, choose the model used by the meta-agent,
|
|
102
|
+
and scaffold a project:
|
|
186
103
|
|
|
187
104
|
```sh
|
|
188
|
-
|
|
189
|
-
zen
|
|
190
|
-
zen init my-project
|
|
191
|
-
zen open my-project
|
|
105
|
+
zen key add openai
|
|
106
|
+
zen meta model --pick
|
|
107
|
+
zen init my-project
|
|
108
|
+
zen open my-project
|
|
192
109
|
```
|
|
193
110
|
|
|
194
|
-
|
|
195
|
-
|
|
111
|
+
Write the job, constraints, and what counts as a successful result in the
|
|
112
|
+
generated `SPECIFICATION.md`. Then ask the meta-agent to bring the implementation
|
|
113
|
+
in line with it, validate the setup, and run it:
|
|
196
114
|
|
|
197
115
|
```sh
|
|
198
116
|
zen meta run my-project /spec-sync-project
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
Validate the result and run it against a real directory:
|
|
202
|
-
|
|
203
|
-
```sh
|
|
204
117
|
zen check my-project
|
|
205
|
-
|
|
206
|
-
zen
|
|
207
|
-
zen inspect # open the run's report.html
|
|
118
|
+
zen run my-project "Summarize this repository and write NOTES.md"
|
|
119
|
+
zen inspect
|
|
208
120
|
```
|
|
209
121
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
zen list --sessions # every project, its sessions and last run
|
|
215
|
-
zen list --runs # the most recent runs across every project
|
|
216
|
-
echo "triage this" | zen run my-project --json | jq
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
Inside a project folder the name is optional: a bare `zen run`, `zen check` or
|
|
220
|
-
`zen inspect` means the project you are in.
|
|
221
|
-
|
|
222
|
-
A prompt on the command line skips every question: it starts a fresh session
|
|
223
|
-
and uses the current directory as the workspace, with write access.
|
|
224
|
-
`--session`, `--workspace` and `--read-only` override that.
|
|
225
|
-
|
|
226
|
-
## Concepts
|
|
227
|
-
|
|
228
|
-
- **Project**: a named directory holding a complete agent definition and the
|
|
229
|
-
sessions run against it. `agents.yaml` is what makes a directory a project,
|
|
230
|
-
so moving or cloning it loses nothing.
|
|
231
|
-
- **Specification**: `SPECIFICATION.md`, the description of what the project is
|
|
232
|
-
for. Every other file implements it, and where they disagree it wins.
|
|
233
|
-
- **Meta agent**: a coding agent that works _on_ the project, keeping its files
|
|
234
|
-
in line with the specification and improving them from evidence.
|
|
235
|
-
- **Session**: a context that persists across runs: one workspace, one memory,
|
|
236
|
-
one store for large files, and a full record of what happened. Resumable.
|
|
237
|
-
- **Run**: one prompt in, one answer out, inside a session. Recorded in full,
|
|
238
|
-
whether or not you were watching.
|
|
239
|
-
- **Workspace**: the directory the agents may read and write. A command-line
|
|
240
|
-
prompt uses the current directory; the TUI offers the session's own empty
|
|
241
|
-
folder and asks before using anything outside it.
|
|
242
|
-
- **Keyring**: `~/.zenera/neo`, readable only by you. See
|
|
243
|
-
[Models and credentials](#models-and-credentials).
|
|
244
|
-
- **Cache**: `~/.zenera/neo/cache`, shared by every project on the machine and
|
|
245
|
-
never emptied by anything but you. See [Cache](#cache).
|
|
246
|
-
|
|
247
|
-
## How it works
|
|
248
|
-
|
|
249
|
-
### The specification and the meta agent
|
|
250
|
-
|
|
251
|
-
`zen init` writes `SPECIFICATION.md` first, and everything else in the folder
|
|
252
|
-
implements it. A change to what the system does therefore starts in the
|
|
253
|
-
specification, not in `agents.yaml`.
|
|
254
|
-
|
|
255
|
-
The scaffolded specification is not a list of headings. It accurately describes
|
|
256
|
-
the project just created, so you can read it alongside the files before
|
|
257
|
-
changing a word:
|
|
258
|
-
|
|
259
|
-
```markdown
|
|
260
|
-
## Agents
|
|
261
|
-
|
|
262
|
-
One agent, `default`, which is the entry point and the whole system. It has
|
|
263
|
-
nobody to hand work to, because there is no second job to hand on.
|
|
264
|
-
|
|
265
|
-
## Done means
|
|
266
|
-
|
|
267
|
-
- The change asked for is in the workspace, or the question is answered from
|
|
268
|
-
what is actually in it.
|
|
269
|
-
- Everything the agent claims a command did, that command actually did - it was
|
|
270
|
-
run, and its output was read.
|
|
271
|
-
- The reply names what changed, file by file, and says what it deliberately did
|
|
272
|
-
not do.
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
The editing cycle is four steps, each a single command:
|
|
276
|
-
|
|
277
|
-
1. **Edit `SPECIFICATION.md`** (`zen open` launches your editor): what the
|
|
278
|
-
system is for, which agents exist, what each may use, what _done_ means.
|
|
279
|
-
2. **Run `zen meta run /spec-sync-project`.** It compares the specification
|
|
280
|
-
with every file that implements it, in both directions, and makes the
|
|
281
|
-
smallest change that closes each gap.
|
|
282
|
-
3. **Answer `SPECIFICATION-FEEDBACK.md`.** For anything it could not do
|
|
283
|
-
without guessing, it asks a question with two to four written-out answers.
|
|
284
|
-
Tick one, delete the rest, or write your own.
|
|
285
|
-
4. **Run `zen meta run /spec-apply-feedback`.** It folds your answers into
|
|
286
|
-
`SPECIFICATION.md` (never into a prompt), then syncs again.
|
|
287
|
-
|
|
288
|
-
Then `zen check`, then `zen run`. Full guide:
|
|
289
|
-
[docs/specification.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/specification.md).
|
|
290
|
-
|
|
291
|
-
<details>
|
|
292
|
-
<summary>The prompts <code>zen init</code> installs</summary>
|
|
293
|
-
|
|
294
|
-
Prompt files live under `.github/prompts/`; `zen meta run /<name>` runs one and
|
|
295
|
-
`zen meta prompts` lists them. `zen init` and `zen open` rewrite them each time,
|
|
296
|
-
so they never go stale, and local edits to them do not survive.
|
|
297
|
-
|
|
298
|
-
| Prompt | Does |
|
|
299
|
-
| :--------------------- | :--------------------------------------------------------------- |
|
|
300
|
-
| `/spec-sync-project` | Makes every file match `SPECIFICATION.md`, both directions. |
|
|
301
|
-
| `/spec-apply-feedback` | Folds your answers in `SPECIFICATION-FEEDBACK.md` into the spec. |
|
|
302
|
-
| `/project-review` | Reviews the project as a human reviewer would, and reports. |
|
|
303
|
-
| `/analyze [run]` | Analyzes one run and says which instruction to change. |
|
|
304
|
-
| `/dataset` | Builds or refreshes the evaluation dataset from the spec. |
|
|
305
|
-
| `/new-agent` | Adds an agent: prompt, wiring and hand-offs. |
|
|
306
|
-
| `/new-skill` | Adds a skill under `agents/skills/`. |
|
|
307
|
-
|
|
308
|
-
Alongside them, `.github/copilot-instructions.md` explains this runtime to
|
|
309
|
-
whatever coding agent opens the folder, and `.github/skills/zen-cli/` is the
|
|
310
|
-
CLI's own reference for it.
|
|
311
|
-
|
|
312
|
-
</details>
|
|
122
|
+
The meta-agent can ask for clarification in `SPECIFICATION-FEEDBACK.md` rather
|
|
123
|
+
than silently guessing. After you answer, apply that feedback with
|
|
124
|
+
`zen meta run my-project /spec-apply-feedback`. For the full workflow, see the
|
|
125
|
+
[specification-driven projects guide](https://github.com/zenera-ai/ZeneraNeo/blob/main/docs/specification.md).
|
|
313
126
|
|
|
314
|
-
|
|
127
|
+
## Run it your way
|
|
315
128
|
|
|
316
|
-
|
|
317
|
-
|
|
129
|
+
With no prompt, `zen run` opens the terminal UI. Provide a prompt for a
|
|
130
|
+
one-shot run, or use JSON and batch mode to integrate with other tools:
|
|
318
131
|
|
|
319
132
|
```sh
|
|
320
|
-
zen
|
|
321
|
-
zen
|
|
322
|
-
zen
|
|
323
|
-
zen
|
|
324
|
-
zen run
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
The full walkthrough, with the specification, the generated `agents.yaml` and
|
|
328
|
-
prompts, is in
|
|
329
|
-
[docs/specification.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/specification.md#a-worked-example).
|
|
330
|
-
For complete projects, see
|
|
331
|
-
[examples/projects](https://github.com/andreyryabov/ZeneraNeo/tree/main/examples/projects);
|
|
332
|
-
for what each `agents.yaml` key means, see
|
|
333
|
-
[docs/agents-yaml.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/agents-yaml.md).
|
|
334
|
-
|
|
335
|
-
### Anatomy of a project
|
|
336
|
-
|
|
337
|
-
Prompts, agent wiring, skills and tool selections are files (Markdown and YAML),
|
|
338
|
-
not code buried in an application. Model credentials live in `$HOME`, never in
|
|
339
|
-
the project, so there is no secret to strip before sharing.
|
|
340
|
-
|
|
341
|
-
```
|
|
342
|
-
my-project/
|
|
343
|
-
SPECIFICATION.md what this is for - the intent
|
|
344
|
-
agents.yaml who exists, what they may use
|
|
345
|
-
agents/ house rules, one prompt per agent, skills
|
|
346
|
-
assets/ dataset/ finetune/ sandbox/ scripts/
|
|
347
|
-
sessions/ what happened when it ran
|
|
133
|
+
zen run my-project # interactive terminal UI
|
|
134
|
+
zen run my-project "Review the latest changes"
|
|
135
|
+
git diff | zen run my-project
|
|
136
|
+
zen run my-project "Summarize the changes" --read-only
|
|
137
|
+
zen run my-project "Triage these alerts" --json | jq
|
|
138
|
+
zen run batch --input cases.json # run a set of requests
|
|
348
139
|
```
|
|
349
140
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
The full file-by-file layout, including `.github/`, `.spec-sync/` and `.env`, is
|
|
355
|
-
in
|
|
356
|
-
[docs/projects.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/projects.md#layout).
|
|
141
|
+
Runs are recorded in the project so you can continue sessions and review the
|
|
142
|
+
work later. `zen inspect` opens a report; `zen inspect graph` produces a
|
|
143
|
+
Mermaid view of the run, and `zen inspect ask` lets you question a recorded
|
|
144
|
+
model call.
|
|
357
145
|
|
|
358
146
|
## The self-improving loop
|
|
359
147
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
B --> C[zen check]
|
|
364
|
-
C --> D[zen run]
|
|
365
|
-
D --> E[zen inspect]
|
|
366
|
-
E -->|refine the spec| A
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
Every step is a command, and everything each step reads or writes is a plain
|
|
370
|
-
file. That means the loop does not need you in it: the meta agent can run the
|
|
371
|
-
whole cycle on the system it just built.
|
|
148
|
+
An agent system should get better from the work it actually does. ZeneraNeo
|
|
149
|
+
keeps the specification, project checks, and run traces close together so you
|
|
150
|
+
can find what went wrong and improve the instruction that caused it:
|
|
372
151
|
|
|
373
|
-
|
|
152
|
+
1. Update the specification to clarify the intended behavior.
|
|
153
|
+
2. Run `zen meta run /spec-sync-project` to sync the implementation.
|
|
154
|
+
3. Run `zen check`, then try the task again with `zen run`.
|
|
155
|
+
4. Use `zen inspect` to review the trace, tool calls, and result.
|
|
374
156
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
For a model rather than a person, `zen inspect graph` writes the whole run as
|
|
381
|
-
one compact Mermaid flowchart: one line per node, short sequential ids, tool
|
|
382
|
-
counts in a header. It is small enough to read whole, so the meta agent can
|
|
383
|
-
find the failing loop or branch and then open just the nodes that explain it:
|
|
384
|
-
|
|
385
|
-
```sh
|
|
386
|
-
DIR=$(zen run my-project "fix the tests" --json | jq -r .run.dir)
|
|
387
|
-
zen inspect graph --dir "$DIR" # the shape of the run
|
|
388
|
-
zen inspect node n14..n20 --dir "$DIR" # those nodes in full
|
|
389
|
-
zen inspect ask n17 "why python -c here?" --dir "$DIR" # ask the model itself
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
### Ask the model why
|
|
393
|
-
|
|
394
|
-
`zen inspect ask` replays one recorded call (its system prompt, messages and
|
|
395
|
-
tool schemas) with your question appended and tool calling off. The model is
|
|
396
|
-
told the run is over and that its instructions may be quoted. This is how a
|
|
397
|
-
prompt that reads correctly but behaves wrongly explains itself.
|
|
398
|
-
|
|
399
|
-
- **One-shot:** pass the question on the command line, via `--question-file`,
|
|
400
|
-
or with `--json`. Meant for scripts and the meta agent: stdout carries only
|
|
401
|
-
the answer, then the command exits.
|
|
402
|
-
- **Interactive:** omit the question. At a terminal, it walks you through the
|
|
403
|
-
session, run and call, then keeps taking follow-ups until you submit an empty
|
|
404
|
-
one. Without a terminal it errors rather than waiting.
|
|
405
|
-
|
|
406
|
-
### Let the meta agent close the loop
|
|
407
|
-
|
|
408
|
-
Because the specification, the `zen check` findings (each with a code, location
|
|
409
|
-
and fix) and the run records are all files, you can hand the whole cycle to the
|
|
410
|
-
meta agent: test, read the failure, change the sentence in the specification
|
|
411
|
-
that caused it, rebuild, run again. "Fix my project" is one instruction. (On
|
|
412
|
-
first use, `scripts/_setup.sh` prepares the tool container.)
|
|
413
|
-
|
|
414
|
-
The rule that keeps this working: **when a run comes out wrong, fix the
|
|
415
|
-
specification first, and let the prompt change follow.** Prompts patched
|
|
416
|
-
directly drift away from the document that describes them, and a project whose
|
|
417
|
-
specification is no longer true has no specification.
|
|
157
|
+
This makes improvement repeatable and reviewable instead of accumulating
|
|
158
|
+
one-off prompt patches. The meta-agent can also analyze a run and recommend
|
|
159
|
+
which instruction to change. See the
|
|
160
|
+
[specification-driven workflow](https://github.com/zenera-ai/ZeneraNeo/blob/main/docs/specification.md).
|
|
418
161
|
|
|
419
162
|
## Evaluate and fine-tune
|
|
420
163
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
### 1. Build a dataset
|
|
427
|
-
|
|
428
|
-
```sh
|
|
429
|
-
zen meta run /dataset # build or refresh dataset/ from its sources
|
|
430
|
-
zen meta dataset # revision, counts, what drifted
|
|
431
|
-
zen meta dataset drift # cases whose source sections changed
|
|
432
|
-
zen meta dataset sample --rubric yes -n 12 --format batch -o cases.json
|
|
433
|
-
zen meta dataset log planning-organize-day # every change and verdict for one case
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
`dataset/` holds every case with its **rubric**, an anchor to the section it was
|
|
437
|
-
derived from, and a journal of changes and findings. Only `zen meta dataset`
|
|
438
|
-
writes it. `/dataset` re-reads just the sections that changed, and a case whose
|
|
439
|
-
question or rubric changed is marked as restarted. See the `zen-dataset` skill
|
|
440
|
-
under `.github/skills/`.
|
|
441
|
-
|
|
442
|
-
### 2. Run it in batch
|
|
443
|
-
|
|
444
|
-
```sh
|
|
445
|
-
zen run batch --input cases.json # a file of questions, 16 at a time
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
One project, many questions, each in its own session, workspace and memory
|
|
449
|
-
under a batch directory. Answers are written as they arrive, and a failure is
|
|
450
|
-
recorded as data rather than stopping the batch. While it runs,
|
|
451
|
-
`<batch-dir>/README.md` is a live dashboard, rewritten every second: what each
|
|
452
|
-
item is doing, what finished items cost (per model, since agents may use
|
|
453
|
-
different ones), and what is still queued.
|
|
454
|
-
|
|
455
|
-
Memory is isolated by default: each item gets a copy, and
|
|
456
|
-
`zen memory merge <batch-dir>/*/memory` folds what they learned back in.
|
|
457
|
-
`--memory-read-only` instead lets every item recall from one shared graph,
|
|
458
|
-
which is safe because nothing is written.
|
|
459
|
-
|
|
460
|
-
### 3. Fine-tune on it
|
|
164
|
+
For systematic improvement, build an evaluation dataset from representative
|
|
165
|
+
requests and rubrics that describe what a successful run should do. Then run
|
|
166
|
+
cases in isolation or use the tuning loop to analyze traces, apply focused
|
|
167
|
+
changes, and try again:
|
|
461
168
|
|
|
462
169
|
```sh
|
|
463
|
-
zen meta
|
|
464
|
-
zen meta
|
|
465
|
-
zen
|
|
466
|
-
zen meta finetune
|
|
467
|
-
zen meta finetune
|
|
170
|
+
zen meta run /dataset
|
|
171
|
+
zen meta dataset
|
|
172
|
+
zen run batch --input cases.json
|
|
173
|
+
zen meta finetune start
|
|
174
|
+
zen meta finetune
|
|
468
175
|
```
|
|
469
176
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
ablation that checks stored knowledge actually helps);
|
|
476
|
-
3. collects improvement requests and applies them **in batches** between runs,
|
|
477
|
-
each apply producing a new, diffable version of the prose.
|
|
478
|
-
|
|
479
|
-
Progress is in `finetune/STATUS.md`, whose summary shows whether the fixes and
|
|
480
|
-
the memory are making runs cheaper. Each case has its own
|
|
481
|
-
`finetune/cases/<id>/FEEDBACK.md` with the latest analysis and the metrics of
|
|
482
|
-
every attempt. `start` prints a local address that shows these pages in a
|
|
483
|
-
browser, with diagrams rendered and updated live.
|
|
484
|
-
|
|
485
|
-
The full method, including how to write rubrics that tune the right thing:
|
|
486
|
-
[docs/finetuning.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/finetuning.md).
|
|
177
|
+
Fine-tuning here improves the agent system—its prompts, skills, instructions,
|
|
178
|
+
and memory practices—not model weights. Dataset cases and results provide a
|
|
179
|
+
repeatable way to check that changes improve the work rather than just reword
|
|
180
|
+
the prompts. Read the [fine-tuning guide](https://github.com/zenera-ai/ZeneraNeo/blob/main/docs/finetuning.md)
|
|
181
|
+
for dataset and rubric guidance.
|
|
487
182
|
|
|
488
183
|
## Share a project
|
|
489
184
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
```sh
|
|
494
|
-
zen export # ./<project>-<stamp>.zip, from inside the project
|
|
495
|
-
zen export my-project --out /tmp/a.zip
|
|
496
|
-
zen export --no-vectors # much smaller; needs a restore step on arrival
|
|
497
|
-
|
|
498
|
-
zen import a.zip # unpacks into ./<project> and registers it
|
|
499
|
-
zen import a.zip ~/code/theirs --name theirs
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
**Included:** `agents.yaml`, `agents/`, the specification and its feedback,
|
|
503
|
-
`assets/`, `memory/`, `sandbox/`, `scripts/` and editor files.
|
|
504
|
-
**Left out:** `sessions/`, `.tmp/`, `.git/`, `node_modules/`, lock files, any
|
|
505
|
-
top-level `*.zip`, and `.env`.
|
|
506
|
-
|
|
507
|
-
`.env` **values** never travel, and no flag changes that. The names do, as a
|
|
508
|
-
`.env.example` with blank values, because which credentials a project needs is
|
|
509
|
-
the first thing the recipient wants to know.
|
|
510
|
-
|
|
511
|
-
Vectors travel by default. A RAG index without its `lance/` tree looks built but
|
|
512
|
-
cannot search, and memory without vectors falls back to term overlap.
|
|
513
|
-
`--no-vectors` produces a much smaller archive; the import then tells you to run
|
|
514
|
-
`zen rag <subject> restore`.
|
|
515
|
-
|
|
516
|
-
**Import is safe by design.** The archive is treated as untrusted: every path is
|
|
517
|
-
checked against escaping the target directory, symbolic links are refused, and
|
|
518
|
-
the unpacked size is bounded. **Nothing inside is executed**, not
|
|
519
|
-
`scripts/_setup.sh`, not the Dockerfile, not the `.github/` tree. The next
|
|
520
|
-
commands are printed for you to read and run yourself.
|
|
521
|
-
|
|
522
|
-
## Reference
|
|
523
|
-
|
|
524
|
-
### Commands
|
|
525
|
-
|
|
526
|
-
| Stage | Command | Does |
|
|
527
|
-
| :----------- | :----------- | :----------------------------------------------------------------------- |
|
|
528
|
-
| **Set up** | `key` | The credential keyring: add, check, switch, remove. |
|
|
529
|
-
| | `models` | What this machine can use: list, search, test, pick. |
|
|
530
|
-
| | `completion` | Tab completion for zsh, bash and fish. |
|
|
531
|
-
| **Build** | `init` | Creates a project here or in `<dir>`, and registers it. |
|
|
532
|
-
| | `open` | Opens a project in your editor. |
|
|
533
|
-
| | `meta` | Runs the meta agent over the project; includes `dataset` and `finetune`. |
|
|
534
|
-
| | `check` | Validates the project and every file it names, and pings the models. |
|
|
535
|
-
| **Run** | `run` | Runs the project: the TUI at a terminal, a single answer otherwise. |
|
|
536
|
-
| | `sandbox` | Checks and prepares the container command-line tools run in. |
|
|
537
|
-
| **Inspect** | `inspect` | Opens or rebuilds a run's report, graph and nodes; `ask` queries a call. |
|
|
538
|
-
| | `memory` | What the agents remember: size, listing, one node, or a whole page. |
|
|
539
|
-
| | `view` | Shows a folder in the browser, redrawn live as files change. |
|
|
540
|
-
| **Share** | `export` | Writes the project to a shareable zip archive. |
|
|
541
|
-
| | `import` | Unpacks one and registers it, executing nothing. |
|
|
542
|
-
| **Maintain** | `list` | Every known project: sessions, last run, whether one is live. |
|
|
543
|
-
| | `cache` | What work has been kept, and removing it. |
|
|
544
|
-
| | `version` | CLI, library and Node versions. |
|
|
545
|
-
|
|
546
|
-
#### Commands from other packages
|
|
547
|
-
|
|
548
|
-
Some commands come from packages installed alongside the CLI, so new
|
|
549
|
-
capabilities arrive as subcommands rather than separate binaries: one tool on
|
|
550
|
-
your path, one keyring. `zen --help` lists them whether or not they are
|
|
551
|
-
installed, and says what to install. Nothing is loaded until you use it.
|
|
552
|
-
|
|
553
|
-
| Command | Package | Does |
|
|
554
|
-
| :------ | :-------------- | :--------------------------------------------------- |
|
|
555
|
-
| `faker` | `@zenera/faker` | A working mock API from an OpenAPI/Swagger document. |
|
|
556
|
-
| `rag` | `@zenera/rag` | Indexing and search for documents and API schemas. |
|
|
557
|
-
|
|
558
|
-
**`zen faker`** turns an OpenAPI or Swagger description into a mock server. It
|
|
559
|
-
generates each route's behavior, checks responses against the contract, and
|
|
560
|
-
reuses the generated implementation on later requests.
|
|
561
|
-
|
|
562
|
-
```sh
|
|
563
|
-
npm i -g @zenera/faker
|
|
564
|
-
zen faker serve api/openapi.yaml --port 8787 # response bodies written by a model
|
|
565
|
-
|
|
566
|
-
curl -s localhost:8787/users/12324
|
|
567
|
-
# { "user_id": 12324, "email": "brooke.hoffman@example.org", … }
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
**`zen rag`** adds retrieval over the knowledge agents work from. Document
|
|
571
|
-
indexes support semantic, full-text and hybrid search, returning passages with
|
|
572
|
-
their source lines. Schema indexes add graph-aware retrieval across operations,
|
|
573
|
-
types, fields, requests and responses, so results carry connected API context
|
|
574
|
-
rather than isolated matches.
|
|
575
|
-
|
|
576
|
-
```sh
|
|
577
|
-
npm i -g @zenera/rag
|
|
578
|
-
zen rag schema index --embedding openai:text-embedding-3-small ./specs/*.yaml
|
|
579
|
-
zen rag schema search --output-property "user billing history" --format ts
|
|
580
|
-
|
|
581
|
-
zen rag docs index ./handbook --embedding openai:text-embedding-3-small
|
|
582
|
-
zen rag docs search "how does failover work when the primary is unreachable"
|
|
583
|
-
```
|
|
584
|
-
|
|
585
|
-
Details: [@zenera/faker](https://github.com/andreyryabov/ZeneraNeo/blob/main/packages/faker/README.md)
|
|
586
|
-
· [@zenera/rag](https://github.com/andreyryabov/ZeneraNeo/blob/main/packages/rag/README.md).
|
|
587
|
-
|
|
588
|
-
### Conventions and exit codes
|
|
589
|
-
|
|
590
|
-
- Global flags: `-h/--help`, `-v/--version`, `--json`, `-C <dir>`.
|
|
591
|
-
- `stdout` carries the answer and `stderr` the narration. `--json` works on
|
|
592
|
-
every command, so `zen run … | jq` is a supported use, not an accident.
|
|
593
|
-
|
|
594
|
-
| Exit code | Meaning |
|
|
595
|
-
| :-------- | :------------------- |
|
|
596
|
-
| `0` | ok |
|
|
597
|
-
| `1` | the run failed |
|
|
598
|
-
| `2` | bad invocation |
|
|
599
|
-
| `3` | invalid project |
|
|
600
|
-
| `4` | no usable credential |
|
|
601
|
-
| `5` | sandbox unavailable |
|
|
602
|
-
|
|
603
|
-
### The meta agent
|
|
604
|
-
|
|
605
|
-
`zen run` runs the agents your project describes. `zen meta` runs an agent
|
|
606
|
-
_over_ the project: a coding agent rooted at the project directory that reads
|
|
607
|
-
`SPECIFICATION.md`, edits `agents.yaml`, prompts and skills, and runs whatever
|
|
608
|
-
commands it needs to check its work. It uses the keys in your keyring, not
|
|
609
|
-
anyone's subscription, which makes the spec-to-system loop scriptable.
|
|
610
|
-
|
|
611
|
-
```sh
|
|
612
|
-
zen meta run "what does this project do?"
|
|
613
|
-
zen meta run acme "review the last commit"
|
|
614
|
-
zen meta prompts # which /<name> prompts this project has
|
|
615
|
-
zen meta run /project-review # runs .github/prompts/project-review.prompt.md
|
|
616
|
-
zen meta run acme /spec-sync-project agents/triage.md
|
|
617
|
-
zen meta run /analyze 20260825-143012-a7f3 # analyze one run
|
|
618
|
-
git diff | zen meta run "what broke?" --allow-tool read
|
|
619
|
-
zen meta run --dry-run "hello" # what would run, secrets masked
|
|
620
|
-
```
|
|
621
|
-
|
|
622
|
-
Every prompt, typed or from a file, goes through `run`, so a bare word after
|
|
623
|
-
`zen meta` is never ambiguous between a subcommand and a question. Prompt files
|
|
624
|
-
are plain Markdown with frontmatter; `zen` strips the frontmatter and sends the
|
|
625
|
-
body, so the same prompt works from a terminal, a script and CI. With no
|
|
626
|
-
argument, `zen meta run` asks which prompt to run.
|
|
627
|
-
|
|
628
|
-
**Permissions.** By default it uses every tool without asking: its prompts need
|
|
629
|
-
to read, write and run commands, and a non-interactive run has nobody to answer
|
|
630
|
-
a question, so asking would only stall it. Narrow it with
|
|
631
|
-
`--allow-tool read` or `--allow-tool 'shell(git:*)'`, or restore prompting with
|
|
632
|
-
`--ask`. Treat it like `git push`: fine on a project you own, worth narrowing on
|
|
633
|
-
one you don't.
|
|
634
|
-
|
|
635
|
-
**Output.** The answer goes to stdout and progress to stderr, so
|
|
636
|
-
`zen meta run "…" > out.md` captures only the answer. Progress is a small
|
|
637
|
-
self-rewriting window. The full log (prompt, every tool call, the answer) is
|
|
638
|
-
written live to `.tmp/logs/meta.<when>.log`, whose path is printed at start, so
|
|
639
|
-
`tail -f` can follow a running session. The answer alone is saved as
|
|
640
|
-
`.tmp/logs/meta.<when>.md`.
|
|
641
|
-
|
|
642
|
-
#### Which model it runs on
|
|
643
|
-
|
|
644
|
-
```sh
|
|
645
|
-
zen meta model # the whole chain, with the winner marked
|
|
646
|
-
zen meta model vertex/gemini-3.8-flash # for every project on this machine
|
|
647
|
-
zen meta model --local openai/gpt-5.6-sol # for this project only, via its .env
|
|
648
|
-
zen meta model --pick # choose from providers you hold a key for
|
|
649
|
-
```
|
|
650
|
-
|
|
651
|
-
Precedence, highest first: `--model`; `ZENERA_META_MODEL` in the shell; the
|
|
652
|
-
same variable in the project's `.env`; `zen meta model`; the project's
|
|
653
|
-
`agents.yaml` `model:`. If none applies, `zen` picks the best model it knows
|
|
654
|
-
for the first provider you hold a key for, and says so on stderr. A fresh
|
|
655
|
-
machine needs only a key.
|
|
656
|
-
|
|
657
|
-
This setting is kept apart from `agents.yaml` on purpose: the model a coding
|
|
658
|
-
agent runs on is a personal tool choice, like a key, while `agents.yaml` is a
|
|
659
|
-
committed decision about the project's own agents.
|
|
660
|
-
|
|
661
|
-
Use a **reasoning model** (`gpt-5.6-sol`, `claude-opus-5`, `gemini-3.8-flash`):
|
|
662
|
-
the meta agent declares its tools in a form only reasoning APIs accept. These
|
|
663
|
-
three are also the fallbacks and what `--pick` offers. Setting a model sends it
|
|
664
|
-
a one-word test question first, so a model that won't answer is rejected now,
|
|
665
|
-
with the provider's own error. A prefix that names no provider (`vertes/...`)
|
|
666
|
-
is caught before anything is sent. `--force` skips the check.
|
|
667
|
-
|
|
668
|
-
### Models and credentials
|
|
669
|
-
|
|
670
|
-
One keyring serves every provider, and every key goes in the same way:
|
|
671
|
-
|
|
672
|
-
```sh
|
|
673
|
-
zen key add <provider> # prompts for the key without echoing it
|
|
674
|
-
zen key add <provider> < key.txt # or pipe it in
|
|
675
|
-
```
|
|
676
|
-
|
|
677
|
-
The value is never accepted as an argument: command lines are visible in the
|
|
678
|
-
process list, saved in shell history and captured in CI logs.
|
|
679
|
-
|
|
680
|
-
Keys live in `~/.zenera/neo/keys.json`, readable only by you, and are copied
|
|
681
|
-
into the environment just before a run. So an environment variable you set
|
|
682
|
-
yourself always wins, and a project checked out on a machine without `zen`
|
|
683
|
-
still runs.
|
|
684
|
-
|
|
685
|
-
| Provider | The value is | Exported as |
|
|
686
|
-
| :----------- | :--------------------------------------------- | :-------------------------------------------------- |
|
|
687
|
-
| `openai` | a secret | `OPENAI_API_KEY` |
|
|
688
|
-
| `anthropic` | a secret | `ANTHROPIC_API_KEY` |
|
|
689
|
-
| `google` | a secret (AI Studio) | `GEMINI_API_KEY` |
|
|
690
|
-
| `vertex` | a service-account JSON path, or an express key | `GOOGLE_APPLICATION_CREDENTIALS` / `VERTEX_API_KEY` |
|
|
691
|
-
| `openrouter` | a secret | `OPENROUTER_API_KEY` |
|
|
692
|
-
| `exa` | a secret, for the web search tool | `EXA_API_KEY` |
|
|
693
|
-
|
|
694
|
-
`zen key add` verifies the credential with the provider but stores it either
|
|
695
|
-
way: a key that can't be checked right now (offline, behind a proxy) is not
|
|
696
|
-
necessarily wrong. `--no-check` skips the call.
|
|
697
|
-
|
|
698
|
-
#### Model references
|
|
699
|
-
|
|
700
|
-
A model reference is `[provider[/api]:]model`, and the first segment names a
|
|
701
|
-
**provider, not a vendor**. `vertex:gemini-3.5-flash` and
|
|
702
|
-
`google:gemini-3.5-flash` are the same model through two services with two
|
|
703
|
-
different credentials. A bare `gpt-5.4-mini` goes to the default provider,
|
|
704
|
-
`openai`.
|
|
705
|
-
|
|
706
|
-
`zen check` resolves every reference in a project, says which credential each
|
|
707
|
-
needs, and spends a few tokens asking each model to answer, which is the only
|
|
708
|
-
way to catch a model id your account isn't served. `--no-models` stops before
|
|
709
|
-
that.
|
|
710
|
-
|
|
711
|
-
#### Finding models
|
|
712
|
-
|
|
713
|
-
`zen check` answers _does my project work_. `zen models` answers _what can I
|
|
714
|
-
use_, needs no project, and asks the providers directly:
|
|
715
|
-
|
|
716
|
-
```sh
|
|
717
|
-
zen models # who has a credential, and what is cached
|
|
718
|
-
zen models openai # everything OpenAI serves this account
|
|
719
|
-
zen models search haiku --tools --free # narrow it
|
|
720
|
-
zen models show openrouter:anthropic/claude-haiku-4.5
|
|
721
|
-
zen models test vertex:gemini-embedding-001 # one real call, one verdict
|
|
722
|
-
zen models browse # interactive: arrows, / to filter, p to pick
|
|
723
|
-
```
|
|
724
|
-
|
|
725
|
-
Listings are cached for a day. If a provider is unreachable, the last listing is
|
|
726
|
-
used and marked stale. `zen models browse` prints the picked ref on stdout, so
|
|
727
|
-
`ref="$(zen models browse)"` works.
|
|
728
|
-
|
|
729
|
-
`zen models test` distinguishes three failures, each needing a different fix:
|
|
730
|
-
|
|
731
|
-
- **refused**: the provider rejected the credential. Fix or replace the key.
|
|
732
|
-
- **blocked**: the key was accepted but the account said no (API disabled,
|
|
733
|
-
empty balance, model not granted). The fix command is printed with the error.
|
|
734
|
-
- **unknown**: the request never arrived (offline, proxy, timeout). Try again.
|
|
735
|
-
|
|
736
|
-
```
|
|
737
|
-
$ zen models test vertex:gemini-embedding-001
|
|
738
|
-
vertex:gemini-embedding-001 blocked Vertex AI API has not been used in project my-proj …
|
|
739
|
-
fix vertex:gemini-embedding-001 gcloud services enable aiplatform.googleapis.com --project my-proj
|
|
740
|
-
error 1 of 1 did not answer
|
|
741
|
-
see what else there is: zen models ls --embeddings
|
|
742
|
-
```
|
|
743
|
-
|
|
744
|
-
#### Provider setup
|
|
745
|
-
|
|
746
|
-
<details>
|
|
747
|
-
<summary><strong>OpenAI</strong></summary>
|
|
748
|
-
|
|
749
|
-
```sh
|
|
750
|
-
zen key add openai
|
|
751
|
-
```
|
|
752
|
-
|
|
753
|
-
`openai` is the default provider: `gpt-5.4-mini` and `openai:gpt-5.4-mini` are
|
|
754
|
-
the same model.
|
|
755
|
-
|
|
756
|
-
</details>
|
|
757
|
-
|
|
758
|
-
<details>
|
|
759
|
-
<summary><strong>Anthropic</strong></summary>
|
|
185
|
+
Keep the work portable: export a project to a ZIP archive, then import and
|
|
186
|
+
register it on another machine.
|
|
760
187
|
|
|
761
188
|
```sh
|
|
762
|
-
zen
|
|
763
|
-
zen
|
|
189
|
+
zen export my-project --out my-project.zip
|
|
190
|
+
zen import my-project.zip
|
|
764
191
|
```
|
|
765
192
|
|
|
766
|
-
|
|
193
|
+
Exports include the agent setup and project resources while excluding local
|
|
194
|
+
sessions and `.env` values. Credential names are retained in `.env.example`,
|
|
195
|
+
so collaborators can see what to configure without receiving your secrets.
|
|
196
|
+
Vectors are included by default; `--no-vectors` makes a smaller archive that
|
|
197
|
+
may need an index or memory restore step. Import treats archives as untrusted
|
|
198
|
+
and does not execute their scripts or setup files.
|
|
767
199
|
|
|
768
|
-
|
|
769
|
-
<summary><strong>OpenRouter</strong></summary>
|
|
200
|
+
## Commands at a glance
|
|
770
201
|
|
|
771
|
-
|
|
772
|
-
|
|
202
|
+
| Need | Commands |
|
|
203
|
+
| -------------------- | --------------------------------------------------------- |
|
|
204
|
+
| Create and find work | `zen init`, `zen open`, `zen list` |
|
|
205
|
+
| Build and validate | `zen meta`, `zen check`, `zen sandbox` |
|
|
206
|
+
| Run and review | `zen run`, `zen inspect`, `zen view` |
|
|
207
|
+
| Configure providers | `zen key`, `zen models` |
|
|
208
|
+
| Work with memory | `zen memory` |
|
|
209
|
+
| Share and maintain | `zen export`, `zen import`, `zen cache`, `zen completion` |
|
|
773
210
|
|
|
774
|
-
|
|
775
|
-
zen key add openrouter
|
|
776
|
-
zen models search haiku --tools --free
|
|
777
|
-
zen run --model openrouter:anthropic/claude-haiku-4.5 "summarise this repo"
|
|
778
|
-
```
|
|
211
|
+
Run `zen --help` or `zen <command> --help` for details and options.
|
|
779
212
|
|
|
780
|
-
|
|
213
|
+
### Optional Zenera commands
|
|
781
214
|
|
|
782
|
-
|
|
783
|
-
<summary><strong>Google AI Studio</strong></summary>
|
|
215
|
+
The CLI can expose commands supplied by sibling Zenera packages:
|
|
784
216
|
|
|
785
|
-
|
|
217
|
+
- **`@zenera/rag`** adds `zen rag` for indexing and searching documents and API
|
|
218
|
+
schemas.
|
|
219
|
+
- **`@zenera/gym`** adds `zen gym` for building and serving mock APIs from
|
|
220
|
+
OpenAPI or Swagger specifications.
|
|
786
221
|
|
|
787
|
-
|
|
788
|
-
zen key add google
|
|
789
|
-
zen check # google:gemini-3.5-flash now resolves
|
|
790
|
-
```
|
|
791
|
-
|
|
792
|
-
The same models are also served by Vertex AI under a different credential. Both
|
|
793
|
-
can be configured at once; the prefix decides which is used:
|
|
222
|
+
Install either package separately to use its command:
|
|
794
223
|
|
|
795
224
|
```sh
|
|
796
|
-
|
|
797
|
-
zen run --model vertex:gemini-3.5-flash "summarise this repo"
|
|
225
|
+
npm install --global @zenera/rag @zenera/gym
|
|
798
226
|
```
|
|
799
227
|
|
|
800
|
-
|
|
228
|
+
## The rest of the family
|
|
801
229
|
|
|
802
|
-
|
|
803
|
-
|
|
230
|
+
`@zenera/cli` is the command-line front end for ZeneraNeo. The other packages
|
|
231
|
+
provide the runtime and optional capabilities that work alongside it:
|
|
804
232
|
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
233
|
+
| Package | What it is |
|
|
234
|
+
| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------- |
|
|
235
|
+
| [`@zenera/cli`](https://github.com/zenera-ai/ZeneraNeo/blob/main/packages/cli/README.md) | `zen` — agent projects on the command line |
|
|
236
|
+
| [`@zenera/neo`](https://github.com/zenera-ai/ZeneraNeo/blob/main/packages/neo/README.md) | The runtime — agents, models, tools, skills, and memory |
|
|
237
|
+
| [`@zenera/gym`](https://github.com/zenera-ai/ZeneraNeo/blob/main/packages/gym/README.md) | `zen gym` — mock APIs from OpenAPI or Swagger documents |
|
|
238
|
+
| [`@zenera/rag`](https://github.com/zenera-ai/ZeneraNeo/blob/main/packages/rag/README.md) | `zen rag` — indexing and search for documents and API schemas |
|
|
239
|
+
| [`@zenera/view`](https://github.com/zenera-ai/ZeneraNeo/blob/main/packages/view/README.md) | `zen view` — a live local viewer for a folder |
|
|
809
240
|
|
|
810
|
-
|
|
811
|
-
|
|
241
|
+
`@zenera/rag` also exports tools that can be passed to `loadProject`, allowing
|
|
242
|
+
an agent to search an API schema it has not read beforehand.
|
|
812
243
|
|
|
813
|
-
|
|
814
|
-
zen key add vertex --gcp-location us-central1
|
|
815
|
-
# Paste the key, or a path to the file: /Users/you/keys/vertex-sa.json
|
|
816
|
-
|
|
817
|
-
# in a script:
|
|
818
|
-
echo ~/keys/vertex-sa.json | zen key add vertex --gcp-location us-central1
|
|
819
|
-
```
|
|
820
|
-
|
|
821
|
-
The prompt is read by `zen`, not your shell, so `~` is not expanded there; give
|
|
822
|
-
a full path. The file is copied into `~/.zenera/neo/keys/`, so moving the
|
|
823
|
-
original later breaks nothing.
|
|
824
|
-
|
|
825
|
-
- **`--gcp-location`** is worth setting: the file names the project but not the
|
|
826
|
-
region. Use a concrete region, or a multi-region endpoint: `us` and `eu` pool
|
|
827
|
-
capacity while keeping processing in that territory; `global` uses whatever
|
|
828
|
-
is free, with no residency guarantee, and costs about ten seconds of cold
|
|
829
|
-
start on each process's first request (a named region answers in about two).
|
|
830
|
-
- **Model availability varies by location** and can't be guessed. In one
|
|
831
|
-
project `gemini-embedding-2` worked at `us` but returned 404 at
|
|
832
|
-
`us-central1`, while `gemini-2.5-flash` did the opposite. New models often
|
|
833
|
-
reach `global`, `us` and `eu` first. `zen models test vertex:<model>` settles
|
|
834
|
-
it.
|
|
835
|
-
- **`--gcp-project`** is needed only to bill a project other than the file's
|
|
836
|
-
`project_id`:
|
|
837
|
-
|
|
838
|
-
```sh
|
|
839
|
-
echo ~/keys/vertex-sa.json \
|
|
840
|
-
| zen key add vertex --gcp-project other-project --gcp-location europe-west4
|
|
841
|
-
```
|
|
842
|
-
|
|
843
|
-
**Express-mode API key**: a single secret stored as `VERTEX_API_KEY`. It needs
|
|
844
|
-
no project or region, so those flags don't apply:
|
|
845
|
-
|
|
846
|
-
```sh
|
|
847
|
-
zen key add vertex
|
|
848
|
-
```
|
|
849
|
-
|
|
850
|
-
**An existing `gcloud` login also works.** After
|
|
851
|
-
`gcloud auth application-default login`, Vertex works with nothing stored:
|
|
852
|
-
`zen key ls` shows it as `adc`, marked `~` because it comes from outside the
|
|
853
|
-
keyring. Anything already in `GOOGLE_APPLICATION_CREDENTIALS`, `VERTEX_API_KEY`
|
|
854
|
-
or `GEMINI_API_KEY` is listed the same way and takes precedence.
|
|
855
|
-
|
|
856
|
-
</details>
|
|
857
|
-
|
|
858
|
-
<details>
|
|
859
|
-
<summary><strong>Exa</strong> (web search)</summary>
|
|
860
|
-
|
|
861
|
-
Not a model provider: Exa backs the search tool agents use to look things up on
|
|
862
|
-
the web.
|
|
863
|
-
|
|
864
|
-
```sh
|
|
865
|
-
zen key add exa
|
|
866
|
-
```
|
|
867
|
-
|
|
868
|
-
</details>
|
|
869
|
-
|
|
870
|
-
<details>
|
|
871
|
-
<summary><strong>Several keys for one provider</strong></summary>
|
|
872
|
-
|
|
873
|
-
Entries are named; one per provider is active:
|
|
874
|
-
|
|
875
|
-
```sh
|
|
876
|
-
zen key add openai/work # a second entry
|
|
877
|
-
zen key use openai/work # make it active
|
|
878
|
-
zen key ls --check # everything stored, and whether it still works
|
|
879
|
-
zen key show vertex/default # masked; --reveal prints the secret
|
|
880
|
-
zen key env openai # shell exports, for other tools
|
|
881
|
-
zen key rm openai/work
|
|
882
|
-
```
|
|
883
|
-
|
|
884
|
-
Common with Vertex:
|
|
885
|
-
|
|
886
|
-
```sh
|
|
887
|
-
echo ~/keys/prod-sa.json | zen key add vertex/prod --gcp-location us-central1
|
|
888
|
-
echo ~/keys/dev-sa.json | zen key add vertex/dev --gcp-location global
|
|
889
|
-
zen key add vertex/express
|
|
890
|
-
zen key use vertex/dev
|
|
891
|
-
```
|
|
892
|
-
|
|
893
|
-
`zen key ls` marks the active entry with `*` and anything found outside the
|
|
894
|
-
keyring with `~`.
|
|
895
|
-
|
|
896
|
-
</details>
|
|
897
|
-
|
|
898
|
-
<details>
|
|
899
|
-
<summary><strong>All models through a Bifrost gateway</strong></summary>
|
|
900
|
-
|
|
901
|
-
One virtual key instead of every vendor key:
|
|
902
|
-
|
|
903
|
-
```sh
|
|
904
|
-
zen key add bifrost --url https://bifrost.example.com
|
|
905
|
-
zen key mode bifrost # every run goes through the gateway
|
|
906
|
-
zen key mode direct # back to vendor keys
|
|
907
|
-
```
|
|
908
|
-
|
|
909
|
-
`agents.yaml` doesn't change. Each model keeps its vendor's protocol and is sent
|
|
910
|
-
to the gateway's matching endpoint (`vertex:gemini-3.5-flash` reaches `/genai`
|
|
911
|
-
as `vertex/gemini-3.5-flash`), so thinking and cache accounting survive. Full
|
|
912
|
-
details: [docs/gateway.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/gateway.md).
|
|
913
|
-
|
|
914
|
-
</details>
|
|
915
|
-
|
|
916
|
-
### Sandbox
|
|
917
|
-
|
|
918
|
-
When a project grants command-line tools, agents run them in an isolated
|
|
919
|
-
container. `zen run` prepares it automatically; these commands make setup,
|
|
920
|
-
diagnostics and cleanup explicit.
|
|
921
|
-
|
|
922
|
-
```sh
|
|
923
|
-
zen sandbox status # engine, project image and active containers
|
|
924
|
-
zen sandbox up # prepare the environment for this project
|
|
925
|
-
zen sandbox pull # pull or build this project's image only
|
|
926
|
-
zen sandbox status --project my-app # inspect a named project from anywhere
|
|
927
|
-
zen sandbox top # live memory and CPU: host, VM, each container
|
|
928
|
-
zen sandbox top --once # printed once (also with --json or when piped)
|
|
929
|
-
zen sandbox disk # storage used by the engine and known projects
|
|
930
|
-
zen sandbox clean # remove containers created by zen
|
|
931
|
-
zen sandbox clean --idle # only those no live run is using
|
|
932
|
-
```
|
|
933
|
-
|
|
934
|
-
`status`, `up` and `pull` act on the current project or `--project <name|dir>`;
|
|
935
|
-
`--image <ref>` picks an image explicitly. `top`, `disk` and `clean` are
|
|
936
|
-
machine-wide.
|
|
937
|
-
|
|
938
|
-
`top` annotates each figure with a short explanation (`--brief` hides them;
|
|
939
|
-
`--interval <seconds>` sets the refresh rate). On macOS it also explains why
|
|
940
|
-
Activity Monitor shows "Virtual Machine Service for vfkit" holding many
|
|
941
|
-
gigabytes: it compares what macOS attributes to the VM with what is in use
|
|
942
|
-
inside it, and names the command that reclaims the difference.
|
|
943
|
-
|
|
944
|
-
### Cache
|
|
945
|
-
|
|
946
|
-
Embedding text, parsing documents, listing a provider's models: these are slow
|
|
947
|
-
or costly and always give the same answer. So results are kept in
|
|
948
|
-
`~/.zenera/neo/cache/<kind>/`, keyed on every input that produced them. Change
|
|
949
|
-
an input and the key changes, so entries never need invalidating; stale ones
|
|
950
|
-
are simply never read again.
|
|
951
|
-
|
|
952
|
-
```sh
|
|
953
|
-
zen cache ls # what is kept, by kind
|
|
954
|
-
zen cache ls --kind vectors # contents of one kind
|
|
955
|
-
zen cache prune --older-than 30d # drop entries unread for a month
|
|
956
|
-
zen cache prune --max-size 2GB # or keep it under a ceiling
|
|
957
|
-
zen cache clear --kind docs-parse # discard one kind
|
|
958
|
-
```
|
|
244
|
+
## Learn more
|
|
959
245
|
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
## Ecosystem
|
|
966
|
-
|
|
967
|
-
The CLI is a shell over [`@zenera/neo`](https://www.npmjs.com/package/@zenera/neo),
|
|
968
|
-
the runtime for agents, models, tools, skills, memory and run records. Use it
|
|
969
|
-
directly to embed the runtime in your own application:
|
|
970
|
-
[its README](https://github.com/andreyryabov/ZeneraNeo/blob/main/packages/neo/README.md).
|
|
971
|
-
|
|
972
|
-
| Package | What it is |
|
|
973
|
-
| :---------------------------------------------------------------------------------------------- | :----------------------------------------------------------- |
|
|
974
|
-
| **`@zenera/cli`** | `zen`: agent projects on the command line |
|
|
975
|
-
| [`@zenera/neo`](https://github.com/andreyryabov/ZeneraNeo/blob/main/packages/neo/README.md) | the runtime: agents, models, tools, skills, memory |
|
|
976
|
-
| [`@zenera/faker`](https://github.com/andreyryabov/ZeneraNeo/blob/main/packages/faker/README.md) | `zen faker`: a mock API from an OpenAPI/Swagger document |
|
|
977
|
-
| [`@zenera/rag`](https://github.com/andreyryabov/ZeneraNeo/blob/main/packages/rag/README.md) | `zen rag`: indexing and search for documents and API schemas |
|
|
978
|
-
| [`@zenera/view`](https://github.com/andreyryabov/ZeneraNeo/blob/main/packages/view/README.md) | `zen view`: a live local viewer for a folder |
|
|
979
|
-
|
|
980
|
-
## Documentation
|
|
981
|
-
|
|
982
|
-
| Guide | Covers |
|
|
983
|
-
| :-------------------------------------------------------------------------------------------- | :----------------------------------------------------------- |
|
|
984
|
-
| [specification.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/specification.md) | Writing the specification the project implements. |
|
|
985
|
-
| [projects.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/projects.md) | The project folder, file by file. |
|
|
986
|
-
| [agents-yaml.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/agents-yaml.md) | Every key in the configuration file. |
|
|
987
|
-
| [knowledge.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/knowledge.md) | Building a searchable document index. |
|
|
988
|
-
| [integrations.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/integrations.md) | Making an API description searchable and mockable. |
|
|
989
|
-
| [memory.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/memory.md) | What agents keep between sessions. |
|
|
990
|
-
| [finetuning.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/finetuning.md) | Datasets, rubrics, and tuning the project on them. |
|
|
991
|
-
| [gateway.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/gateway.md) | Every model through a Bifrost gateway, with one virtual key. |
|
|
246
|
+
- [ZeneraNeo repository and overview](https://github.com/zenera-ai/ZeneraNeo)
|
|
247
|
+
- [Specification-driven projects](https://github.com/zenera-ai/ZeneraNeo/blob/main/docs/specification.md)
|
|
248
|
+
- [Agent configuration reference](https://github.com/zenera-ai/ZeneraNeo/blob/main/docs/agents-yaml.md)
|
|
249
|
+
- [Memory](https://github.com/zenera-ai/ZeneraNeo/blob/main/docs/memory.md) · [Knowledge and retrieval](https://github.com/zenera-ai/ZeneraNeo/blob/main/docs/knowledge.md) · [Fine-tuning](https://github.com/zenera-ai/ZeneraNeo/blob/main/docs/finetuning.md)
|
|
250
|
+
- [Examples](https://github.com/zenera-ai/ZeneraNeo/tree/main/examples/projects)
|
|
992
251
|
|
|
993
252
|
## License
|
|
994
253
|
|
|
995
|
-
|
|
996
|
-
[MIT](LICENSE).
|
|
254
|
+
MIT
|