@zenera/cli 1.1.11 → 1.1.14

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 (36) hide show
  1. package/README.md +20 -0
  2. package/dist/banner.js +69 -47
  3. package/dist/commands/index.js +3 -0
  4. package/dist/commands/init.js +8 -4
  5. package/dist/commands/inspect.js +23 -5
  6. package/dist/commands/memory.d.ts +3 -0
  7. package/dist/commands/memory.js +375 -0
  8. package/dist/engine.js +15 -9
  9. package/dist/main.js +9 -0
  10. package/dist/podman.js +43 -9
  11. package/dist/projects.js +10 -2
  12. package/dist/scaffold.js +22 -1
  13. package/dist/tui/app.js +19 -11
  14. package/dist/tui/theme.d.ts +7 -0
  15. package/dist/tui/theme.js +18 -11
  16. package/package.json +2 -2
  17. package/templates/editor/.github/copilot-instructions.md +151 -43
  18. package/templates/editor/.github/prompts/review-project.prompt.md +5 -0
  19. package/templates/editor/.github/prompts/sync-with-spec.prompt.md +7 -4
  20. package/templates/editor/.github/skills/zen-cli/SKILL.md +3 -0
  21. package/templates/editor/.github/skills/zen-cli/references/memory.md +113 -0
  22. package/templates/editor/.github/skills/zen-cli/references/rag.md +2 -2
  23. package/templates/editor/.github/skills/zen-cli/references/run.md +3 -1
  24. package/templates/editor/.github/skills/zen-memory/SKILL.md +555 -0
  25. package/templates/editor/.github/skills/zen-rag-docs/SKILL.md +16 -16
  26. package/templates/editor/.github/skills/zen-rag-schema/SKILL.md +2 -2
  27. package/templates/editor/.vscode/settings.json +4 -2
  28. package/templates/parts/exa.prompt.md.tmpl +4 -0
  29. package/templates/parts/exa.spec.md.tmpl +2 -0
  30. package/templates/project/INSTRUCTIONS.md +8 -0
  31. package/templates/project/SPECIFICATION.md.tmpl +47 -0
  32. package/templates/project/agents/prompts/{default.md → default.md.tmpl} +4 -0
  33. package/templates/project/agents.yaml.tmpl +4 -0
  34. package/templates/project/gitignore +7 -1
  35. package/templates/project/scripts/_setup.sh +101 -0
  36. package/templates/project/SPECIFICATION.md +0 -6
@@ -147,7 +147,7 @@ documentation tree is what makes "which release says this?" answerable at all.
147
147
 
148
148
  ```sh
149
149
  zen rag docs index ./docs ./README.md ./packages/*/README.md --embedding openai:text-embedding-3-small
150
- zen rag docs index "releases/nsx_4.*/**/*.md" --embedding google:gemini-embedding-001 -o .index/nsx
150
+ zen rag docs index "releases/acme_4.*/**/*.md" --embedding google:gemini-embedding-001 -o .index/acme
151
151
  ```
152
152
 
153
153
  ### The name is the identity
@@ -157,8 +157,8 @@ everything you named. Nothing anywhere records where the file was on the machine
157
157
  that built the index.
158
158
 
159
159
  That name is what `--file` patterns match, so it is worth arranging on purpose.
160
- Indexing two release trees at once keeps `nsx_4.1.0/api/routing.md` and
161
- `nsx_4.2.0/api/routing.md` apart, and a search can be pinned to one of them.
160
+ Indexing two release trees at once keeps `acme_4.1.0/api/routing.md` and
161
+ `acme_4.2.0/api/routing.md` apart, and a search can be pinned to one of them.
162
162
  Indexing one tree from inside it gives you `api/routing.md`. Two files that
163
163
  would land on the same name are deduped rather than merged.
164
164
 
@@ -229,7 +229,7 @@ zen rag docs search "how are rate limits counted"
229
229
  The answer is the corpus quoting itself:
230
230
 
231
231
  ```
232
- ## nsx_4.2.0/api/routing.md — 9 of 148 lines
232
+ ## acme_4.2.0/api/routing.md — 9 of 148 lines
233
233
 
234
234
  5 | ## Rate limits
235
235
  7 | Requests are counted per tenant and rejected past the limit.
@@ -259,14 +259,14 @@ question with a narrowing on it — not a different command.
259
259
  | `--exclude-id <id>` | a passage already seen. Repeatable |
260
260
 
261
261
  ```sh
262
- zen rag docs search --file "nsx_4.2.*/api/**" "rate limit for the users route"
262
+ zen rag docs search --file "acme_4.2.*/api/**" "rate limit for the users route"
263
263
  zen rag docs search --section "Rate limits" --kind table "requests per minute"
264
264
  zen rag docs search --mode text "X-RateLimit-Remaining"
