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

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 (92) hide show
  1. package/dist/bin.js +35 -2
  2. package/dist/bin.js.map +1 -1
  3. package/dist/commands/audit.d.ts.map +1 -1
  4. package/dist/commands/audit.js +169 -17
  5. package/dist/commands/audit.js.map +1 -1
  6. package/dist/commands/claude/claude-config.d.ts.map +1 -1
  7. package/dist/commands/claude/claude-config.js +6 -0
  8. package/dist/commands/claude/claude-config.js.map +1 -1
  9. package/dist/commands/claude/org/helpers.d.ts +59 -1
  10. package/dist/commands/claude/org/helpers.d.ts.map +1 -1
  11. package/dist/commands/claude/org/helpers.js +58 -7
  12. package/dist/commands/claude/org/helpers.js.map +1 -1
  13. package/dist/commands/claude/org/index.d.ts.map +1 -1
  14. package/dist/commands/claude/org/index.js +24 -16
  15. package/dist/commands/claude/org/index.js.map +1 -1
  16. package/dist/commands/claude/org/skills.d.ts +428 -0
  17. package/dist/commands/claude/org/skills.d.ts.map +1 -1
  18. package/dist/commands/claude/org/skills.js +1189 -91
  19. package/dist/commands/claude/org/skills.js.map +1 -1
  20. package/dist/commands/claude/org/users.d.ts.map +1 -1
  21. package/dist/commands/claude/org/users.js +3 -1
  22. package/dist/commands/claude/org/users.js.map +1 -1
  23. package/dist/commands/claude/org/workspaces.d.ts.map +1 -1
  24. package/dist/commands/claude/org/workspaces.js +5 -2
  25. package/dist/commands/claude/org/workspaces.js.map +1 -1
  26. package/dist/commands/claude/plugin/install.js +0 -1
  27. package/dist/commands/claude/plugin/install.js.map +1 -1
  28. package/dist/commands/corpus/runner.d.ts.map +1 -1
  29. package/dist/commands/corpus/runner.js +1 -19
  30. package/dist/commands/corpus/runner.js.map +1 -1
  31. package/dist/commands/inventory.js +1 -1
  32. package/dist/commands/inventory.js.map +1 -1
  33. package/dist/commands/resources/check-progress.d.ts +145 -0
  34. package/dist/commands/resources/check-progress.d.ts.map +1 -0
  35. package/dist/commands/resources/check-progress.js +205 -0
  36. package/dist/commands/resources/check-progress.js.map +1 -0
  37. package/dist/commands/resources/check-supervisor.d.ts +465 -0
  38. package/dist/commands/resources/check-supervisor.d.ts.map +1 -0
  39. package/dist/commands/resources/check-supervisor.js +566 -0
  40. package/dist/commands/resources/check-supervisor.js.map +1 -0
  41. package/dist/commands/resources/check.d.ts +454 -0
  42. package/dist/commands/resources/check.d.ts.map +1 -0
  43. package/dist/commands/resources/check.js +1237 -0
  44. package/dist/commands/resources/check.js.map +1 -0
  45. package/dist/commands/resources/index.d.ts.map +1 -1
  46. package/dist/commands/resources/index.js +277 -6
  47. package/dist/commands/resources/index.js.map +1 -1
  48. package/dist/commands/resources/query.d.ts +89 -0
  49. package/dist/commands/resources/query.d.ts.map +1 -0
  50. package/dist/commands/resources/query.js +146 -0
  51. package/dist/commands/resources/query.js.map +1 -0
  52. package/dist/commands/resources/scan.js +1 -1
  53. package/dist/commands/resources/scan.js.map +1 -1
  54. package/dist/commands/skill/review-checklist.d.ts.map +1 -1
  55. package/dist/commands/skill/review-checklist.js +35 -0
  56. package/dist/commands/skill/review-checklist.js.map +1 -1
  57. package/dist/commands/skill/test/configure.d.ts +37 -0
  58. package/dist/commands/skill/test/configure.d.ts.map +1 -1
  59. package/dist/commands/skill/test/configure.js +57 -12
  60. package/dist/commands/skill/test/configure.js.map +1 -1
  61. package/dist/commands/skills/install.js +0 -1
  62. package/dist/commands/skills/install.js.map +1 -1
  63. package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
  64. package/dist/commands/skills/skill-discovery.js +4 -2
  65. package/dist/commands/skills/skill-discovery.js.map +1 -1
  66. package/dist/utils/agent-runner.d.ts.map +1 -1
  67. package/dist/utils/agent-runner.js +7 -3
  68. package/dist/utils/agent-runner.js.map +1 -1
  69. package/dist/utils/command-error.d.ts +56 -1
  70. package/dist/utils/command-error.d.ts.map +1 -1
  71. package/dist/utils/command-error.js +66 -3
  72. package/dist/utils/command-error.js.map +1 -1
  73. package/dist/utils/config-loader.d.ts.map +1 -1
  74. package/dist/utils/config-loader.js +30 -7
  75. package/dist/utils/config-loader.js.map +1 -1
  76. package/dist/utils/issue-severity.d.ts +12 -5
  77. package/dist/utils/issue-severity.d.ts.map +1 -1
  78. package/dist/utils/issue-severity.js +1 -1
  79. package/dist/utils/issue-severity.js.map +1 -1
  80. package/dist/utils/projection-query.d.ts +263 -0
  81. package/dist/utils/projection-query.d.ts.map +1 -0
  82. package/dist/utils/projection-query.js +262 -0
  83. package/dist/utils/projection-query.js.map +1 -0
  84. package/dist/utils/projection-store.d.ts +104 -2
  85. package/dist/utils/projection-store.d.ts.map +1 -1
  86. package/dist/utils/projection-store.js +126 -4
  87. package/dist/utils/projection-store.js.map +1 -1
  88. package/dist/utils/vat-bin-path.d.ts +36 -0
  89. package/dist/utils/vat-bin-path.d.ts.map +1 -0
  90. package/dist/utils/vat-bin-path.js +49 -0
  91. package/dist/utils/vat-bin-path.js.map +1 -0
  92. package/package.json +25 -14
