@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.
Files changed (30) hide show
  1. package/README.md +183 -119
  2. package/dist/banner.d.ts +5 -1
  3. package/dist/banner.js +2 -2
  4. package/dist/command.d.ts +5 -0
  5. package/dist/main.js +10 -6
  6. package/package.json +2 -2
  7. package/templates/editor/.github/copilot-instructions.md +253 -218
  8. package/templates/editor/.github/prompts/new-agent.prompt.md +6 -6
  9. package/templates/editor/.github/prompts/new-skill.prompt.md +7 -7
  10. package/templates/editor/.github/prompts/review-project.prompt.md +1 -1
  11. package/templates/editor/.github/prompts/sync-with-spec.prompt.md +26 -26
  12. package/templates/editor/.github/skills/zen-cli/SKILL.md +62 -6
  13. package/templates/editor/.github/skills/zen-cli/references/check.md +3 -3
  14. package/templates/editor/.github/skills/zen-cli/references/faker.md +14 -14
  15. package/templates/editor/.github/skills/zen-cli/references/frame.md +6 -6
  16. package/templates/editor/.github/skills/zen-cli/references/inspect.md +3 -3
  17. package/templates/editor/.github/skills/zen-cli/references/keys.md +9 -9
  18. package/templates/editor/.github/skills/zen-cli/references/memory.md +11 -11
  19. package/templates/editor/.github/skills/zen-cli/references/models.md +8 -8
  20. package/templates/editor/.github/skills/zen-cli/references/projects.md +3 -3
  21. package/templates/editor/.github/skills/zen-cli/references/rag.md +191 -56
  22. package/templates/editor/.github/skills/zen-cli/references/run.md +3 -3
  23. package/templates/editor/.github/skills/zen-cli/references/sandbox.md +8 -8
  24. package/templates/editor/.github/skills/zen-memory/SKILL.md +50 -50
  25. package/templates/editor/.github/skills/zen-rag-docs/SKILL.md +71 -48
  26. package/templates/editor/.github/skills/zen-rag-schema/SKILL.md +67 -67
  27. package/templates/editor/.vscode/settings.json +5 -2
  28. package/templates/project/INSTRUCTIONS.md +1 -1
  29. package/templates/project/assets/README.md +1 -1
  30. package/templates/project/sandbox/Dockerfile.tmpl +3 -0
@@ -14,8 +14,8 @@ true, and you should say which:
14
14
  - its instructions **contradict** an existing agent's rather than extend them
15
15
  - it is a **parallel branch** target for a `fork:`
16
16
 
17
- If none holds, propose the smaller change instead — a skill, a prompt line, a
18
- tool grant — and stop. Adding an agent to solve a prompt problem is the failure
17
+ If none holds, propose the smaller change instead - a skill, a prompt line, a
18
+ tool grant - and stop. Adding an agent to solve a prompt problem is the failure
19
19
  mode this project cares most about.
20
20
 
21
21
  If it is warranted:
@@ -23,18 +23,18 @@ If it is warranted:
23
23
  1. Pick a name matching `^[a-z0-9]+(?:[-_][a-z0-9]+)*$`. It reaches the model as
24
24
  `transfer_to_<name>`, so the name is part of the routing surface.
25
25
  2. Write `agents/prompts/<name>.md`: one sentence of identity, a short procedure
26
- or three to five rules, then what it must **not** do — especially the
26
+ or three to five rules, then what it must **not** do - especially the
27
27
  neighbouring agent's job. Second person, imperative, failure paths stated.
28
28
  No frontmatter, no meta-talk about the runtime.
29
- 3. Add the `agents.yaml` entry. `description:` is written **for the model** — it
29
+ 3. Add the `agents.yaml` entry. `description:` is written **for the model** - it
30
30
  is the whole of what a sibling sees when deciding to hand off. Grant the
31
31
  narrowest `tools:` the job needs.
32
32
  4. Wire the return edge. A handoff does not come back on its own, so every
33
- `A → B` needs a path from B back to A — directly, or through another agent.
33
+ `A → B` needs a path from B back to A - directly, or through another agent.
34
34
  `zen check` warns on an edge that has none. If what this agent really wants
35
35
  is an _answer_ rather than to give up the conversation, declare `fork:`
36
36
  instead: a branch returns by itself.
37
- 5. Add a one-line comment above the entry saying why this agent exists — its
37
+ 5. Add a one-line comment above the entry saying why this agent exists - its
38
38
  job or its tier, not what the keys mean.
39
39
 
40
40
  Then run `zen check` and report what it said. If it fails, fix the file it
@@ -3,29 +3,29 @@ mode: agent
3
3
  description: Add a skill under agents/skills, with a description that routes.
4
4
  ---
5
5
 
6
- Add a skill to this project. A skill is curated instruction content — and
7
- optionally tools — loaded on demand instead of sitting in every system prompt.
6
+ Add a skill to this project. A skill is curated instruction content - and
7
+ optionally tools - loaded on demand instead of sitting in every system prompt.
8
8
  Reach for one whenever a rule applies only sometimes, or holds a fact that will