265
265
  ```
266
266
 
267
267
  A `--file` pattern with `*` or `?` is a glob matched against the whole document
268
268
  name; a plain word is a substring. So `--file routing` finds
269
- `nsx_4.2.0/api/routing.md` and `--file "routing*"` finds nothing.
269
+ `acme_4.2.0/api/routing.md` and `--file "routing*"` finds nothing.
270
270
 
271
271
  `--section` takes a heading title, a structure id, or the structure path an
272
272
  earlier answer printed. A title that appears in four documents becomes four
@@ -397,7 +397,7 @@ think it is?".
397
397
  | "what is the shape of this manual?" | `list sections --depth 2` |
398
398
  | "where is the table of per-route limits?" | `list tables --file "api/**"` |
399
399
  | "the exact error string, not something like it" | `search --mode text "connection reset by peer"` |
400
- | "same question, but only the 4.2 docs" | `search --file "nsx_4.2*/**" "…"` |
400
+ | "same question, but only the 4.2 docs" | `search --file "acme_4.2*/**" "…"` |
401
401
  | "is this index the right one?" | `stats` |
402
402
 
403
403
  The rule: **a question about meaning is a `search`; a question about presence,
@@ -461,7 +461,7 @@ list, so an empty answer and an absent thing look identical. `grep_docs` is how
461
461
 
462
462
  `search_docs` is shaped for the **second** call rather than the first. The first
463
463
  is always a sentence and always returns some of the wrong tree; the second is
464
- the same sentence with `files: ["nsx_4.2*/api/**"]`, or `section: "Rate limits"`,
464
+ the same sentence with `files: ["acme_4.2*/api/**"]`, or `section: "Rate limits"`,
465
465
  or `kind: ["table"]`. Those are parameters and not separate tools, so narrowing
466
466
  costs one call instead of three. `exclude_ids` takes the ids from an earlier
467
467
  answer, so asking again moves on instead of repeating itself.
@@ -482,7 +482,7 @@ project.** Not optional, and not the same thing as passing the tools in.
482
482
 
483
483
  Wiring alone leaves the model to infer everything that matters. A tool
484
484
  description says what `grep_docs` does; it cannot say that this index holds the
485
- NSX 4.1 and 4.2 manuals side by side, that every answer must be pinned to a
485
+ ACME 4.1 and 4.2 manuals side by side, that every answer must be pinned to a
486
486
  release with `files`, that the API reference lives under `*/api/**` and the
487
487
  task guides under `*/guides/**`, or that the numbers anybody actually wants are
488
488
  in tables and so `kind: ["table_row"]` is the right first move. That is project
@@ -530,19 +530,19 @@ Best practice, in order of how often it is got wrong:
530
530
 
531
531
  ```md
532
532
  ---
533
- name: nsx-docs
534
- description: How to find an answer in the NSX 4.1 and 4.2 manuals — which document says it,
533
+ name: acme-docs
534
+ description: How to find an answer in the ACME 4.1 and 4.2 manuals — which document says it,
535
535
  what it says verbatim, and which release it is true of. Use before answering anything
536
- about NSX behaviour, limits or API routes.
536
+ about ACME behaviour, limits or API routes.
537
537
  ---
538
538
 
539
- # The NSX manuals
539
+ # The ACME manuals
540
540
 
541
541
  Indexed at `/assets/docs-db` (already in `$ZEN_DOCS_DB`). Two releases side by
542
- side; document names begin `nsx_4.1.0/` or `nsx_4.2.0/`, then `api/` for the
542
+ side; document names begin `acme_4.1.0/` or `acme_4.2.0/`, then `api/` for the
543
543
  reference and `guides/` for the task documentation.
544
544
 
545
- - Always pin the release: `files: ["nsx_4.2.0/**"]`. An unpinned search mixes them.
545
+ - Always pin the release: `files: ["acme_4.2.0/**"]`. An unpinned search mixes them.
546
546
  - Vague question ("how does edge failover work?") → `search_docs`, then ask again
547
547
  with `section` or `files` once you can see which half of the tree it is in.
548
548
  - Does X exist, how is it spelled, how many are there → `grep_docs`. It is
@@ -553,7 +553,7 @@ reference and `guides/` for the task documentation.
553
553
  - Never `grep`/`rg`/`cat` the tree — the tools above are local and exact.
554
554
 
555
555
  Worked: per-route rate limits are the table under "Rate limits" in
556
- `nsx_4.2.0/api/routing.md` (lines 24-31); the retry envelope is described two
556
+ `acme_4.2.0/api/routing.md` (lines 24-31); the retry envelope is described two
557
557
  sections down. Cite the document name and the line numbers.
558
558
  ```
559
559
 
@@ -577,8 +577,8 @@ project.** Not optional, and not the same thing as passing the tools in.
577
577
 
578
578
  Wiring alone leaves the model to infer everything that matters. A tool
579
579
  description says what `grep_api` does; it cannot say that this index holds the
580
- NSX policy API, that names are `snake_case`, that every route is under
581
- `/policy/api/v1`, or that `list_api` is the right first move here because the
580
+ ACME policy API, that names are `snake_case`, that every route is under
581
+ `/api/v1/policy`, or that `list_api` is the right first move here because the
582
582
  API has three hundred operations and search will hand back five. That is
583
583
  project knowledge, and project knowledge belongs in a skill — where it is
584
584
  loaded only when the model is actually working on this API, instead of sitting
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "chat.useNestedAgentsMdFiles": false,
3
- "chat.tools.terminal.autoApprove": {
4
- "*": true
3
+ "chat.tools.terminal.enableAutoApprove": true,
4
+ "chat.tools.terminal.ignoreDefaultAutoApproveRules": true,
5
+ "chat.tools.edits.autoApprove": {
6
+ "**": true
5
7
  }
6
8
  }
@@ -0,0 +1,4 @@
1
+
2
+ You can also search the web and read a page from it. Prefer the workspace when
3
+ both could answer, and when an answer comes from the web, say which page it
4
+ came from.
@@ -0,0 +1,2 @@
1
+ - Web — search and read a page. Anything taken from one is attributed to the
2
+ page it came from.
@@ -5,3 +5,11 @@ place for the things that are true regardless of who is answering: tone,
5
5
  constraints, what to do when the answer is not knowable.
6
6
 
7
7
  Replace this with yours.
8
+
9
+ ## Reporting
10
+
11
+ Say what you did, file by file, and say what you deliberately did not do.
12
+
13
+ Every claim about what a command did has to be one you can make because you ran
14
+ it and read the output. When something cannot be established, say so and say
15
+ what would settle it — a guess offered as an answer is worse than no answer.
@@ -0,0 +1,47 @@
1
+ # Specification
2
+
3
+ What this project is for. The files around it are the implementation; where the
4
+ two disagree, this one wins.
5
+
6
+ ## Purpose
7
+
8
+ Carry out work inside a workspace on request — read it, change it, run
9
+ something in it — and report what was done in enough detail to be checked.
10
+
11
+ ## Scope
12
+
13
+ - One request at a time, in one workspace, with the person who asked it present.
14
+ - No schedule, no queue, nothing that outlives the session it was asked in.
15
+
16
+ ## Agents
17
+
18
+ - `default` — the entry point and the only agent; nobody to hand work to.
19
+ - Establishes what it is looking at before it acts: reads a file before
20
+ changing it, runs a command rather than predicting its output.
21
+
22
+ ## Tools and boundaries
23
+
24
+ - Files — read, search, create, edit, move, delete. The workspace is the only
25
+ writable thing, symlinks included.
26
+ - Shell — commands run in the container, on that same workspace.
27
+ - `assets/` is reference material, and read-only.
28
+ {{web}}
29
+
30
+ ## Environment
31
+
32
+ - Model: `{{modelRef}}`, one for the whole project.
33
+ - Sandbox: built from `sandbox/Dockerfile`, persists between runs, and can
34
+ reach the network. What the work always needs belongs in the image, not in an
35
+ instruction that reinstalls it on every run.
36
+ - Setup: none. `scripts/_setup.sh` is where a step would go, and it has none.
37
+
38
+ ## Done means
39
+
40
+ - The change asked for is in the workspace, or the question is answered from
41
+ what is actually in it.
42
+ - Every claim about a command is one that was run and whose output was read.
43
+ - The reply names what changed, file by file, and says what it deliberately did
44
+ not do.
45
+ - An answer that cannot be produced honestly is a refusal with the reason.
46
+
47
+
@@ -7,9 +7,13 @@ You can also run shell commands. They run in a container over the same
7
7
  workspace, not on the user's machine, so a command that fails there has cost
8
8
  them nothing — but it is still their work in the directory, so read before you
9
9
  overwrite and say what you ran.
10
+ {{webPrompt}}
10
11
 
11
12
  Read a file before you change it: `apply_patch` matches the surrounding text
12
13
  exactly, so a patch written from memory will not apply. Use `apply_patch` to
13
14
  change part of a file and `write_file` only for a new one.
14
15
 
16
+ Anything under `/assets` is reference material: read it, search it, and do not
17
+ try to change it.
18
+
15
19
  Say what you changed.
@@ -1,5 +1,9 @@
1
1
  # Who exists, and what they may reach for.
2
2
  #
3
+ # This implements the Agents, Tools and boundaries, and Environment sections of
4
+ # SPECIFICATION.md. Change what the system does there first, then bring this
5
+ # file to match it — `/sync-with-spec` in your editor does exactly that.
6
+ #
3
7
  version: 1
4
8
 
5
9
  {{model}}
@@ -1,7 +1,13 @@
1
- # Sessions hold run state, memory, blobs and whatever the agent wrote.
1
+ # Sessions hold run state, blobs and whatever the agent wrote.
2
2
  # None of it is source.
3
3
  sessions/
4
4
 
5
+ # Memory is worth keeping: `graph.json` and `files/` are what the agents
6
+ # learned, and they diff. The vectors are not — they are derived from the
7
+ # graph and can be rebuilt with `zen memory reembed`.
8
+ memory/vectors.*
9
+ memory/.lock
10
+
5
11
  # Scratch, inside the workspace so the sandbox can reach it.
6
12
  .tmp/
7
13
 
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # The one command that initialises this project.
4
+ #
5
+ # scripts/_setup.sh do whatever is not done yet
6
+ # scripts/_setup.sh --force do all of it again
7
+ #
8
+ # Anything that has to be in place before a run — an index built, a document
9
+ # fetched, a file generated — is a script in this directory rather than a
10
+ # paragraph somebody is meant to follow. The leading underscore is what
11
+ # separates the runner from the steps it runs.
12
+ #
13
+ # Each step is `scripts/<name>.sh`, named below in the order they depend on
14
+ # each other. A step:
15
+ #
16
+ # - starts `set -eu` and `cd "$(dirname "$0")/.."`, so it works from anywhere
17
+ # - takes no arguments, and reads $FORCE to know whether to redo finished work
18
+ # - exits 0 when it did the work, 3 when there was nothing to do, non-zero
19
+ # when it failed
20
+ # - writes under .tmp/ and moves the result into place, so an interrupted run
21
+ # never leaves half an artefact behind
22
+ #
23
+ # Running this twice has to be safe, and the second run is what proves it: every
24
+ # step should report `skipped`.
25
+
26
+ set -eu
27
+ cd "$(dirname "$0")/.."
28
+
29
+ FORCE=0
30
+ if [ "${1:-}" = "--force" ]; then
31
+ FORCE=1
32
+ fi
33
+ export FORCE
34
+
35
+ LOGS=.tmp/logs
36
+
37
+ # The steps, in order. Nothing here yet — a project with nothing to build
38
+ # before it runs is a project with no steps, and that is a real answer.
39
+ #
40
+ # An example of what one looks like, for when there is something to build:
41
+ #
42
+ # STEPS="docs_index"
43
+ #
44
+ # with scripts/docs_index.sh holding
45
+ #
46
+ # set -eu
47
+ # cd "$(dirname "$0")/.."
48
+ # if [ "${FORCE:-0}" = 0 ] && [ -f assets/docs-db/manifest.json ]; then
49
+ # echo "assets/docs-db is already built"
50
+ # exit 3
51
+ # fi
52
+ # rm -rf .tmp/docs-db
53
+ # zen rag docs index assets/docs \
54
+ # --embedding openai:text-embedding-3-small --out .tmp/docs-db
55
+ # rm -rf assets/docs-db
56
+ # mv .tmp/docs-db assets/docs-db
57
+ #
58
+ STEPS=""
59
+
60
+ if [ -z "$STEPS" ]; then
61
+ echo "nothing to set up — this project builds nothing before it runs"
62
+ exit 0
63
+ fi
64
+
65
+ mkdir -p "$LOGS"
66
+ summary=""
67
+ failed=0
68
+
69
+ for name in $STEPS; do
70
+ log="$LOGS/setup-$name.log"
71
+ echo
72
+ echo "-- $name $(date '+%H:%M:%S') ($log)"
73
+
74
+ # Watched rather than waited on: the output goes to the screen and to its
75
+ # own log at once, so a long step can be followed from either.
76
+ set +e
77
+ "scripts/$name.sh" 2>&1 | tee "$log"
78
+ code=${PIPESTATUS[0]}
79
+ set -e
80
+
81
+ case "$code" in
82
+ 0) word=ok ;;
83
+ 3) word=skipped ;;
84
+ *)
85
+ word="failed ($code)"
86
+ failed=1
87
+ ;;
88
+ esac
89
+ summary="${summary} ${name}: ${word}
90
+ "
91
+ # Later steps depend on earlier ones, so a failure stops rather than
92
+ # producing a second failure that is only a consequence of the first.
93
+ if [ "$failed" = 1 ]; then
94
+ break
95
+ fi
96
+ done
97
+
98
+ echo
99
+ echo "setup:"
100
+ printf '%s' "$summary"
101
+ exit "$failed"
@@ -1,6 +0,0 @@
1
- # Specification
2
-
3
- What the project is meant to produce, the constraints it has to hold to, and
4
- how to tell a finished job from an unfinished one.
5
-
6
- Anything written here is the specification; while it is empty there is none.