@zenera/cli 1.1.21 → 1.1.23
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 +40 -3
- package/dist/archive.d.ts +139 -0
- package/dist/archive.js +376 -0
- package/dist/banner.d.ts +33 -24
- package/dist/banner.js +25 -6
- package/dist/commands/check.js +1 -0
- package/dist/commands/export.d.ts +3 -0
- package/dist/commands/export.js +255 -0
- package/dist/commands/import.d.ts +3 -0
- package/dist/commands/import.js +173 -0
- package/dist/commands/index.d.ts +5 -1
- package/dist/commands/index.js +13 -1
- package/dist/commands/init.js +1 -0
- package/dist/commands/inspect.js +1 -0
- package/dist/commands/key.js +1 -0
- package/dist/commands/list.js +1 -0
- package/dist/commands/memory.js +118 -10
- package/dist/commands/open.js +1 -0
- package/dist/commands/run.js +3 -0
- package/dist/commands/sandbox.js +1 -0
- package/dist/commands/version.js +1 -0
- package/dist/lib.d.ts +2 -1
- package/dist/lib.js +2 -1
- package/dist/meta.d.ts +1 -1
- package/dist/meta.js +5 -28
- package/dist/resolve.js +19 -12
- package/dist/sandbox.js +1 -0
- package/dist/scaffold.d.ts +8 -0
- package/dist/scaffold.js +7 -2
- package/dist/term.d.ts +2 -0
- package/dist/term.js +2 -0
- package/dist/tui/markdown.d.ts +16 -0
- package/dist/tui/markdown.js +259 -0
- package/dist/tui/theme.js +1 -1
- package/dist/tui/wrap.d.ts +1 -1
- package/dist/validate.js +150 -4
- package/package.json +12 -6
- package/templates/editor/.github/copilot-instructions.md +62 -33
- package/templates/editor/.github/prompts/spec-sync-project.prompt.md +56 -3
- package/templates/editor/.github/skills/zen-cli/SKILL.md +21 -16
- package/templates/editor/.github/skills/zen-cli/references/check.md +6 -0
- package/templates/editor/.github/skills/zen-cli/references/export.md +107 -0
- package/templates/editor/.github/skills/zen-cli/references/memory.md +51 -13
- package/templates/editor/.github/skills/zen-cli/references/projects.md +1 -0
- package/templates/editor/.github/skills/zen-cli/references/rag.md +43 -3
- package/templates/editor/.github/skills/zen-cli/references/sandbox.md +30 -2
- package/templates/editor/.github/skills/zen-instructions/SKILL.md +232 -0
- package/templates/editor/.github/skills/zen-memory/SKILL.md +2 -1
- package/templates/editor/.github/skills/zen-memory-warmup/SKILL.md +684 -0
- package/templates/editor/.github/skills/zen-rag-docs/SKILL.md +56 -23
- package/templates/editor/.github/skills/zen-rag-schema/SKILL.md +55 -28
- package/templates/editor/.github/skills/zen-review/SKILL.md +17 -1
- package/templates/editor/.github/skills/zen-sandbox/SKILL.md +257 -0
- package/templates/editor/.github/skills/zen-spec-sync/SKILL.md +16 -3
- package/templates/editor/.vscode/agents.schema.json +8 -3
- package/templates/project/SPECIFICATION.md.tmpl +4 -1
- package/templates/project/agents/files-instructions.md +86 -0
- package/templates/project/agents/fork-instructions.md +17 -0
- package/templates/project/agents/memory-instructions.md +37 -0
- package/templates/project/agents.yaml.tmpl +3 -3
- package/templates/project/gitignore +12 -1
- package/templates/project/scripts/_setup.sh +68 -11
|
@@ -45,12 +45,22 @@ not reconstruct `zen` arguments from memory or call `--help` to discover them.
|
|
|
45
45
|
**Every runtime capability a project turns on carries obligations that are not
|
|
46
46
|
visible in `agents.yaml` and that `zen check` does not report.** Before
|
|
47
47
|
reviewing or changing a project, list the capabilities it has turned on and load
|
|
48
|
-
the editor skill for each one - `zen-memory` for a `memory:` block,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
the editor skill for each one - `zen-memory` for a `memory:` block,
|
|
49
|
+
`zen-sandbox` for sandbox configuration or shell tools, `zen-rag-schema` or
|
|
50
|
+
`zen-rag-docs` for an index, `zen-cli` always. A capability that is already
|
|
51
|
+
configured and already passing `zen check` is exactly the case that looks
|
|
52
|
+
finished and is not: the obligation lives in the skill, so a review that never
|
|
53
|
+
opens the skill cannot find what is missing. This applies whatever prompted the
|
|
54
|
+
change - a task scoped to `SPECIFICATION.md` does not narrow it.
|
|
55
|
+
|
|
56
|
+
**Load `zen-instructions` before writing, editing, reviewing or deleting any
|
|
57
|
+
`agents/*instructions.md`.** They are the house rules, prepended to every
|
|
58
|
+
agent's prompt, and three of them are `zen`'s own copies rather than the
|
|
59
|
+
project's: an edit made inside one is lost at the next `zen check --fix`, `zen
|
|
60
|
+
init` or `zen open`, with no diff to show for it. The skill is what says which
|
|
61
|
+
three those are, where a project's own rules on the same subjects go instead,
|
|
62
|
+
how `requires:` conditions a document, and what filename order decides. None of
|
|
63
|
+
that is visible in the file being edited.
|
|
54
64
|
|
|
55
65
|
First determine whether the target project uses RAG: a `zen rag` command in an
|
|
56
66
|
agent prompt or skill, RAG tools supplied by its host, or a documentation or
|
|
@@ -222,6 +232,7 @@ my-project/
|
|
|
222
232
|
├── agents.yaml who exists, what they may reach for
|
|
223
233
|
├── agents/
|
|
224
234
|
│ ├── instructions.md house rules, prepended to every agent
|
|
235
|
+
│ ├── files-instructions.md and more - how files are handled
|
|
225
236
|
│ ├── fork-instructions.md more of them - any `<topic>-instructions.md`
|
|
226
237
|
│ ├── memory-instructions.md and more - how the graph is used
|
|
227
238
|
│ ├── tools-instructions.md and more - how tools are called
|
|
@@ -631,9 +642,19 @@ follow. So:
|
|
|
631
642
|
- Anything only one agent needs goes in that agent's prompt instead. If you find
|
|
632
643
|
yourself writing "if you are the router…", you are in the wrong file.
|
|
633
644
|
|
|
634
|
-
Target 20
|
|
645
|
+
Target 20-60 lines each. If one exceeds ~100, split the stable half out into a
|
|
635
646
|
preloaded skill.
|
|
636
647
|
|
|
648
|
+
Four of these documents are **`zen`'s, not the project's** -
|
|
649
|
+
`tools-instructions.md`, `files-instructions.md`, `memory-instructions.md` and
|
|
650
|
+
`fork-instructions.md`. They are replaced by `zen check --fix`, and a copy that
|
|
651
|
+
differs is reported as `rules.stale`. This project's own rules on any of those
|
|
652
|
+
subjects go in a topic file beside them - `agents/files-policy-instructions.md`,
|
|
653
|
+
`agents/memory-policy-instructions.md` and the like, carrying the same
|
|
654
|
+
`requires:`. The `zen-instructions` skill is the full treatment: the two owners,
|
|
655
|
+
the naming and ordering that keeps a policy after the rules it qualifies, and
|
|
656
|
+
every finding these files can produce. Load it before touching one.
|
|
657
|
+
|
|
637
658
|
### 3.3 `agents/prompts/<name>.md`
|
|
638
659
|
|
|
639
660
|
Plain Markdown, no frontmatter. This is the agent's _job description_, appended
|
|
@@ -644,7 +665,7 @@ Structure that works:
|
|
|
644
665
|
```markdown
|
|
645
666
|
<one sentence: who this agent is and what it owns>
|
|
646
667
|
|
|
647
|
-
<what it does, as a short numbered procedure or 3
|
|
668
|
+
<what it does, as a short numbered procedure or 3-5 rules>
|
|
648
669
|
|
|
649
670
|
<what it must NOT do - especially the neighbouring agent's job>
|
|
650
671
|
|
|
@@ -677,7 +698,7 @@ already did, §3.2), never repeats one of them, and never describes the runtime.
|
|
|
677
698
|
Every line should be an instruction the model can act on or a boundary it can
|
|
678
699
|
check itself against.
|
|
679
700
|
|
|
680
|
-
Target 10
|
|
701
|
+
Target 10-40 lines. A 200-line prompt is a skill catalog that has not been split
|
|
681
702
|
yet.
|
|
682
703
|
|
|
683
704
|
### 3.4 Skills
|
|
@@ -798,21 +819,21 @@ Three rules follow:
|
|
|
798
819
|
|
|
799
820
|
- **Grant the narrowest set the job needs.** An agent that only reviews should
|
|
800
821
|
not be holding the tools that overwrite files.
|
|
801
|
-
- **Grant by group, then subtract.** Write `workspace:*` and take
|
|
802
|
-
agent must not have - not a hand-picked list of names. The tools
|
|
803
|
-
designed to be used together, and a list assembled one name at
|
|
804
|
-
the companion the model reaches for next: `write_file`
|
|
805
|
-
turns every one-line edit into a whole-file rewrite, and
|
|
806
|
-
`list_dir` and `find_files` leaves it guessing at paths. A
|
|
807
|
-
runtime - a tool added to it later reaches the agent,
|
|
808
|
-
silently stays behind.
|
|
822
|
+
- **Grant by group, then subtract.** Write `files:*` (or `workspace:*`) and take
|
|
823
|
+
away what this agent must not have - not a hand-picked list of names. The tools
|
|
824
|
+
in a group are designed to be used together, and a list assembled one name at
|
|
825
|
+
a time leaves out the companion the model reaches for next: `write_file`
|
|
826
|
+
without `apply_patch` turns every one-line edit into a whole-file rewrite, and
|
|
827
|
+
`read_file` without `list_dir` and `find_files` leaves it guessing at paths. A
|
|
828
|
+
group also tracks the runtime - a tool added to it later reaches the agent,
|
|
829
|
+
where an enumerated list silently stays behind.
|
|
809
830
|
- **Say in the prompt when to reach for what.** A granted tool the prompt never
|
|
810
831
|
mentions is used at the model's discretion, which is not the same as never.
|
|
811
832
|
|
|
812
833
|
Skills can own tools too - `tools:` in a skill's frontmatter (§3.4) names tools
|
|
813
834
|
that refuse to run until that skill is active.
|
|
814
835
|
|
|
815
|
-
### 3.6 The
|
|
836
|
+
### 3.6 The file tools (`files:*`, alias `workspace:*`)
|
|
816
837
|
|
|
817
838
|
`zen run` builds this set for you, rooted at the session's workspace directory.
|
|
818
839
|
Nothing else reaches the file system, so an agent whose `tools:` does not name
|
|
@@ -841,27 +862,27 @@ container involved there is no second name and everything stays relative.
|
|
|
841
862
|
|
|
842
863
|
**Selecting them.** A `tools:` entry is a selector, not only a name:
|
|
843
864
|
|
|
844
|
-
| Selector
|
|
845
|
-
|
|
|
846
|
-
| `read_file`
|
|
847
|
-
| `
|
|
848
|
-
| `workspace:*`
|
|
849
|
-
| `'*'`
|
|
850
|
-
| `-<any>`
|
|
865
|
+
| Selector | Selects |
|
|
866
|
+
| ------------------------------- | ------------------------------------------------- |
|
|
867
|
+
| `read_file` | that one tool |
|
|
868
|
+
| `files:read_file` | the same tool, written out in full |
|
|
869
|
+
| `files:*` (alias `workspace:*`) | every tool in the group |
|
|
870
|
+
| `'*'` | every tool the runtime provides |
|
|
871
|
+
| `-<any>` | removes what it matches from the selection so far |
|
|
851
872
|
|
|
852
873
|
```yaml
|
|
853
874
|
agents:
|
|
854
875
|
- name: editor
|
|
855
|
-
tools: [
|
|
876
|
+
tools: [files:*]
|
|
856
877
|
|
|
857
878
|
- name: reviewer
|
|
858
879
|
# Everything except the four that can change something.
|
|
859
|
-
tools: [
|
|
880
|
+
tools: [files:*, -write_file, -apply_patch, -move_file, -delete_file]
|
|
860
881
|
```
|
|
861
882
|
|
|
862
883
|
Selectors apply in the order written, so a `-` line reads as an exception to the
|
|
863
884
|
line above it. Quote a lone `'*'`: unquoted, YAML reads it as an alias and
|
|
864
|
-
refuses the file. `workspace:*` needs no quoting. There is no name globbing -
|
|
885
|
+
refuses the file. `files:*` (and `workspace:*`) needs no quoting. There is no name globbing -
|
|
865
886
|
`read_*` is an unknown tool, because a selector should track a declared set, not
|
|
866
887
|
a naming habit.
|
|
867
888
|
|
|
@@ -983,12 +1004,12 @@ sandbox:
|
|
|
983
1004
|
|
|
984
1005
|
agents:
|
|
985
1006
|
- name: builder
|
|
986
|
-
tools: [
|
|
1007
|
+
tools: [files:*, sandbox:*]
|
|
987
1008
|
sandbox:
|
|
988
1009
|
image: docker.io/library/node:22-bookworm-slim
|
|
989
1010
|
memory: 8192
|
|
990
1011
|
- name: analyst
|
|
991
|
-
tools: [
|
|
1012
|
+
tools: [files:*, sandbox:*] # shares the project's container
|
|
992
1013
|
```
|
|
993
1014
|
|
|
994
1015
|
**Write `persist: true` unless you have a reason not to.** By default the
|
|
@@ -1053,7 +1074,7 @@ over several pages, and wastes it when a specific document is wanted.
|
|
|
1053
1074
|
```yaml
|
|
1054
1075
|
agents:
|
|
1055
1076
|
- name: researcher
|
|
1056
|
-
tools: [exa:*,
|
|
1077
|
+
tools: [exa:*, files:*]
|
|
1057
1078
|
|
|
1058
1079
|
- name: fact-checker
|
|
1059
1080
|
# Find and read, but never let a model on the far side do the reasoning.
|
|
@@ -1839,6 +1860,9 @@ input`, or tools quietly unused). This is not a config error and `zen check`
|
|
|
1839
1860
|
publishes no embeddings API. Point it at another provider - §3.1.1.
|
|
1840
1861
|
- **Changing `dimensions:` on an embedding invalidates every stored vector.**
|
|
1841
1862
|
Widths are not comparable, so anything already indexed has to be re-embedded.
|
|
1863
|
+
For a `zen rag` index that is `zen rag <subject> restore --dimensions <n>`,
|
|
1864
|
+
which rebuilds from the copies the index already holds rather than from the
|
|
1865
|
+
documents; the same command with `--embedding <ref>` moves it to another model.
|
|
1842
1866
|
|
|
1843
1867
|
### 7.8 How to choose, in practice
|
|
1844
1868
|
|
|
@@ -1940,9 +1964,13 @@ Before finishing any change here:
|
|
|
1940
1964
|
- [ ] Nothing duplicated between a house-rules file and an agent prompt
|
|
1941
1965
|
- [ ] Each `agents/<topic>-instructions.md` is about one capability, and is true
|
|
1942
1966
|
of every agent it reaches - `requires:` if it is about one of them
|
|
1967
|
+
- [ ] If any agent has file tools, `agents/files-instructions.md` is present - §3.6
|
|
1943
1968
|
- [ ] If any agent has `fork:`, `agents/fork-instructions.md` is present - §6.4
|
|
1944
|
-
- [ ] No `rules.stale`: the
|
|
1969
|
+
- [ ] No `rules.stale`: the four files that are `zen`'s rather than yours say
|
|
1945
1970
|
what this version of the runtime does, and `zen check --fix` replaces them
|
|
1971
|
+
- [ ] Any change to an `agents/*instructions.md` was made with the
|
|
1972
|
+
`zen-instructions` skill loaded, and nothing of this project's was written
|
|
1973
|
+
into one of `zen`'s - §3.2
|
|
1946
1974
|
- [ ] Every tool and agent referenced by its exact name
|
|
1947
1975
|
- [ ] Failure paths stated for every instruction that can fail
|
|
1948
1976
|
- [ ] No facts, rates or figures embedded in a prompt
|
|
@@ -1984,7 +2012,7 @@ candidates; these are the judgements to make about each one)**
|
|
|
1984
2012
|
- [ ] No agent holds `write_file` without `apply_patch`, or `read_file` without
|
|
1985
2013
|
`list_dir` and `find_files`
|
|
1986
2014
|
- [ ] An agent that only reads is not holding `write_file`, `apply_patch`,
|
|
1987
|
-
`move_file` or `delete_file` - subtract them from `workspace:*`
|
|
2015
|
+
`move_file` or `delete_file` - subtract them from `files:*` (or `workspace:*`)
|
|
1988
2016
|
- [ ] `sandbox:*` is granted only where a shell is actually needed
|
|
1989
2017
|
- [ ] `sandbox.persist: true`, unless a throwaway rootfs is wanted on purpose
|
|
1990
2018
|
- [ ] The `sandbox:` image carries what the work needs, rather than the prompt
|
|
@@ -2056,6 +2084,7 @@ candidates; these are the judgements to make about each one)**
|
|
|
2056
2084
|
| Works through N independent items serially | `fork:` on that agent, and a prompt line - §6.4 |
|
|
2057
2085
|
| Forks when the steps actually depend | Prompt line: branches cannot see each other |
|
|
2058
2086
|
| Forks a sequence, or loses a branch's working | `agents/fork-instructions.md` is missing or empty - §6.4 |
|
|
2087
|
+
| Edits files blindly or breaks patches | `agents/files-instructions.md` is missing or empty - §3.6 |
|
|
2059
2088
|
| Slow and expensive on trivial cases | Demote that agent's model tier / reasoning effort |
|
|
2060
2089
|
| Fails only on genuinely hard cases | Promote that agent's tier, or split the hard path out |
|
|
2061
2090
|
| Shows no reasoning while it works | Turn summaries on for that model - §7.6 |
|
|
@@ -31,7 +31,7 @@ because a prompt or skill someone changed outside a pass still has to be
|
|
|
31
31
|
accounted for against the specification.
|
|
32
32
|
|
|
33
33
|
The scope decides what you **read and edit**. It never decides what you
|
|
34
|
-
**verify**: §6, §7 and the
|
|
34
|
+
**verify**: §6, §7 and the five checks in the skill run at full size on every
|
|
35
35
|
pass, however small the diff.
|
|
36
36
|
|
|
37
37
|
## 1. Read before changing anything
|
|
@@ -115,7 +115,10 @@ the model to compute or remember. Specifically:
|
|
|
115
115
|
in it to the version of `zen` in hand. Read that version with `zen --version`
|
|
116
116
|
and write it into the `npm install -g` line, so the CLI an agent runs inside
|
|
117
117
|
the container is the same one that built it. An unpinned name drifts away from
|
|
118
|
-
the host on the next image build; a stale pin
|
|
118
|
+
the host on the next image build; a stale pin leaves the container holding an
|
|
119
|
+
older `zen` than the session outside it. `zen check` reports both, as
|
|
120
|
+
`sandbox.pin.absent` and `sandbox.pin.stale`, but will not repair either - the
|
|
121
|
+
Dockerfile is the project's file, so this edit is yours to make.
|
|
119
122
|
|
|
120
123
|
Never delete an **extra** without saying so. Report it, say why the
|
|
121
124
|
specification does not cover it, and leave it unless I tell you to remove it.
|
|
@@ -148,9 +151,51 @@ not a paragraph of instructions for a human.
|
|
|
148
151
|
to a temporary path and moving it into place so an interrupted run never leaves
|
|
149
152
|
a half-built artefact behind. `scripts/_setup.sh --force` redoes everything,
|
|
150
153
|
and reaches each step as `$FORCE=1`.
|
|
154
|
+
- **Every step answers a dry run.** `scripts/_setup.sh --check` reaches each step
|
|
155
|
+
as `$CHECK=1` and means: make the same "already done" test, then do none of the
|
|
156
|
+
work. Exit **3** when the answer is yes, otherwise say what is missing and exit
|
|
157
|
+
**4**, which the runner reports as `needs setup`. This is the one command that
|
|
158
|
+
says whether the project can run without spending the download and the
|
|
159
|
+
embedding to find out, so the line a step prints under `$CHECK` is the whole
|
|
160
|
+
value of it: name the artefact and the command that produces it. Pass a tool's
|
|
161
|
+
own words through rather than writing a second opinion: `zen rag docs ready`
|
|
162
|
+
without `--quiet` already prints what is wrong and the `restore` or `index`
|
|
163
|
+
that fixes it. A check must not assume an earlier step has run: a missing
|
|
164
|
+
prerequisite is a 4 of its own, not a failure, or the first unbuilt thing
|
|
165
|
+
hides everything after it.
|
|
166
|
+
- **A step's "already done" test must name something that survives a clone.**
|
|
167
|
+
Git-ignored output does not. A rag index commits its `manifest.json` and
|
|
168
|
+
ignores `lance/`, so `[ -f "$OUT/manifest.json" ]` is true on a fresh checkout
|
|
169
|
+
that cannot search at all - every step reports `skipped` and the failure
|
|
170
|
+
surfaces much later, as a search error nobody connects to setup. Ask the tool
|
|
171
|
+
rather than guessing at files: `zen rag docs ready --dir "$OUT" --quiet` exits
|
|
172
|
+
0 when the index can answer and 3 when it cannot, and
|
|
173
|
+
`zen rag docs restore --dir "$OUT"` re-embeds it from the copies it already
|
|
174
|
+
holds instead of indexing the documents again. A step that builds an index
|
|
175
|
+
looks like this:
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
if [ "${FORCE:-0}" = 0 ] && zen rag docs ready --dir "$OUT" --quiet; then
|
|
179
|
+
echo "$OUT is already built"
|
|
180
|
+
exit 3
|
|
181
|
+
fi
|
|
182
|
+
if [ "${CHECK:-0}" = 1 ]; then
|
|
183
|
+
zen rag docs ready --dir "$OUT" || true # its reason and its fix
|
|
184
|
+
exit 4
|
|
185
|
+
fi
|
|
186
|
+
if [ "${FORCE:-0}" = 0 ] && [ -f "$OUT/manifest.json" ]; then
|
|
187
|
+
zen rag docs restore --dir "$OUT" # committed index, ignored vectors
|
|
188
|
+
exit 0
|
|
189
|
+
fi
|
|
190
|
+
rm -rf .tmp/docs-db
|
|
191
|
+
zen rag docs index assets/docs --embedding <ref> --out .tmp/docs-db
|
|
192
|
+
rm -rf "$OUT" && mv .tmp/docs-db "$OUT"
|
|
193
|
+
```
|
|
194
|
+
|
|
151
195
|
- **It must be watchable.** `scripts/_setup.sh` tees each step's output to
|
|
152
196
|
`.tmp/logs/setup-<step>.log`, prints a heartbeat line while a long step runs,
|
|
153
|
-
and finishes with one line per step: `ok`, `skipped`, or
|
|
197
|
+
and finishes with one line per step: `ok`, `skipped`, `needs setup`, or
|
|
198
|
+
`failed`.
|
|
154
199
|
- **Everything transient goes under `.tmp/`** - logs, scratch files, downloads,
|
|
155
200
|
test output, and the temporary path a step writes to before moving its
|
|
156
201
|
artefact into place. Nothing else in the tree is a scratch directory, and
|
|
@@ -354,6 +399,14 @@ background and follow the logs instead of waiting blind:
|
|
|
354
399
|
for the same reason, stop and raise it in `SPECIFICATION-FEEDBACK.md`.
|
|
355
400
|
- Prove re-entrancy: once it has succeeded, run `scripts/_setup.sh` once more and
|
|
356
401
|
check that every step reports `skipped` rather than rebuilding.
|
|
402
|
+
- Prove the dry run: `scripts/_setup.sh --check` must then report every step
|
|
403
|
+
`skipped` and exit 0. `needs setup` for something setup has just built means
|
|
404
|
+
the step's two tests disagree, and one of them is wrong.
|
|
405
|
+
- **`skipped` on a machine that has never built it is a bug, not a pass.** A
|
|
406
|
+
step that tests for a committed file skips on a fresh clone and leaves the
|
|
407
|
+
project unusable. For every index the project builds, check it can actually
|
|
408
|
+
answer - `zen rag docs ready --dir <dir>` - and fix the step's test if the
|
|
409
|
+
answer disagrees with what setup reported.
|
|
357
410
|
|
|
358
411
|
## 7. Verify and report
|
|
359
412
|
|
|
@@ -24,13 +24,15 @@ zen key <ls|add|use|check|rm|show|env> [ref] [options]
|
|
|
24
24
|
zen models <providers|ls|search|show|test|pick> [ref] [options]
|
|
25
25
|
zen check [name|dir] [--project <name|dir>] [--no-sandbox] [--no-models] [--strict] [--quiet]
|
|
26
26
|
zen inspect [run] [--session <id>] [--open] [--rebuild] [--serve [port]]
|
|
27
|
-
zen memory [stats|ls|show|export|forget] [args] [options]
|
|
27
|
+
zen memory [stats|ls|show|export|merge|forget] [args] [options]
|
|
28
|
+
zen export [project] [--out <file>] [--no-vectors] [--no-memory] [--force]
|
|
29
|
+
zen import <file.zip> [dir] [--name <name>] [--force] [--no-register]
|
|
28
30
|
zen sandbox [status|up|pull|clean|disk] [options]
|
|
29
31
|
zen version
|
|
30
32
|
|
|
31
33
|
zen faker <serve|build|cache> [spec...]
|
|
32
|
-
zen rag schema <index|search|list|grep|trace|show|stats> [spec...]
|
|
33
|
-
zen rag docs <index|search|list|grep|show|stats> [path...]
|
|
34
|
+
zen rag schema <index|restore|ready|search|list|grep|trace|show|stats> [spec...]
|
|
35
|
+
zen rag docs <index|restore|ready|search|list|grep|show|stats> [path...]
|
|
34
36
|
```
|
|
35
37
|
|
|
36
38
|
## Read the reference before answering
|
|
@@ -39,19 +41,20 @@ The full reference lives next to this file, one document per part of the command
|
|
|
39
41
|
line. **Read the one that covers the question before answering it** - do not
|
|
40
42
|
guess a flag, and do not read them all.
|
|
41
43
|
|
|
42
|
-
| The question is about | Read
|
|
43
|
-
| ------------------------------------------------------------------- |
|
|
44
|
-
| Global flags, `--json`, exit codes, environment, where files live | [frame.md](./references/frame.md)
|
|
45
|
-
| Creating, finding or opening a project | [projects.md](./references/projects.md)
|
|
46
|
-
| Running: the TUI, one-shot answers, sessions, workspaces, overrides | [run.md](./references/run.md)
|
|
47
|
-
| Validating: `zen check`, what it can and cannot see | [check.md](./references/check.md)
|
|
48
|
-
| API keys, providers, the keyring, "no credential" errors | [keys.md](./references/keys.md)
|
|
49
|
-
| Which models exist, whether one works, recovering from a refusal | [models.md](./references/models.md)
|
|
50
|
-
| The container shell commands run in, images, `persist` | [sandbox.md](./references/sandbox.md)
|
|
51
|
-
| Run reports, trajectories, what a session directory holds | [inspect.md](./references/inspect.md)
|
|
52
|
-
| What the agents remember, why something was recalled, forgetting | [memory.md](./references/memory.md)
|
|
53
|
-
|
|
|
54
|
-
| `zen
|
|
44
|
+
| The question is about | Read |
|
|
45
|
+
| ------------------------------------------------------------------- | --------------------------------------------------------------- |
|
|
46
|
+
| Global flags, `--json`, exit codes, environment, where files live | [frame.md](./references/frame.md) |
|
|
47
|
+
| Creating, finding or opening a project | [projects.md](./references/projects.md) |
|
|
48
|
+
| Running: the TUI, one-shot answers, sessions, workspaces, overrides | [run.md](./references/run.md) |
|
|
49
|
+
| Validating: `zen check`, what it can and cannot see | [check.md](./references/check.md) |
|
|
50
|
+
| API keys, providers, the keyring, "no credential" errors | [keys.md](./references/keys.md) |
|
|
51
|
+
| Which models exist, whether one works, recovering from a refusal | [models.md](./references/models.md) |
|
|
52
|
+
| The container shell commands run in, images, `persist` | [sandbox.md](./references/sandbox.md) (and `zen-sandbox` skill) |
|
|
53
|
+
| Run reports, trajectories, what a session directory holds | [inspect.md](./references/inspect.md) |
|
|
54
|
+
| What the agents remember, why something was recalled, forgetting | [memory.md](./references/memory.md) |
|
|
55
|
+
| Sharing a project: archives, what travels, importing one safely | [export.md](./references/export.md) |
|
|
56
|
+
| `zen faker` - a mock API from an OpenAPI/Swagger document | [faker.md](./references/faker.md) |
|
|
57
|
+
| `zen rag` - searching an API description, or a pile of markdown | [rag.md](./references/rag.md) |
|
|
55
58
|
|
|
56
59
|
## The short version
|
|
57
60
|
|
|
@@ -62,6 +65,8 @@ zen run the TUI
|
|
|
62
65
|
zen run "what changed?" one answer, this directory as the workspace
|
|
63
66
|
zen inspect --open what the model was actually given
|
|
64
67
|
zen memory export --open the whole memory graph, as a page
|
|
68
|
+
zen export the project as a zip you can send
|
|
69
|
+
zen import a.zip unpack one somebody sent, run nothing in it
|
|
65
70
|
zen key ls --check which credentials still work
|
|
66
71
|
zen models test <ref> whether one model actually answers
|
|
67
72
|
zen models pick --embedding the first embedder that does, on stdout
|
|
@@ -51,6 +51,11 @@ checked too. A word that is neither is a usage error (exit 2), not a report.
|
|
|
51
51
|
exist, and - unless `--no-sandbox` - the image **builds** and one command runs
|
|
52
52
|
in it, against a temporary directory rather than your workspace. No container
|
|
53
53
|
engine at all is a warning, not an error.
|
|
54
|
+
- The `@zenera/*` the Dockerfile installs are pinned to **this** `zen`. The pin
|
|
55
|
+
is written once, by `zen init`, and nothing rewrites it afterwards, so it falls
|
|
56
|
+
behind the host on the next upgrade and the container ends up holding a
|
|
57
|
+
different `zen` than the session outside it. Read rather than run, so this one
|
|
58
|
+
is reported with `--no-sandbox` too.
|
|
54
59
|
|
|
55
60
|
### Findings
|
|
56
61
|
|
|
@@ -66,6 +71,7 @@ fork.unknown skills.missing skill.unloadable / .no-skill-md
|
|
|
66
71
|
skills.no-catalog skills.unreachable skill.unused
|
|
67
72
|
assets.missing assets.overbroad sandbox.dockerfile.missing
|
|
68
73
|
sandbox.build sandbox.smoke sandbox.start / .unchecked
|
|
74
|
+
sandbox.pin.stale sandbox.pin.absent
|
|
69
75
|
provider.invalid model.none model.unresolvable
|
|
70
76
|
model.refused model.unreachable model.unusable
|
|
71
77
|
embedding.refused embedding.unreachable embedding.unusable
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Sharing a project - `zen export` and `zen import`
|
|
2
|
+
|
|
3
|
+
A project is a directory, so moving one is a zip - except that half of the
|
|
4
|
+
directory belongs to that machine rather than to the project. These two write
|
|
5
|
+
and read the other half.
|
|
6
|
+
|
|
7
|
+
## `zen export`
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
zen export [project] [--out <file>] [--no-vectors] [--no-memory] [--force]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Aliases: `pack`, `archive`, `share`.
|
|
14
|
+
|
|
15
|
+
Writes `./<project>-<stamp>.zip` in the working directory unless `--out` names
|
|
16
|
+
somewhere else. The stamp means two exports in one afternoon are two files, not
|
|
17
|
+
one silently replaced; an `--out` that already exists is a usage error until
|
|
18
|
+
`--force`.
|
|
19
|
+
|
|
20
|
+
| Flag | Meaning |
|
|
21
|
+
| -------------- | ------------------------------------------------------------ |
|
|
22
|
+
| `--out <file>` | Where the archive goes |
|
|
23
|
+
| `--no-vectors` | Leave out `assets/**/lance/` - much smaller, needs a restore |
|
|
24
|
+
| `--no-memory` | Leave out `memory/` entirely |
|
|
25
|
+
| `--force` | Overwrite the target, and export past a held memory lock |
|
|
26
|
+
|
|
27
|
+
### What travels
|
|
28
|
+
|
|
29
|
+
Everything that is the project: `agents.yaml`, the `agents/` tree,
|
|
30
|
+
`SPECIFICATION.md` and its feedback, `assets/`, `memory/`, `sandbox/`,
|
|
31
|
+
`scripts/`, and the editor files (`.github/`, `.vscode/`).
|
|
32
|
+
|
|
33
|
+
What does not: `sessions/`, `.tmp/`, `.git/`, `node_modules/`, lock files,
|
|
34
|
+
`.DS_Store`, any `*.zip` at the top of the project (the default destination
|
|
35
|
+
puts one there, and a second export must not pack the first), and `.env`.
|
|
36
|
+
Symbolic links are counted and never followed. A zip that is genuine project
|
|
37
|
+
material lives under `assets/`, where this rule does not look.
|
|
38
|
+
|
|
39
|
+
**The values in `.env` never travel, behind no flag.** The names do, as a
|
|
40
|
+
`.env.example` with every value blank and every comment kept - so the other end
|
|
41
|
+
knows which credentials to supply without being handed any.
|
|
42
|
+
|
|
43
|
+
### The vectors travel by default
|
|
44
|
+
|
|
45
|
+
This is the decision the command is built around. A rag index without its
|
|
46
|
+
`lance/` tree looks built and cannot search, and memory has no fallback at all:
|
|
47
|
+
a graph without `vectors.f32` recalls by term overlap until every node is
|
|
48
|
+
written again. So the default archive works when it is opened.
|
|
49
|
+
|
|
50
|
+
`--no-vectors` makes a much smaller one for someone who will run
|
|
51
|
+
`zen rag <subject> restore` on arrival. The manifest records the choice and
|
|
52
|
+
`zen import` prints the restore step when it was taken.
|
|
53
|
+
|
|
54
|
+
### What it refuses
|
|
55
|
+
|
|
56
|
+
Only one thing: memory held by a live run, because a graph copied mid-write is
|
|
57
|
+
an archive that opens and is wrong. `--force` overrides it, and
|
|
58
|
+
`--no-memory` sidesteps it.
|
|
59
|
+
|
|
60
|
+
A project that fails `zen check` is exported anyway, with a warning. Sending
|
|
61
|
+
someone a broken project to ask for help is a legitimate reason to export one.
|
|
62
|
+
|
|
63
|
+
`--json` prints `{file, bytes, files, project, root, vectors, memory, skipped, ok}`.
|
|
64
|
+
|
|
65
|
+
## `zen import`
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
zen import <file.zip> [dir] [--name <name>] [--force] [--no-register]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Aliases: `unpack`.
|
|
72
|
+
|
|
73
|
+
Unpacks into `./<project>` unless a directory is named, and registers it so
|
|
74
|
+
`zen list` and `zen open` find it by name. A target directory with anything in
|
|
75
|
+
it is refused until `--force`.
|
|
76
|
+
|
|
77
|
+
| Flag | Meaning |
|
|
78
|
+
| --------------- | --------------------------------------------------- |
|
|
79
|
+
| `--name <name>` | Register under this name - use it when one is taken |
|
|
80
|
+
| `--force` | Write into a directory that is not empty |
|
|
81
|
+
| `--no-register` | Unpack and leave the registry alone |
|
|
82
|
+
|
|
83
|
+
A zip without `zenera-export.json` at its root is a usage error: only an archive
|
|
84
|
+
`zen export` wrote can be imported.
|
|
85
|
+
|
|
86
|
+
### It treats the archive as hostile
|
|
87
|
+
|
|
88
|
+
Every path, size and mode in a zip is a claim made by whoever sent it. So:
|
|
89
|
+
entry paths that are absolute, contain `..`, or fall outside the single
|
|
90
|
+
directory the manifest names are refused; an entry claiming to be a symbolic
|
|
91
|
+
link is refused; the entry count and unpacked size are bounded; and file modes
|
|
92
|
+
are replaced rather than honoured (`0644`, and `0755` for `*.sh` only).
|
|
93
|
+
|
|
94
|
+
**Nothing in the archive is executed** - not `scripts/_setup.sh`, not the
|
|
95
|
+
Dockerfile, not a line of the `.github/` tree. The commands to run next are
|
|
96
|
+
printed instead, so they can be read before they are typed.
|
|
97
|
+
|
|
98
|
+
### After importing
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
cp .env.example .env # and fill in the credentials; they were not in the archive
|
|
102
|
+
zen check <name> # what this machine is still missing
|
|
103
|
+
zen rag <subject> restore # only when the archive was made with --no-vectors
|
|
104
|
+
zen open <name>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`--json` prints `{dir, name, files, bytes, registered, from, vectors, memory}`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Memory - `zen memory`
|
|
2
2
|
|
|
3
3
|
```
|
|
4
|
-
zen memory [stats|ls|show|export|forget] [args] [options]
|
|
4
|
+
zen memory [stats|ls|show|export|merge|forget] [args] [options]
|
|
5
5
|
```
|
|
6
6
|
|
|
7
7
|
Alias: `mem`.
|
|
@@ -24,20 +24,24 @@ skill.
|
|
|
24
24
|
| `zen memory ls` | Nodes, newest first. Changes nothing |
|
|
25
25
|
| `zen memory show <id>` | One node in full, with what it links to |
|
|
26
26
|
| `zen memory export [f]` | The whole graph as one HTML page |
|
|
27
|
+
| `zen memory merge <dir…>` | Fold other memories into this one |
|
|
27
28
|
| `zen memory forget <id…>` | Remove nodes, their vectors and their files |
|
|
28
29
|
|
|
29
|
-
| Flag | Meaning
|
|
30
|
-
| ----------------------- |
|
|
31
|
-
| `--project <name\|dir>` | Which project. Inferred from the directory
|
|
32
|
-
| `--dir <dir>` | Read this memory directory instead
|
|
33
|
-
| `--kind <name>` | Only this kind of node
|
|
34
|
-
| `--audience <name>` | Only nodes committed under this label
|
|
35
|
-
| `--files` | Only nodes that remember a file
|
|
36
|
-
| `--stale` | Only nodes something has superseded
|
|
37
|
-
| `--limit <n>` | Rows to list. Default 30
|
|
38
|
-
| `--out <file>` | Where `export` writes. Default `memory.html`
|
|
39
|
-
| `--open` | Open the exported page
|
|
40
|
-
| `--
|
|
30
|
+
| Flag | Meaning |
|
|
31
|
+
| ----------------------- | --------------------------------------------- |
|
|
32
|
+
| `--project <name\|dir>` | Which project. Inferred from the directory |
|
|
33
|
+
| `--dir <dir>` | Read this memory directory instead |
|
|
34
|
+
| `--kind <name>` | Only this kind of node |
|
|
35
|
+
| `--audience <name>` | Only nodes committed under this label |
|
|
36
|
+
| `--files` | Only nodes that remember a file |
|
|
37
|
+
| `--stale` | Only nodes something has superseded |
|
|
38
|
+
| `--limit <n>` | Rows to list. Default 30 |
|
|
39
|
+
| `--out <file>` | Where `export` writes. Default `memory.html` |
|
|
40
|
+
| `--open` | Open the exported page |
|
|
41
|
+
| `--dry-run` | Say what `merge` would do, and stop |
|
|
42
|
+
| `--no-dedupe` | Keep memories `merge` would otherwise fold |
|
|
43
|
+
| `--force` | Let `merge` pick a winner where copies differ |
|
|
44
|
+
| `--yes` | Do not ask before removing or merging |
|
|
41
45
|
|
|
42
46
|
## A graph that is not the project's
|
|
43
47
|
|
|
@@ -90,6 +94,40 @@ It is a single file with no server behind it, so it attaches to a bug report.
|
|
|
90
94
|
The only network it does is fetching Mermaid; without that it degrades to a
|
|
91
95
|
working list and detail view.
|
|
92
96
|
|
|
97
|
+
## Merging
|
|
98
|
+
|
|
99
|
+
The lock is per directory, so two runs cannot warm the same memory at once.
|
|
100
|
+
They each warm their own, and `merge` puts the results back together:
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
zen memory merge .tmp/warmup-*/memory into the project’s
|
|
104
|
+
zen memory merge a/memory b/memory --dir merged/memory into a named one
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Sources are positional and the target is `--dir`, or the project you are in —
|
|
108
|
+
the same shape as everywhere else here. The shell expands the glob, so a
|
|
109
|
+
twelve-way fan-out is still one word. `merge` is the one subcommand that will
|
|
110
|
+
write a memory into existence: a target that is not there yet is created.
|
|
111
|
+
|
|
112
|
+
It is offline and contacts no model, which is why every side has to have been
|
|
113
|
+
embedded with the same model already. Node ids are kept, so the interesting
|
|
114
|
+
case is the same id on both sides:
|
|
115
|
+
|
|
116
|
+
- **Same revision, same content** — a shared ancestor, because the runs started
|
|
117
|
+
from a copy of the same memory. Use counts and timestamps reconcile to the
|
|
118
|
+
larger of the two, never the sum, so merging a source twice changes nothing.
|
|
119
|
+
- **Anything else** — a divergence. The whole merge is refused, nothing is
|
|
120
|
+
written, and every conflicting id is listed with both revisions. `--force`
|
|
121
|
+
takes the highest revision instead.
|
|
122
|
+
|
|
123
|
+
Memories that are not the same node but say the same thing fold together on the
|
|
124
|
+
same rule a commit uses for duplicates — near-identical by cosine, same kind,
|
|
125
|
+
same audience, never one that remembers a file. `--no-dedupe` turns that off.
|
|
126
|
+
Edges follow whatever their ends folded onto, and an edge whose ends both
|
|
127
|
+
landed on the same memory is dropped.
|
|
128
|
+
|
|
129
|
+
`--dry-run` reports all of it and writes nothing.
|
|
130
|
+
|
|
93
131
|
## Forgetting
|
|
94
132
|
|
|
95
133
|
```sh
|
|
@@ -21,6 +21,7 @@ What it writes:
|
|
|
21
21
|
zenera.json { version, name }
|
|
22
22
|
agents.yaml the configuration
|
|
23
23
|
agents/instructions.md house rules, prepended to every agent
|
|
24
|
+
agents/files-instructions.md more of them, for agents that work with files
|
|
24
25
|
agents/fork-instructions.md more of them, for agents that can fork
|
|
25
26
|
agents/memory-instructions.md more of them, for agents with the memory store
|
|
26
27
|
agents/tools-instructions.md more of them, about how tools are called
|