9
9
  change without the prompt changing.
10
10
 
11
11
  Ask what the skill must say and when it applies, if I have not already said.
12
12
 
13
13
  1. Create `agents/skills/<name>/SKILL.md`. That is the only skill layout there
14
- is — a bare `agents/skills/<name>.md` fails `zen check` — and the folder is
14
+ is - a bare `agents/skills/<name>.md` fails `zen check` - and the folder is
15
15
  what lets the skill carry companions later: a rate table, an example letter,
16
16
  a schema, a script.
17
17
  2. Write the `description`. This is the routing key and the only thing the model
18
18
  sees before deciding to load the skill, so write it as **the condition under
19
19
  which the skill is needed**, not as a title. `Water policy` is a title;
20
- `Escape of water from plumbing and tanks — and the freezing exclusion` is a
20
+ `Escape of water from plumbing and tanks - and the freezing exclusion` is a
21
21
  condition. If two skills could both match a case, sharpen both until they
22
22
  cannot.
23
23
  3. Write the body as instructions the model can act on: thresholds, exact
24
24
  wording, the boundaries of the rule, and what to do when the case falls
25
- outside it. Put the facts here rather than in a prompt — that is the point of
25
+ outside it. Put the facts here rather than in a prompt - that is the point of
26
26
  the file.
27
27
  4. Put anything the rule computes or looks up in a file beside `SKILL.md` and
