llmnav 0.5.1

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 (68) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/LICENSE +21 -0
  3. package/README.md +294 -0
  4. package/ROADMAP.md +71 -0
  5. package/bin/llmnav.js +16 -0
  6. package/docs/agent-integration.md +114 -0
  7. package/docs/api.md +290 -0
  8. package/docs/architecture.md +286 -0
  9. package/docs/benchmarking.md +164 -0
  10. package/docs/ci.md +196 -0
  11. package/docs/cli.md +233 -0
  12. package/docs/configuration.md +117 -0
  13. package/docs/editor-integration.md +29 -0
  14. package/docs/faq.md +59 -0
  15. package/docs/graph.md +92 -0
  16. package/docs/language-examples.md +130 -0
  17. package/docs/migration.md +130 -0
  18. package/docs/performance-v0.2.md +42 -0
  19. package/docs/provider-neutral-integration.md +66 -0
  20. package/docs/publishing.md +86 -0
  21. package/docs/quickstart.md +139 -0
  22. package/docs/research.md +31 -0
  23. package/docs/spec.md +424 -0
  24. package/examples/provider-neutral-host.d.mts +17 -0
  25. package/examples/provider-neutral-host.mjs +40 -0
  26. package/package.json +79 -0
  27. package/schema/config.schema.json +296 -0
  28. package/src/agent-protocol.js +117 -0
  29. package/src/agent-tools.js +61 -0
  30. package/src/agents.js +127 -0
  31. package/src/boundaries.js +50 -0
  32. package/src/changes.js +168 -0
  33. package/src/cli.js +459 -0
  34. package/src/config.js +305 -0
  35. package/src/contracts.js +70 -0
  36. package/src/declaration.js +334 -0
  37. package/src/doctor.js +124 -0
  38. package/src/editor.js +107 -0
  39. package/src/evaluation.js +67 -0
  40. package/src/files.js +81 -0
  41. package/src/formatter.js +23 -0
  42. package/src/generator.js +528 -0
  43. package/src/graph-input.js +157 -0
  44. package/src/graph.js +403 -0
  45. package/src/incremental.js +262 -0
  46. package/src/index.d.ts +673 -0
  47. package/src/index.js +115 -0
  48. package/src/initializer.js +137 -0
  49. package/src/inverted-index.js +350 -0
  50. package/src/parser.js +449 -0
  51. package/src/project.js +65 -0
  52. package/src/prompt-bundle.js +108 -0
  53. package/src/registry.js +107 -0
  54. package/src/sarif.js +70 -0
  55. package/src/search-shards.js +75 -0
  56. package/src/search.js +636 -0
  57. package/src/spec.d.ts +27 -0
  58. package/src/spec.js +237 -0
  59. package/src/tokenizer.js +37 -0
  60. package/src/transaction.js +557 -0
  61. package/src/util.js +256 -0
  62. package/src/validator.js +635 -0
  63. package/templates/file-card.txt +8 -0
  64. package/templates/lexicon.json +7 -0
  65. package/templates/line-card.txt +9 -0
  66. package/templates/module-card.txt +9 -0
  67. package/templates/queries.jsonl +1 -0
  68. package/templates/symbol-card.txt +10 -0
