@zenera/cli 1.1.17 → 1.1.19
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 +99 -16
- package/dist/banner.d.ts +19 -0
- package/dist/banner.js +17 -10
- package/dist/command.d.ts +3 -0
- package/dist/commands/index.js +4 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/inspect.js +77 -13
- package/dist/commands/key.js +49 -1
- package/dist/commands/memory.js +16 -3
- package/dist/commands/meta.d.ts +3 -0
- package/dist/commands/meta.js +596 -0
- package/dist/commands/run.js +63 -38
- package/dist/engine.d.ts +15 -0
- package/dist/engine.js +20 -1
- package/dist/home.d.ts +2 -0
- package/dist/home.js +2 -0
- package/dist/main.js +1 -1
- package/dist/meta.d.ts +221 -0
- package/dist/meta.js +695 -0
- package/dist/podman.js +64 -2
- package/dist/projects.d.ts +9 -1
- package/dist/projects.js +19 -2
- package/dist/resolve.js +7 -1
- package/dist/sandbox.d.ts +2 -0
- package/dist/sandbox.js +1 -1
- package/dist/scaffold.js +1 -1
- package/dist/session.d.ts +10 -0
- package/dist/session.js +19 -1
- package/dist/term.d.ts +21 -0
- package/dist/term.js +74 -2
- package/dist/tui/app.js +313 -150
- package/dist/tui/theme.d.ts +26 -7
- package/dist/tui/theme.js +62 -36
- package/dist/tui/wrap.d.ts +41 -16
- package/dist/tui/wrap.js +191 -18
- package/dist/validate.js +3 -16
- package/package.json +3 -2
- package/templates/editor/.github/copilot-instructions.md +61 -7
- package/templates/editor/.github/prompts/{review-project.prompt.md → project-review.prompt.md} +0 -1
- package/templates/editor/.github/prompts/{update-spec-from-feedback.prompt.md → spec-apply-feedback.prompt.md} +5 -5
- package/templates/editor/.github/prompts/{sync-with-spec.prompt.md → spec-sync-project.prompt.md} +4 -4
- package/templates/editor/.github/skills/zen-cli/references/check.md +0 -2
- package/templates/editor/.github/skills/zen-cli/references/inspect.md +4 -3
- package/templates/editor/.github/skills/zen-cli/references/memory.md +14 -0
- package/templates/editor/.github/skills/zen-cli/references/projects.md +1 -0
- package/templates/editor/.github/skills/zen-cli/references/run.md +75 -16
- package/templates/editor/.github/skills/zen-memory/SKILL.md +52 -4
- package/templates/editor/.github/skills/zen-review/SKILL.md +2 -2
- package/templates/editor/.github/skills/zen-review/scripts/review.sh +1 -1
- package/templates/editor/.github/skills/zen-spec-sync/SKILL.md +2 -2
- package/templates/editor/.github/skills/zen-spec-sync/scripts/snapshot.sh +1 -1
- package/templates/project/SPECIFICATION.md.tmpl +25 -2
- package/templates/project/agents/tools-instructions.md +8 -0
- package/templates/project/agents.yaml.tmpl +3 -3
- package/templates/project/env +7 -1
- package/templates/project/gitignore +4 -4
|
@@ -59,8 +59,9 @@ schema index it is expected to consult all count. When it does, also load the
|
|
|
59
59
|
|
|
60
60
|
Then create or maintain `agents/skills/rag_search/SKILL.md` in the target
|
|
61
61
|
project. Its description must say when an agent should load it. Its body must
|
|
62
|
-
name the target's actual RAG surface and index location,
|
|
63
|
-
|
|
62
|
+
name the target's actual RAG surface and index location, open by stating what an
|
|
63
|
+
agent needs to follow it and what to do without that, and give an executable
|
|
64
|
+
retrieval procedure:
|
|
64
65
|
|
|
65
66
|
1. Discover document and section names with the exact listing command or tool.
|
|
66
67
|
2. Start with hybrid search for a complete natural-language question.
|
|
@@ -72,6 +73,16 @@ use it, and give an executable retrieval procedure:
|
|
|
72
73
|
5. Retrieve a complete section verbatim, or list a table and read its inclusive
|
|
73
74
|
line range when every row is needed.
|
|
74
75
|
|
|
76
|
+
**State the prerequisite, not the audience.** `skills.allow` restricts loading
|
|
77
|
+
and `zen check` validates it; a list of agent names in the body is a second copy
|
|
78
|
+
of that binding with nothing keeping the two in step, and it is stale the first
|
|
79
|
+
time an agent is renamed (§4.2, rule 10). What a reader can act on is what the
|
|
80
|
+
procedure needs - the RAG tools, or `sandbox:*` and the index at its path - and
|
|
81
|
+
what to do without them: _"say so and stop; do not answer from memory"_ (§4.2,
|
|
82
|
+
rule 6). Put it in the first lines of the body, because the catalog is mounted
|
|
83
|
+
whole at `/skills` before any binding applies (§3.4.1), so an agent that was
|
|
84
|
+
never granted this skill can still read the file and start following it.
|
|
85
|
+
|
|
75
86
|
Keep this as runtime guidance, not a pointer to this editor reference: a target
|
|
76
87
|
agent cannot read `.github/` or this project layout while it runs. Include only
|
|
77
88
|
the commands, tools, paths, and corpus-specific constraints that exist in the
|
|
@@ -106,7 +117,7 @@ without losing anything. Never paraphrase the reference into prose of your own.
|
|
|
106
117
|
See §5.3.
|
|
107
118
|
|
|
108
119
|
A project with a `SPECIFICATION.md` carries one more: **`.spec-sync/` records
|
|
109
|
-
what the last `/sync-
|
|
120
|
+
what the last `/spec-sync-project` pass applied**, and the `zen-spec-sync` skill is
|
|
110
121
|
loaded before running that prompt, whether or not a baseline exists yet. The
|
|
111
122
|
state is committed, because a record only the last machine has is not a record.
|
|
112
123
|
Two things to watch for, neither of which `zen check` reports: a baseline that
|
|
@@ -207,11 +218,12 @@ my-project/
|
|
|
207
218
|
│ ├── prompts/*.prompt.md tasks you invoke by name
|
|
208
219
|
│ └── skills/*/SKILL.md reference the editor loads on demand
|
|
209
220
|
├── .env this project's environment - NEVER committed
|
|
210
|
-
├── .spec-sync/ what the last /sync-
|
|
221
|
+
├── .spec-sync/ what the last /spec-sync-project applied - §0.1
|
|
211
222
|
├── agents.yaml who exists, what they may reach for
|
|
212
223
|
├── agents/
|
|
213
224
|
│ ├── instructions.md house rules, prepended to every agent
|
|
214
225
|
│ ├── memory-instructions.md more of them - any `<topic>-instructions.md`
|
|
226
|
+
│ ├── tools-instructions.md and more - how tools are called
|
|
215
227
|
│ ├── prompts/
|
|
216
228
|
│ │ ├── intake.md one agent's own brief
|
|
217
229
|
│ │ └── adjuster.md
|
|
@@ -236,8 +248,7 @@ The config is found by name, in order: `agents.yaml`, `agents.yml`,
|
|
|
236
248
|
|
|
237
249
|
The house rules are `agents/instructions.md` plus every
|
|
238
250
|
`agents/<topic>-instructions.md`, read in filename order and prepended to every
|
|
239
|
-
agent (§3.2).
|
|
240
|
-
the root; that still loads, and `zen check` says to move it.
|
|
251
|
+
agent (§3.2).
|
|
241
252
|
|
|
242
253
|
### 2.2 Variants
|
|
243
254
|
|
|
@@ -767,10 +778,18 @@ groups - the workspace tools (§3.6), the sandbox tools (§3.7) and the web tool
|
|
|
767
778
|
the machine, so `tools:` is the whole permission model: an agent that does not
|
|
768
779
|
name a tool cannot use it, whatever its prompt says.
|
|
769
780
|
|
|
770
|
-
|
|
781
|
+
Three rules follow:
|
|
771
782
|
|
|
772
783
|
- **Grant the narrowest set the job needs.** An agent that only reviews should
|
|
773
784
|
not be holding the tools that overwrite files.
|
|
785
|
+
- **Grant by group, then subtract.** Write `workspace:*` and take away what this
|
|
786
|
+
agent must not have - not a hand-picked list of names. The tools in a group are
|
|
787
|
+
designed to be used together, and a list assembled one name at a time leaves out
|
|
788
|
+
the companion the model reaches for next: `write_file` without `apply_patch`
|
|
789
|
+
turns every one-line edit into a whole-file rewrite, and `read_file` without
|
|
790
|
+
`list_dir` and `find_files` leaves it guessing at paths. A group also tracks the
|
|
791
|
+
runtime - a tool added to it later reaches the agent, where an enumerated list
|
|
792
|
+
silently stays behind.
|
|
774
793
|
- **Say in the prompt when to reach for what.** A granted tool the prompt never
|
|
775
794
|
mentions is used at the model's discretion, which is not the same as never.
|
|
776
795
|
|
|
@@ -830,6 +849,13 @@ refuses the file. `workspace:*` needs no quoting. There is no name globbing -
|
|
|
830
849
|
`read_*` is an unknown tool, because a selector should track a declared set, not
|
|
831
850
|
a naming habit.
|
|
832
851
|
|
|
852
|
+
Both agents above are written the way to write them: **the group, minus the
|
|
853
|
+
exceptions**. `tools: [read_file, write_file]` is the shape to avoid - it reads
|
|
854
|
+
as a considered decision and is usually an incomplete one, since the tool that
|
|
855
|
+
makes the granted one usable is the tool that was left out. Subtracting says
|
|
856
|
+
which capability is being withheld, which is the thing a reviewer needs to check
|
|
857
|
+
and the thing the next tool added to the group will not quietly defeat.
|
|
858
|
+
|
|
833
859
|
`zen run --read-only` withholds the four mutating tools whatever `agents.yaml`
|
|
834
860
|
asks for: the deployment overriding the repository, as everywhere else.
|
|
835
861
|
|
|
@@ -1075,6 +1101,7 @@ zen run open the entry agent on this project
|
|
|
1075
1101
|
zen run "what changed?" one shot; stdout is the answer
|
|
1076
1102
|
zen run --session <id> continue a session
|
|
1077
1103
|
zen run --workspace ./repo what the agent may read and write
|
|
1104
|
+
zen run --memory ./mem where the agents remember into, instead of memory/
|
|
1078
1105
|
zen run --model careful override the default model for this run
|
|
1079
1106
|
zen run --image <ref> override the sandbox image for this run, ignoring build:
|
|
1080
1107
|
zen run --read-only withhold every tool that can write
|
|
@@ -1095,11 +1122,17 @@ OPENAI_API_KEY=...
|
|
|
1095
1122
|
ANTHROPIC_API_KEY=...
|
|
1096
1123
|
GOOGLE_APPLICATION_CREDENTIALS=./.keys/vertex.json
|
|
1097
1124
|
EXA_API_KEY=...
|
|
1125
|
+
ZENERA_META_MODEL=vertex/gemini-3.8-flash
|
|
1098
1126
|
```
|
|
1099
1127
|
|
|
1100
1128
|
Never commit. Never inline a key into `agents.yaml` - use `${VAR}`. Never print a
|
|
1101
1129
|
key in a log line, a test fixture, or a chat message.
|
|
1102
1130
|
|
|
1131
|
+
`ZENERA_META_MODEL` is the exception that is not a credential: it names the model
|
|
1132
|
+
`zen meta` runs the meta agent on in this project, as a zen ref. It is here
|
|
1133
|
+
rather than in `agents.yaml` because it is a choice about a tool, not about the
|
|
1134
|
+
project's own agents. `zen meta model` prints where the answer came from.
|
|
1135
|
+
|
|
1103
1136
|
### 3.11 `assets/`
|
|
1104
1137
|
|
|
1105
1138
|
`assets/` next to `agents.yaml` - or `assets: <path>` - is reference material
|
|
@@ -1915,10 +1948,17 @@ candidates; these are the judgements to make about each one)**
|
|
|
1915
1948
|
- [ ] Catalog >~30 entries → `discovery: search`
|
|
1916
1949
|
- [ ] A skill that ships a script writes its `/skills/<name>/...` path, the agent
|
|
1917
1950
|
holds `sandbox:*`, and the sandbox image already has the interpreter
|
|
1951
|
+
- [ ] A skill whose procedure needs particular tools, an index or a mounted file
|
|
1952
|
+
opens by naming them and says what to do without them - rather than naming
|
|
1953
|
+
the agents allowed to load it, which `agents.yaml` already decides - §0.1
|
|
1918
1954
|
|
|
1919
1955
|
**Tools**
|
|
1920
1956
|
|
|
1921
1957
|
- [ ] Every agent holds the narrowest set its job needs
|
|
1958
|
+
- [ ] Every `tools:` list is a group selector minus its exceptions, not an
|
|
1959
|
+
enumeration of individual names - §3.5
|
|
1960
|
+
- [ ] No agent holds `write_file` without `apply_patch`, or `read_file` without
|
|
1961
|
+
`list_dir` and `find_files`
|
|
1922
1962
|
- [ ] An agent that only reads is not holding `write_file`, `apply_patch`,
|
|
1923
1963
|
`move_file` or `delete_file` - subtract them from `workspace:*`
|
|
1924
1964
|
- [ ] `sandbox:*` is granted only where a shell is actually needed
|
|
@@ -2062,3 +2102,17 @@ Update it when:
|
|
|
2062
2102
|
|
|
2063
2103
|
Do not let it grow without pruning. When a section is only true of one agent, it
|
|
2064
2104
|
belongs in that agent's prompt, not here.
|
|
2105
|
+
---
|
|
2106
|
+
|
|
2107
|
+
## 13. Function calling rules
|
|
2108
|
+
|
|
2109
|
+
Before every tool call, write **one line** saying what you are about to do and
|
|
2110
|
+
why. One line per call, in front of it - not a plan for the whole turn, and not
|
|
2111
|
+
a summary afterwards.
|
|
2112
|
+
|
|
2113
|
+
- Say the intent and the reason, not the tool's name or its arguments:
|
|
2114
|
+
_"Reading `agents.yaml` to see which agents hold `sandbox:*`."_
|
|
2115
|
+
- When several calls go out together, write one line covering the batch.
|
|
2116
|
+
- Keep it to a sentence. If it needs two, the call needs splitting, not the
|
|
2117
|
+
sentence.
|
|
2118
|
+
- Do not narrate the result in the same line - the tool answers that.
|
|
@@ -12,7 +12,7 @@ answered.
|
|
|
12
12
|
You change two files and no others: `SPECIFICATION.md` and
|
|
13
13
|
`SPECIFICATION-FEEDBACK.md`. You implement nothing - not a prompt, not a skill,
|
|
14
14
|
not `agents.yaml`. Making the project match the specification is
|
|
15
|
-
`/sync-
|
|
15
|
+
`/spec-sync-project`, which runs after this.
|
|
16
16
|
|
|
17
17
|
## 1. Read both files before editing either
|
|
18
18
|
|
|
@@ -83,7 +83,7 @@ put it where the line above the block says it goes.
|
|
|
83
83
|
edits rather than trusting the line numbers you read at the start.
|
|
84
84
|
|
|
85
85
|
Nothing outside `SPECIFICATION.md` changes here. If an answer's text implies an
|
|
86
|
-
agent, a tool grant, a script or a skill, that is the next `/sync-
|
|
86
|
+
agent, a tool grant, a script or a skill, that is the next `/spec-sync-project`
|
|
87
87
|
pass's work, and saying so is all you do about it.
|
|
88
88
|
|
|
89
89
|
## 4. Mark the question answered
|
|
@@ -108,7 +108,7 @@ order:
|
|
|
108
108
|
the specification to be true again, or `Nothing - the project already does
|
|
109
109
|
this.`
|
|
110
110
|
|
|
111
|
-
That last line is what the next `/sync-
|
|
111
|
+
That last line is what the next `/spec-sync-project` works from, so write it as
|
|
112
112
|
work, not as a summary.
|
|
113
113
|
|
|
114
114
|
Then bring the top of the file back into step: the opening paragraph's count of
|
|
@@ -124,7 +124,7 @@ answer you think is wrong is still the answer; say why in the chat and leave the
|
|
|
124
124
|
text alone.
|
|
125
125
|
|
|
126
126
|
Do not run `zen check`, `scripts/_setup.sh` or anything under `.spec-sync/`. The
|
|
127
|
-
baseline moves at the end of a `/sync-
|
|
127
|
+
baseline moves at the end of a `/spec-sync-project` pass and nowhere else -
|
|
128
128
|
committing it here would record a specification as applied that nothing has
|
|
129
129
|
implemented yet.
|
|
130
130
|
|
|
@@ -138,5 +138,5 @@ In the chat:
|
|
|
138
138
|
- what is still open, split into: more than one answer left, more than one box
|
|
139
139
|
marked, every answer rejected, and could not be applied because the place it
|
|
140
140
|
names is gone
|
|
141
|
-
- then, in one line: send `/sync-
|
|
141
|
+
- then, in one line: send `/spec-sync-project` to make the project match the
|
|
142
142
|
specification you have just changed.
|
package/templates/editor/.github/prompts/{sync-with-spec.prompt.md → spec-sync-project.prompt.md}
RENAMED
|
@@ -172,7 +172,7 @@ nothing to raise, say so in the chat and do not create the file.
|
|
|
172
172
|
**It is a questionnaire, and answering it must take one gesture.** Every
|
|
173
173
|
question carries two to four written-out answers, each with a `[ ]` box in its
|
|
174
174
|
heading. The reader marks the box of the one they want - `[x]` - and deletes the
|
|
175
|
-
others, then sends `/
|
|
175
|
+
others, then sends `/spec-apply-feedback`, which folds what survived into
|
|
176
176
|
`SPECIFICATION.md`. Either gesture alone is enough, and the file says so in
|
|
177
177
|
every question.
|
|
178
178
|
|
|
@@ -190,7 +190,7 @@ Two rules that come before everything else in this section:
|
|
|
190
190
|
The file opens with one short paragraph: how many questions are open, and how to
|
|
191
191
|
answer them - put an `x` in the box of the answer you want, delete the answers
|
|
192
192
|
you do not want, or replace them all with a sentence of your own, then send
|
|
193
|
-
`/
|
|
193
|
+
`/spec-apply-feedback`. Then a contents list, one line per question: its
|
|
194
194
|
number as an anchor link, the question in under ten words, and what is built in
|
|
195
195
|
the meantime. Then the questions, grouped under these headings, omitting any
|
|
196
196
|
heading with no questions. The file is scanned before it is read, so keep the
|
|
@@ -212,7 +212,7 @@ emoji on every heading:
|
|
|
212
212
|
## ✅ Answered - folded into the specification
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
-
`✅` is written by `/
|
|
215
|
+
`✅` is written by `/spec-apply-feedback`, not by you. Leave what is there
|
|
216
216
|
alone except to strike an entry this pass has actually implemented, and say in
|
|
217
217
|
the chat which ones you closed.
|
|
218
218
|
|
|
@@ -329,7 +329,7 @@ retires with it.
|
|
|
329
329
|
Read the feedback diff from §0 before writing: a question the human answered
|
|
330
330
|
since the last pass is work to close, not a question to ask again. If a question
|
|
331
331
|
has a box marked `[x]`, or one answer left under it, and no `✅` entry, the
|
|
332
|
-
reader answered it and never ran `/
|
|
332
|
+
reader answered it and never ran `/spec-apply-feedback` - implement that
|
|
333
333
|
answer, fold its text into `SPECIFICATION.md` yourself, and say so in the chat.
|
|
334
334
|
|
|
335
335
|
## 6. Run `scripts/_setup.sh` and watch it finish
|
|
@@ -33,8 +33,6 @@ checked too. A word that is neither is a usage error (exit 2), not a report.
|
|
|
33
33
|
rather than ignored.
|
|
34
34
|
- Every file the configuration names is on disk and non-empty: the house rules
|
|
35
35
|
under `agents/`, each agent's prompt, each skill's `SKILL.md`, each asset glob.
|
|
36
|
-
A root `INSTRUCTIONS.md` is still read, and reported as something to move to
|
|
37
|
-
`agents/instructions.md`.
|
|
38
36
|
- Hand-offs and forks name agents that exist, and no agent hands off to itself.
|
|
39
37
|
- Tool selectors resolve against the real tool set, including a skill's own
|
|
40
38
|
`tools:` frontmatter.
|
|
@@ -7,12 +7,13 @@ zen inspect [run] [--session <id>] [--open] [--rebuild] [--serve [port]]
|
|
|
7
7
|
Alias: `report`.
|
|
8
8
|
|
|
9
9
|
Renders the trajectory of a run: every message, tool call, skill activation and
|
|
10
|
-
hand-off, in order, with what each one cost. With no arguments it
|
|
11
|
-
|
|
10
|
+
hand-off, in order, with what each one cost. With no arguments it asks which
|
|
11
|
+
session and which run; where there is nothing to ask on — a script, `--json`,
|
|
12
|
+
an agent — it takes the newest run of the newest session that has one.
|
|
12
13
|
|
|
13
14
|
| Flag | Meaning |
|
|
14
15
|
| ---------------- | ------------------------------------------------------- |
|
|
15
|
-
| `[run]` | A run id
|
|
16
|
+
| `[run]` | A run id, in whichever session holds it |
|
|
16
17
|
| `--session <id>` | Which session the run belongs to |
|
|
17
18
|
| `--open` | Open the report in a browser |
|
|
18
19
|
| `--rebuild` | Rebuild `report.html` from the recorded state |
|
|
@@ -29,6 +29,7 @@ skill.
|
|
|
29
29
|
| Flag | Meaning |
|
|
30
30
|
| ----------------------- | -------------------------------------------- |
|
|
31
31
|
| `--project <name\|dir>` | Which project. Inferred from the directory |
|
|
32
|
+
| `--dir <dir>` | Read this memory directory instead |
|
|
32
33
|
| `--kind <name>` | Only this kind of node |
|
|
33
34
|
| `--audience <name>` | Only nodes committed under this label |
|
|
34
35
|
| `--files` | Only nodes that remember a file |
|
|
@@ -38,6 +39,19 @@ skill.
|
|
|
38
39
|
| `--open` | Open the exported page |
|
|
39
40
|
| `--yes` | Do not ask before removing |
|
|
40
41
|
|
|
42
|
+
## A graph that is not the project's
|
|
43
|
+
|
|
44
|
+
`--dir` opens a memory directory as it stands, and skips project resolution
|
|
45
|
+
entirely: there need be no `agents.yaml` anywhere above it. That is what to use
|
|
46
|
+
for a graph a run was pointed at with `zen run --memory <dir>`, and for a copy
|
|
47
|
+
taken out of a running session - copy the directory, delete its `.lock`, and
|
|
48
|
+
read the copy while the run continues.
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
zen run --memory .tmp/mem "…" remember into .tmp/mem for this run
|
|
52
|
+
zen memory --dir .tmp/mem stats then read that graph, from anywhere
|
|
53
|
+
```
|
|
54
|
+
|
|
41
55
|
## It reads unmasked, on purpose
|
|
42
56
|
|
|
43
57
|
Memory is masked per agent: a node's `audience` decides who can see it. Recall
|
|
@@ -22,6 +22,7 @@ zenera.json { version, name }
|
|
|
22
22
|
agents.yaml the configuration
|
|
23
23
|
agents/instructions.md house rules, prepended to every agent
|
|
24
24
|
agents/memory-instructions.md more of them, about the memory store
|
|
25
|
+
agents/tools-instructions.md more of them, about how tools are called
|
|
25
26
|
agents/prompts/default.md the default agent's prompt
|
|
26
27
|
agents/skills/ empty, for skills
|
|
27
28
|
assets/README.md
|
|
@@ -9,24 +9,78 @@ answers once on stdout and exits.
|
|
|
9
9
|
|
|
10
10
|
## Options
|
|
11
11
|
|
|
12
|
-
| Flag | What it does
|
|
13
|
-
| ----------------------- |
|
|
14
|
-
| `--project <name\|dir>` | Which project. Inferred from the directory otherwise
|
|
15
|
-
| `--session <id>` | Continue a particular session
|
|
16
|
-
| `--new` | Start a
|
|
17
|
-
| `--workspace <dir>` | What the agent may read and write
|
|
18
|
-
| `--
|
|
19
|
-
| `--
|
|
20
|
-
| `--
|
|
21
|
-
| `--
|
|
22
|
-
| `--plain` |
|
|
23
|
-
| `--theme <dark\|light>` |
|
|
24
|
-
| `--out <file>` |
|
|
25
|
-
| `--yes` |
|
|
12
|
+
| Flag | What it does |
|
|
13
|
+
| ----------------------- | -------------------------------------------------------- |
|
|
14
|
+
| `--project <name\|dir>` | Which project. Inferred from the directory otherwise |
|
|
15
|
+
| `--session <id>` | Continue a particular session |
|
|
16
|
+
| `--new` | Start a new session rather than continuing one |
|
|
17
|
+
| `--workspace <dir>` | What the agent may read and write |
|
|
18
|
+
| `--memory <dir>` | Where the agents remember into, instead of the project's |
|
|
19
|
+
| `--model <ref>` | Override the default model for this run |
|
|
20
|
+
| `--image <ref>` | Override the container image commands run in |
|
|
21
|
+
| `--read-only` | Withhold every tool that can write |
|
|
22
|
+
| `--plain` | Never open the TUI; a prompt is then required |
|
|
23
|
+
| `--theme <dark\|light>` | Palette for the TUI; `auto` detects. `$ZENERA_THEME` |
|
|
24
|
+
| `--out <file>` | Put the answer in this file instead of on stdout |
|
|
25
|
+
| `--yes` | Say yes to the workspace and install questions |
|
|
26
26
|
|
|
27
27
|
Flags always beat the file: the repository states intent, the invocation
|
|
28
28
|
overrides it.
|
|
29
29
|
|
|
30
|
+
## Where the answer goes
|
|
31
|
+
|
|
32
|
+
The answer goes to stdout and the progress to stderr, so `zen run "…" >
|
|
33
|
+
answer.md` leaves a file with the answer in it and nothing else, watched or not.
|
|
34
|
+
`--out` is a destination rather than a copy: it takes the answer off stdout, so
|
|
35
|
+
the file is the only place it lands.
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
zen run "what changed?" > out.md answer in the file, progress on screen
|
|
39
|
+
zen run "what changed?" > out.md 2>/dev/null ... and nothing on screen at all
|
|
40
|
+
zen run --out out.md "what changed?" the same file, stdout left empty
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
There is no `--quiet`. Narration is on stderr already, so a redirect is enough;
|
|
44
|
+
`--json` silences it for machine use.
|
|
45
|
+
|
|
46
|
+
`--json` answers with the paths as well as the answer: the session and run
|
|
47
|
+
directories, every file the run left behind, and every tree the agent could see,
|
|
48
|
+
with the path it had on this machine beside the path it had inside the
|
|
49
|
+
container.
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"session": { "id": "...", "dir": "<project>/sessions/<id>" },
|
|
54
|
+
"run": {
|
|
55
|
+
"id": "...",
|
|
56
|
+
"dir": "<project>/sessions/<id>/runs/<run-id>",
|
|
57
|
+
"input": ".../input.md",
|
|
58
|
+
"output": ".../output.md",
|
|
59
|
+
"state": ".../state.json",
|
|
60
|
+
"meta": ".../meta.json",
|
|
61
|
+
"report": ".../report.html"
|
|
62
|
+
},
|
|
63
|
+
"mounts": [
|
|
64
|
+
{ "host": "...", "at": "/workspace", "readOnly": false },
|
|
65
|
+
{ "host": "...", "at": "/assets", "readOnly": true },
|
|
66
|
+
{ "host": "...", "at": "/skills/<name>", "readOnly": true }
|
|
67
|
+
],
|
|
68
|
+
"agent": "...",
|
|
69
|
+
"stopReason": "final",
|
|
70
|
+
"durationMs": 0,
|
|
71
|
+
"usage": {},
|
|
72
|
+
"output": "the answer"
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`mounts` also lists the container's `$HOME` and, when keys are forwarded, the
|
|
77
|
+
credential files mounted under `/run/zenera/keys`.
|
|
78
|
+
|
|
79
|
+
`--plain` never opens the TUI. The TUI is the only thing that can ask for a
|
|
80
|
+
prompt, so with `--plain` the prompt has to be there already - in the argument
|
|
81
|
+
or on stdin - and `zen run --plain` with neither is an error instead of a
|
|
82
|
+
window. Say it in a script that must not meet one.
|
|
83
|
+
|
|
30
84
|
## Which word is the project
|
|
31
85
|
|
|
32
86
|
The first positional is read as a project when it names one, and as the first
|
|
@@ -42,7 +96,7 @@ zen run --project why "why?" when the project is called "why"
|
|
|
42
96
|
The prompt comes from the argument, or from stdin, or from the TUI:
|
|
43
97
|
|
|
44
98
|
```
|
|
45
|
-
git diff | zen run
|
|
99
|
+
git diff | zen run "summarise this diff"
|
|
46
100
|
```
|
|
47
101
|
|
|
48
102
|
## What a prompt on the command line implies
|
|
@@ -56,10 +110,15 @@ there is someone to ask, still asks.
|
|
|
56
110
|
There is no `resume`. A session continues itself, because its state is what it
|
|
57
111
|
is; `--session <id>` picks which one.
|
|
58
112
|
|
|
113
|
+
`--new` only matters when there is no prompt. A prompt on the command line
|
|
114
|
+
already starts a new session, so `zen run --new "what changed?"` is the same as
|
|
115
|
+
`zen run "what changed?"`. Without a prompt the TUI asks which session to
|
|
116
|
+
continue, and `--new` is how you skip that question. It contradicts `--session`.
|
|
117
|
+
|
|
59
118
|
## The TUI
|
|
60
119
|
|
|
61
120
|
Drawn only when there is a terminal on both stdin and stdout, no prompt,
|
|
62
|
-
no `--plain
|
|
121
|
+
no `--plain` and no `--json`. It streams the answer, shows
|
|
63
122
|
reasoning as it arrives, and reports per-turn and per-session token usage in the
|
|
64
123
|
footer.
|
|
65
124
|
|
|
@@ -197,8 +197,9 @@ below.
|
|
|
197
197
|
└── .lock held while a run is writing; a dead pid's lock is stale
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
It is
|
|
201
|
-
mounted **read-only** at `/memory` in the agent's
|
|
200
|
+
It is committed with the project - everything but `.lock`, which is runtime
|
|
201
|
+
state. The directory is mounted **read-only** at `/memory` in the agent's
|
|
202
|
+
namespace.
|
|
202
203
|
|
|
203
204
|
## Designing a memory strategy
|
|
204
205
|
|
|
@@ -363,6 +364,40 @@ lands at `<project>/memory/files/<id>.<ext>` and appears to the agent as:
|
|
|
363
364
|
| Mount | `/memory`, **read-only** |
|
|
364
365
|
| Extension | preserved, because it decides how the file runs and renders |
|
|
365
366
|
|
|
367
|
+
### The agent has to be able to write the file first
|
|
368
|
+
|
|
369
|
+
`memory_commit` **copies** a file that already exists. It is not an upload
|
|
370
|
+
channel and it cannot create one. So everything too big for a node's `text` - a
|
|
371
|
+
script, a config, an assembled passage - depends on the agent having a tool that
|
|
372
|
+
puts bytes in the **workspace**, and an agent with none can only ever commit
|
|
373
|
+
text no matter how much the memory design leans on `file` nodes.
|
|
374
|
+
|
|
375
|
+
| The agent's `tools:` | Can it commit a `file`? |
|
|
376
|
+
| ---------------------------- | ----------------------------------------------------------------------- |
|
|
377
|
+
| `write_file` / `apply_patch` | Yes. Write it, then name the same path |
|
|
378
|
+
| `run_command` only | Yes, but only under `/workspace` - a heredoc into `/tmp` is unreachable |
|
|
379
|
+
| Neither | No. Everything worth keeping has to fit on one line of `text` |
|
|
380
|
+
|
|
381
|
+
The workspace is the only tree that round-trips, because it is the only
|
|
382
|
+
writable one. `/assets`, `/skills` and `/memory` resolve as well - they are
|
|
383
|
+
mounts the file tools know by name - but they are **read-only**, so nothing can
|
|
384
|
+
be put there to be remembered. Every other absolute path is real to
|
|
385
|
+
`run_command` and outside the workspace root, so a file written to `/tmp` comes
|
|
386
|
+
back as:
|
|
387
|
+
|
|
388
|
+
```
|
|
389
|
+
error: outside the workspace: /tmp/report.py
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
A bare error carrying none of the `hint` the other memory refusals do, because
|
|
393
|
+
containment is a workspace answer rather than a memory one.
|
|
394
|
+
|
|
395
|
+
This is the trap in a `tools:` list trimmed to `run_command` alone: the shell
|
|
396
|
+
can create the file, so `file` nodes look supported, but nothing in the agent's
|
|
397
|
+
context ever uses workspace vocabulary and the model has no reason to prefer
|
|
398
|
+
`/workspace` over `/tmp`. Either give it the file tools, or say in its prompt
|
|
399
|
+
that work it means to keep goes in `/workspace`.
|
|
400
|
+
|
|
366
401
|
Reusing one is the point of keeping it:
|
|
367
402
|
|
|
368
403
|
```
|
|
@@ -552,9 +587,17 @@ so inspection is free and offline.
|
|
|
552
587
|
| Why was that recalled? | `zen memory show <id>` |
|
|
553
588
|
| That should never have been written down | `zen memory forget <id>` |
|
|
554
589
|
|
|
590
|
+
The directory is not fixed. `zen run --memory <dir>` sends one run's memory
|
|
591
|
+
somewhere else - a scratch graph for a trial, one per branch, or a shared one
|
|
592
|
+
outside the repository - and `zen memory --dir <dir>` reads any such directory
|
|
593
|
+
with no project around it. Together they are also how you read a graph while a
|
|
594
|
+
run holds its `.lock`: copy the directory, delete the copy's `.lock`, and point
|
|
595
|
+
`--dir` at the copy.
|
|
596
|
+
|
|
555
597
|
`zen inspect` answers the other half: a run report shows the recollection block
|
|
556
598
|
exactly as the model received it, which is how you tell "memory had nothing"
|
|
557
|
-
apart from "memory had it and the model ignored it".
|
|
599
|
+
apart from "memory had it and the model ignored it". A run given `--memory`
|
|
600
|
+
wants `zen inspect --memory <dir>` to rebuild its report against the same graph.
|
|
558
601
|
|
|
559
602
|
## A worked configuration
|
|
560
603
|
|
|
@@ -597,6 +640,9 @@ agents:
|
|
|
597
640
|
- [ ] Every agent that should learn has a `memory:` binding - the top-level
|
|
598
641
|
block alone enables nothing.
|
|
599
642
|
- [ ] `access: full` appears at most once.
|
|
643
|
+
- [ ] Any agent the design expects to commit `file` nodes can write to the
|
|
644
|
+
workspace - `write_file`/`apply_patch`, or `run_command` with `/workspace`
|
|
645
|
+
named in its prompt. Nothing else round-trips.
|
|
600
646
|
- [ ] `sees`/`writes` exist because an agent would be **misled** by the other
|
|
601
647
|
slice, not merely because it does not need it.
|
|
602
648
|
- [ ] `autoRecall: false` on any agent whose user message is a payload.
|
|
@@ -612,7 +658,7 @@ agents:
|
|
|
612
658
|
| The `memory_*` tools are missing | No `memory:` on the agent. They come from the binding, never from `tools:` |
|
|
613
659
|
| `zen memory` says the project has none | Neither a `memory:` block nor an agent binding - nothing is opened and no directory is made |
|
|
614
660
|
| Recall finds a memory only when reworded | No embedder. `zen memory stats` says `embedding none` |
|
|
615
|
-
| Recall finds nothing after changing the embedder | Refused rather than mixed - a manifest records the model.
|
|
661
|
+
| Recall finds nothing after changing the embedder | Refused rather than mixed - a manifest records the model. Change it back, or start a new memory |
|
|
616
662
|
| Vectors fewer than nodes | Some nodes were committed with no embedder; they are only reachable by term overlap |
|
|
617
663
|
| The graph fills with restated requests | The commit rule is not in a prompt or skill. State the "would a later run redo this" test |
|
|
618
664
|
| An agent greps `/memory` or reads `graph.json` | The house-rules block is missing from `agents/memory-instructions.md` - the system prompt never forbids it |
|
|
@@ -621,6 +667,8 @@ agents:
|
|
|
621
667
|
| A wrong memory keeps coming back | It was edited instead of superseded, or superseded in the wrong direction - the **new** node is the source |
|
|
622
668
|
| An agent cannot see a node you can | Its `audience` is not in that agent's `sees`. Invisible and missing are the same thing, on purpose |
|
|
623
669
|
| "this agent cannot remember files" | The agent has no workspace, so a path cannot be resolved. Commit without `file` |
|
|
670
|
+
| `error: outside the workspace: /tmp/…` | The file is real to the shell and outside the only tree memory reads. Write it under `/workspace` |
|
|
671
|
+
| Long content arrives as `text`, never as a `file` | The agent has no tool that writes to the workspace, so it has no path to name |
|
|
624
672
|
| A remembered file will not run | It is not self-contained - it referenced the workspace it was written in |
|
|
625
673
|
| Recollections are large and unhelpful | `autoRecall.limit` is too high, or node texts describe answers rather than questions |
|
|
626
674
|
| The model recalls a route the API no longer has | Nothing re-checks memory against a rebuilt index. Supersede, and require verification |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zen-review
|
|
3
|
-
description: Checking a project before committing - the four mechanical checks `/review
|
|
3
|
+
description: Checking a project before committing - the four mechanical checks `/project-review` makes before any judgement (`zen check`, the §2.5 path sweep, the memory house-rules copy, the spec-sync record), what each one owns, what their exit codes mean, and what deliberately has no check because no tool can make it. Load before running `/project-review`, before saying a project is ready, and whenever a review finding needs verifying rather than restating.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Reviewing a project
|
|
@@ -104,7 +104,7 @@ Not because it would be hard, but because the answer would be wrong:
|
|
|
104
104
|
- **Whether the newest spec-sync history entry is honest.** A pass can claim
|
|
105
105
|
anything; only reading the diff says whether it did it.
|
|
106
106
|
|
|
107
|
-
That list is `/review
|
|
107
|
+
That list is `/project-review`, and §9 of the copilot instructions is the long
|
|
108
108
|
form. Run the script first so the prompt is spent on this.
|
|
109
109
|
|
|
110
110
|
## Where these scripts live, and why edits to them vanish
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
#
|
|
8
8
|
# What it prints is findings. What it cannot see — whether an agent has one job,
|
|
9
9
|
# whether a description is a condition, whether a fact belongs in a skill — is
|
|
10
|
-
# the rest of /review
|
|
10
|
+
# the rest of /project-review, and the reason that prompt still exists.
|
|
11
11
|
#
|
|
12
12
|
# Every step runs even when an earlier one fails: a review that stops at the
|
|
13
13
|
# first problem is one somebody has to run four times. The exit code is 1 if
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zen-spec-sync
|
|
3
|
-
description: Running `/sync-
|
|
3
|
+
description: Running `/spec-sync-project` as an incremental pass - the committed `.spec-sync` baseline of what the last pass applied, how to scope a pass from the specification and feedback diffs and from what moved in the project itself, the four checks a narrow pass may never skip, the iteration history format, and why the baseline is written last. Load before every `/spec-sync-project`, including the first one on a project that has no baseline yet.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Syncing a project with its specification, one change at a time
|
|
@@ -84,7 +84,7 @@ editing anything, and report it in the chat as the pass's scope.
|
|
|
84
84
|
2. **The `SPECIFICATION-FEEDBACK.md` diff.** The file is a questionnaire the
|
|
85
85
|
human answers by ticking one answer's `[ ]` box or deleting the answers they
|
|
86
86
|
do not want. A question that has moved under `✅ Answered` was folded into the
|
|
87
|
-
specification by `/
|
|
87
|
+
specification by `/spec-apply-feedback`, and its **Still to implement**
|
|
88
88
|
line is the work. A question with a box marked `[x]`, or one answer left
|
|
89
89
|
under it, and no `✅` entry was answered and never folded in - implement it,
|
|
90
90
|
put its text into `SPECIFICATION.md`, and say so. A new question someone else
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
#
|
|
3
|
-
# The committed record of what the last completed /sync-
|
|
3
|
+
# The committed record of what the last completed /spec-sync-project pass applied.
|
|
4
4
|
#
|
|
5
5
|
# snapshot.sh status full | incremental | tampered, and what differs
|
|
6
6
|
# snapshot.sh diff the difference the next pass has to work
|
|
@@ -13,6 +13,22 @@ something in it — and report what was done in enough detail to be checked.
|
|
|
13
13
|
- One request at a time, in one workspace, with the person who asked it present.
|
|
14
14
|
- No schedule, no queue, nothing that outlives the session it was asked in.
|
|
15
15
|
|
|
16
|
+
## Models
|
|
17
|
+
|
|
18
|
+
- `{{modelRef}}` — one model for the whole project, used by every agent.
|
|
19
|
+
- Named once in `agents.yaml` so it can be swapped in one place. Nothing here
|
|
20
|
+
depends on which model it is; a project that later needs a cheaper model for
|
|
21
|
+
one job adds a second alias rather than scattering the choice.
|
|
22
|
+
|
|
23
|
+
## Setup
|
|
24
|
+
|
|
25
|
+
- Run once, before any session: whatever has to exist before work can start —
|
|
26
|
+
an index built, a document fetched, a file generated.
|
|
27
|
+
- `scripts/_setup.sh` is the one command that does it, and `scripts/<name>.sh`
|
|
28
|
+
are the steps it runs in order. A step is safe to run twice and reports
|
|
29
|
+
`skipped` the second time.
|
|
30
|
+
- Currently: no steps. Nothing has to be prepared before a run.
|
|
31
|
+
|
|
16
32
|
## Agents
|
|
17
33
|
|
|
18
34
|
- `default` — the entry point and the only agent; nobody to hand work to.
|
|
@@ -34,13 +50,20 @@ something in it — and report what was done in enough detail to be checked.
|
|
|
34
50
|
|
|
35
51
|
## Environment
|
|
36
52
|
|
|
37
|
-
- Model: `{{modelRef}}`, one for the whole project.
|
|
38
53
|
- Memory: `memory/`, kept with the project and committed except for its
|
|
39
54
|
vectors, which are derived.
|
|
40
55
|
- Sandbox: built from `sandbox/Dockerfile`, persists between runs, and can
|
|
41
56
|
reach the network. What the work always needs belongs in the image, not in an
|
|
42
57
|
instruction that reinstalls it on every run.
|
|
43
|
-
|
|
58
|
+
|
|
59
|
+
## Testing
|
|
60
|
+
|
|
61
|
+
- `zen check` passes: the project loads, and every model, tool and skill an
|
|
62
|
+
agent is given resolves. It says nothing about whether the prose is right.
|
|
63
|
+
- `scripts/_setup.sh` run twice in a row reports every step `skipped` the
|
|
64
|
+
second time.
|
|
65
|
+
- A run against a real request: the workspace holds the change described, and
|
|
66
|
+
the reply's account of it matches what is on disk.
|
|
44
67
|
|
|
45
68
|
## Done means
|
|
46
69
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Tool calls
|
|
2
|
+
|
|
3
|
+
These rules are about _how_ tools are called, and hold for every agent.
|
|
4
|
+
|
|
5
|
+
- Say what you are about to do in one sentence before each tool call, so the
|
|
6
|
+
run reads as an account of the work rather than a list of results.
|
|
7
|
+
- Make independent calls together. Only wait for a result when the next call
|
|
8
|
+
needs it.
|