@vibe-agent-toolkit/cli 0.2.0-rc.2 → 0.2.0-rc.4

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 (211) hide show
  1. package/dist/bin/vat +68 -16
  2. package/dist/bin/vat.js +68 -16
  3. package/dist/bin/vat.js.map +1 -1
  4. package/dist/bin.js +157 -37
  5. package/dist/bin.js.map +1 -1
  6. package/dist/command-loaders.d.ts +44 -0
  7. package/dist/command-loaders.d.ts.map +1 -0
  8. package/dist/command-loaders.js +58 -0
  9. package/dist/command-loaders.js.map +1 -0
  10. package/dist/commands/agent/index.js +1 -1
  11. package/dist/commands/agent/install.d.ts.map +1 -1
  12. package/dist/commands/agent/install.js +46 -5
  13. package/dist/commands/agent/install.js.map +1 -1
  14. package/dist/commands/audit/distributed-tree.d.ts +2 -2
  15. package/dist/commands/audit/distributed-tree.d.ts.map +1 -1
  16. package/dist/commands/audit/distributed-tree.js +2 -1
  17. package/dist/commands/audit/distributed-tree.js.map +1 -1
  18. package/dist/commands/audit/git-url-clone.d.ts +1 -1
  19. package/dist/commands/audit/git-url-clone.d.ts.map +1 -1
  20. package/dist/commands/audit/git-url-clone.js.map +1 -1
  21. package/dist/commands/audit/hierarchical-output.d.ts +1 -1
  22. package/dist/commands/audit/hierarchical-output.d.ts.map +1 -1
  23. package/dist/commands/audit/hierarchical-output.js +1 -1
  24. package/dist/commands/audit/hierarchical-output.js.map +1 -1
  25. package/dist/commands/audit.d.ts +22 -1
  26. package/dist/commands/audit.d.ts.map +1 -1
  27. package/dist/commands/audit.js +224 -24
  28. package/dist/commands/audit.js.map +1 -1
  29. package/dist/commands/build.d.ts +1 -1
  30. package/dist/commands/build.d.ts.map +1 -1
  31. package/dist/commands/build.js +15 -12
  32. package/dist/commands/build.js.map +1 -1
  33. package/dist/commands/cache/cache-control.d.ts +82 -0
  34. package/dist/commands/cache/cache-control.d.ts.map +1 -0
  35. package/dist/commands/cache/cache-control.js +86 -0
  36. package/dist/commands/cache/cache-control.js.map +1 -0
  37. package/dist/commands/cache/clear.d.ts +17 -3
  38. package/dist/commands/cache/clear.d.ts.map +1 -1
  39. package/dist/commands/cache/clear.js +68 -3
  40. package/dist/commands/cache/clear.js.map +1 -1
  41. package/dist/commands/cache/index.d.ts +13 -63
  42. package/dist/commands/cache/index.d.ts.map +1 -1
  43. package/dist/commands/cache/index.js +38 -79
  44. package/dist/commands/cache/index.js.map +1 -1
  45. package/dist/commands/claude/budget.d.ts +157 -0
  46. package/dist/commands/claude/budget.d.ts.map +1 -0
  47. package/dist/commands/claude/budget.js +412 -0
  48. package/dist/commands/claude/budget.js.map +1 -0
  49. package/dist/commands/claude/context.d.ts +340 -0
  50. package/dist/commands/claude/context.d.ts.map +1 -0
  51. package/dist/commands/claude/context.js +1079 -0
  52. package/dist/commands/claude/context.js.map +1 -0
  53. package/dist/commands/claude/index.d.ts +13 -0
  54. package/dist/commands/claude/index.d.ts.map +1 -1
  55. package/dist/commands/claude/index.js +24 -2
  56. package/dist/commands/claude/index.js.map +1 -1
  57. package/dist/commands/claude/marketplace/git-publish.d.ts.map +1 -1
  58. package/dist/commands/claude/marketplace/git-publish.js +18 -19
  59. package/dist/commands/claude/marketplace/git-publish.js.map +1 -1
  60. package/dist/commands/claude/marketplace/validate.d.ts +19 -1
  61. package/dist/commands/claude/marketplace/validate.d.ts.map +1 -1
  62. package/dist/commands/claude/marketplace/validate.js +41 -21
  63. package/dist/commands/claude/marketplace/validate.js.map +1 -1
  64. package/dist/commands/claude/plugin/build.d.ts +18 -2
  65. package/dist/commands/claude/plugin/build.d.ts.map +1 -1
  66. package/dist/commands/claude/plugin/build.js +55 -18
  67. package/dist/commands/claude/plugin/build.js.map +1 -1
  68. package/dist/commands/claude/plugin/helpers.d.ts.map +1 -1
  69. package/dist/commands/claude/plugin/helpers.js +2 -1
  70. package/dist/commands/claude/plugin/helpers.js.map +1 -1
  71. package/dist/commands/claude/plugin/install.d.ts.map +1 -1
  72. package/dist/commands/claude/plugin/install.js +24 -3
  73. package/dist/commands/claude/plugin/install.js.map +1 -1
  74. package/dist/commands/claude/plugin/tree-copy.d.ts.map +1 -1
  75. package/dist/commands/claude/plugin/tree-copy.js +2 -1
  76. package/dist/commands/claude/plugin/tree-copy.js.map +1 -1
  77. package/dist/commands/consistency-check.d.ts.map +1 -1
  78. package/dist/commands/consistency-check.js +4 -3
  79. package/dist/commands/consistency-check.js.map +1 -1
  80. package/dist/commands/corpus/report.d.ts +1 -1
  81. package/dist/commands/corpus/report.d.ts.map +1 -1
  82. package/dist/commands/corpus/runner.d.ts.map +1 -1
  83. package/dist/commands/corpus/runner.js +3 -2
  84. package/dist/commands/corpus/runner.js.map +1 -1
  85. package/dist/commands/corpus/scan.d.ts.map +1 -1
  86. package/dist/commands/corpus/scan.js +18 -8
  87. package/dist/commands/corpus/scan.js.map +1 -1
  88. package/dist/commands/doctor.d.ts +36 -0
  89. package/dist/commands/doctor.d.ts.map +1 -1
  90. package/dist/commands/doctor.js +99 -2
  91. package/dist/commands/doctor.js.map +1 -1
  92. package/dist/commands/inventory.d.ts +13 -1
  93. package/dist/commands/inventory.d.ts.map +1 -1
  94. package/dist/commands/inventory.js +118 -13
  95. package/dist/commands/inventory.js.map +1 -1
  96. package/dist/commands/mcp/collections.d.ts +1 -1
  97. package/dist/commands/mcp/collections.d.ts.map +1 -1
  98. package/dist/commands/phase-utils.d.ts +155 -104
  99. package/dist/commands/phase-utils.d.ts.map +1 -1
  100. package/dist/commands/phase-utils.js +109 -155
  101. package/dist/commands/phase-utils.js.map +1 -1
  102. package/dist/commands/rag/index-command.d.ts +39 -0
  103. package/dist/commands/rag/index-command.d.ts.map +1 -1
  104. package/dist/commands/rag/index-command.js +28 -2
  105. package/dist/commands/rag/index-command.js.map +1 -1
  106. package/dist/commands/rag/index.d.ts.map +1 -1
  107. package/dist/commands/rag/index.js +21 -10
  108. package/dist/commands/rag/index.js.map +1 -1
  109. package/dist/commands/resources/index.d.ts.map +1 -1
  110. package/dist/commands/resources/index.js +10 -2
  111. package/dist/commands/resources/index.js.map +1 -1
  112. package/dist/commands/resources/scan.d.ts +24 -0
  113. package/dist/commands/resources/scan.d.ts.map +1 -1
  114. package/dist/commands/resources/scan.js +19 -6
  115. package/dist/commands/resources/scan.js.map +1 -1
  116. package/dist/commands/resources/validate.d.ts +12 -1
  117. package/dist/commands/resources/validate.d.ts.map +1 -1
  118. package/dist/commands/resources/validate.js +102 -51
  119. package/dist/commands/resources/validate.js.map +1 -1
  120. package/dist/commands/skill/review-checklist.d.ts.map +1 -1
  121. package/dist/commands/skill/review-checklist.js +1 -0
  122. package/dist/commands/skill/review-checklist.js.map +1 -1
  123. package/dist/commands/skill/review.js +2 -2
  124. package/dist/commands/skill/review.js.map +1 -1
  125. package/dist/commands/skill/test/configure.d.ts +19 -0
  126. package/dist/commands/skill/test/configure.d.ts.map +1 -1
  127. package/dist/commands/skill/test/configure.js +18 -3
  128. package/dist/commands/skill/test/configure.js.map +1 -1
  129. package/dist/commands/skill/test/run.d.ts +51 -4
  130. package/dist/commands/skill/test/run.d.ts.map +1 -1
  131. package/dist/commands/skill/test/run.js +123 -12
  132. package/dist/commands/skill/test/run.js.map +1 -1
  133. package/dist/commands/skills/build.d.ts +11 -1
  134. package/dist/commands/skills/build.d.ts.map +1 -1
  135. package/dist/commands/skills/build.js +154 -61
  136. package/dist/commands/skills/build.js.map +1 -1
  137. package/dist/commands/skills/package.d.ts +1 -1
  138. package/dist/commands/skills/package.d.ts.map +1 -1
  139. package/dist/commands/skills/package.js.map +1 -1
  140. package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
  141. package/dist/commands/skills/skill-discovery.js +2 -1
  142. package/dist/commands/skills/skill-discovery.js.map +1 -1
  143. package/dist/commands/skills/validate.d.ts +79 -2
  144. package/dist/commands/skills/validate.d.ts.map +1 -1
  145. package/dist/commands/skills/validate.js +101 -48
  146. package/dist/commands/skills/validate.js.map +1 -1
  147. package/dist/commands/validate.d.ts.map +1 -1
  148. package/dist/commands/validate.js +26 -16
  149. package/dist/commands/validate.js.map +1 -1
  150. package/dist/commands/verify.d.ts +11 -10
  151. package/dist/commands/verify.d.ts.map +1 -1
  152. package/dist/commands/verify.js +49 -38
  153. package/dist/commands/verify.js.map +1 -1
  154. package/dist/utils/command-error.d.ts +33 -2
  155. package/dist/utils/command-error.d.ts.map +1 -1
  156. package/dist/utils/command-error.js +34 -10
  157. package/dist/utils/command-error.js.map +1 -1
  158. package/dist/utils/config-loader.d.ts.map +1 -1
  159. package/dist/utils/config-loader.js +7 -1
  160. package/dist/utils/config-loader.js.map +1 -1
  161. package/dist/utils/context-budget-issues.d.ts +108 -0
  162. package/dist/utils/context-budget-issues.d.ts.map +1 -0
  163. package/dist/utils/context-budget-issues.js +280 -0
  164. package/dist/utils/context-budget-issues.js.map +1 -0
  165. package/dist/utils/corpus-target.d.ts +48 -0
  166. package/dist/utils/corpus-target.d.ts.map +1 -0
  167. package/dist/utils/corpus-target.js +61 -0
  168. package/dist/utils/corpus-target.js.map +1 -0
  169. package/dist/utils/issue-anchor.d.ts +2 -2
  170. package/dist/utils/issue-anchor.d.ts.map +1 -1
  171. package/dist/utils/issue-anchor.js +1 -1
  172. package/dist/utils/issue-rendering.d.ts +1 -1
  173. package/dist/utils/issue-rendering.d.ts.map +1 -1
  174. package/dist/utils/issue-rendering.js +1 -1
  175. package/dist/utils/issue-rendering.js.map +1 -1
  176. package/dist/utils/issue-severity.d.ts +1 -1
  177. package/dist/utils/issue-severity.d.ts.map +1 -1
  178. package/dist/utils/issue-severity.js +1 -1
  179. package/dist/utils/issue-severity.js.map +1 -1
  180. package/dist/utils/optional-backend.d.ts +77 -0
  181. package/dist/utils/optional-backend.d.ts.map +1 -0
  182. package/dist/utils/optional-backend.js +115 -0
  183. package/dist/utils/optional-backend.js.map +1 -0
  184. package/dist/utils/output.d.ts +17 -0
  185. package/dist/utils/output.d.ts.map +1 -1
  186. package/dist/utils/output.js +19 -0
  187. package/dist/utils/output.js.map +1 -1
  188. package/dist/utils/population-wiring.d.ts +100 -0
  189. package/dist/utils/population-wiring.d.ts.map +1 -0
  190. package/dist/utils/population-wiring.js +98 -0
  191. package/dist/utils/population-wiring.js.map +1 -0
  192. package/dist/utils/projection-store.d.ts +188 -0
  193. package/dist/utils/projection-store.d.ts.map +1 -0
  194. package/dist/utils/projection-store.js +257 -0
  195. package/dist/utils/projection-store.js.map +1 -0
  196. package/dist/utils/resource-loader.d.ts +128 -2
  197. package/dist/utils/resource-loader.d.ts.map +1 -1
  198. package/dist/utils/resource-loader.js +234 -7
  199. package/dist/utils/resource-loader.js.map +1 -1
  200. package/dist/utils/verdict-helpers.d.ts +1 -1
  201. package/dist/utils/verdict-helpers.d.ts.map +1 -1
  202. package/dist/utils/verdict-helpers.js +1 -1
  203. package/dist/utils/verdict-helpers.js.map +1 -1
  204. package/docs/agent.md +2 -2
  205. package/docs/mcp.md +2 -2
  206. package/docs/resources.md +8 -1
  207. package/package.json +15 -12
  208. package/dist/commands/resources/command-helpers.d.ts +0 -5
  209. package/dist/commands/resources/command-helpers.d.ts.map +0 -1
  210. package/dist/commands/resources/command-helpers.js +0 -6
  211. package/dist/commands/resources/command-helpers.js.map +0 -1
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Lazy loading for **optional heavy backends** — the seam that keeps a
3
+ * multi-hundred-megabyte dependency out of every other command's cost.
4
+ *
5
+ * ## Why this exists rather than four `await import()` calls
6
+ *
7
+ * `@vibe-agent-toolkit/rag-lancedb` pulls a platform-native LanceDB binary
8
+ * (119.6 MiB unpacked on `win32-x64`, 40.3 MiB compressed to download) plus
9
+ * `onnxruntime-web` (133 MB) and `gpt-tokenizer` (44 MB). Measured on the
10
+ * published `vibe-agent-toolkit@0.1.42`: **275 MB of a 351 MB install is the
11
+ * RAG lane**, and a static import chain from `bin.ts` meant
12
+ * `import('@lancedb/lancedb')` — **1,350 ms cold** — ran before `vat --version`
13
+ * could print a string. It is a named seam rather than a one-off fix because
14
+ * "optional backend" is a shape VAT keeps growing — a projection store is
15
+ * loaded through it too — not because any one dependency is special.
16
+ *
17
+ * ## What it does NOT do
18
+ *
19
+ * It does not fall back, retry, or degrade. An absent backend is a legible
20
+ * error naming the package to install, and nothing more — the point is that
21
+ * the failure is readable, not that it is survivable.
22
+ */
23
+ // Deliberately NOT `commands/rag/command-helpers.js`, which is where the rest
24
+ // of the rag lane's shared helpers live: that module statically imports
25
+ // `@vibe-agent-toolkit/rag-lancedb`, so reaching for its `handleCommandError`
26
+ // here would load the very backend this file exists to defer.
27
+ import { writeYamlOutput } from './output.js';
28
+ /**
29
+ * Node's code for "the module is genuinely not installed".
30
+ *
31
+ * Matched on `code`, never on the message: the message embeds the specifier and
32
+ * the importing file and is not a stable contract, while the code is. A miss
33
+ * here would be reported as a missing backend when the real cause was a syntax
34
+ * error *inside* the backend, which is the worst possible diagnosis.
35
+ */
36
+ const MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
37
+ /**
38
+ * Whether a thrown value is Node's "module not installed" error.
39
+ *
40
+ * Exported because every optional backend asks it, and a second copy would be
41
+ * free to drift onto the message.
42
+ *
43
+ * @param error - The thrown value
44
+ * @returns True when the module could not be resolved at all
45
+ */
46
+ export function isModuleMissing(error) {
47
+ return (typeof error === 'object'
48
+ && error !== null
49
+ && 'code' in error
50
+ && error.code === MODULE_NOT_FOUND);
51
+ }
52
+ /**
53
+ * Report an uninstalled backend and exit, in the shape every other command
54
+ * failure takes.
55
+ *
56
+ * Exit code **2** — a system error, not a validation failure. An absent
57
+ * optional package is a fact about the installation rather than about the
58
+ * user's corpus, and a caller scripting `vat` must be able to tell those apart
59
+ * from the exit code alone.
60
+ *
61
+ * Exported for the backends that are not selected by a Commander action —
62
+ * {@link lazyAction} is the shape most take, but a store chosen by an
63
+ * environment variable is loaded from inside a command rather than in place of
64
+ * one, and it must fail the same way.
65
+ *
66
+ * @param backend - What to name and how to install it
67
+ * @returns Never; the process exits
68
+ */
69
+ export function reportMissingBackend(backend) {
70
+ const install = `npm install ${backend.packageName}`;
71
+ process.stderr.write(`${backend.feature} is an optional feature and its backend is not installed.\n`
72
+ + `\nInstall it with: ${install}\n`
73
+ + '\nIt ships separately because it carries a platform-native binary that every\n'
74
+ + 'other vat command would otherwise download and load.\n');
75
+ writeYamlOutput({
76
+ status: 'error',
77
+ error: `${backend.feature} backend not installed: ${backend.packageName}`,
78
+ fix: install,
79
+ });
80
+ process.exit(2);
81
+ }
82
+ /**
83
+ * Bind a Commander action that loads its implementation on first invocation.
84
+ *
85
+ * The returned function has the same shape Commander expects, so a command
86
+ * declaration keeps every option, description and help block it had — only the
87
+ * *implementation* moves behind the `await`. Help text is static data and must
88
+ * stay eagerly available, which is exactly why the split is at the action
89
+ * rather than at the command.
90
+ *
91
+ * @param backend - What to name in the error when the import fails to resolve
92
+ * @param load - Imports the module and returns the handler out of it
93
+ * @returns A Commander action that loads, then delegates
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * .action(lazyAction(RAG_BACKEND, async () => (await import('./index-command.js')).indexCommand))
98
+ * ```
99
+ */
100
+ export function lazyAction(backend, load) {
101
+ return async (...args) => {
102
+ let handler;
103
+ try {
104
+ handler = await load();
105
+ }
106
+ catch (error) {
107
+ if (!isModuleMissing(error)) {
108
+ throw error;
109
+ }
110
+ reportMissingBackend(backend);
111
+ }
112
+ await handler(...args);
113
+ };
114
+ }
115
+ //# sourceMappingURL=optional-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optional-backend.js","sourceRoot":"","sources":["../../src/utils/optional-backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,8EAA8E;AAC9E,wEAAwE;AACxE,8EAA8E;AAC9E,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;;;;GAOG;AACH,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;AAEhD;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;WACtB,KAAK,KAAK,IAAI;WACd,MAAM,IAAI,KAAK;WACd,KAA4B,CAAC,IAAI,KAAK,gBAAgB,CAC3D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAwB;IAC3D,MAAM,OAAO,GAAG,eAAe,OAAO,CAAC,WAAW,EAAE,CAAC;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,OAAO,CAAC,OAAO,6DAA6D;UAC7E,uBAAuB,OAAO,IAAI;UAClC,gFAAgF;UAChF,wDAAwD,CAC3D,CAAC;IACF,eAAe,CAAC;QACd,MAAM,EAAE,OAAO;QACf,KAAK,EAAE,GAAG,OAAO,CAAC,OAAO,2BAA2B,OAAO,CAAC,WAAW,EAAE;QACzE,GAAG,EAAE,OAAO;KACb,CAAC,CAAC;IACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAUD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,UAAU,CACxB,OAAwB,EACxB,IAA+C;IAE/C,OAAO,KAAK,EAAE,GAAG,IAAU,EAAiB,EAAE;QAC5C,IAAI,OAA0C,CAAC;QAC/C,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,IAAI,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5B,MAAM,KAAK,CAAC;YACd,CAAC;YACD,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IACzB,CAAC,CAAC;AACJ,CAAC"}
@@ -76,6 +76,23 @@ export declare function writeAllSync(write: SyncWriter, buffer: Buffer, options?
76
76
  * @param data - Data to serialize as YAML
77
77
  */
78
78
  export declare function writeYamlOutput(data: unknown): void;
79
+ /**
80
+ * Write a single JSON document to stdout.
81
+ *
82
+ * The sibling of {@link writeYamlOutput}, for the same payloads, and it exists
83
+ * because a consumer that has to parse YAML needs a YAML parser: JSON is the
84
+ * format every language reads without one. `vat resources validate` already
85
+ * offers `--format json` for exactly this reason; a scan document that could
86
+ * only be had as YAML made the population it reports the harder of the two to
87
+ * consume programmatically, which is backwards.
88
+ *
89
+ * Written the same way as its YAML sibling, and the comment there applies
90
+ * verbatim: the ordinary stream write keeps this summary behind any
91
+ * human-readable progress already buffered on the same channel.
92
+ *
93
+ * @param data - Data to serialize as JSON
94
+ */
95
+ export declare function writeJsonOutput(data: unknown): void;
79
96
  /**
80
97
  * Write a test-format finding to stderr.
81
98
  *
@@ -1 +1 @@
1
- {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKrD;AAED;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAoCpF,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,CAAC,kBAAkB,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,mBAAwB,GAChC,IAAI,CA+BN;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAWnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,IAAI,CAEN"}
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKrD;AAED;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAoCpF,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,CAAC,kBAAkB,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,mBAAwB,GAChC,IAAI,CA+BN;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAWnD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAEnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,IAAI,CAEN"}
@@ -138,6 +138,25 @@ export function writeYamlOutput(data) {
138
138
  aliasDuplicateObjects: false,
139
139
  })}`);
140
140
  }
141
+ /**
142
+ * Write a single JSON document to stdout.
143
+ *
144
+ * The sibling of {@link writeYamlOutput}, for the same payloads, and it exists
145
+ * because a consumer that has to parse YAML needs a YAML parser: JSON is the
146
+ * format every language reads without one. `vat resources validate` already
147
+ * offers `--format json` for exactly this reason; a scan document that could
148
+ * only be had as YAML made the population it reports the harder of the two to
149
+ * consume programmatically, which is backwards.
150
+ *
151
+ * Written the same way as its YAML sibling, and the comment there applies
152
+ * verbatim: the ordinary stream write keeps this summary behind any
153
+ * human-readable progress already buffered on the same channel.
154
+ *
155
+ * @param data - Data to serialize as JSON
156
+ */
157
+ export function writeJsonOutput(data) {
158
+ process.stdout.write(`${JSON.stringify(data, null, 2)}\n`);
159
+ }
141
160
  /**
142
161
  * Write a test-format finding to stderr.
143
162
  *
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The three arguments every CLI lane hands a projection population builder the
3
+ * same way: the blob-stage observer, the ignore oracle, and the run's store.
4
+ *
5
+ * ## Why this is CLI code and not `resources` code
6
+ *
7
+ * Nothing here decides anything about a projection. The observer's whole body is
8
+ * `describeBlobRefusals` — owned by `@vibe-agent-toolkit/resources` — routed to a
9
+ * {@link Logger}, which is a CLI type no other package has; the two spreads exist
10
+ * only because `exactOptionalPropertyTypes` makes "absent" and "present and
11
+ * undefined" different arguments. That is command plumbing, in the same family as
12
+ * `projection-store.ts` next door, so it stays inside the package the CLI-stays-
13
+ * dumb rule allows it in.
14
+ *
15
+ * ## The observer is the reason this is shared rather than retyped
16
+ *
17
+ * `buildInventoryPopulation` and `buildClaudeContextPopulation` both REQUIRE
18
+ * `onBlobPopulation` — a caller with nothing to do with the counts must name
19
+ * `DISCARD_BLOB_POPULATION` rather than leave it off — because a tree whose every
20
+ * document was declined as binary otherwise populates as empty and reports
21
+ * success. Two hand-written copies of the reporting half is two places for that
22
+ * report to quietly become a no-op.
23
+ */
24
+ import { type BlobPopulationReport, type CollectionConfig, type PopulationCache } from '@vibe-agent-toolkit/resources';
25
+ import type { GitTracker } from '@vibe-agent-toolkit/utils/git';
26
+ import type { Logger } from './logger.js';
27
+ /**
28
+ * The population arguments {@link populationWiring} supplies.
29
+ *
30
+ * Spread into a builder's options object, so the three optional inputs are
31
+ * optional in the `exactOptionalPropertyTypes` sense — omitted entirely when
32
+ * they are absent, never present-and-undefined.
33
+ */
34
+ export interface PopulationWiring {
35
+ onBlobPopulation: (report: BlobPopulationReport) => void;
36
+ gitTracker?: GitTracker | undefined;
37
+ cache?: PopulationCache | undefined;
38
+ collections?: Readonly<Record<string, CollectionConfig>> | undefined;
39
+ }
40
+ /**
41
+ * Wire one population's blob-stage observer, ignore oracle and store.
42
+ *
43
+ * `describeBlobRefusals` returns undefined on a run that refused nothing, so a
44
+ * clean population stays exactly as quiet as it was — which is the only thing
45
+ * that keeps the line worth reading when it does appear.
46
+ *
47
+ * ⚠ïļ The refusals go to `logger.warn`, i.e. **stderr**. Both callers write a
48
+ * parseable document to stdout, and a diagnostic in the middle of it breaks every
49
+ * consumer.
50
+ *
51
+ * @param logger - Where blob-stage refusals are reported
52
+ * @param gitTracker - The ignore oracle, or undefined when there is none. Not
53
+ * cosmetic: `resource_realizations.gitignored` is filled only when a tracker
54
+ * was supplied, so its absence decides whether a consumer can TELL which
55
+ * members were ignored
56
+ * @param cache - The run's projection store, or undefined to re-derive
57
+ * @param root - The project root, from which the run's declared `mimeType`
58
+ * routing is READ rather than passed. See {@link collectionsOption}
59
+ * @returns The options to spread into the population builder's argument
60
+ */
61
+ export declare function populationWiring(logger: Logger, gitTracker: GitTracker | undefined, cache: PopulationCache | undefined, root: string): PopulationWiring;
62
+ /**
63
+ * The project's collection declarations at `root`, or undefined for a project
64
+ * that declares none.
65
+ *
66
+ * ## Why this is READ here and not passed in
67
+ *
68
+ * A declared `mimeType` changes which parser runs, which changes the content
69
+ * key, which is folded into the projection store's key through the routing's
70
+ * fingerprint. So two lanes of ONE command that disagree about whether to supply
71
+ * the declarations do not merely disagree about parsing — they **evict each
72
+ * other's stored extents over an unchanged tree, run after run.**
73
+ *
74
+ * Taking a `root` and reading the config here rather than accepting a
75
+ * `collections` argument is what makes that disagreement unrepresentable: there
76
+ * is one answer per root and every lane that goes through this helper gets it.
77
+ * An optional argument would have been a thing three call sites could each
78
+ * forget, and forgetting is silent — a cache that never hits looks exactly like
79
+ * a cache that is merely cold.
80
+ *
81
+ * `loadConfigCached` is keyed on the root, so the repeat calls across a
82
+ * command's lanes cost one parse between them. A broken config throws here, as
83
+ * it does everywhere else — a population silently typed by the built-in tables
84
+ * because the config would not parse is the conflation
85
+ * {@link loadConfigCached} exists to refuse.
86
+ *
87
+ * Returned as a SPREADABLE rather than a value: `exactOptionalPropertyTypes`
88
+ * makes an absent key and one holding `undefined` different arguments, and the
89
+ * population builders declare `collections` optional. Every caller spreads this,
90
+ * so no call site writes its own `!== undefined &&` and none can get the two
91
+ * states the wrong way round.
92
+ *
93
+ * @param root - The project root whose config declares the collections
94
+ * @returns `{ collections }`, or `{}` when there is no config or no
95
+ * `resources.collections` in it
96
+ */
97
+ export declare function collectionsOption(root: string): {
98
+ collections?: Readonly<Record<string, CollectionConfig>>;
99
+ };
100
+ //# sourceMappingURL=population-wiring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"population-wiring.d.ts","sourceRoot":"","sources":["../../src/utils/population-wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAGhE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACzD,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACpC,KAAK,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACpC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,GAAG,SAAS,CAAC;CACtE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,KAAK,EAAE,eAAe,GAAG,SAAS,EAClC,IAAI,EAAE,MAAM,GACX,gBAAgB,CAUlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,GACX;IAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAA;CAAE,CAG9D"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * The three arguments every CLI lane hands a projection population builder the
3
+ * same way: the blob-stage observer, the ignore oracle, and the run's store.
4
+ *
5
+ * ## Why this is CLI code and not `resources` code
6
+ *
7
+ * Nothing here decides anything about a projection. The observer's whole body is
8
+ * `describeBlobRefusals` — owned by `@vibe-agent-toolkit/resources` — routed to a
9
+ * {@link Logger}, which is a CLI type no other package has; the two spreads exist
10
+ * only because `exactOptionalPropertyTypes` makes "absent" and "present and
11
+ * undefined" different arguments. That is command plumbing, in the same family as
12
+ * `projection-store.ts` next door, so it stays inside the package the CLI-stays-
13
+ * dumb rule allows it in.
14
+ *
15
+ * ## The observer is the reason this is shared rather than retyped
16
+ *
17
+ * `buildInventoryPopulation` and `buildClaudeContextPopulation` both REQUIRE
18
+ * `onBlobPopulation` — a caller with nothing to do with the counts must name
19
+ * `DISCARD_BLOB_POPULATION` rather than leave it off — because a tree whose every
20
+ * document was declined as binary otherwise populates as empty and reports
21
+ * success. Two hand-written copies of the reporting half is two places for that
22
+ * report to quietly become a no-op.
23
+ */
24
+ import { describeBlobRefusals, } from '@vibe-agent-toolkit/resources';
25
+ import { loadConfigCached } from './config-loader.js';
26
+ /**
27
+ * Wire one population's blob-stage observer, ignore oracle and store.
28
+ *
29
+ * `describeBlobRefusals` returns undefined on a run that refused nothing, so a
30
+ * clean population stays exactly as quiet as it was — which is the only thing
31
+ * that keeps the line worth reading when it does appear.
32
+ *
33
+ * ⚠ïļ The refusals go to `logger.warn`, i.e. **stderr**. Both callers write a
34
+ * parseable document to stdout, and a diagnostic in the middle of it breaks every
35
+ * consumer.
36
+ *
37
+ * @param logger - Where blob-stage refusals are reported
38
+ * @param gitTracker - The ignore oracle, or undefined when there is none. Not
39
+ * cosmetic: `resource_realizations.gitignored` is filled only when a tracker
40
+ * was supplied, so its absence decides whether a consumer can TELL which
41
+ * members were ignored
42
+ * @param cache - The run's projection store, or undefined to re-derive
43
+ * @param root - The project root, from which the run's declared `mimeType`
44
+ * routing is READ rather than passed. See {@link collectionsOption}
45
+ * @returns The options to spread into the population builder's argument
46
+ */
47
+ export function populationWiring(logger, gitTracker, cache, root) {
48
+ return {
49
+ onBlobPopulation: (report) => {
50
+ const refusals = describeBlobRefusals(report);
51
+ if (refusals !== undefined)
52
+ logger.warn(refusals);
53
+ },
54
+ ...(gitTracker !== undefined && { gitTracker }),
55
+ ...(cache !== undefined && { cache }),
56
+ ...collectionsOption(root),
57
+ };
58
+ }
59
+ /**
60
+ * The project's collection declarations at `root`, or undefined for a project
61
+ * that declares none.
62
+ *
63
+ * ## Why this is READ here and not passed in
64
+ *
65
+ * A declared `mimeType` changes which parser runs, which changes the content
66
+ * key, which is folded into the projection store's key through the routing's
67
+ * fingerprint. So two lanes of ONE command that disagree about whether to supply
68
+ * the declarations do not merely disagree about parsing — they **evict each
69
+ * other's stored extents over an unchanged tree, run after run.**
70
+ *
71
+ * Taking a `root` and reading the config here rather than accepting a
72
+ * `collections` argument is what makes that disagreement unrepresentable: there
73
+ * is one answer per root and every lane that goes through this helper gets it.
74
+ * An optional argument would have been a thing three call sites could each
75
+ * forget, and forgetting is silent — a cache that never hits looks exactly like
76
+ * a cache that is merely cold.
77
+ *
78
+ * `loadConfigCached` is keyed on the root, so the repeat calls across a
79
+ * command's lanes cost one parse between them. A broken config throws here, as
80
+ * it does everywhere else — a population silently typed by the built-in tables
81
+ * because the config would not parse is the conflation
82
+ * {@link loadConfigCached} exists to refuse.
83
+ *
84
+ * Returned as a SPREADABLE rather than a value: `exactOptionalPropertyTypes`
85
+ * makes an absent key and one holding `undefined` different arguments, and the
86
+ * population builders declare `collections` optional. Every caller spreads this,
87
+ * so no call site writes its own `!== undefined &&` and none can get the two
88
+ * states the wrong way round.
89
+ *
90
+ * @param root - The project root whose config declares the collections
91
+ * @returns `{ collections }`, or `{}` when there is no config or no
92
+ * `resources.collections` in it
93
+ */
94
+ export function collectionsOption(root) {
95
+ const collections = loadConfigCached(root)?.resources?.collections;
96
+ return collections === undefined ? {} : { collections };
97
+ }
98
+ //# sourceMappingURL=population-wiring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"population-wiring.js","sourceRoot":"","sources":["../../src/utils/population-wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EACL,oBAAoB,GAIrB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAiBtD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAc,EACd,UAAkC,EAClC,KAAkC,EAClC,IAAY;IAEZ,OAAO;QACL,gBAAgB,EAAE,CAAC,MAAM,EAAE,EAAE;YAC3B,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;YAC9C,IAAI,QAAQ,KAAK,SAAS;gBAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,CAAC;QACD,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,CAAC;QAC/C,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC;QACrC,GAAG,iBAAiB,CAAC,IAAI,CAAC;KAC3B,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAY;IAEZ,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,WAAW,CAAC;IACnE,OAAO,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Selecting, opening and keying the **projection store** — the cross-process
3
+ * cache that makes a second population of an unchanged tree cheap.
4
+ *
5
+ * ## Why the CLI owns this and `resources` does not
6
+ *
7
+ * `@vibe-agent-toolkit/resources` states the {@link ProjectionStore} contract
8
+ * and never picks a backend, for the same reason it states the parse contract
9
+ * and never picks a parser: it is the toolkit's most widely installed package,
10
+ * and a storage engine is a *choice*. The choice is made here, at the edge that
11
+ * already owns every other optional backend — see `optional-backend.ts`, whose
12
+ * header names a projection store as one of the shapes it exists for.
13
+ *
14
+ * So `populate()` takes a {@link PopulationCache} it is handed, and this module
15
+ * is the only place in the toolkit that knows `@vibe-agent-toolkit/projection-
16
+ * sqlite` exists.
17
+ *
18
+ * ## The key, and why it is a whole-repository tree hash
19
+ *
20
+ * A stored extent is filed under `(rootId, treeHash)`. `populate()` derives the
21
+ * root id itself so a caller cannot file one root's contents under another's;
22
+ * this module supplies the other half.
23
+ *
24
+ * {@link gitTreeSnapshot} answers it with `git write-tree` against a throwaway
25
+ * index, which covers staged edits, unstaged edits and untracked files, and
26
+ * carries **no timestamp** — byte-identical content always produces the same
27
+ * hash. ðŸŠĪ Never `git stash create`: a stash is a *commit*, so two calls over
28
+ * identical content agree only within the same wall-clock second, and every
29
+ * read would miss.
30
+ *
31
+ * ⚠ïļ That hash covers the whole **repository**, not the subtree the root names.
32
+ * An edit anywhere in the repository therefore cools the cache for every root
33
+ * inside it. This is conservative in the safe direction and cheap to be
34
+ * conservative about — `git write-tree` against a throwaway index is the same
35
+ * call `vibe-validate` makes on every commit.
36
+ *
37
+ * ## An opted-in cache that quietly does nothing is worse than no cache
38
+ *
39
+ * Every failure here is loud, and that is deliberate rather than harsh. A
40
+ * selector nobody honours produces a measurement arm that believes it is
41
+ * testing a cache and is testing an ordinary cold run — the "subject that
42
+ * exercises nothing looks like a clean result" failure that has already cost
43
+ * this project one whole A/B. So an uninstalled backend exits with the seam's
44
+ * standard legible error, and a tree that cannot be keyed says so on stderr
45
+ * rather than silently declining.
46
+ */
47
+ import type { PopulationCache } from '@vibe-agent-toolkit/resources';
48
+ /**
49
+ * The env var that selects a projection store for this process.
50
+ *
51
+ * An environment switch rather than a config field, for the same reason
52
+ * `VAT_INVENTORY_CRAWL` and `VAT_RESOURCES_CRAWL` are: it selects which
53
+ * INSTRUMENT runs, not what the project means, and it has to be reachable from
54
+ * the lab, which spawns the binary and controls its environment. A config field
55
+ * would put the A and B arms inside the subject's own tree, where a measurement
56
+ * edits the thing it measures.
57
+ *
58
+ * 🔑 It is read from the environment, and **every phase now runs in the process
59
+ * that read it** — phases used to be child processes inheriting it across a
60
+ * `spawnSync`, which reached the same place by a longer route. `vat validate`'s
61
+ * phases see the same selection their orchestrator did, and can no longer fail
62
+ * to.
63
+ *
64
+ * 🔑 **That sharing has a within-verb instance.** `vat build`'s two
65
+ * phases — `skills build` and `claude plugin build` — both reach the lane
66
+ * through `withResourcePopulationSource` (see `resource-loader.ts`), and both
67
+ * root their population at the same directory, so phase 2 reads the extent
68
+ * phase 1 wrote. Measured on `packages/vat-development-agents` with
69
+ * `VAT_CRAWL_TIMING`: with a cold store phase 1 files `builtin:filesystem`
70
+ * 39.2 ms and `projection-store:write` 10.1 ms, phase 2 files neither and its
71
+ * `resource-registry:enumerate` reads 3.6 ms against phase 1's 66.6 ms.
72
+ *
73
+ * It did NOT need the closure to emit reasons, which is what an earlier reading
74
+ * of this expected: the packaging lanes consume `resource_realizations` and let
75
+ * `walkLinkGraph` keep running on top of the registry, so the base extent alone
76
+ * answers them — the same shape `buildResourcePopulation` already had.
77
+ *
78
+ * The cross-INVOCATION win is unchanged and independent: `vat validate` and
79
+ * `vat verify` spawn a byte-identical `resources validate` child, so the second
80
+ * hits the store.
81
+ *
82
+ * ⚠ïļ One packaging enumeration is still on the walk: `vat claude plugin build`'s
83
+ * per-skill post-build validation, which reaches `crawlAndResolveRegistry` in
84
+ * `packaging-validator.ts` without a source — its `withResourcePopulationSource`
85
+ * bracket closes around `createProjectRegistry` and does not span the
86
+ * marketplace loop. `vat skills build` no longer does: it holds one bracket over
87
+ * the whole run, and the registry memo is keyed on the population source, so
88
+ * both of its registries source from the projection.
89
+ */
90
+ export declare const PROJECTION_STORE_ENV = "VAT_PROJECTION_STORE";
91
+ /** {@link PROJECTION_STORE_ENV}'s value that selects the SQLite backend. */
92
+ export declare const PROJECTION_STORE_SQLITE = "sqlite";
93
+ /**
94
+ * The env var that turns VAT's disk caches off for a run.
95
+ *
96
+ * Not this module's invention — `ParseCache` has read it since the parse cache
97
+ * shipped, and `vat`'s root `--no-cache` exports it from a `preAction` hook so
98
+ * the decision reaches every spawned phase. Named here rather than spelled
99
+ * inline so the projection store is visibly the same tenant as the caches the
100
+ * flag was written for.
101
+ */
102
+ export declare const CACHE_ENV = "VAT_CACHE";
103
+ /** {@link CACHE_ENV}'s one off value. Exactly `'0'`, never truthiness — see {@link projectionStoreSelected}. */
104
+ export declare const CACHE_DISABLED = "0";
105
+ /**
106
+ * Whether this process should read and write a projection store.
107
+ *
108
+ * **Off unless asked for**, which is the opposite of `vat inventory`'s crawl
109
+ * selector and matches `vat resources scan`'s. A cache changes no answer, so
110
+ * the reason to hold it back is not correctness but evidence: the win is a
111
+ * claim about cost, and a default flipped before the cost is measured on real
112
+ * corpora is a claim nobody checked.
113
+ *
114
+ * Read from the environment at each call rather than memoized at module load:
115
+ * `vitest.setup.js` deletes every `VAT_*` variable before any test module
116
+ * loads, so a module-level binding would make the switch unobservable to every
117
+ * test that sets it.
118
+ *
119
+ * ## The two switches are AND-ed, and the second one is a veto
120
+ *
121
+ * {@link PROJECTION_STORE_ENV} says *which* backend; {@link CACHE_ENV} says
122
+ * whether this run caches at all. A store selected while `VAT_CACHE=0` was
123
+ * measured writing a 9.8 MB, 18,079-row store on this repository and hitting it
124
+ * on the next run — a user who asked for no cache silently got one, and
125
+ * `vat cache`'s own help text described three caches while a fourth was being
126
+ * written beside them.
127
+ *
128
+ * ðŸŠĪ Compared against `'0'` exactly, never for truthiness, matching
129
+ * `ParseCache`'s `env['VAT_CACHE'] !== '0'`. `VAT_CACHE=1` is the value an
130
+ * operator writes to turn caching ON, and a truthiness test would read it as a
131
+ * reason to decline.
132
+ *
133
+ * @returns `true` when a store is selected
134
+ */
135
+ export declare function projectionStoreSelected(): boolean;
136
+ /** An open store, the key half it is used with, and the way to let it go. */
137
+ export interface OpenedPopulationCache {
138
+ /** Hand this to `populate()`. */
139
+ readonly cache: PopulationCache;
140
+ /**
141
+ * Close the underlying connection.
142
+ *
143
+ * Must be called. A `DatabaseSync` left open holds its file handle and, in
144
+ * WAL mode, its read transaction — see `projection-sqlite`'s note on why an
145
+ * unfinalized read statement pins a connection to a stale snapshot.
146
+ */
147
+ close(): Promise<void>;
148
+ }
149
+ /**
150
+ * Open the projection store this process selected, keyed to one tree.
151
+ *
152
+ * Returns `undefined` when no store is selected, and when the tree cannot be
153
+ * keyed — the two "carry on without a cache" answers. It does **not** return
154
+ * `undefined` for an uninstalled backend: a user who set the selector asked for
155
+ * a store, and answering that request by silently not having one is how an
156
+ * opted-in cache becomes an unmeasured one.
157
+ *
158
+ * @param options - Where the corpus is
159
+ * @param options.root - The absolute corpus root. Used to find the repository;
160
+ * the resulting hash covers that whole repository, not this subtree
161
+ * @returns The cache and its closer, or `undefined` to populate uncached
162
+ */
163
+ export declare function openPopulationCache(options: {
164
+ root: string;
165
+ }): Promise<OpenedPopulationCache | undefined>;
166
+ /**
167
+ * Run one command's work with a projection store open for its whole duration,
168
+ * and closed however it ends.
169
+ *
170
+ * A scope rather than a bare open/close pair, because the store must outlive the
171
+ * call that builds a population source and not merely the call that uses it: the
172
+ * inventory extractor MEMOIZES its population provider and may reach it well
173
+ * after the frame that supplied it has returned. A store closed at the end of
174
+ * that frame would be closed under its own consumer.
175
+ *
176
+ * It is also the `withGitSnapshotCache` bracket for the work inside it, so the
177
+ * key and the extent filed under it come from ONE git snapshot — see the note
178
+ * on the call below.
179
+ *
180
+ * @param options - Where the corpus is
181
+ * @param options.root - The absolute corpus root
182
+ * @param work - Given the cache, or `undefined` when there is none to give
183
+ * @returns Whatever `work` returned
184
+ */
185
+ export declare function withPopulationCache<T>(options: {
186
+ root: string;
187
+ }, work: (cache: PopulationCache | undefined) => Promise<T>): Promise<T>;
188
+ //# sourceMappingURL=projection-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection-store.d.ts","sourceRoot":"","sources":["../../src/utils/projection-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAKrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,WAAW,CAAC;AAEhD;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,cAAc,CAAC;AAErC,gHAAgH;AAChH,eAAO,MAAM,cAAc,MAAM,CAAC;AAelC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAGjD;AAED,6EAA6E;AAC7E,MAAM,WAAW,qBAAqB;IACpC,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC;;;;;;OAMG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE;IACjD,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAsB7C;AAuBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EACzB,IAAI,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,GACvD,OAAO,CAAC,CAAC,CAAC,CA0BZ"}