@@ -6,10 +6,16 @@
6
6
  */
7
7
  import { readFileSync, existsSync } from 'node:fs';
8
8
  import { dirname } from 'node:path';
9
- import { ProjectConfigSchema } from '@vibe-agent-toolkit/resources';
9
+ import { parseConfigAllowingUnknownKeys, ProjectConfigSchema } from '@vibe-agent-toolkit/resources';
10
10
  import { safePath } from '@vibe-agent-toolkit/utils';
11
11
  import * as yaml from 'yaml';
12
12
  const CONFIG_FILENAME = 'vibe-agent-toolkit.config.yaml';
13
+ /**
14
+ * Config paths already warned about for unknown keys, so one config governing
15
+ * many skills produces one line rather than one per skill. Cleared with the
16
+ * config cache, which is what a test isolating a fixture resets.
17
+ */
18
+ const warnedConfigPaths = new Set();
13
19
  /**
14
20
  * A `vibe-agent-toolkit.config.yaml` exists but failed to parse or validate.
15
21
  *
@@ -61,12 +67,26 @@ export function loadConfig(projectRoot) {
61
67
  // eslint-disable-next-line security/detect-non-literal-fs-filename -- configPath is derived from projectRoot parameter
62
68
  const content = readFileSync(configPath, 'utf-8');
63
69
  const parsed = yaml.parse(content);
64
- // Validate with canonical schema from resources package
65
- const result = ProjectConfigSchema.safeParse(parsed);
66
- if (!result.success) {
67
- throw new Error(`Invalid configuration file: ${result.error.message}`);
68
- }
69
- return result.data;
70
+ // Validate with canonical schema from resources package.
71
+ //
72
+ // 🔑 The message comes from the shared formatter, NOT from `error.message`.
73
+ // In Zod 3 that property is a **JSON dump of the issue array**, and it was
74
+ // what an adopter got: five verbs exiting 2 in under a second on a blob that
75
+ // never named this file, never said which key was refused in words, and
76
+ // offered no remedy. Every strict block in the schema is a refusal an
77
+ // adopter has to be able to act on from the terminal alone.
78
+ // An UNKNOWN key warns and is dropped; every other validation failure still
79
+ // throws. See `parseConfigAllowingUnknownKeys` for the reasoning — briefly:
80
+ // a key VAT has no field for is a key VAT was already discarding, and
81
+ // turning that into an exit 2 broke commands that never read the section it
82
+ // was in. Warned once per config path, because `loadConfigCached` will
83
+ // otherwise re-warn for every skill under one project.
84
+ return parseConfigAllowingUnknownKeys(ProjectConfigSchema, parsed, (message) => {
85
+ if (warnedConfigPaths.has(configPath))
86
+ return;
87
+ warnedConfigPaths.add(configPath);
88
+ process.stderr.write(`${message}\n`);
89
+ }, { configPath });
70
90
  }
71
91
  catch (error) {
72
92
  if (error instanceof Error) {
@@ -113,6 +133,9 @@ const loadErrorCache = new Map();
113
133
  export function resetLoadedConfigCache() {
114
134
  loadedConfigCache.clear();
115
135
  loadErrorCache.clear();
136
+ // The warn-once ledger is part of this cache's state: a test that resets the
137
+ // caches and re-loads the same fixture expects to see the warning again.
138
+ warnedConfigPaths.clear();
116
139
  }
117
140
  /**
118
141
  * Cached variant of {@link loadConfig} keyed by `projectRoot`.
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/utils/config-loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/utils/config-loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,8BAA8B,EAAE,mBAAmB,EAAsB,MAAM,+BAA+B,CAAC;AACxH,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,MAAM,eAAe,GAAG,gCAAgC,CAAC;AAEzD;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;AAE5C;;;;;;;;GAQG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAC/B,WAAW,CAAS;IAC7B,YAAY,WAAmB,EAAE,KAAc;QAC7C,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,KAAK,YAAY,KAAK;YAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACjD,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,UAAU,CAAC,WAAmB;IAC5C,sEAAsE;IACtE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IAEjG,uIAAuI;IACvI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC;QACH,uHAAuH;QACvH,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEnC,yDAAyD;QACzD,EAAE;QACF,4EAA4E;QAC5E,2EAA2E;QAC3E,6EAA6E;QAC7E,wEAAwE;QACxE,sEAAsE;QACtE,4DAA4D;QAC5D,4EAA4E;QAC5E,4EAA4E;QAC5E,sEAAsE;QACtE,4EAA4E;QAC5E,uEAAuE;QACvE,uDAAuD;QACvD,OAAO,8BAA8B,CACnC,mBAAmB,EACnB,MAAM,EACN,CAAC,OAAO,EAAE,EAAE;YACV,IAAI,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC;gBAAE,OAAO;YAC9C,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACvC,CAAC,EACD,EAAE,UAAU,EAAE,CACf,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,qEAAqE;YACrE,wEAAwE;YACxE,0EAA0E;YAC1E,4EAA4E;YAC5E,uEAAuE;YACvE,8CAA8C;YAC9C,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC7C,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,iBAAiB,GAAsC,IAAI,GAAG,EAAE,CAAC;AAEvE;;;;GAIG;AACH,MAAM,cAAc,GAAiC,IAAI,GAAG,EAAE,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB;IACpC,iBAAiB,CAAC,KAAK,EAAE,CAAC;IAC1B,cAAc,CAAC,KAAK,EAAE,CAAC;IACvB,6EAA6E;IAC7E,yEAAyE;IACzE,iBAAiB,CAAC,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACpD,IAAI,WAAW,KAAK,SAAS;QAAE,MAAM,WAAW,CAAC;IACjD,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAClD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,IAAI,SAAS,CAAC;IACrD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QACvC,iBAAiB,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC;QACnD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,4EAA4E;QAC5E,8EAA8E;QAC9E,MAAM,SAAS,GAAG,GAAG,YAAY,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC/F,cAAc,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAC3C,MAAM,SAAS,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -18,11 +18,18 @@
18
18
  * findings imports this; nobody writes a fourth copy. Same rule as
19
19
  * `resolveAssetReference` and `resolveSkillReference` in CLAUDE.md.
20
20
  */