28
- name it from the body by its absolute path — `python
28
+ name it from the body by its absolute path - `python
29
29
  /skills/<name>/scripts/calculate.py <id>`, not `scripts/calculate.py`. The
30
30
  folder is mounted read-only at `/skills/<name>/`, so the script writes
31
31
  nothing there; the agent needs `sandbox:*` to run it, and the interpreter has
@@ -37,7 +37,7 @@ Ask what the skill must say and when it applies, if I have not already said.
37
37
  6. Leave `name` out unless it must differ from the folder name, and leave
38
38
  `version`/`tags` out unless something uses them.
39
39
 
40
- Do not `preload:` it unless every case genuinely needs it — a preloaded skill is
40
+ Do not `preload:` it unless every case genuinely needs it - a preloaded skill is
41
41
  a longer prompt, paid for on every call. Bind it under `agents[].skills.allow`
42
42
  if the agent's catalog is restricted.
43
43
 
@@ -28,7 +28,7 @@ Work the checklist in §9 of the copilot instructions. In particular:
28
28
  - **Routing.** Handoff targets have descriptions written for the model. No
29
29
  ping-pong edges. No router that answers.
30
30
  - **Models.** Each agent on the cheapest tier that is right, not the safest.
31
- - **Cache.** Nothing volatile — dates, ids, counts — in the stable prefix.
31
+ - **Cache.** Nothing volatile - dates, ids, counts - in the stable prefix.
32
32
  - **Secrets.** No key inlined anywhere; `.env` ignored, `sessions/` ignored.
33
33
 
34
34
  Report as a list of findings, each naming the file and the line, ordered by how
@@ -3,7 +3,7 @@ description: Bring the project into compliance with SPECIFICATION.md, and record
3
3
  ---
4
4
 
5
5
  Make this project match `SPECIFICATION.md`. The specification is the intent;
6
- the files are the implementation. Where they disagree, the specification wins —
6
+ the files are the implementation. Where they disagree, the specification wins -
7
7
  except where it is ambiguous, contradictory or impossible, which is what
8
8
  `SPECIFICATION-FEEDBACK.md` is for.
9
9
 
@@ -11,14 +11,14 @@ except where it is ambiguous, contradictory or impossible, which is what
11
11
 
12
12
  Read, in this order, and do not edit until all of it is read:
13
13
 
14
- 1. `SPECIFICATION.md` — what the system is meant to be.
15
- 2. `agents.yaml` — providers, models, embeddings, agents, tools, handoffs,
14
+ 1. `SPECIFICATION.md` - what the system is meant to be.
15
+ 2. `agents.yaml` - providers, models, embeddings, agents, tools, handoffs,
16
16
  skills, sandbox.
17
17
  3. `INSTRUCTIONS.md` and every file under `agents/prompts/`.
18
18
  4. Every `agents/skills/*/SKILL.md`, plus what each skill folder ships.
19
19
  5. `assets/`, `sandbox/Dockerfile` and every script under `scripts/`, starting
20
20
  with `scripts/_setup.sh`.
21
- 6. `SPECIFICATION-FEEDBACK.md`, if it exists — do not re-raise something already
21
+ 6. `SPECIFICATION-FEEDBACK.md`, if it exists - do not re-raise something already
22
22
  open there.
23
23
 
24
24
  Run `zen check` first and record what it said. A project that does not load is
@@ -29,11 +29,11 @@ the first thing to fix.
29
29
  Produce a difference list before touching a file. For every item in the
30
30
  specification, decide which of these it is:
31
31
 
32
- - **present and correct** — leave it alone
33
- - **missing** — the specification asks for it and nothing implements it
34
- - **divergent** — implemented, but not as specified
35
- - **extra** — implemented, and the specification does not ask for it
36
- - **unclear** — the specification does not say enough to implement it
32
+ - **present and correct** - leave it alone
33
+ - **missing** - the specification asks for it and nothing implements it
34
+ - **divergent** - implemented, but not as specified
35
+ - **extra** - implemented, and the specification does not ask for it
36
+ - **unclear** - the specification does not say enough to implement it
37
37
 
38
38
  Check at least: the model and embedding ids and which agent uses which; that
39
39
  every agent named in the specification exists with that job and no second job;
@@ -43,18 +43,18 @@ specification implies; and every setup step, index or asset it depends on.
43
43
  Then build the difference the other way, because the list above can only find
44
44
  what the specification asked for and nothing implements. Read `INSTRUCTIONS.md`,
45
45
  each `agents/prompts/*.md` and each `SKILL.md` **line by line**, and for every
46
- line name the specification item it serves. A line serving none is an **extra** —
46
+ line name the specification item it serves. A line serving none is an **extra** -
47
47
  the category covers a single sentence in a prompt, not only a whole file. Three
48
48
  things to look for while reading, none of which the forward pass can see:
49
49
 
50
50
  - **A line that contradicts another file.** One prompt against another, a prompt
51
- against `INSTRUCTIONS.md`, or a prompt against `agents.yaml` — an instruction
51
+ against `INSTRUCTIONS.md`, or a prompt against `agents.yaml` - an instruction
52
52
  to use a tool the agent does not hold, to hand to an agent that is not in its
53
53
  `handoffs:`, or to load a skill outside its `allow:`.
54
54
  - **A line that asks for something the system already supplies.** A question put
55
55
  to the user about a value that arrives from the environment, a file or an
56
56
  earlier step is unanswerable, and the answer would be discarded.
57
- - **A line the agent cannot carry out** — naming a path it cannot reach, a tool
57
+ - **A line the agent cannot carry out** - naming a path it cannot reach, a tool
58
58
  it was not granted, or an agent it cannot transfer to.
59
59
 
60
60
  These are bugs whatever the specification says: fix them in place and report each
@@ -83,19 +83,19 @@ the model to compute or remember. Specifically:
83
83
  Never delete an **extra** without saying so. Report it, say why the
84
84
  specification does not cover it, and leave it unless I tell you to remove it.
85
85
 
86
- Do not invent a value the specification does not state — a model id, a limit, a
86
+ Do not invent a value the specification does not state - a model id, a limit, a
87
87
  retry count, a file path. That is an entry in `SPECIFICATION-FEEDBACK.md`, not a
88
88
  guess.
89
89
 
90
90
  ## 4. Every setup step is a script
91
91
 
92
- Anything the project needs done before it can run — building an index, fetching
93
- a document, generating a file, warming the sandbox image — is a shell script,
92
+ Anything the project needs done before it can run - building an index, fetching
93
+ a document, generating a file, warming the sandbox image - is a shell script,
94
94
  not a paragraph of instructions for a human.
95
95
 
96
96
  - One step per file, under `scripts/`, named after the step:
97
97
  `scripts/build-schema-index.sh`, `scripts/fetch-api-docs.sh`.
98
- - `scripts/_setup.sh` is the **only** entry point — the leading underscore is
98
+ - `scripts/_setup.sh` is the **only** entry point - the leading underscore is
99
99
  what separates the runner from the steps it runs. It runs the steps in the
100
100
  order they depend on each other and is the single command that initialises the
101
101
  project. `zen init` writes it; adding a step is adding `scripts/<name>.sh` and
@@ -114,7 +114,7 @@ not a paragraph of instructions for a human.
114
114
  - **It must be watchable.** `scripts/_setup.sh` tees each step's output to
115
115
  `.tmp/logs/setup-<step>.log`, prints a heartbeat line while a long step runs,
116
116
  and finishes with one line per step: `ok`, `skipped`, or `failed`.
117
- - **Everything transient goes under `.tmp/`** — logs, scratch files, downloads,
117
+ - **Everything transient goes under `.tmp/`** - logs, scratch files, downloads,
118
118
  test output, and the temporary path a step writes to before moving its
119
119
  artefact into place. Nothing else in the tree is a scratch directory, and
120
120
  `.tmp/` is git-ignored: add it to `.gitignore` if it is not there already.
@@ -138,26 +138,26 @@ The file is scanned before it is read, so keep the emoji on every heading:
138
138
  ```markdown
139
139
  # Feedback on SPECIFICATION.md
140
140
 
141
- ## 🛑 Blocking — cannot implement without an answer
141
+ ## 🛑 Blocking - cannot implement without an answer
142
142
 
143
- ## ❓ Ambiguous — implemented one way, confirm the choice
143
+ ## ❓ Ambiguous - implemented one way, confirm the choice
144
144
 
145
145
  ## ⚡ Contradictions
146
146
 
147
147
  ## ✏️ Errors and typos
148
148
 
149
- ## ➕ Out of scope — implemented but unspecified
149
+ ## ➕ Out of scope - implemented but unspecified
150
150
  ```
151
151
 
152
152
  Each entry is one bullet, opening with the emoji of the heading it sits under,
153
153
  then four parts in this order:
154
154
 
155
155
  - **What the specification says**, quoted, with the section it is in.
156
- - **Why it cannot be implemented as written** — the specific gap, not "unclear".
157
- - **What was done in the meantime**, or "nothing — blocked".
156
+ - **Why it cannot be implemented as written** - the specific gap, not "unclear".
157
+ - **What was done in the meantime**, or "nothing - blocked".
158
158
  - **The question**, phrased so a one-line answer unblocks it.
159
159
 
160
- Use no other emoji anywhere in the file — one per entry is what makes them
160
+ Use no other emoji anywhere in the file - one per entry is what makes them
161
161
  scannable. Keep entries factual and short. Do not editorialise about the
162
162
  specification's quality, do not restate the runtime, and do not copy the whole
163
163
  section in.
@@ -169,7 +169,7 @@ this pass has actually resolved it, and say in the chat which ones you closed.
169
169
  After `zen check` passes, run `scripts/_setup.sh` yourself. A pass is not done
170
170
  until it has run to completion in this session.
171
171
 
172
- It is slow — an embedding index is minutes, not seconds — so start it in the
172
+ It is slow - an embedding index is minutes, not seconds - so start it in the
173
173
  background and follow the logs instead of waiting blind:
174
174
 
175
175
  - Tail `.tmp/logs/setup-*.log` and check the output artefact is still growing.
@@ -182,7 +182,7 @@ background and follow the logs instead of waiting blind:
182
182
  - Do not kill a quiet step. Confirm the process is dead or the log and the
183
183
  output have both stopped growing before calling it stuck.
184
184
  - On failure, read that step's log, fix the cause, and run `scripts/_setup.sh`
185
- again — re-running is the fix path, not a reset. If the same step fails twice
185
+ again - re-running is the fix path, not a reset. If the same step fails twice
186
186
  for the same reason, stop and raise it in `SPECIFICATION-FEEDBACK.md`.
187
187
  - Prove re-entrancy: once it has succeeded, run `scripts/_setup.sh` once more and
188
188
  check that every step reports `skipped` rather than rebuilding.
@@ -196,7 +196,7 @@ fail. Then report in the chat:
196
196
 
197
197
  - what changed, file by file, and which specification item each change closes
198
198
  - every prompt or skill line that served no specification item, and what became
199
- of it — corrected, or reported and left alone
199
+ of it - corrected, or reported and left alone
200
200
  - the outcome of every `scripts/_setup.sh` step, and what each one produced
201
201
  - what is still open, with a pointer to its `SPECIFICATION-FEEDBACK.md` entry
202
202
  - anything you found that the specification does not cover at all
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: zen-cli
3
- description: How to drive this project from the terminal with `zen` — running it, validating it, credentials, the sandbox, run reports, and the `faker` and `rag` modules.
3
+ description: How to drive this project from the terminal with `zen` - running it, validating it, credentials, the sandbox, run reports, and the `faker` and `rag` modules.
4
4
  ---
5
5
 
6
6
  # The `zen` command line
@@ -36,7 +36,7 @@ zen rag docs <index|search|list|grep|show|stats> [path...]
36
36
  ## Read the reference before answering
37
37
 
38
38
  The full reference lives next to this file, one document per part of the command
39
- line. **Read the one that covers the question before answering it** — do not
39
+ line. **Read the one that covers the question before answering it** - do not
40
40
  guess a flag, and do not read them all.
41
41
 
42
42
  | The question is about | Read |
@@ -50,8 +50,8 @@ guess a flag, and do not read them all.
50
50
  | The container shell commands run in, images, `persist` | [sandbox.md](./references/sandbox.md) |
51
51
  | Run reports, trajectories, what a session directory holds | [inspect.md](./references/inspect.md) |
52
52
  | What the agents remember, why something was recalled, forgetting | [memory.md](./references/memory.md) |
53
- | `zen faker` — a mock API from an OpenAPI/Swagger document | [faker.md](./references/faker.md) |
54
- | `zen rag` — searching an API description, or a pile of markdown | [rag.md](./references/rag.md) |
53
+ | `zen faker` - a mock API from an OpenAPI/Swagger document | [faker.md](./references/faker.md) |
54
+ | `zen rag` - searching an API description, or a pile of markdown | [rag.md](./references/rag.md) |
55
55
 
56
56
  ## The short version
57
57
 
@@ -67,6 +67,62 @@ zen models test <ref> whether one model actually answers
67
67
  zen models pick --embedding the first embedder that does, on stdout
68
68
  ```
69
69
 
70
+ ## Searching documents without help
71
+
72
+ Use `zen rag docs` for a directory of Markdown or text, and put the index path
73
+ in `-d <index-dir>` when it is not beside the working directory. These commands
74
+ are enough to discover the corpus and retrieve evidence; do not spend a turn on
75
+ `--help` first:
76
+
77
+ ```sh
78
+ zen rag docs list files -d <index-dir>
79
+ zen rag docs list sections -d <index-dir> --file "<path-pattern>"
80
+ zen rag docs search -d <index-dir> "<question in natural language>"
81
+ zen rag docs search -d <index-dir> --file "<path-pattern>" --section "<heading>" "<question>"
82
+ zen rag docs grep -d <index-dir> "<exact string>" --file "<path-pattern>"
83
+ zen rag docs show -d <index-dir> "<file>" --section "<heading>"
84
+ ```
85
+
86
+ Start with one ordinary hybrid question. It is the best default for concepts and
87
+ open questions. Search returns candidates, not proof: read the quoted lines,
88
+ then use `show` or `grep` before claiming a fact is present or absent.
89
+
90
+ When the first answer is from the wrong product area, version, file, or heading,
91
+ ask the same question again with `--file` and then `--section`. A bare `--file`
92
+ value is a substring; `*` and `?` make it a glob. Use `--kind table` or
93
+ `--kind table_row` for limits and matrices, `--mode text` for a known exact
94
+ phrase, and `--exclude-id <id>` to continue past an already-read passage.
95
+
96
+ `--file` is the primary scope control: repeat it to admit several document
97
+ families, and use `--exclude-file` to remove a noisy family. Both are resolved
98
+ before ranking, so a result cannot come from an excluded document. `--section`
99
+ then keeps only a matching heading and its nested headings within those files.
100
+ For example, search two manual families but exclude archived releases:
101
+
102
+ ```sh
103
+ zen rag docs search -d <index-dir> --file "manual-*/**" --file "guide-*/**" \
104
+ --exclude-file "*-archive/**" --section "Operations" "<question>"
105
+ ```
106
+
107
+ Hybrid is not a vector reranker. It retrieves a candidate list from full-text
108
+ search and another from vector similarity, then fuses their ranks. Full-text
109
+ finds literal terms; vector search finds passages with the same meaning even
110
+ when their wording differs. `--mode text` or `--mode vector` runs only one leg;
111
+ ordinary hybrid runs both and is normally the right choice.
112
+
113
+ Use `--text-query` with `--vector-query` only when one wording cannot serve both
114
+ retrievers: a distinctive corpus term or command for the text leg, and the full
115
+ question for the vector leg. For example:
116
+
117
+ ```sh
118
+ zen rag docs search -d <index-dir> --text-query "exact identifier" \
119
+ --vector-query "what it means and how to use it"
120
+ ```
121
+
122
+ This is not a general upgrade over hybrid search. Generic product names and
123
+ common nouns make weak text legs that can displace better semantic results. The
124
+ two flags replace positional text and `--mode`; give neither alongside them.
125
+
70
126
  Run `zen check` after any edit to `agents.yaml`, a prompt or a skill: it reads
71
127
  the project the way a run does, reports everything wrong at once, and calls no
72
128
  model. It is the cheapest possible test.
@@ -75,7 +131,7 @@ When behaviour is wrong and the prompt looks right, open the run report. It
75
131
  shows what the model was actually given, which is rarely what you assumed.
76
132
 
77
133
  Flags always beat the file: the repository states intent, the invocation
78
- overrides it. Failure messages name the offending key or file — a load error
79
- names the exact path, as in `agents.yaml: agents[1].skills.discovery — …` — so
134
+ overrides it. Failure messages name the offending key or file - a load error
135
+ names the exact path, as in `agents.yaml: agents[1].skills.discovery - …` - so
80
136
  read it rather than guessing. The loader is strict on purpose, and an unknown
81
137
  key is an error rather than a value quietly ignored.
@@ -1,4 +1,4 @@
1
- # Validating — `zen check`
1
+ # Validating - `zen check`
2
2
 
3
3
  It reads the project without running it, and spends a few tokens asking each
4
4
  model to answer once; `--no-models` gives an answer that costs nothing at all.
@@ -47,7 +47,7 @@ checked too. A word that is neither is a usage error (exit 2), not a report.
47
47
  is a warning (`.unreachable`), because that is the network's problem and not
48
48
  the project's.
49
49
  - The sandbox: paths stay inside the project, the Dockerfile and its context
50
- exist, and — unless `--no-sandbox` — the image **builds** and one command runs
50
+ exist, and - unless `--no-sandbox` - the image **builds** and one command runs
51
51
  in it, against a temporary directory rather than your workspace. No container
52
52
  engine at all is a warning, not an error.
53
53
 
@@ -71,7 +71,7 @@ embedding.refused embedding.unreachable embedding.unusable
71
71
  credential.* service.credential
72
72
  ```
73
73
 
74
- The report goes to **stdout** — it is the answer. `--json` gives the same
74
+ The report goes to **stdout** - it is the answer. `--json` gives the same
75
75
  findings as data.
76
76
 
77
77
  Exit codes: `0` nothing wrong, `3` at least one error, or with `--strict` at
@@ -1,10 +1,10 @@
1
- # Mock APIs — `zen faker`
1
+ # Mock APIs - `zen faker`
2
2
 
3
3
  ```
4
4
  zen faker <serve|build|cache> [spec...]
5
5
  ```
6
6
 
7
- Alias: `zen mock`. Provided by `@zenera/faker` — `npm i -g @zenera/faker` if
7
+ Alias: `zen mock`. Provided by `@zenera/faker` - `npm i -g @zenera/faker` if
8
8
  `zen faker` says it is not installed.
9
9
 
10
10
  Serves a mock API from one or more OpenAPI/Swagger documents. For each
@@ -39,16 +39,16 @@ front and exits non-zero, with a table, if any could not be written.
39
39
  | `--model <ref>` | project default | Which model writes the generators |
40
40
  | `--image <ref>` | a baked image | Skip the baked image and use this one |
41
41
  | `--cache <dir>` | `~/.zenera/neo/faker` | Where generators live |
42
- | `--seed <n>` | — | Answer the same request the same way every time |
42
+ | `--seed <n>` | - | Answer the same request the same way every time |
43
43
  | `--attempts <n>` | `3` | Tries per generator before giving up |
44
44
  | `--concurrency <n>` | `4` | Generators written at once |
45
45
  | `--timeout <s>` | `30` | Seconds one generator may take |
46
46
  | `--max-body <n>` | 1 MB | Largest request body accepted, in bytes |
47
- | `--rebuild` | — | Ignore what is cached and write it again |
48
- | `--no-cache` | — | Do not record what is written |
49
- | `--quiet` | — | No narration |
47
+ | `--rebuild` | - | Ignore what is cached and write it again |
48
+ | `--no-cache` | - | Do not record what is written |
49
+ | `--quiet` | - | No narration |
50
50
 
51
- Credentials come from the `zen` keyring — see [keys.md](keys.md).
51
+ Credentials come from the `zen` keyring - see [keys.md](keys.md).
52
52
 
53
53
  ## Serving
54
54
 
@@ -66,19 +66,19 @@ Response headers:
66
66
  | Header | Meaning |
67
67
  | ------------------- | ----------------------------------------------------- |
68
68
  | `x-faker-operation` | The `operationId` that answered |
69
- | `x-faker-cache` | `hit` or `miss` — whether this call cost a model turn |
69
+ | `x-faker-cache` | `hit` or `miss` - whether this call cost a model turn |
70
70
 
71
71
  Incoming headers are filtered: `authorization`, `cookie` and anything matching
72
72
  `key|token|secret|password|credential` never reach a generator.
73
73
 
74
74
  `--seed` makes each request's seed a hash of the seed, the operation and the
75
- parameters, so the same request answers identically across restarts — which is
75
+ parameters, so the same request answers identically across restarts - which is
76
76
  what makes a mock usable in a test.
77
77
 
78
78
  ## What "correct" means here
79
79
 
80
80
  A generator is judged on two synthetic probes: the body validates against the
81
- response schema, **and** it obeys the **echo rule** — a value given in the path
81
+ response schema, **and** it obeys the **echo rule** - a value given in the path
82
82
  comes back in the answer. `GET /users/12324` must return `user_id: 12324`. A body
83
83
  can validate perfectly and still be about the wrong entity, which is exactly the
84
84
  mock that wastes an afternoon.
@@ -87,16 +87,16 @@ Query parameters are deliberately not enforced: `?source=realtime`, `?page_size`
87
87
  and `?cursor` are controls, and their names collide with unrelated response
88
88
  fields.
89
89
 
90
- Probes are synthetic on purpose — real request bodies never reach a prompt.
90
+ Probes are synthetic on purpose - real request bodies never reach a prompt.
91
91
 
92
92
  ## The cache
93
93
 
94
94
  Generators live in the machine's shared cache, `~/.zenera/neo/cache/faker-generator/`,
95
- keyed by the operation's shape — so the same spec served from two directories is
95
+ keyed by the operation's shape - so the same spec served from two directories is
96
96
  written once, and a spec edit produces a new key rather than a stale answer. A
97
97
  generator that a model gave up on is remembered for the life of the process, so
98
- a hopeless operation is not re-asked on every request; a _transient_ failure — a
99
- 429, a dropped socket — is not, because it is about this minute rather than this
98
+ a hopeless operation is not re-asked on every request; a _transient_ failure - a
99
+ 429, a dropped socket - is not, because it is about this minute rather than this
100
100
  operation.
101
101
 
102
102
  `~/.zenera/neo/faker/` is the container's workspace, and scratch: a cache hit is
@@ -48,7 +48,7 @@ Progress, banners, warnings and the spinner go to stderr. So
48
48
 
49
49
  `--json` applies to every command and prints one machine-readable document on
50
50
  stdout in place of the rendered form. Under `--json` nothing is asked
51
- interactively — the questions a run would ask are taken as answered.
51
+ interactively - the questions a run would ask are taken as answered.
52
52
 
53
53
  The banner is drawn only when stderr is a terminal, so a piped invocation never
54
54
  sees it.
@@ -60,13 +60,13 @@ sees it.
60
60
  | 0 | ok | It worked |
61
61
  | 1 | failed | It ran and did not succeed |
62
62
  | 2 | usage | The command line was wrong |
63
- | 3 | invalid | The project is not valid — bad `agents.yaml`, missing file |
63
+ | 3 | invalid | The project is not valid - bad `agents.yaml`, missing file |
64
64
  | 4 | credentials | No usable credential for what was asked |
65
65
  | 5 | sandbox | No container engine, or the image could not be prepared |
66
66
 
67
67
  A wrong invocation and a wrong answer are deliberately not the same code, which
68
68
  is what a script needs. Failure messages name the offending key or file; a load
69
- error names the exact path, as in `agents.yaml: agents[1].skills.discovery — …`.
69
+ error names the exact path, as in `agents.yaml: agents[1].skills.discovery - …`.
70
70
  Read it rather than guessing: the loader is strict on purpose and an unknown key
71
71
  is an error, not a value quietly ignored.
72
72
 
@@ -74,7 +74,7 @@ is an error, not a value quietly ignored.
74
74
 
75
75
  Most commands operate on a project directory, resolved in this order:
76
76
 
77
- 1. `--project <name|dir>` — a registry name or a path.
77
+ 1. `--project <name|dir>` - a registry name or a path.
78
78
  2. The working directory, if it is a project (or is inside one).
79
79
  3. For `zen run`, a bare first word that names a registered project.
80
80
 
@@ -92,7 +92,7 @@ unregistered directory can still be validated.
92
92
  | `ZENERA_DEBUG` | Print a stack trace when something unexpected escapes |
93
93
  | `VISUAL`, `EDITOR` | Consulted by `zen open` after `ZENERA_EDITOR` |
94
94
  | `COLORFGBG` | Read as a hint when the palette is being detected |
95
- | Provider keys | `OPENAI_API_KEY` and friends — see [keys.md](keys.md) |
95
+ | Provider keys | `OPENAI_API_KEY` and friends - see [keys.md](keys.md) |
96
96
 
97
97
  A real environment variable always beats the keyring.
98
98
 
@@ -112,7 +112,7 @@ A real environment variable always beats the keyring.
112
112
  agents/prompts/ one .md per agent
113
113
  agents/skills/ one directory per skill, each with SKILL.md
114
114
  sandbox/Dockerfile the image commands run in, when the project builds one
115
- sessions/ run state, memory, blobs, reports — never committed
115
+ sessions/ run state, memory, blobs, reports - never committed
116
116
  ```
117
117
 
118
118
  Credential files are refused if anyone but the owner can read them, the way
@@ -1,4 +1,4 @@
1
- # Reports — `zen inspect`
1
+ # Reports - `zen inspect`
2
2
 
3
3
  ```
4
4
  zen inspect [run] [--session <id>] [--open] [--rebuild] [--serve [port]]
@@ -29,7 +29,7 @@ was assembled differently from how it looks in the repository: a skill that did
29
29
  not activate, a hand-off that fired early, a tool that was withheld, an asset
30
30
  that was not attached.
31
31
 
32
- The report also draws the architecture — agents, their tools, their hand-offs —
32
+ The report also draws the architecture - agents, their tools, their hand-offs -
33
33
  and falls back to reconstructing the wiring from the trajectory when the run
34
34
  did not record it.
35
35
 
@@ -52,7 +52,7 @@ resolves them back.
52
52
 
53
53
  ## What it prints
54
54
 
55
- The path to `report.html` on stdout — it is the answer, so it pipes. `--json`
55
+ The path to `report.html` on stdout - it is the answer, so it pipes. `--json`
56
56
  gives `{ session, run, report }` instead. A report that is missing is built
57
57
  before either; `--rebuild` builds one that already exists again, which is always
58
58
  safe because the report is derived and `state.json` is the truth. That is also
@@ -1,4 +1,4 @@
1
- # Credentials — `zen key`
1
+ # Credentials - `zen key`
2
2
 
3
3
  ```
4
4
  zen key <ls|add|use|check|rm|show|env> [ref] [options]
@@ -85,7 +85,7 @@ behind, marked `~` and named for the variable rather than for a key:
85
85
  ~ vertex/adc …/application_default_credentials.json
86
86
  ```
87
87
 
88
- These can be listed and checked, not chosen or forgotten — there is nothing to
88
+ These can be listed and checked, not chosen or forgotten - there is nothing to
89
89
  choose between, and nothing of ours to remove. Unset the variable, or
90
90
  `gcloud auth application-default revoke`.
91
91
 
@@ -94,15 +94,15 @@ choose between, and nothing of ours to remove. Unset the variable, or
94
94
  `zen key check` and `zen key ls --check` do one round trip per key and record
95
95
  the verdict:
96
96
 
97
- - **live** — authenticated. A rate-limited answer counts as live, because it
97
+ - **live** - authenticated. A rate-limited answer counts as live, because it
98
98
  proves the credential.
99
- - **dead** — the provider rejected it. A verdict.
100
- - **blocked** — the credential was accepted and the **account** refused: an API
99
+ - **dead** - the provider rejected it. A verdict.
100
+ - **blocked** - the credential was accepted and the **account** refused: an API
101
101
  switched off in the project, an empty balance, a model this key was never
102
102
  granted. Do not rotate the key; a new one is refused identically. The check
103
- carries a `fix` — for a disabled Google API, the exact
103
+ carries a `fix` - for a disabled Google API, the exact
104
104
  `gcloud services enable <api> --project <id>`.
105
- - **unknown** — the provider could not be asked. Says nothing about the key;
105
+ - **unknown** - the provider could not be asked. Says nothing about the key;
106
106
  usually the network.
107
107
 
108
108
  `zen init` uses the same probe to pick which provider to scaffold with, so a
@@ -110,9 +110,9 @@ project is not built around a revoked key.
110
110
 
111
111
  ## When a run says there is no credential
112
112
 
113
- The frame does **not** materialise the keyring for you — each command that needs
113
+ The frame does **not** materialise the keyring for you - each command that needs
114
114
  a credential opens the store itself. If `zen key ls` shows a key as live and a
115
- command still says `provider "openai": no api key — set OPENAI_API_KEY`, the
115
+ command still says `provider "openai": no api key - set OPENAI_API_KEY`, the
116
116
  credential is fine and the command is at fault. Everything that runs a model
117
117
  (`run`, `check`, `models`, `faker`, `rag`) already does this.
118
118
 
@@ -1,4 +1,4 @@
1
- # Memory — `zen memory`
1
+ # Memory - `zen memory`
2
2
 
3
3
  ```
4
4
  zen memory [stats|ls|show|export|forget] [args] [options]
@@ -45,7 +45,7 @@ is masked, ranked and truncated as well, so what an agent gets is never the
45
45
  whole picture.
46
46
 
47
47
  This command ignores all of that. When the mask is the thing that is wrong, the
48
- part that was hidden is exactly the part you need — and this is a person at a
48
+ part that was hidden is exactly the part you need - and this is a person at a
49
49
  terminal in the project directory, not an agent inside a run.
50
50
 
51
51
  It also contacts no model. The store is opened without an embedder, so
@@ -60,12 +60,12 @@ zen memory export --open
60
60
 
61
61
  One self-contained HTML file, three panes:
62
62
 
63
- - **left** — every node, with a search box and filters for kind, audience,
63
+ - **left** - every node, with a search box and filters for kind, audience,
64
64
  files, superseded and unlinked
65
- - **middle** — the graph as a Mermaid diagram, coloured by kind, with pan,
65
+ - **middle** - the graph as a Mermaid diagram, coloured by kind, with pan,
66
66
  zoom, and a hop-focus selector for following one node's neighbourhood
67
- - **right** — whatever you clicked, in full: the text, the metadata, the links,
68
- and **the remembered file's actual content** — rendered as an image when it is
67
+ - **right** - whatever you clicked, in full: the text, the metadata, the links,
68
+ and **the remembered file's actual content** - rendered as an image when it is
69
69
  one, and as text otherwise
70
70
 
71
71
  Clicking a node in either the list or the diagram selects it in both. Above 300
@@ -83,15 +83,15 @@ zen memory forget 01M1YPN0C8QRQS5BCZ03ABQ1G0
83
83
  ```
84
84
 
85
85
  Asks first, unless `--yes`, and refuses outright when there is no terminal to
86
- ask at. A node, its vector row and its remembered file bytes go together —
86
+ ask at. A node, its vector row and its remembered file bytes go together -
87
87
  there is one implementation of that, shared with the agent-facing tool, so the
88
88
  three cannot drift apart.
89
89
 
90
90
  **Forgetting is rarely the right correction.** The agents' own way to fix a
91
91
  wrong memory is to commit the corrected node and supersede the old one, which
92
92
  keeps the record of having been wrong. `zen memory ls --stale` lists what has
93
- been superseded that way. Use `forget` for what should never have been stored —
94
- a secret, a mistake, a pile of noise — not for what merely became untrue.
93
+ been superseded that way. Use `forget` for what should never have been stored -
94
+ a secret, a mistake, a pile of noise - not for what merely became untrue.
95
95
 
96
96
  ## Reading `stats`
97
97
 
@@ -100,8 +100,8 @@ nodes 7
100
100
  edges 6
101
101
  superseded 1
102
102
  files 1 · 640 B
103
- embedding none — recall falls back to term overlap
104
- vectors —
103
+ embedding none - recall falls back to term overlap
104
+ vectors -
105
105
  ```
106
106
 
107
107
  `embedding none` is worth noticing: without an embedder, recall matches on