@@ -0,0 +1,164 @@
1
+ # Benchmarking navigation impact
2
+
3
+ ## Two benchmark layers
4
+
5
+ LLMNav measures two different things.
6
+
7
+ The repository retrieval layer asks whether a task query reaches the correct semantic card quickly and without excessive memory.
8
+
9
+ The end-to-end agent layer asks whether the coding agent opens less irrelevant source, uses fewer uncached tokens, and still completes the task correctly.
10
+
11
+ Do not substitute one layer for the other.
12
+
13
+ ## Built-in v0.2 regression suite
14
+
15
+ Run:
16
+
17
+ ```sh
18
+ npm test
19
+ ```
20
+
21
+ The large synthetic search test creates 5,000 indexed cards and 50 deterministic queries. It compares the v0.2 prepared inverted-index path with the v0.1-compatible legacy path.
22
+
23
+ It requires:
24
+
25
+ * expected first result for every query
26
+ * identical ranked-result checksum
27
+ * lower elapsed time for the isolated v0.2 query loop
28
+ * bounded generated search-index bytes
29
+ * bounded RSS and heap use
30
+
31
+ The incremental source fixture requires a no-op run to parse zero files, a one-file edit to parse one file, and a one-card semantic edit to retokenize one card. It then forces a full rebuild and compares deterministic output bytes.
32
+
33
+ These tests are regression gates. They do not claim a universal speedup on every repository or machine.
34
+
35
+ ## Reproducible v0.2 measurement
36
+
37
+ Run:
38
+
39
+ ```sh
40
+ npm run benchmark:v0.2
41
+ ```
42
+
43
+ The command creates a temporary synthetic repository with 1,000 source files and 5,000 cards by default. It records:
44
+
45
+ * cold initial generation
46
+ * one-file incremental regeneration
47
+ * the same change through forced full regeneration
48
+ * no-op incremental regeneration
49
+ * byte equality between incremental and full cache trees
50
+ * fresh-process v0.1-compatible query timing
51
+ * fresh-process v0.2 inverted-index query timing
52
+ * median and p95 query latency
53
+ * RSS, heap, index bytes, and search-index bytes
54
+ * exact result checksum equality
55
+
56
+ The benchmark writes raw JSON under `benchmarks/results/` and regenerates `docs/performance-v0.2.md`.
57
+
58
+ Environment variables can reduce or expand the fixture during development:
59
+
60
+ ```sh
61
+ LLMNAV_BENCH_FILES=500 LLMNAV_BENCH_QUERY_RUNS=5 npm run benchmark:v0.2
62
+ ```
63
+
64
+ Published repository results use the defaults. The report states that each query starts a fresh Node.js process and that the operating-system filesystem cache is not flushed. That distinction prevents a warm page cache from being mislabeled as cold disk I/O.
65
+
66
+ ## Measurement integrity
67
+
68
+ A benchmark result is accepted only after these checks pass:
69
+
70
+ ```text
71
+ legacy expected result count equals query count
72
+ inverted expected result count equals query count
73
+ legacy and inverted result checksums match
74
+ incremental and full generated cache trees are byte-identical
75
+ reported fixture cardinality matches generated files and cards
76
+ ```
77
+
78
+ Wall-clock speed is reported exactly as measured. It is not used to invent a speedup estimate for other hardware.
79
+
80
+ ## Repository search evaluation
81
+
82
+ Add real task descriptions to `.llmnav/eval/queries.jsonl`.
83
+
84
+ ```jsonl
85
+ {"query":"duplicate webhook applies payment twice","expected":["billing.payment.apply-provider-event"]}
86
+ {"query":"same collapse seed produces a different arena","expected":["game.arena.collapse-sequence"]}
87
+ ```
88
+
89
+ Run:
90
+
91
+ ```sh
92
+ npx llmnav eval --json
93
+ ```
94
+
95
+ Track at least Recall@1, Recall@5, and mean reciprocal rank. Record every acceptable target ID when a task has multiple valid entry points.
96
+
97
+ ## End-to-end agent metrics
98
+
99
+ A successful deployment should reduce exploration cost without reducing task correctness.
100
+
101
+ | Metric | Meaning |
102
+ | --- | --- |
103
+ | first correct source time | elapsed time until the agent opens the right declaration |
104
+ | files opened | breadth of repository exploration |
105
+ | search tool calls | grep, glob, tree, language-server, and LLMNav calls |
106
+ | source lines read | code inserted into model context |
107
+ | uncached input tokens | new model input processed for the task |
108
+ | token cache ratio | cached input divided by total input |
109
+ | task success | tests and acceptance criteria pass |
110
+ | wrong-edit rate | edits made in an irrelevant boundary |
111
+
112
+ A request-level cache hit is not enough. Track cached tokens and uncached tokens separately.
113
+
114
+ ## Experimental groups
115
+
116
+ Compare three configurations.
117
+
118
+ | Group | Configuration |
119
+ | --- | --- |
120
+ | `baseline` | current agent instructions and search tools |
121
+ | `comments-only` | source cards without generated query or catalog tools |
122
+ | `full` | cards, generated catalogs, inverted query, bounded context, and stable prompt placement |
123
+
124
+ The comments-only group exposes designs that merely add prompt tokens without improving navigation.
125
+
126
+ ## Task set and repetition
127
+
128
+ Use 30 to 50 historical tasks when possible. Mix bug fixes, feature additions, API changes, refactors, performance work, test failures, migrations, and cross-module workflows.
129
+
130
+ Agent execution is variable. Repeat tasks with the same model, reasoning configuration, tools, repository state, and timeout policy. Report medians and failure ranges rather than one favorable run.
131
+
132
+ ## Initial deployment gates
133
+
134
+ These are targets to validate per repository, not measured package guarantees.
135
+
136
+ | Metric | Initial target |
137
+ | --- | ---: |
138
+ | Recall@1 | at least 0.75 |
139
+ | Recall@5 | at least 0.90 |
140
+ | median first correct symbol calls | at most 2 navigation calls |
141
+ | median files opened | at most 4 |
142
+ | uncached input tokens | at least 40% below baseline |
143
+ | first correct symbol time | at least 35% below baseline |
144
+ | task success | no decrease from baseline |
145
+ | stale semantic metadata failures | zero |
146
+
147
+ ## Failure analysis
148
+
149
+ Classify every miss before changing ranking weights.
150
+
151
+ ```text
152
+ missing card
153
+ weak or generic role
154
+ missing task-language alias
155
+ overloaded search phrase
156
+ wrong module boundary
157
+ missing semantic relation
158
+ declaration attachment failure
159
+ generated cache stale
160
+ lexical ranker limitation
161
+ task legitimately requires broader structural analysis
162
+ ```
163
+
164
+ Only measured lexical failures justify adding a more complex retrieval layer.
package/docs/ci.md ADDED
@@ -0,0 +1,196 @@
1
+ # CI and enforcement
2
+
3
+ ## Consumer repository gates
4
+
5
+ A practical LLMNav gate has four stages.
6
+
7
+ ```sh
8
+ npx llmnav format --check
9
+ npx llmnav check --format github
10
+ npx llmnav generate --full --check
11
+ npx llmnav eval
12
+ ```
13
+
14
+ `format --check` rejects non-canonical source-card serialization.
15
+
16
+ `check` rejects invalid meaning, unresolved or retired semantic relations, malformed registry state, missing configured coverage, path escape, and declaration attachment failures.
17
+
18
+ Use `npx llmnav check --format sarif > llmnav.sarif` when a code-scanning system accepts SARIF 2.1.0 rather than GitHub workflow annotations. SARIF output is deterministic for the same ordered diagnostics and uses repository-relative paths.
19
+
20
+ `generate --full --check` performs a read-only reconstruction from canonical source and rejects stale or poisoned primary indexes, inverted indexes, file state, graph state, manifests, and catalogs. Use plain incremental generation during local iteration; release and CI gates should not trust disposable accelerators.
21
+
22
+ `eval` catches ranking regressions that remain syntactically valid.
23
+
24
+ ## Machine-readable impact gate
25
+
26
+ CI or an agent orchestrator can inspect one generation result without parsing terminal text.
27
+
28
+ ```sh
29
+ npx llmnav generate --json > llmnav-generation.json
30
+ ```
31
+
32
+ Useful fields are:
33
+
34
+ ```text
35
+ changedFiles
36
+ changedCards[].id
37
+ changedCards[].change
38
+ changedCards[].dimensions
39
+ affectedCatalogs[].kind
40
+ affectedCatalogs[].id
41
+ incremental.files.parsedFiles
42
+ incremental.cards.indexedCards
43
+ incremental.graph.rebuiltPartitions
44
+ transaction.recovered
45
+ transaction.recoveryAction
46
+ ```
47
+
48
+ Array order is deterministic. A policy can require review when `semantic` changes occur in `auth`, `money`, or `privacy` cards while allowing body-only changes to proceed normally.
49
+
50
+ ## Included GitHub Actions workflow
51
+
52
+ This repository's `.github/workflows/ci.yml` executes:
53
+
54
+ | Operating system | Node.js |
55
+ | --- | --- |
56
+ | Ubuntu | 22, 24 |
57
+ | Windows | 22, 24 |
58
+
59
+ Every matrix entry runs linting, all tests, source-card validation, and generated-cache verification. Node.js 22 entries also install the actual npm tarball into a clean project and run initialization, generation, query, validation, verification, and doctor commands.
60
+
61
+ The Windows matrix is required because directory rename, file locking, process interruption, and executable shims differ materially from Linux.
62
+
63
+ A smaller consumer workflow can use:
64
+
65
+ ```yaml
66
+ name: LLMNav
67
+
68
+ on:
69
+ pull_request:
70
+ push:
71
+ branches: [main]
72
+
73
+ jobs:
74
+ llmnav:
75
+ runs-on: ubuntu-latest
76
+ steps:
77
+ - uses: actions/checkout@v7
78
+ - uses: actions/setup-node@v7
79
+ with:
80
+ node-version: 24
81
+ cache: npm
82
+ - run: npm ci
83
+ - run: npx llmnav format --check
84
+ - run: npx llmnav check --format github
85
+ - run: npx llmnav generate --full --check
86
+ - run: npx llmnav eval
87
+ ```
88
+
89
+ Repositories that depend on Windows development should add a `windows-latest` job rather than assuming cache replacement behaves identically.
90
+
91
+ ## Transaction failure regression
92
+
93
+ The repository test suite injects failures at several transaction phases:
94
+
95
+ ```text
96
+ after writing a staged artifact, before a journal exists
97
+ after moving the previous cache to backup
98
+ after installing a new cache, before commit
99
+ ```
100
+
101
+ The assertions compare the restored `index.json`, ID registry, and stable order with their previous bytes, prove concurrent writers serialize, and prove a query waits instead of rolling back an active writer. Transient Windows error codes `EACCES`, `EBUSY`, `EEXIST`, `ENOTEMPTY`, and `EPERM` are injected into rename operations to verify bounded retries.
102
+
103
+ These tests are not a substitute for the Windows CI runner. They make exact phases reproducible on every platform, while the matrix executes the same filesystem workflow on Windows.
104
+
105
+ ## Performance regression gates
106
+
107
+ `tests/performance.test.js` uses a 5,000-card synthetic index and compares the v0.2 prepared search path with the v0.1-compatible legacy path.
108
+
109
+ The test requires:
110
+
111
+ * every query to return the expected first card
112
+ * complete result checksum equality between search paths
113
+ * v0.2 elapsed time below the legacy elapsed time in the isolated query loop
114
+ * generated search index below the configured size limit
115
+ * RSS and heap use below configured limits
116
+
117
+ `tests/incremental.test.js` uses a multi-file source fixture and requires:
118
+
119
+ * no-op generation to parse zero files when stat hints match
120
+ * a one-file edit to parse exactly one file
121
+ * one-card semantic change to retokenize exactly one card
122
+ * full and incremental output to be byte-identical
123
+ * graph and graph-state output to be byte-identical after partition reuse
124
+
125
+ The standalone `npm run benchmark:v0.2` command records timings but is not a hard CI gate because shared runner variance is too high. Its raw JSON and generated Markdown report preserve the exact environment and fixture.
126
+
127
+ ## npm package gate
128
+
129
+ ```sh
130
+ npm run smoke:pack
131
+ ```
132
+
133
+ The smoke test creates the actual npm tarball, installs it in a clean temporary project, confirms zero runtime dependencies, and executes the installed `bin/llmnav.js` rather than importing source from the working tree.
134
+
135
+ This catches missing files in the package allowlist, broken executable paths, stale type or schema payloads, and package-only initialization failures.
136
+
137
+ ## Coverage rules
138
+
139
+ LLMNav does not force every source file to contain a card. Repositories define boundaries that must be covered.
140
+
141
+ ```json
142
+ {
143
+ "coverageRules": [
144
+ {
145
+ "name": "HTTP entry points",
146
+ "match": ["src/routes/**/*.ts", "src/api/**/*.ts"],
147
+ "scope": "file",
148
+ "requiredFields": ["effect", "stability"]
149
+ },
150
+ {
151
+ "name": "database migrations",
152
+ "match": ["migrations/**/*.sql"],
153
+ "scope": "file",
154
+ "requiredFields": ["invariant", "risk"]
155
+ }
156
+ ]
157
+ }
158
+ ```
159
+
160
+ Do not add a broad `src/**/*.ts` rule. It converts a selective navigation protocol into mandatory comment noise.
161
+
162
+ ## Diagnostic policy
163
+
164
+ Errors block generation. Warnings do not block `check` by default.
165
+
166
+ | Code | Meaning |
167
+ | --- | --- |
168
+ | `LNV001` | required card or field missing |
169
+ | `LNV002` | duplicate, invalid, retired, or conflicting ID |
170
+ | `LNV003` | volatile data stored in a source card |
171
+ | `LNV004` | generated structural relation maintained by hand |
172
+ | `LNV005` | invalid key or controlled value |
173
+ | `LNV006` | weak or oversized role |
174
+ | `LNV007` | search phrase quality, count, or saturation failure |
175
+ | `LNV008` | unresolved semantic relation |
176
+ | `LNV009` | exported API or effective configuration fingerprint drift |
177
+ | `LNV010` | non-canonical or stale generated representation |
178
+ | `LNV011` | parser or declaration attachment failure |
179
+ | `LNV012` | deleted or renamed ID lacks lifecycle handling |
180
+ | `LNV013` | card or repository comment budget exceeded |
181
+ | `LNV014` | generated graph input is missing, malformed, unsafe, or incompatible |
182
+ | `LNV014` | search regression gate failure |
183
+
184
+ ## Pull-request review
185
+
186
+ Review semantic card changes as contract changes, not harmless comments. A useful PR report is the JSON output from generation plus evaluation results.
187
+
188
+ Body-only changes should not force semantic text edits. Conversely, a changed invariant or externally visible role should not be hidden inside a body-only diff.
189
+
190
+ ## Generated files
191
+
192
+ Commit `.llmnav/cache`. It is consumed by agents, diffable during review, and verified deterministically.
193
+
194
+ Do not commit `.llmnav/state`, `.llmnav/.transactions`, `.llmnav/generation.lock`, or `.llmnav/generation-transaction.json`. They contain volatile acceleration, ownership, or interrupted-operation state.
195
+
196
+ Do not manually edit generated cache files. Manual edits fail manifest or generation verification and are replaced on the next successful transaction.
package/docs/cli.md ADDED
@@ -0,0 +1,233 @@
1
+ # CLI reference
2
+
3
+ ## Global behavior
4
+
5
+ Repository commands accept `--root <path>`. Without it, the CLI searches ancestors for `.llmnav`; when none exists, it falls back to the nearest `package.json` or `.git` boundary. The repository-independent `tools` command does not accept a root.
6
+
7
+ Commands with structured results accept `--json`.
8
+
9
+ | Status | Meaning |
10
+ | ---: | --- |
11
+ | 0 | success |
12
+ | 1 | validation, generation, evaluation, integrity, or lookup failure |
13
+ | 2 | invalid command usage |
14
+ | 86 | test-only injected process interruption during a cache transaction |
15
+
16
+ Unknown options, missing option values, and invalid integer values fail instead of being ignored.
17
+
18
+ ## `llmnav init`
19
+
20
+ ```sh
21
+ llmnav init [--agents <adapters>] [--package-scripts] [--force]
22
+ ```
23
+
24
+ Creates project configuration, schema, registry, lexicon, evaluation file, agent protocol, deterministic cache, volatile state ignore rules, and transaction ignore rules.
25
+
26
+ `--agents` accepts `agents`, `claude`, `copilot`, `cursor`, a comma-separated combination, `all`, or `none`. The default is `agents`.
27
+
28
+ `--package-scripts` adds `llmnav:check`, `llmnav:format`, `llmnav:generate`, and `llmnav:eval` to an existing package.json.
29
+
30
+ `--force` refreshes configuration templates, schema, managed agent blocks, and `.llmnav/.gitignore`. It never resets semantic ID history, catalog order, aliases, evaluation cases, or source cards.
31
+
32
+ ## `llmnav check`
33
+
34
+ ```sh
35
+ llmnav check [paths...] [--format text|json|github|sarif|editor]
36
+ ```
37
+
38
+ Validates syntax, canonical key order, required fields, IDs, role quality, search phrase limits, controlled effects and risks, relation targets, registry consistency, configured coverage, block size, comment ratio, and symbol attachment.
39
+
40
+ Passing paths restricts source parsing, but project-level relation and registry checks are most reliable on a full scan.
41
+
42
+ `--format github` emits workflow commands suitable for GitHub Actions annotations.
43
+
44
+ `--format sarif` emits a deterministic SARIF 2.1.0 log with one rule per LLMNav diagnostic code and repository-relative artifact locations. The command exit status still depends on LLMNav errors, not on the selected serialization.
45
+
46
+ `--format editor` emits schemaVersion 1 documents with repository-relative paths, zero-based ranges, numeric and textual severity, code, source, and message. Editors bind paths to workspace URIs themselves.
47
+
48
+ ## `llmnav format`
49
+
50
+ ```sh
51
+ llmnav format [paths...] [--check]
52
+ ```
53
+
54
+ Canonicalizes key order, list serialization, spacing, and terminators. The formatter refuses to rewrite malformed cards, unknown fields, overlapping blocks, or duplicate scalar fields.
55
+
56
+ `--check` reports files that would change and exits with status 1 without writing.
57
+
58
+ ## `llmnav generate`
59
+
60
+ ```sh
61
+ llmnav generate [--check] [--full] [--json]
62
+ llmnav index [--check] [--full] [--json]
63
+ ```
64
+
65
+ `index` remains an alias for `generate`.
66
+
67
+ Generation performs these operations:
68
+
69
+ 1. Recover an interrupted cache transaction when a journal exists.
70
+ 2. Reuse unchanged parsed files from `file-state.json`.
71
+ 3. Parse changed files and validate the complete project.
72
+ 4. Reuse unchanged card search documents from `search-index.json`.
73
+ 5. Build every deterministic artifact in memory.
74
+ 6. Write and verify a complete staging cache.
75
+ 7. Replace the live cache through a recoverable directory transaction.
76
+ 8. Persist volatile stat hints after the deterministic cache commits.
77
+
78
+ `--check`, also accepted as `--verify`, performs no writes and fails when generated artifacts differ. It still validates whether a pending transaction must be recovered before reading the cache.
79
+
80
+ `--full` bypasses `file-state.json`, `search-index.json`, and `graph-state.json` accelerators and rebuilds every derived artifact from canonical source. CI, release, and trust-boundary verification should use `--full --check`; incremental mode remains the default for local iteration.
81
+
82
+ Generation stops before cache mutation when semantic validation contains errors.
83
+
84
+ ### JSON output
85
+
86
+ ```json
87
+ {
88
+ "ok": true,
89
+ "changedFiles": [],
90
+ "changedCards": [],
91
+ "affectedCatalogs": [],
92
+ "incremental": {
93
+ "enabled": true,
94
+ "files": {
95
+ "totalFiles": 120,
96
+ "parsedFiles": 1,
97
+ "reusedFiles": 119,
98
+ "reusedFilesByStat": 119,
99
+ "reusedFilesByHash": 0,
100
+ "deletedFiles": 0,
101
+ "bytesRead": 824,
102
+ "cardsParsed": 2,
103
+ "cardsReused": 418
104
+ },
105
+ "cards": {
106
+ "totalCards": 420,
107
+ "reusedCards": 419,
108
+ "indexedCards": 1,
109
+ "removedCards": 0,
110
+ "changedIds": ["billing.credit.reserve"],
111
+ "removedIds": []
112
+ },
113
+ "graph": {
114
+ "totalPartitions": 420,
115
+ "reusedPartitions": 419,
116
+ "rebuiltPartitions": 1,
117
+ "removedPartitions": 0
118
+ }
119
+ },
120
+ "transaction": {
121
+ "committed": true,
122
+ "skipped": false,
123
+ "recovered": false,
124
+ "recoveryAction": "none"
125
+ },
126
+ "diagnostics": []
127
+ }
128
+ ```
129
+
130
+ `changedCards` is sorted by semantic ID. Each record identifies `added`, `modified`, or `removed` and lists changed `semantic`, `structure`, and `body` hash dimensions.
131
+
132
+ `affectedCatalogs` contains only repository, module, agent-context, or prompt-prefix catalogs whose generated bytes changed. Generic cache files remain visible through `changedFiles`.
133
+
134
+ A no-op generation returns zero parsed files, zero indexed cards, and `transaction.skipped=true` when volatile stat hints are available and current.
135
+
136
+ ## `llmnav query`
137
+
138
+ ```sh
139
+ llmnav query "<task language>" [--top <n>] [--json]
140
+ ```
141
+
142
+ Ranks cards using exact ID matching, multilingual aliases, pre-tokenized deterministic posting lists, inverse document frequency, exact phrase bonuses, and one-hop semantic relation expansion.
143
+
144
+ Only query text is tokenized per invocation. Card fields are read from `search-index.json`. A missing or incompatible search index is rebuilt in memory from the v0.1-compatible `index.json`.
145
+
146
+ The ranker uses no network calls, embeddings, model API, MCP server, or hosted service. `--top` is bounded from 1 to 100.
147
+
148
+ Before reading the cache, `query` waits for an active generation lock and then recovers an abandoned transaction if necessary. It never rolls back a live writer or observes an uncommitted cache as authoritative.
149
+
150
+ ## `llmnav show`
151
+
152
+ ```sh
153
+ llmnav show <semantic-id> [--json]
154
+ ```
155
+
156
+ Prints one compact card. Redirected registry IDs resolve to their active target. Qualified and unique external workspace IDs resolve to generated graph definitions when no local card exists. Ambiguous unqualified workspace IDs fail and report the qualified candidates.
157
+
158
+ ## `llmnav context`
159
+
160
+ ```sh
161
+ llmnav context <semantic-id> [--depth <n>] [--budget <tokens>] [--max-edges <n>] [--json]
162
+ ```
163
+
164
+ Resolves redirected IDs, traverses confidence-ordered outgoing and incoming graph edges breadth-first, and emits cards until the approximate token budget is reached. `--max-edges` defaults to 24 and can be set to zero to disable graph edge traversal. When no compatible graph is available, source-card semantic relations remain the fallback.
165
+
166
+ Depth defaults to 1 and is bounded from 0 to 8. Budget defaults to 2,500 approximate tokens and is bounded from 128 to 100,000. The root card is retained even when it must be truncated.
167
+
168
+ ## `llmnav eval`
169
+
170
+ ```sh
171
+ llmnav eval [--file <queries.jsonl>] [--top <n>] [--json]
172
+ ```
173
+
174
+ Runs records in this format:
175
+
176
+ ```json
177
+ {"query":"task language","expected":["one.id","another.id"]}
178
+ ```
179
+
180
+ Reports Recall@1, Recall@5, and mean reciprocal rank. Gates come from `.llmnav/config.json`. The selected query file must remain inside the repository and cannot traverse a symbolic link.
181
+
182
+ An empty query file succeeds with zero metrics. It is not evidence of search quality.
183
+
184
+ ## `llmnav doctor`
185
+
186
+ ```sh
187
+ llmnav doctor [--json]
188
+ ```
189
+
190
+ Checks:
191
+
192
+ * configuration and Node.js version
193
+ * interrupted transaction recovery
194
+ * required control and generated files
195
+ * primary index and inverted-index consistency
196
+ * file-state schema compatibility
197
+ * manifest hashes
198
+ * generated-file drift against a full source rebuild
199
+ * unreplaced release metadata in the LLMNav repository itself
200
+
201
+ `doctor` may perform transaction recovery, but it does not regenerate stale cache content.
202
+
203
+ ## `llmnav spec`
204
+
205
+ ```sh
206
+ llmnav spec [--json]
207
+ ```
208
+
209
+ Prints the active source specification version, canonical key order, stability values, effect vocabulary, risk vocabulary, and semantic relation types. The package version is separate from the `llmnav/1` source grammar version.
210
+
211
+ ## `llmnav tools`
212
+
213
+ ```sh
214
+ llmnav tools [--json]
215
+ ```
216
+
217
+ Prints the fixed provider-neutral tool definitions for `query`, `show`, `context`, and `check`. JSON output wraps the ordered definitions in a schemaVersion 1 object. Tool inputs reject unknown fields and never accept a repository root; a trusted host binds repository scope when it calls the library dispatcher.
218
+
219
+ ## `llmnav bundle`
220
+
221
+ ```sh
222
+ llmnav bundle [--json]
223
+ ```
224
+
225
+ Loads `.llmnav/cache/prompt-prefix.json`, rejects incompatible or manifest-mismatched content, and prints its package, repository, and module cache partitions. Text output is a compact ID, scope, estimated-token, and hash summary. JSON output returns the complete deterministic bundle including partition content.
226
+
227
+ ## `llmnav editor`
228
+
229
+ ```sh
230
+ llmnav editor vscode
231
+ ```
232
+
233
+ Prints a schemaVersion 1 editor integration envelope containing a VS Code `tasks.json` configuration. The command is repository-independent and does not write `.vscode` files. Merge the returned task into an existing configuration when necessary.