21
- import { type ValidationIssue } from '@vibe-agent-toolkit/schema';
22
- /** A `validation.severity` map as it appears in config, or nothing. */
23
- export interface SeverityOverrides {
24
- severity?: Record<string, string> | undefined;
25
- }
21
+ import { type SeverityConfig, type ValidationIssue } from '@vibe-agent-toolkit/schema';
22
+ /**
23
+ * A `validation.severity` map as it appears in config, or nothing.
24
+ *
25
+ * ⚠ïļ **Do not re-hand-roll this as `Record<string, string>`.** It was that, and
26
+ * the key space is now the registry enum PLUS `CUSTOM:<name>` — a `Partial`
27
+ * mapped type whose values are `SeverityLevel | undefined`. A
28
+ * `Record<string, string>` is not assignable to it and broke every consumer the
29
+ * moment the custom key space landed. `SeverityConfig` is the schema's own
30
+ * `Pick<ValidationConfig, 'severity'>`, so the two cannot drift again.
31
+ */
32
+ export type SeverityOverrides = SeverityConfig;
26
33
  /**
27
34
  * Re-severity findings against a `validation.severity` map, dropping the codes
28
35
  * resolved to `ignore`.
@@ -1 +1 @@
1
- {"version":3,"file":"issue-severity.d.ts","sourceRoot":"","sources":["../../src/utils/issue-severity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAmC,KAAK,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAEnG,uEAAuE;AACvE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,UAAU,EAAE,iBAAiB,GAAG,SAAS,GACxC,eAAe,EAAE,CAenB"}
1
+ {"version":3,"file":"issue-severity.d.ts","sourceRoot":"","sources":["../../src/utils/issue-severity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AAEpC;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,UAAU,EAAE,iBAAiB,GAAG,SAAS,GACxC,eAAe,EAAE,CAenB"}
@@ -18,7 +18,7 @@
18
18
  * findings imports this; nobody writes a fourth copy. Same rule as
19
19
  * `resolveAssetReference` and `resolveSkillReference` in CLAUDE.md.
20
20
  */
