@zenera/cli 1.1.14 → 1.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +563 -206
- package/dist/banner.d.ts +5 -1
- package/dist/banner.js +2 -2
- package/dist/command.d.ts +5 -0
- package/dist/commands/init.js +46 -2
- package/dist/main.js +10 -6
- package/dist/validate.js +1 -1
- package/package.json +2 -2
- package/templates/editor/.github/copilot-instructions.md +253 -218
- package/templates/editor/.github/prompts/new-agent.prompt.md +6 -6
- package/templates/editor/.github/prompts/new-skill.prompt.md +7 -7
- package/templates/editor/.github/prompts/review-project.prompt.md +1 -1
- package/templates/editor/.github/prompts/sync-with-spec.prompt.md +26 -26
- package/templates/editor/.github/skills/zen-cli/SKILL.md +62 -6
- package/templates/editor/.github/skills/zen-cli/references/check.md +3 -3
- package/templates/editor/.github/skills/zen-cli/references/faker.md +14 -14
- package/templates/editor/.github/skills/zen-cli/references/frame.md +6 -6
- package/templates/editor/.github/skills/zen-cli/references/inspect.md +3 -3
- package/templates/editor/.github/skills/zen-cli/references/keys.md +9 -9
- package/templates/editor/.github/skills/zen-cli/references/memory.md +11 -11
- package/templates/editor/.github/skills/zen-cli/references/models.md +8 -8
- package/templates/editor/.github/skills/zen-cli/references/projects.md +3 -3
- package/templates/editor/.github/skills/zen-cli/references/rag.md +191 -56
- package/templates/editor/.github/skills/zen-cli/references/run.md +3 -3
- package/templates/editor/.github/skills/zen-cli/references/sandbox.md +8 -8
- package/templates/editor/.github/skills/zen-memory/SKILL.md +50 -50
- package/templates/editor/.github/skills/zen-rag-docs/SKILL.md +71 -48
- package/templates/editor/.github/skills/zen-rag-schema/SKILL.md +67 -67
- package/templates/editor/.vscode/settings.json +5 -2
- package/templates/project/INSTRUCTIONS.md +1 -1
- package/templates/project/assets/README.md +1 -1
- package/templates/project/sandbox/Dockerfile.tmpl +3 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zen-rag-docs
|
|
3
|
-
description: What a document index is, how to build one from a folder of `.md` files with `zen rag docs index` (or `npx @zenera/cli`), and how to ask it something
|
|
3
|
+
description: What a document index is, how to build one from a folder of `.md` files with `zen rag docs index` (or `npx @zenera/cli`), and how to ask it something - searching by meaning and narrowing to a release, a heading or a table, listing and grepping it exactly instead of reaching for shell `grep`/`rg`, reading a section back verbatim, giving it to an agent as tools, and writing the project skill that a wired-in index requires. For an OpenAPI description instead of prose, see `zen-rag-schema`.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# The document index
|
|
7
7
|
|
|
8
8
|
A document index is a pile of markdown turned into something that can be
|
|
9
|
-
**asked a question**. It is built once, on disk, and answered from
|
|
9
|
+
**asked a question**. It is built once, on disk, and answered from - and what
|
|
10
10
|
comes back is not a summary but the documents themselves: the passages that
|
|
11
11
|
matched, quoted verbatim, with their line numbers.
|
|
12
12
|
|
|
@@ -31,7 +31,7 @@ zen rag docs <index|search|list|grep|show|stats> [path...]
|
|
|
31
31
|
| `show` | _print this section, verbatim_ | no | instant |
|
|
32
32
|
| `stats` | _what is in this index?_ | no | instant |
|
|
33
33
|
|
|
34
|
-
Only `search` ranks, and only `search` costs a network round trip
|
|
34
|
+
Only `search` ranks, and only `search` costs a network round trip - it embeds
|
|
35
35
|
the query before it can compare anything. The other four read `outline.json`
|
|
36
36
|
and the copies in `sources/` off the disk and answer in milliseconds. Reach for
|
|
37
37
|
`search` when the question is vague and for `list`/`grep`/`show` when it is
|
|
@@ -62,10 +62,10 @@ Three things, and the third is the point.
|
|
|
62
62
|
|
|
63
63
|
```
|
|
64
64
|
docs-db/
|
|
65
|
-
├── README.md what this index holds
|
|
66
|
-
├── manifest.json written LAST
|
|
65
|
+
├── README.md what this index holds - a live progress report while it builds
|
|
66
|
+
├── manifest.json written LAST - its absence means "not indexed"
|
|
67
67
|
├── outline.json headings and tables, read whole
|
|
68
|
-
├── sources/ the documents, verbatim
|
|
68
|
+
├── sources/ the documents, verbatim - where every quoted line comes from
|
|
69
69
|
└── lance/ the chunks
|
|
70
70
|
```
|
|
71
71
|
|
|
@@ -86,7 +86,7 @@ Chunking follows the markdown rather than a character count: a paragraph, a
|
|
|
86
86
|
list, a fenced code block, the frontmatter. Every chunk knows the heading it
|
|
87
87
|
sits under, which is what makes `--section` a filter and not a hope.
|
|
88
88
|
|
|
89
|
-
Tables are indexed **twice over**
|
|
89
|
+
Tables are indexed **twice over** - once as a descriptor carrying the caption
|
|
90
90
|
and the column names, and once per row, with the header row travelling
|
|
91
91
|
alongside so the columns are still named wherever a row lands. A row too wide
|
|
92
92
|
to be one chunk is cut into column groups with the key column repeated. That is
|
|
@@ -99,7 +99,7 @@ Every chunk gets a `kind`: `paragraph`, `list`, `table`, `table_row`, `code`,
|
|
|
99
99
|
## Installing
|
|
100
100
|
|
|
101
101
|
`zen rag` ships in `@zenera/rag`, a sibling of the CLI. It has no binary of its
|
|
102
|
-
own
|
|
102
|
+
own - installing it adds the `rag` subcommand to `zen`, which is also where the
|
|
103
103
|
credentials already live.
|
|
104
104
|
|
|
105
105
|
```sh
|
|
@@ -138,7 +138,7 @@ That is the whole thing: point it at a directory and it walks it.
|
|
|
138
138
|
|
|
139
139
|
`.md`, `.markdown`, `.txt` and `.text` are read; `.txt` and `.text` are treated
|
|
140
140
|
as prose with no headings. Anything else is not a document and is not indexed.
|
|
141
|
-
Hidden directories and `node_modules` are skipped
|
|
141
|
+
Hidden directories and `node_modules` are skipped - a file nobody can see is
|
|
142
142
|
not one anybody meant to index. A file over 16 MB is skipped as a data dump and
|
|
143
143
|
said so on stderr, next to the per-document table.
|
|
144
144
|
|
|
@@ -166,13 +166,13 @@ would land on the same name are deduped rather than merged.
|
|
|
166
166
|
|
|
167
167
|
| Flag | Default | Meaning |
|
|
168
168
|
| -------------------- | ----------- | ------------------------------------------------------------ |
|
|
169
|
-
| `--embedding <ref>` |
|
|
169
|
+
| `--embedding <ref>` | - | Which embedder makes the vectors. Omit it to see the choices |
|
|
170
170
|
| `-o`, `--out <dir>` | `./docs-db` | Where the index goes; `$ZEN_DOCS_DB` if that is set |
|
|
171
171
|
| `--batch <n>` | `96` | Texts per embedding request, and how often progress prints |
|
|
172
172
|
| `--chunk-tokens <n>` | `384` | Target chunk size. Leave it alone unless you have a reason |
|
|
173
|
-
| `--quiet` |
|
|
173
|
+
| `--quiet` | - | No narration |
|
|
174
174
|
|
|
175
|
-
The embedding reference names a provider first
|
|
175
|
+
The embedding reference names a provider first - `openai:text-embedding-3-small`,
|
|
176
176
|
not a bare model id. Credentials come from the `zen` keyring (`zen key ls`), and
|
|
177
177
|
a real environment variable always wins.
|
|
178
178
|
|
|
@@ -184,14 +184,14 @@ the output directory and nothing else**, so `DIR=$(zen rag docs index …)` work
|
|
|
184
184
|
everything else is stderr.
|
|
185
185
|
|
|
186
186
|
This is the one command here that spends money and time: it embeds every chunk.
|
|
187
|
-
While it runs, the output directory narrates itself
|
|
187
|
+
While it runs, the output directory narrates itself - `README.md` is a live
|
|
188
188
|
progress report, rewritten at most every five seconds, replaced on completion by
|
|
189
189
|
a description of what the index turned out to hold, and left saying so if the
|
|
190
190
|
build dies. A `.lock` names the process, so a second build of the same directory
|
|
191
191
|
is refused unless the lock is stale.
|
|
192
192
|
|
|
193
193
|
Rebuild the index when the documents change. Nothing watches them, and a stale
|
|
194
|
-
index is a confident wrong answer
|
|
194
|
+
index is a confident wrong answer - worse here than anywhere, because the quoted
|
|
195
195
|
lines will look exactly as authoritative as they did when they were true.
|
|
196
196
|
|
|
197
197
|
## Which index gets read
|
|
@@ -199,7 +199,7 @@ lines will look exactly as authoritative as they did when they were true.
|
|
|
199
199
|
Every reading command takes `-d`, `--dir`. Without one:
|
|
200
200
|
|
|
201
201
|
1. `$ZEN_DOCS_DB`, if it is set. **Set this once** instead of typing `-d` on
|
|
202
|
-
every command
|
|
202
|
+
every command - `export ZEN_DOCS_DB=/assets/docs-db`.
|
|
203
203
|
2. Otherwise the **nearest index** to the working directory: here, then a short
|
|
204
204
|
way down into it, then up a level and again, stopping at your home
|
|
205
205
|
directory. The one chosen is named on stderr as it is used, so an answer is
|
|
@@ -207,7 +207,7 @@ Every reading command takes `-d`, `--dir`. Without one:
|
|
|
207
207
|
3. Otherwise `./docs-db`, which is only so the error names the directory you
|
|
208
208
|
were expecting.
|
|
209
209
|
|
|
210
|
-
What is looked for is a `manifest.json`, and the search is **scoped by kind**
|
|
210
|
+
What is looked for is a `manifest.json`, and the search is **scoped by kind** -
|
|
211
211
|
a `docs` index and a `schema` index can sit in the same tree without either
|
|
212
212
|
shadowing the other, and nothing searches for a directory literally called
|
|
213
213
|
`docs-db`. That is just the name a new one is given.
|
|
@@ -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
|
-
## acme_4.2.0/api/routing.md
|
|
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.
|
|
@@ -247,7 +247,7 @@ with. The numbers are what `show` and `read_docs` take.
|
|
|
247
247
|
|
|
248
248
|
Nobody finds the paragraph they want on the first ask. They search, see it is
|
|
249
249
|
the wrong release, and search again inside one. So the second call is the same
|
|
250
|
-
question with a narrowing on it
|
|
250
|
+
question with a narrowing on it - not a different command.
|
|
251
251
|
|
|
252
252
|
| Flag | Narrows to |
|
|
253
253
|
| ------------------------ | ------------------------------------------------------------------------------------ |
|
|
@@ -273,28 +273,47 @@ earlier answer printed. A title that appears in four documents becomes four
|
|
|
273
273
|
scopes, not a guess at one.
|
|
274
274
|
|
|
275
275
|
**`--mode text` is the one to remember.** `hybrid` blends meaning and wording,
|
|
276
|
-
which is right for a question; when what you have is an exact string
|
|
277
|
-
message, a header name, a flag
|
|
276
|
+
which is right for a question; when what you have is an exact string - an error
|
|
277
|
+
message, a header name, a flag - `text` is exact wording only, and meaning can
|
|
278
278
|
only dilute it.
|
|
279
279
|
|
|
280
280
|
The narrowings are resolved against the manifest and the outline **before** the
|
|
281
281
|
store is touched, so a `--file` pattern that matches nothing says so instead of
|
|
282
282
|
quietly searching everything.
|
|
283
283
|
|
|
284
|
+
### One wording per leg
|
|
285
|
+
|
|
286
|
+
`hybrid` asks two retrievers the same sentence, and they read it differently:
|
|
287
|
+
the full-text leg wants the words the documents use, the vector leg wants the
|
|
288
|
+
question stated in full. When you know both - the exact header name _and_ what
|
|
289
|
+
you actually want to know about it - say each one:
|
|
290
|
+
|
|
291
|
+
```sh
|
|
292
|
+
zen rag docs search --text-query "Retry-After" \
|
|
293
|
+
--vector-query "how long to wait before trying the request again"
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Both legs run and the results fuse as usual. Either flag alone runs that leg
|
|
297
|
+
alone, so `--text-query` by itself is `--mode text` with its own wording.
|
|
298
|
+
|
|
299
|
+
They **replace** the positional text rather than narrowing it, and they settle
|
|
300
|
+
the mode by existing. `search "x" --text-query "y"` and `--text-query "y"
|
|
301
|
+
--mode vector` are both refused, because each says two things at once.
|
|
302
|
+
|
|
284
303
|
### Shaping the answer
|
|
285
304
|
|
|
286
305
|
| Flag | Default | Meaning |
|
|
287
306
|
| -------------------- | ------- | ----------------------------------------- |
|
|
288
|
-
| `-d`, `--dir <dir>` | found | Which index
|
|
307
|
+
| `-d`, `--dir <dir>` | found | Which index - see "Which index gets read" |
|
|
289
308
|
| `--embedding <ref>` | index's | Must be the one the index was built with |
|
|
290
309
|
| `--limit <n>` | `8` | Passages kept |
|
|
291
310
|
| `-B`, `--before <n>` | `0` | Extra lines quoted before each passage |
|
|
292
311
|
| `-A`, `--after <n>` | `0` | Extra lines quoted after each passage |
|
|
293
312
|
| `--max-lines <n>` | `400` | A ceiling on the whole answer |
|
|
294
|
-
| `--no-numbers` |
|
|
295
|
-
| `--hits` |
|
|
296
|
-
| `--interactive` |
|
|
297
|
-
| `--quiet` |
|
|
313
|
+
| `--no-numbers` | - | Quote the lines without their numbers |
|
|
314
|
+
| `--hits` | - | One row per passage instead of the text |
|
|
315
|
+
| `--interactive` | - | Prompt, search, narrow. Needs a terminal |
|
|
316
|
+
| `--quiet` | - | No narration |
|
|
298
317
|
|
|
299
318
|
`--hits` is the fast triage: it prints where the passages are without spending
|
|
300
319
|
the lines on them, and you follow up with `show`.
|
|
@@ -302,7 +321,7 @@ the lines on them, and you follow up with `show`.
|
|
|
302
321
|
### As a machine interface
|
|
303
322
|
|
|
304
323
|
Non-interactive search is a tool, not an afterthought. `--json` is a stable
|
|
305
|
-
shape
|
|
324
|
+
shape - `{matches, files, scope, mode, considered, truncated}` - no terminal is
|
|
306
325
|
needed, and **an empty result exits 0**: a caller must never have to tell
|
|
307
326
|
"nothing matched" from "the index is missing" by parsing stderr.
|
|
308
327
|
|
|
@@ -330,7 +349,7 @@ quit
|
|
|
330
349
|
|
|
331
350
|
## Reading it without searching
|
|
332
351
|
|
|
333
|
-
None of these need an embedder or a credential
|
|
352
|
+
None of these need an embedder or a credential - they are plain reads of the
|
|
334
353
|
outline and the copies on disk.
|
|
335
354
|
|
|
336
355
|
```
|
|
@@ -365,7 +384,7 @@ zen rag docs stats
|
|
|
365
384
|
```
|
|
366
385
|
|
|
367
386
|
`list files` reports the name, title, format, and how many lines, sections,
|
|
368
|
-
tables and chunks each document holds
|
|
387
|
+
tables and chunks each document holds - which is also the fastest way to learn
|
|
369
388
|
the names your `--file` patterns will be matched against. `list sections` is a
|
|
370
389
|
table of contents with line spans; `list tables` names every table's caption,
|
|
371
390
|
columns and row count, which is how you find the limits table without reading
|
|
@@ -374,14 +393,14 @@ the prose around it.
|
|
|
374
393
|
`grep` reports `found` as the **true total** even when `--limit` cuts the rows,
|
|
375
394
|
so unlike a search it can answer whether a string appears at all. Every hit
|
|
376
395
|
carries the innermost heading it sits under, so a match has a place. Nothing
|
|
377
|
-
matching exits 0 with empty stdout
|
|
396
|
+
matching exits 0 with empty stdout - and that emptiness is trustworthy, which is
|
|
378
397
|
the whole point of it.
|
|
379
398
|
|
|
380
399
|
`show` prints a document, a named section, or a line range, verbatim, with a
|
|
381
400
|
line-number gutter (`--no-numbers` to drop it). It is the natural follow-up to
|
|
382
401
|
every search: find the passage, then read what is actually around it.
|
|
383
402
|
|
|
384
|
-
`stats` says what is in an index and what built it
|
|
403
|
+
`stats` says what is in an index and what built it - the documents, the counts,
|
|
385
404
|
the embedding model. It is the fastest way to answer "is this index the one I
|
|
386
405
|
think it is?".
|
|
387
406
|
|
|
@@ -390,7 +409,7 @@ think it is?".
|
|
|
390
409
|
| The question | The command |
|
|
391
410
|
| ------------------------------------------------- | ----------------------------------------------- |
|
|
392
411
|
| "how does this thing handle retries?" | `search "how are retries handled"` |
|
|
393
|
-
| _anything you would have run `grep` for_ | `grep` / `list`
|
|
412
|
+
| _anything you would have run `grep` for_ | `grep` / `list` - never the shell |
|
|
394
413
|
| "does `X-Request-Id` appear anywhere?" | `grep X-Request-Id` |
|
|
395
414
|
| "what does the rate-limits section actually say?" | `show <file> --section "Rate limits"` |
|
|
396
415
|
| "which documents are even in here?" | `list files` |
|
|
@@ -415,7 +434,7 @@ Add `-d <dir>` when the index is not the nearest one, or name it once with
|
|
|
415
434
|
| `grep -rn "Retry-After" docs/` | `zen rag docs grep "Retry-After"` |
|
|
416
435
|
| `rg -i retry --glob 'api/**'` | `zen rag docs grep retry --file "api/**"` |
|
|
417
436
|
| `grep -E "X-RateLimit-\w+"` | `zen rag docs grep "X-RateLimit-\w+" --regex` |
|
|
418
|
-
| `grep -c` / `wc -l` | `--json`, and read `found`
|
|
437
|
+
| `grep -c` / `wc -l` | `--json`, and read `found` - it counts past `--limit` |
|
|
419
438
|
| `find docs -name '*.md'` | `zen rag docs list files` |
|
|
420
439
|
| `grep '^#' file.md` | `zen rag docs list sections --file file.md` |
|
|
421
440
|
| `sed -n '40,80p' file.md` | `zen rag docs show file.md --lines 40-80` |
|
|
@@ -429,7 +448,7 @@ zen rag docs list sections --file "api/**" --depth 3
|
|
|
429
448
|
```
|
|
430
449
|
|
|
431
450
|
If none of these fits the question, the question is about meaning, and the
|
|
432
|
-
answer is `search`
|
|
451
|
+
answer is `search` - still not the shell.
|
|
433
452
|
|
|
434
453
|
## Giving it to an agent
|
|
435
454
|
|
|
@@ -450,12 +469,12 @@ const project = await loadProject('./my-project', { tools: docs.docsTools(index)
|
|
|
450
469
|
| Tool | For |
|
|
451
470
|
| ------------- | ------------------------------------------------------------ |
|
|
452
471
|
| `search_docs` | the passages that match, quoted with their line numbers |
|
|
453
|
-
| `list_docs` | the documents, their headings, or their tables
|
|
454
|
-
| `grep_docs` | every matching line, counted in full
|
|
472
|
+
| `list_docs` | the documents, their headings, or their tables - no search |
|
|
473
|
+
| `grep_docs` | every matching line, counted in full - no search |
|
|
455
474
|
| `read_docs` | a section or a line range, verbatim and with nothing omitted |
|
|
456
475
|
|
|
457
476
|
Only `search_docs` ranks; the other three are exact, because a model told "no
|
|
458
|
-
results" by a vector search has learned nothing
|
|
477
|
+
results" by a vector search has learned nothing - a ranking returns the top of a
|
|
459
478
|
list, so an empty answer and an absent thing look identical. `grep_docs` is how
|
|
460
479
|
"it is not written down anywhere" can actually be concluded.
|
|
461
480
|
|
|
@@ -466,18 +485,22 @@ or `kind: ["table"]`. Those are parameters and not separate tools, so narrowing
|
|
|
466
485
|
costs one call instead of three. `exclude_ids` takes the ids from an earlier
|
|
467
486
|
answer, so asking again moves on instead of repeating itself.
|
|
468
487
|
|
|
488
|
+
`text_query` and `vector_query` are the tool's version of the two flags above:
|
|
489
|
+
send one to run that leg alone, or both to word each half of a hybrid search.
|
|
490
|
+
They replace `query`, so sending it as well is refused.
|
|
491
|
+
|
|
469
492
|
Every answer carries line numbers and `read_docs` takes them. That is the loop
|
|
470
493
|
the whole subject exists for: **find the passage, read around it, then edit the
|
|
471
494
|
file the passage came from.**
|
|
472
495
|
|
|
473
|
-
Tell the agent in its prompt to call `list_docs` once before its first search
|
|
496
|
+
Tell the agent in its prompt to call `list_docs` once before its first search -
|
|
474
497
|
the document names are what every `files` pattern is matched against, and a
|
|
475
498
|
model guessing at them narrows to nothing and concludes the corpus is empty.
|
|
476
499
|
|
|
477
500
|
## Wiring it into a project means writing the project a skill
|
|
478
501
|
|
|
479
|
-
**Whenever an index is used by a Zenera project
|
|
480
|
-
`zen rag` reachable from the agent's sandbox
|
|
502
|
+
**Whenever an index is used by a Zenera project - as `docs:*` tools, or as
|
|
503
|
+
`zen rag` reachable from the agent's sandbox - write a skill for it in that
|
|
481
504
|
project.** Not optional, and not the same thing as passing the tools in.
|
|
482
505
|
|
|
483
506
|
Wiring alone leaves the model to infer everything that matters. A tool
|
|
@@ -486,7 +509,7 @@ ACME 4.1 and 4.2 manuals side by side, that every answer must be pinned to a
|
|
|
486
509
|
release with `files`, that the API reference lives under `*/api/**` and the
|
|
487
510
|
task guides under `*/guides/**`, or that the numbers anybody actually wants are
|
|
488
511
|
in tables and so `kind: ["table_row"]` is the right first move. That is project
|
|
489
|
-
knowledge, and project knowledge belongs in a skill
|
|
512
|
+
knowledge, and project knowledge belongs in a skill - where it is loaded only
|
|
490
513
|
when the model is working on this corpus, instead of sitting in the system
|
|
491
514
|
prompt of every run.
|
|
492
515
|
|
|
@@ -504,7 +527,7 @@ what unlocks them.
|
|
|
504
527
|
| Section | Because |
|
|
505
528
|
| ------------------ | ----------------------------------------------------------------------------------- |
|
|
506
529
|
| Which corpus | What it is, which version(s), and when it was indexed |
|
|
507
|
-
| Where the index | `ZEN_DOCS_DB`, or the `-d` to pass
|
|
530
|
+
| Where the index | `ZEN_DOCS_DB`, or the `-d` to pass - an agent cannot guess a path |
|
|
508
531
|
| The document names | The shape `--file`/`files` patterns match, with two real examples |
|
|
509
532
|
| Which command | Meaning → `search`; presence or a count → `grep`; what it says → `show`/`read_docs` |
|
|
510
533
|
| Never the shell | State it outright. `grep`/`rg`/`cat` on the tree is the default reflex |
|
|
@@ -522,7 +545,7 @@ Best practice, in order of how often it is got wrong:
|
|
|
522
545
|
3. **Name the narrowing that matters here.** Two releases in one index is the
|
|
523
546
|
common case, and an unpinned search silently mixes them.
|
|
524
547
|
4. **Keep it short.** A skill is prompt. One screen of routing rules beats a
|
|
525
|
-
transcription of this document
|
|
548
|
+
transcription of this document - link to `zen rag docs --help` for the flags.
|
|
526
549
|
5. **Re-index, then re-read the skill.** Both go stale against the same change,
|
|
527
550
|
and a skill quoting headings that no longer exist is worse than none.
|
|
528
551
|
6. **One skill per corpus**, named after it. Two corpora in one skill and the
|
|
@@ -531,7 +554,7 @@ Best practice, in order of how often it is got wrong:
|
|
|
531
554
|
```md
|
|
532
555
|
---
|
|
533
556
|
name: acme-docs
|
|
534
|
-
description: How to find an answer in the ACME 4.1 and 4.2 manuals
|
|
557
|
+
description: How to find an answer in the ACME 4.1 and 4.2 manuals - which document says it,
|
|
535
558
|
what it says verbatim, and which release it is true of. Use before answering anything
|
|
536
559
|
about ACME behaviour, limits or API routes.
|
|
537
560
|
---
|
|
@@ -550,7 +573,7 @@ reference and `guides/` for the task documentation.
|
|
|
550
573
|
- Limits and defaults are in tables → add `kind: ["table_row"]`.
|
|
551
574
|
- Then `read_docs` the lines around the hit before answering. Never answer from
|
|
552
575
|
the excerpt alone.
|
|
553
|
-
- Never `grep`/`rg`/`cat` the tree
|
|
576
|
+
- Never `grep`/`rg`/`cat` the tree - the tools above are local and exact.
|
|
554
577
|
|
|
555
578
|
Worked: per-route rate limits are the table under "Rate limits" in
|
|
556
579
|
`acme_4.2.0/api/routing.md` (lines 24-31); the retry envelope is described two
|
|
@@ -561,13 +584,13 @@ sections down. Cite the document name and the line numbers.
|
|
|
561
584
|
|
|
562
585
|
| Symptom | Cause |
|
|
563
586
|
| ------------------------------------------------ | ------------------------------------------------------------------------------------- |
|
|
564
|
-
| "not installed" | `@zenera/rag` is not resolvable
|
|
587
|
+
| "not installed" | `@zenera/rag` is not resolvable - install it, or use the two-`--package` npx form |
|
|
565
588
|
| `nothing to index` | No `.md`/`.markdown`/`.txt`/`.text` under those paths, or they are all hidden |
|
|
566
|
-
| A document you expected is missing | Hidden directory, `node_modules`, an unlisted extension, or over 16 MB
|
|
589
|
+
| A document you expected is missing | Hidden directory, `node_modules`, an unlisted extension, or over 16 MB - check stderr |
|
|
567
590
|
| Refused for a different embedding | The index records the model that built it; re-index or pass the right `--embedding` |
|
|
568
591
|
| No manifest / not an index | A build that did not finish. `manifest.json` is written last on purpose |
|
|
569
|
-
| A build is refused | `.lock`
|
|
570
|
-
| `provider "openai": no api key` | `zen key ls`
|
|
592
|
+
| A build is refused | `.lock` - another build is running. It is taken over when the process is gone |
|
|
593
|
+
| `provider "openai": no api key` | `zen key ls` - the keyring, or a real environment variable |
|
|
571
594
|
| A usage error before any credential is asked for | Deliberate: everything about the invocation is checked first, so a typo is a typo |
|
|
572
595
|
| `no document matched --file` | The pattern is matched against the document **name**; `list files` prints them |
|
|
573
596
|
| Nothing matched | Exit 0 with an empty answer. Try fewer words, or `--mode text` for an exact string |
|