21
- import { resolveSeverity } from '@vibe-agent-toolkit/schema';
21
+ import { resolveSeverity, } from '@vibe-agent-toolkit/schema';
22
22
  /**
23
23
  * Re-severity findings against a `validation.severity` map, dropping the codes
24
24
  * resolved to `ignore`.
@@ -1 +1 @@
1
- {"version":3,"file":"issue-severity.js","sourceRoot":"","sources":["../../src/utils/issue-severity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAkB,eAAe,EAAwB,MAAM,4BAA4B,CAAC;AAOnG;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAkC,EAClC,UAAyC;IAEzC,MAAM,SAAS,GAAG,UAAU,EAAE,QAAQ,CAAC;IACvC,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;IAEhD,MAAM,QAAQ,GAAsB,EAAE,CAAC;IACvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC;YAC/B,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,IAAiB,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;QACnF,IAAI,QAAQ,KAAK,QAAQ;YAAE,SAAS;QACpC,QAAQ,CAAC,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"issue-severity.js","sourceRoot":"","sources":["../../src/utils/issue-severity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAEL,eAAe,GAGhB,MAAM,4BAA4B,CAAC;AAcpC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAkC,EAClC,UAAyC;IAEzC,MAAM,SAAS,GAAG,UAAU,EAAE,QAAQ,CAAC;IACvC,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;IAEhD,MAAM,QAAQ,GAAsB,EAAE,CAAC;IACvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC;YAC/B,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,IAAiB,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;QACnF,IAAI,QAAQ,KAAK,QAAQ;YAAE,SAAS;QACpC,QAAQ,CAAC,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Populating a tree's resource projection and putting it somewhere ASKABLE —
3
+ * the shared half of every command that runs SQL over it.
4
+ *
5
+ * `vat resources query` runs one statement a person typed; `vat resources check`
6
+ * runs the statements a project wrote down. They differ in what they do with
7
+ * rows and in nothing else: same population, same store selection, same
8
+ * ephemeral fallback, same cache tell. This module is that "and in nothing
9
+ * else", stated once so the two cannot drift into answering about different
10
+ * corpora.
11
+ *
12
+ * ## ðŸšĻ The SQL ALWAYS runs against a per-run in-memory database. Never the store.
13
+ *
14
+ * This is a correctness property, not an optimisation choice, and it was learned
15
+ * the expensive way. The on-disk projection store is **one database per VAT
16
+ * release, shared by every root on the machine** (`defaultStoreDirectory()` is
17
+ * `tmpdir/.vat-cache/<version>/projection-<shapeDigest>`), it retains three tree
18
+ * hashes per root, and its blob tier is never evicted and carries no tree key at
19
+ * all. `ProjectionStore.readExtent` narrows by `(rootId, treeHash)`; **arbitrary
20
+ * SQL does not**, and cannot be made to — a `WHERE` clause the caller wrote is
21
+ * not a key predicate.
22
+ *
23
+ * So running a user's statement against the file-backed store answered from
24
+ * every projection on the machine. Measured on a two-file scratch repository:
25
+ * `SELECT COUNT(*) FROM resource_realizations` returned **3** with no store and
26
+ * **5,779** with one, and `WHERE path LIKE 'packages/%'` returned paths from a
27
+ * different repository entirely. That is a wrong answer and a cross-project
28
+ * disclosure of link text, heading text and frontmatter — the same material
29
+ * `store.ts` cites as the reason it chmods the cache `0o700`.
30
+ *
31
+ * ⇒ The store's job is to make the POPULATION cheap, and that is all. Whatever
32
+ * `populate()` returns — served from the store or derived — is written into a
33
+ * fresh in-memory database that holds this tree and nothing else, and the SQL
34
+ * runs there. The saving is untouched (it was always in the population: on this
35
+ * repository {@link ProjectionProvenance.populationMs} reads 1.16-1.18 s derived
36
+ * against 0.29-0.31 s served), and "one tree, one answer" stops being a claim
37
+ * about how callers behave and becomes a property of the shape.
38
+ *
39
+ * ## The store never reaches a caller
40
+ *
41
+ * Work runs against an `ask` closure rather than a store handle. That is
42
+ * deliberate: `utils/projection-store.ts` is the one module in the toolkit that
43
+ * knows `@vibe-agent-toolkit/projection-sqlite` exists, and handing commands a
44
+ * backend-typed object would spread that knowledge to every future verb. A
45
+ * closure also puts the legible-failure wrapper on the single path that can
46
+ * throw, so no command can forget it.
47
+ */
48
+ import type { Logger } from './logger.js';
49
+ /** Where the POPULATION a statement ran against came from. */
50
+ export type PopulationOrigin = 'derived' | 'store';
51
+ /**
52
+ * What a run's rows are, and where they came from.
53
+ *
54
+ * ⚠ïļ There is deliberately no `engine` field beside these. An earlier version
55
+ * published one (`sqlite | ephemeral`) to say which database answered the SQL;
56
+ * it is gone because the answer is now always the same — see the header — and a
57
+ * field with one possible value tells a reader nothing while implying the other
58
+ * value is reachable.
59
+ */
60
+ export interface ProjectionProvenance {
61
+ /**
62
+ * 🔑 The cache tell. Reported rather than inferred, because it CANNOT be
63
+ * inferred: a correct store hit and a correct re-derivation produce identical
64
+ * rows. A hit short-circuits `populate()` before the builder exists, so no
65
+ * contributor timing is filed — an empty record list IS the hit.
66
+ *
67
+ * It describes the POPULATION, which is the only thing the store now affects.
68
+ */
69
+ readonly population: PopulationOrigin;
70
+ /**
71
+ * 🔑 What that origin was WORTH. {@link population} says whether the
72
+ * projection was served or re-derived; this says what the difference cost, so
73
+ * the tell stops being a bare label a reader has to take on faith.
74
+ *
75
+ * Measured as THIS field, by running `vat resources query 'SELECT COUNT(*) AS
76
+ * n FROM blobs'` against this repository three times per arm with the parse
77
+ * cache warm: **1.16-1.18 s derived against 0.29-0.31 s served**. With a cold
78
+ * parse cache the derived arm is 33-35 s, so the pair above is the store's
79
+ * saving and not the parse cache's.
80
+ *
81
+ * The wall time of the SHARED setup and nothing else: everything
82
+ * {@link withQueriedProjection} does before it hands control to the caller's
83
+ * work — opening the population cache (which, when a store is selected, is a
84
+ * `git write-tree` spawn plus the backend's dynamic import and
85
+ * `openSqliteProjectionStore()`), the git tracker, `buildResourceProjection`,
86
+ * opening the ephemeral database, and writing the blob tier and the extent
87
+ * into it.
88
+ *
89
+ * ⚠ïļ The population cache's CLOSE is outside it, necessarily: that runs in
90
+ * `withPopulationCache`'s `finally`, after the caller's work returns, and a
91
+ * span that ends before the work begins cannot contain it. It is a handle
92
+ * release, not population.
93
+ *
94
+ * ðŸŠĪ **The span's start is load-bearing, and moving it inward is silent.**
95
+ * This shipped with the clock started on the first line INSIDE
96
+ * `withPopulationCache`'s callback — which put the population-cache open, the
97
+ * only part of the setup a store adds, OUTSIDE the measurement, and only on
98
+ * the arm where a store exists. Measured on a two-file corpus with identical
99
+ * total wall time on both arms: no store 0.145 of 0.146 s, cold store 0.0475
100
+ * of 0.161 s. Same work, `populationSecs` three times apart, and a reader
101
+ * comparing a no-store run to a warm-store run read a 42x saving where the
102
+ * honest totals differ by 1.75x. The field was added to stop the cache tell
103
+ * being a label taken on faith and had become the artifact instead. A
104
+ * measurement that flatters one arm is this repository's most-repeated
105
+ * defect; the system suite now pins `populationSecs / durationSecs > 0.6` on a
106
+ * cold run so the next inward move is red rather than quiet.
107
+ *
108
+ * ## Why it belongs on shared provenance rather than on one verb
109
+ *
110
+ * Both verbs pay it, identically, because it is the half of the run they hold
111
+ * in common — a `check` that runs forty statements and a `query` that runs one
112
+ * do the same population first. And a per-statement cost is UNREADABLE without
113
+ * it: `vat resources check` publishes what each rule's SQL cost, and a reader
114
+ * handed forty small numbers and a large total has no way to tell an expensive
115
+ * rule from a setup everybody shares. Absent this field the only arithmetic
116
+ * available is "total minus the statements", which silently attributes the
117
+ * shared setup to whichever rule the reader is looking at.
118
+ *
119
+ * ⚠ïļ Measured with `performance.now()`, not `Date.now()`. A warm population
120
+ * lands well under a millisecond on a small tree, and a millisecond-granularity
121
+ * clock reports that as `0` — which reads as "not measured" rather than "very
122
+ * fast", turning the best case the store has into its least credible number.
123
+ *
124
+ * ⚠ïļ Deliberately ONE number, not a breakdown. Splitting it into crawl, parse
125
+ * and store-load is a real question and it is the lab's: an instrument that
126
+ * gets reviewed and re-run, rather than a product document that would then owe
127
+ * every consumer a stable sub-phase vocabulary.
128
+ */
129
+ readonly populationMs: number;
130
+ }
131
+ /**
132
+ * How much of the tree the population actually covered.
133
+ *
134
+ * ## Why this is not a field on {@link ProjectionProvenance}
135
+ *
136
+ * Provenance is a fact both verbs PUBLISH verbatim — "these rows were served or
137
+ * re-derived" is the same sentence in either document. This is a fact a verb
138
+ * REASONS with, and only one of them has anything to reason about: `vat
139
+ * resources query` prints the rows a person selected, so its reader can see the
140
+ * extent for themselves, while `vat resources check` prints a verdict and a
141
+ * count of rules. Only the second can pass vacuously, and only the second needs
142
+ * to know.
143
+ *
144
+ * ## 🔑 The failure it exists to make visible
145
+ *
146
+ * `vat resources check` reported how many CHECKS ran; nothing said how many ROWS
147
+ * they ran against. So "four checks passed over eight thousand files" and "four
148
+ * checks passed over ZERO files" were byte-identical documents, and the second
149
+ * was a green gate asserting nothing. A broad `.gitignore`, a shallow or sparse
150
+ * checkout, a root that resolved elsewhere, or an extent source that enumerated
151
+ * nothing all produce it — and `buildResourceProjection` DECLINES ignored
152
+ * members rather than flagging them, so an emptied enumeration leaves no trace
153
+ * in the tables either.
154
+ */
155
+ export interface PopulationExtent {
156
+ /**
157
+ * One per `(extentId, path)` row the population enumerated.
158
+ *
159
+ * ðŸŠĪ Realizations rather than any other count, because every alternative
160
+ * fails to reach zero on the case that matters: `roots` always holds exactly
161
+ * one row (the invariant thrown for below), so a total over all twelve tables
162
+ * is never 0; `blobs` is content-keyed and deduped, so it counts parse REACH
163
+ * and already has its own guard in `onBlobPopulation`; and `resources` counts
164
+ * identities, which a corpus can legitimately have none of while enumerating
165
+ * plenty. One row per enumerated path is non-zero exactly when something was
166
+ * enumerated.
167
+ */
168
+ readonly membersEnumerated: number;
169
+ }
170
+ /** Run one read-only statement against the populated projection. */
171
+ export type AskProjection = (sql: string, ...parameters: readonly string[]) => readonly Record<string, unknown>[];
172
+ /**
173
+ * Compile every statement a run intends to ask, against the schema and NO rows,
174
+ * before anything is populated.
175
+ *
176
+ * ## 🔑 What this buys, measured
177
+ *
178
+ * SQLite resolves table and column names when a statement is *prepared*, not
179
+ * when it is stepped — so a typo is knowable before a single row exists. It was
180
+ * not knowable in practice, because the only place a statement met the schema
181
+ * was after the projection had been built. On a real adopter tree, `SELECT path,
182
+ * no_such_column â€Ķ` cost **8.3 s**, every millisecond of it spent building a
183
+ * projection the statement could never have read. The same typo now costs the
184
+ * price of an empty in-memory database — one extra `createSchema` into
185
+ * `:memory:`, which is the whole overhead this adds on the happy path.
186
+ *
187
+ * It also moves the KIND refusals — a second statement, an `ATTACH`, a `PRAGMA`
188
+ * — in front of the population, so a statement rejected for what it is costs no
189
+ * more than one rejected for what it names.
190
+ *
191
+ * ⚠ïļ **This is a pre-flight, not a second gate.** `ask` still compiles and runs
192
+ * the real statement against the real projection, and nothing here is trusted in
193
+ * place of that. A statement that compiles here can still fail there — SQLite
194
+ * resolves names against a schema, and this is the same schema, but a run-time
195
+ * error (a bad cast, an overflow) belongs to stepping and is unreachable from a
196
+ * prepare.
197
+ *
198
+ * ⚠ïļ It deliberately does not STEP anything. Stepping is where a check's
199
+ * unbounded cost lives, and a preflight that ran `WITH RECURSIVE â€Ķ` would hang
200
+ * before the run it exists to make cheap had begun.
201
+ *
202
+ * @param statements - Every statement the run will ask, in any order
203
+ * @throws The same legible failure `ask` throws, for the first statement that
204
+ * does not compile
205
+ */
206
+ export declare function assertQueriesCompile(statements: readonly string[]): Promise<void>;
207
+ /**
208
+ * Populate the tree, load it into something askable, and hand the caller a way
209
+ * to ask.
210
+ *
211
+ * @param options - The run
212
+ * @param options.root - Absolute corpus root
213
+ * @param options.logger - Where blob-stage refusals are reported (stderr, so a
214
+ * parseable document on stdout stays parseable)
215
+ * @param options.preflight - Every statement this run intends to ask, compiled
216
+ * against the empty schema BEFORE the population starts. See
217
+ * {@link assertQueriesCompile}
218
+ * @param work - Given the asker, where its rows came from, and how much of the
219
+ * tree they cover. The store is open for exactly this call and closed however
220
+ * it ends
221
+ * @returns Whatever `work` returned
222
+ */
223
+ export declare function withQueriedProjection<T>(options: {
224
+ root: string;
225
+ logger: Logger;
226
+ preflight?: readonly string[];
227
+ }, work: (ask: AskProjection, provenance: ProjectionProvenance, extent: PopulationExtent) => Promise<T> | T): Promise<T>;
228
+ /**
229
+ * Turn a rejected statement into a message that names the surface it missed.
230
+ *
231
+ * ## Why this wrapper exists
232
+ *
233
+ * VAT ships no schema version, by standing rule — the *cache* is safe across a
234
+ * shape change because its digest self-invalidates, but submitted SQL is not: it
235
+ * simply breaks. Pre-1.0 that is acceptable. A raw SQLite error reaching the
236
+ * user is not, because `no such column: contentHash` says nothing about what the
237
+ * column is called now. It matters more for a CHECK than for a query: a query's
238
+ * author is at the keyboard, while a check's author wrote it months ago and the
239
+ * person reading the failure is someone else.
240
+ *
241
+ * ⚠ïļ **A legibility wrapper, not a validator.** It does not parse SQL and does
242
+ * not check a statement before running it — it reacts to a failure by listing
243
+ * what the query COULD have named. When the statement mentions a known table,
244
+ * that table's columns are listed, which is the case that actually answers "what
245
+ * moved"; otherwise the table names are, which at least answers "what is there".
246
+ *
247
+ * ðŸŠĪ **Only a name that was not found gets the listing.** The engine also refuses
248
+ * a write and this backend refuses a second statement, and neither is answered by
249
+ * a column list — appending one says the problem is the schema when the problem
250
+ * is what the caller asked for. A wrapper that decorates every failure identically
251
+ * teaches the reader to skip the decoration, which costs the case it was written for.
252
+ *
253
+ * Matching is a plain lowercase substring test rather than a regex: the input is
254
+ * user text, and a pattern built from it is both a lint failure here and a
255
+ * needless hazard.
256
+ *
257
+ * @param sql - The statement that was submitted
258
+ * @param message - What the engine said
259
+ * @returns The message to surface, with the queryable surface appended when the
260
+ * failure was a name this projection does not have
261
+ */
262
+ export declare function describeQueryFailure(sql: string, message: string): string;
263
+ //# sourceMappingURL=projection-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection-query.d.ts","sourceRoot":"","sources":["../../src/utils/projection-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAYH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAkB1C,8DAA8D;AAC9D,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,OAAO,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA0DG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC;AAED,oEAAoE;AACpE,MAAM,MAAM,aAAa,GAAG,CAC1B,GAAG,EAAE,MAAM,EACX,GAAG,UAAU,EAAE,SAAS,MAAM,EAAE,KAC7B,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;AAExC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBvF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAC3C,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EACxE,IAAI,EAAE,CACJ,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,gBAAgB,KACrB,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAClB,OAAO,CAAC,CAAC,CAAC,CA4FZ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAezE"}