codesift-mcp 0.12.0 → 0.14.0

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 (183) hide show
  1. package/README.md +44 -1
  2. package/dist/cli/commands.d.ts.map +1 -1
  3. package/dist/cli/commands.js +49 -3
  4. package/dist/cli/commands.js.map +1 -1
  5. package/dist/cli/help.d.ts.map +1 -1
  6. package/dist/cli/help.js +25 -2
  7. package/dist/cli/help.js.map +1 -1
  8. package/dist/cli/hooks/pre-tool-use.d.ts +1 -0
  9. package/dist/cli/hooks/pre-tool-use.d.ts.map +1 -1
  10. package/dist/cli/hooks/pre-tool-use.js +11 -2
  11. package/dist/cli/hooks/pre-tool-use.js.map +1 -1
  12. package/dist/cli/owner-only-file.d.ts +51 -0
  13. package/dist/cli/owner-only-file.d.ts.map +1 -0
  14. package/dist/cli/owner-only-file.js +121 -0
  15. package/dist/cli/owner-only-file.js.map +1 -0
  16. package/dist/cli/service.d.ts +17 -1
  17. package/dist/cli/service.d.ts.map +1 -1
  18. package/dist/cli/service.js +28 -12
  19. package/dist/cli/service.js.map +1 -1
  20. package/dist/cli/setup/codex.d.ts.map +1 -1
  21. package/dist/cli/setup/codex.js +14 -7
  22. package/dist/cli/setup/codex.js.map +1 -1
  23. package/dist/cli/setup/fs.d.ts +12 -0
  24. package/dist/cli/setup/fs.d.ts.map +1 -1
  25. package/dist/cli/setup/fs.js +17 -2
  26. package/dist/cli/setup/fs.js.map +1 -1
  27. package/dist/cli/setup/mcp.d.ts +14 -1
  28. package/dist/cli/setup/mcp.d.ts.map +1 -1
  29. package/dist/cli/setup/mcp.js +55 -5
  30. package/dist/cli/setup/mcp.js.map +1 -1
  31. package/dist/cli/setup/types.d.ts +19 -0
  32. package/dist/cli/setup/types.d.ts.map +1 -1
  33. package/dist/config.d.ts +13 -0
  34. package/dist/config.d.ts.map +1 -1
  35. package/dist/config.js +21 -0
  36. package/dist/config.js.map +1 -1
  37. package/dist/formatters-core.d.ts +7 -0
  38. package/dist/formatters-core.d.ts.map +1 -1
  39. package/dist/formatters-core.js +14 -3
  40. package/dist/formatters-core.js.map +1 -1
  41. package/dist/parser/extractors/hono-inline-analyzer.js +2 -2
  42. package/dist/parser/extractors/hono-inline-analyzer.js.map +1 -1
  43. package/dist/register-tool-groups/core/search.d.ts.map +1 -1
  44. package/dist/register-tool-groups/core/search.js +14 -0
  45. package/dist/register-tool-groups/core/search.js.map +1 -1
  46. package/dist/register-tool-groups/core/symbols.d.ts.map +1 -1
  47. package/dist/register-tool-groups/core/symbols.js +50 -5
  48. package/dist/register-tool-groups/core/symbols.js.map +1 -1
  49. package/dist/register-tools/runtime.d.ts +15 -6
  50. package/dist/register-tools/runtime.d.ts.map +1 -1
  51. package/dist/register-tools/runtime.js +30 -12
  52. package/dist/register-tools/runtime.js.map +1 -1
  53. package/dist/server.d.ts.map +1 -1
  54. package/dist/server.js +96 -11
  55. package/dist/server.js.map +1 -1
  56. package/dist/storage/_shared.d.ts +21 -0
  57. package/dist/storage/_shared.d.ts.map +1 -1
  58. package/dist/storage/_shared.js +36 -0
  59. package/dist/storage/_shared.js.map +1 -1
  60. package/dist/storage/embedding-store.d.ts +12 -1
  61. package/dist/storage/embedding-store.d.ts.map +1 -1
  62. package/dist/storage/embedding-store.js +42 -2
  63. package/dist/storage/embedding-store.js.map +1 -1
  64. package/dist/storage/index-footprint.d.ts +12 -0
  65. package/dist/storage/index-footprint.d.ts.map +1 -0
  66. package/dist/storage/index-footprint.js +41 -0
  67. package/dist/storage/index-footprint.js.map +1 -0
  68. package/dist/storage/index-store.d.ts +61 -3
  69. package/dist/storage/index-store.d.ts.map +1 -1
  70. package/dist/storage/index-store.js +409 -13
  71. package/dist/storage/index-store.js.map +1 -1
  72. package/dist/storage/registry.d.ts.map +1 -1
  73. package/dist/storage/registry.js +64 -1
  74. package/dist/storage/registry.js.map +1 -1
  75. package/dist/storage/shared-embedding-cache.d.ts +29 -0
  76. package/dist/storage/shared-embedding-cache.d.ts.map +1 -0
  77. package/dist/storage/shared-embedding-cache.js +120 -0
  78. package/dist/storage/shared-embedding-cache.js.map +1 -0
  79. package/dist/storage/sqlite/accessors.d.ts +34 -0
  80. package/dist/storage/sqlite/accessors.d.ts.map +1 -0
  81. package/dist/storage/sqlite/accessors.js +178 -0
  82. package/dist/storage/sqlite/accessors.js.map +1 -0
  83. package/dist/storage/sqlite/connection.d.ts +43 -0
  84. package/dist/storage/sqlite/connection.d.ts.map +1 -0
  85. package/dist/storage/sqlite/connection.js +241 -0
  86. package/dist/storage/sqlite/connection.js.map +1 -0
  87. package/dist/storage/sqlite/errors.d.ts +38 -0
  88. package/dist/storage/sqlite/errors.d.ts.map +1 -0
  89. package/dist/storage/sqlite/errors.js +150 -0
  90. package/dist/storage/sqlite/errors.js.map +1 -0
  91. package/dist/storage/sqlite/index-io.d.ts +49 -0
  92. package/dist/storage/sqlite/index-io.d.ts.map +1 -0
  93. package/dist/storage/sqlite/index-io.js +268 -0
  94. package/dist/storage/sqlite/index-io.js.map +1 -0
  95. package/dist/storage/sqlite/meta.d.ts +41 -0
  96. package/dist/storage/sqlite/meta.d.ts.map +1 -0
  97. package/dist/storage/sqlite/meta.js +28 -0
  98. package/dist/storage/sqlite/meta.js.map +1 -0
  99. package/dist/storage/sqlite/rows.d.ts +64 -0
  100. package/dist/storage/sqlite/rows.d.ts.map +1 -0
  101. package/dist/storage/sqlite/rows.js +186 -0
  102. package/dist/storage/sqlite/rows.js.map +1 -0
  103. package/dist/storage/sqlite/runtime.d.ts +6 -0
  104. package/dist/storage/sqlite/runtime.d.ts.map +1 -0
  105. package/dist/storage/sqlite/runtime.js +31 -0
  106. package/dist/storage/sqlite/runtime.js.map +1 -0
  107. package/dist/storage/sqlite/schema.d.ts +34 -0
  108. package/dist/storage/sqlite/schema.d.ts.map +1 -0
  109. package/dist/storage/sqlite/schema.js +98 -0
  110. package/dist/storage/sqlite/schema.js.map +1 -0
  111. package/dist/storage/sqlite-index-store.d.ts +49 -0
  112. package/dist/storage/sqlite-index-store.d.ts.map +1 -0
  113. package/dist/storage/sqlite-index-store.js +48 -0
  114. package/dist/storage/sqlite-index-store.js.map +1 -0
  115. package/dist/storage/telemetry/config.d.ts.map +1 -1
  116. package/dist/storage/telemetry/config.js +14 -3
  117. package/dist/storage/telemetry/config.js.map +1 -1
  118. package/dist/storage/telemetry/payload.d.ts.map +1 -1
  119. package/dist/storage/telemetry/payload.js +4 -1
  120. package/dist/storage/telemetry/payload.js.map +1 -1
  121. package/dist/storage/telemetry/retro-aggregator.d.ts +27 -0
  122. package/dist/storage/telemetry/retro-aggregator.d.ts.map +1 -0
  123. package/dist/storage/telemetry/retro-aggregator.js +179 -0
  124. package/dist/storage/telemetry/retro-aggregator.js.map +1 -0
  125. package/dist/storage/telemetry/sanitizer.d.ts +30 -0
  126. package/dist/storage/telemetry/sanitizer.d.ts.map +1 -1
  127. package/dist/storage/telemetry/sanitizer.js +23 -0
  128. package/dist/storage/telemetry/sanitizer.js.map +1 -1
  129. package/dist/storage/telemetry/uploader.d.ts.map +1 -1
  130. package/dist/storage/telemetry/uploader.js +6 -0
  131. package/dist/storage/telemetry/uploader.js.map +1 -1
  132. package/dist/storage/workspace-resolver.js +1 -1
  133. package/dist/storage/workspace-resolver.js.map +1 -1
  134. package/dist/tools/index-tools/file-indexer.js +19 -19
  135. package/dist/tools/index-tools/file-indexer.js.map +1 -1
  136. package/dist/tools/index-tools/folder-indexer.d.ts.map +1 -1
  137. package/dist/tools/index-tools/folder-indexer.js +4 -1
  138. package/dist/tools/index-tools/folder-indexer.js.map +1 -1
  139. package/dist/tools/index-tools/parse.d.ts.map +1 -1
  140. package/dist/tools/index-tools/parse.js +4 -1
  141. package/dist/tools/index-tools/parse.js.map +1 -1
  142. package/dist/tools/index-tools/registry.d.ts +16 -0
  143. package/dist/tools/index-tools/registry.d.ts.map +1 -1
  144. package/dist/tools/index-tools/registry.js +95 -1
  145. package/dist/tools/index-tools/registry.js.map +1 -1
  146. package/dist/tools/index-tools.d.ts +2 -2
  147. package/dist/tools/index-tools.d.ts.map +1 -1
  148. package/dist/tools/index-tools.js +2 -2
  149. package/dist/tools/index-tools.js.map +1 -1
  150. package/dist/tools/plan-turn/stale-index.d.ts +32 -0
  151. package/dist/tools/plan-turn/stale-index.d.ts.map +1 -1
  152. package/dist/tools/plan-turn/stale-index.js +42 -5
  153. package/dist/tools/plan-turn/stale-index.js.map +1 -1
  154. package/dist/tools/search-tools/types.d.ts +20 -0
  155. package/dist/tools/search-tools/types.d.ts.map +1 -1
  156. package/dist/tools/search-tools/zero-hit.d.ts.map +1 -1
  157. package/dist/tools/search-tools/zero-hit.js +0 -0
  158. package/dist/tools/search-tools/zero-hit.js.map +1 -1
  159. package/dist/tools/status-tools.d.ts +20 -0
  160. package/dist/tools/status-tools.d.ts.map +1 -1
  161. package/dist/tools/status-tools.js +69 -18
  162. package/dist/tools/status-tools.js.map +1 -1
  163. package/dist/tools/symbol-tools.d.ts +95 -1
  164. package/dist/tools/symbol-tools.d.ts.map +1 -1
  165. package/dist/tools/symbol-tools.js +182 -26
  166. package/dist/tools/symbol-tools.js.map +1 -1
  167. package/dist/tools/workspace-scope-helper.d.ts.map +1 -1
  168. package/dist/tools/workspace-scope-helper.js +8 -1
  169. package/dist/tools/workspace-scope-helper.js.map +1 -1
  170. package/dist/tools/workspace-tools.d.ts.map +1 -1
  171. package/dist/tools/workspace-tools.js +9 -1
  172. package/dist/tools/workspace-tools.js.map +1 -1
  173. package/dist/types.d.ts +6 -0
  174. package/dist/types.d.ts.map +1 -1
  175. package/dist/utils/git-head.d.ts +12 -0
  176. package/dist/utils/git-head.d.ts.map +1 -1
  177. package/dist/utils/git-head.js +25 -0
  178. package/dist/utils/git-head.js.map +1 -1
  179. package/dist/utils/loopback.d.ts +23 -0
  180. package/dist/utils/loopback.d.ts.map +1 -0
  181. package/dist/utils/loopback.js +71 -0
  182. package/dist/utils/loopback.js.map +1 -0
  183. package/package.json +6 -4
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Runtime availability of `node:sqlite`.
3
+ *
4
+ * The memoised constructor lives HERE and nowhere else. ESM gives one instance per module, so a
5
+ * second copy of `sqliteCtor` (say, re-declared in the barrel rather than re-exported) would fork
6
+ * the memo: `setSqliteCtorForTesting` would pin one copy while the code under test read the other,
7
+ * and nothing about that failure looks like a wiring bug.
8
+ */
9
+ /** `node:sqlite` landed in Node 22.5. The engines floor is still >=20, so its absence is a
10
+ * supported state, not an error — callers fall back to the JSON backend. */
11
+ let sqliteCtor;
12
+ export async function loadSqliteCtor() {
13
+ if (sqliteCtor !== undefined)
14
+ return sqliteCtor;
15
+ try {
16
+ const mod = await import("node:sqlite");
17
+ sqliteCtor = mod.DatabaseSync;
18
+ }
19
+ catch {
20
+ sqliteCtor = null;
21
+ }
22
+ return sqliteCtor;
23
+ }
24
+ export async function isSqliteAvailable() {
25
+ return (await loadSqliteCtor()) !== null;
26
+ }
27
+ /** Tests need to prove the JSON fallback still works on a runtime that has sqlite. */
28
+ export function setSqliteCtorForTesting(ctor) {
29
+ sqliteCtor = ctor;
30
+ }
31
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/storage/sqlite/runtime.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH;6EAC6E;AAC7E,IAAI,UAAsD,CAAC;AAE3D,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QACxC,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,OAAO,CAAC,MAAM,cAAc,EAAE,CAAC,KAAK,IAAI,CAAC;AAC3C,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,uBAAuB,CAAC,IAAgD;IACtF,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Table definitions and the v1 -> v2 migration, as SQL text only.
3
+ *
4
+ * No behaviour here on purpose: `connection.ts` decides WHEN to run these, under which lock, and
5
+ * what to record afterwards. Keeping the statements inert makes the schema readable as a schema.
6
+ */
7
+ /**
8
+ * v2 dropped the PRIMARY KEY on `symbols.id`.
9
+ *
10
+ * `id` is `repo:file:name:line`, which is NOT unique: a minified bundle puts hundreds of
11
+ * distinct symbols on line 1 of one file, and PHPDoc `@method` synthesis emits a `field`
12
+ * and a `method` at the same line. As a PRIMARY KEY with `ON CONFLICT DO UPDATE`, every
13
+ * such collision silently overwrote the previous row — so the store quietly held fewer
14
+ * symbols than it was given, and re-indexing reproduced the loss instead of repairing it.
15
+ *
16
+ * Measured over the 16 indexes that failed the migration's count check: 73,165 dropped
17
+ * rows, every one carrying content different from the row that survived, and 7,514 of them
18
+ * in real source rather than minified or vendored output.
19
+ *
20
+ * JSON never enforced uniqueness here, so this is parity, not a new tolerance. Lookups by
21
+ * id return the first match exactly as the array scan did.
22
+ */
23
+ export declare const SCHEMA_VERSION = 2;
24
+ export declare const SCHEMA_SQL = "\nCREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS files (\n path TEXT PRIMARY KEY,\n language TEXT NOT NULL,\n symbol_count INTEGER NOT NULL,\n last_modified INTEGER NOT NULL,\n mtime_ms INTEGER,\n stale INTEGER\n);\n\nCREATE TABLE IF NOT EXISTS symbols (\n id TEXT NOT NULL,\n file TEXT NOT NULL,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n start_line INTEGER NOT NULL,\n end_line INTEGER NOT NULL,\n start_col INTEGER,\n end_col INTEGER,\n start_byte INTEGER,\n end_byte INTEGER,\n signature TEXT,\n docstring TEXT,\n source TEXT,\n parent TEXT,\n is_async INTEGER,\n is_exported INTEGER,\n extras TEXT\n);\n\nCREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file);\nCREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);\nCREATE INDEX IF NOT EXISTS idx_symbols_id ON symbols(id);\n";
25
+ /**
26
+ * v1 -> v2: rebuild `symbols` without the PRIMARY KEY, keeping every row already stored.
27
+ *
28
+ * Rebuilt in place rather than by re-importing: for most repos the JSON source is gone, so
29
+ * the db IS the index — dropping it to force a reindex would trade a store that is merely
30
+ * incomplete for no store at all. This recovers nothing on its own; rows lost under v1 come
31
+ * back when the repo is next indexed from source, which now keeps them.
32
+ */
33
+ export declare const MIGRATE_V1_TO_V2_SQL = "\nALTER TABLE symbols RENAME TO symbols_v1;\nCREATE TABLE symbols (\n id TEXT NOT NULL,\n file TEXT NOT NULL,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n start_line INTEGER NOT NULL,\n end_line INTEGER NOT NULL,\n start_col INTEGER,\n end_col INTEGER,\n start_byte INTEGER,\n end_byte INTEGER,\n signature TEXT,\n docstring TEXT,\n source TEXT,\n parent TEXT,\n is_async INTEGER,\n is_exported INTEGER,\n extras TEXT\n);\nINSERT INTO symbols SELECT * FROM symbols_v1;\nDROP TABLE symbols_v1;\nCREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file);\nCREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);\nCREATE INDEX IF NOT EXISTS idx_symbols_id ON symbols(id);\n";
34
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,eAAO,MAAM,UAAU,+9BAsCtB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,gwBA0BhC,CAAC"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Table definitions and the v1 -> v2 migration, as SQL text only.
3
+ *
4
+ * No behaviour here on purpose: `connection.ts` decides WHEN to run these, under which lock, and
5
+ * what to record afterwards. Keeping the statements inert makes the schema readable as a schema.
6
+ */
7
+ /**
8
+ * v2 dropped the PRIMARY KEY on `symbols.id`.
9
+ *
10
+ * `id` is `repo:file:name:line`, which is NOT unique: a minified bundle puts hundreds of
11
+ * distinct symbols on line 1 of one file, and PHPDoc `@method` synthesis emits a `field`
12
+ * and a `method` at the same line. As a PRIMARY KEY with `ON CONFLICT DO UPDATE`, every
13
+ * such collision silently overwrote the previous row — so the store quietly held fewer
14
+ * symbols than it was given, and re-indexing reproduced the loss instead of repairing it.
15
+ *
16
+ * Measured over the 16 indexes that failed the migration's count check: 73,165 dropped
17
+ * rows, every one carrying content different from the row that survived, and 7,514 of them
18
+ * in real source rather than minified or vendored output.
19
+ *
20
+ * JSON never enforced uniqueness here, so this is parity, not a new tolerance. Lookups by
21
+ * id return the first match exactly as the array scan did.
22
+ */
23
+ export const SCHEMA_VERSION = 2;
24
+ export const SCHEMA_SQL = `
25
+ CREATE TABLE IF NOT EXISTS meta (
26
+ key TEXT PRIMARY KEY,
27
+ value TEXT NOT NULL
28
+ );
29
+
30
+ CREATE TABLE IF NOT EXISTS files (
31
+ path TEXT PRIMARY KEY,
32
+ language TEXT NOT NULL,
33
+ symbol_count INTEGER NOT NULL,
34
+ last_modified INTEGER NOT NULL,
35
+ mtime_ms INTEGER,
36
+ stale INTEGER
37
+ );
38
+
39
+ CREATE TABLE IF NOT EXISTS symbols (
40
+ id TEXT NOT NULL,
41
+ file TEXT NOT NULL,
42
+ name TEXT NOT NULL,
43
+ kind TEXT NOT NULL,
44
+ start_line INTEGER NOT NULL,
45
+ end_line INTEGER NOT NULL,
46
+ start_col INTEGER,
47
+ end_col INTEGER,
48
+ start_byte INTEGER,
49
+ end_byte INTEGER,
50
+ signature TEXT,
51
+ docstring TEXT,
52
+ source TEXT,
53
+ parent TEXT,
54
+ is_async INTEGER,
55
+ is_exported INTEGER,
56
+ extras TEXT
57
+ );
58
+
59
+ CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file);
60
+ CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
61
+ CREATE INDEX IF NOT EXISTS idx_symbols_id ON symbols(id);
62
+ `;
63
+ /**
64
+ * v1 -> v2: rebuild `symbols` without the PRIMARY KEY, keeping every row already stored.
65
+ *
66
+ * Rebuilt in place rather than by re-importing: for most repos the JSON source is gone, so
67
+ * the db IS the index — dropping it to force a reindex would trade a store that is merely
68
+ * incomplete for no store at all. This recovers nothing on its own; rows lost under v1 come
69
+ * back when the repo is next indexed from source, which now keeps them.
70
+ */
71
+ export const MIGRATE_V1_TO_V2_SQL = `
72
+ ALTER TABLE symbols RENAME TO symbols_v1;
73
+ CREATE TABLE symbols (
74
+ id TEXT NOT NULL,
75
+ file TEXT NOT NULL,
76
+ name TEXT NOT NULL,
77
+ kind TEXT NOT NULL,
78
+ start_line INTEGER NOT NULL,
79
+ end_line INTEGER NOT NULL,
80
+ start_col INTEGER,
81
+ end_col INTEGER,
82
+ start_byte INTEGER,
83
+ end_byte INTEGER,
84
+ signature TEXT,
85
+ docstring TEXT,
86
+ source TEXT,
87
+ parent TEXT,
88
+ is_async INTEGER,
89
+ is_exported INTEGER,
90
+ extras TEXT
91
+ );
92
+ INSERT INTO symbols SELECT * FROM symbols_v1;
93
+ DROP TABLE symbols_v1;
94
+ CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file);
95
+ CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
96
+ CREATE INDEX IF NOT EXISTS idx_symbols_id ON symbols(id);
97
+ `;
98
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/storage/sqlite/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCzB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BnC,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * SQLite backend for the per-repo index. See docs/adr/ADR-003-index-storage-format.md.
3
+ *
4
+ * The point of this module is NOT that SQL is nicer than JSON. It is that the JSON blob
5
+ * forced every write to cost the size of the whole repo: `saveIncremental` re-parsed and
6
+ * re-serialised 262 MB to record one edited file, and the PostToolUse hook — a fresh process
7
+ * per edit, so it can never batch — paid that on every single Write/Edit an agent made.
8
+ * Here a one-file re-index touches one row.
9
+ *
10
+ * Fidelity over elegance: hot fields get real columns (so a full load builds objects without
11
+ * parsing anything), and the rarely-populated tail (`tokens`, `decorators`, `extends`,
12
+ * `implements`, `meta`) is kept as one JSON `extras` column. That keeps the round-trip
13
+ * lossless for language-specific fields nobody here should have to know about, while the
14
+ * common symbol costs zero JSON.parse calls.
15
+ *
16
+ * ---------------------------------------------------------------------------
17
+ *
18
+ * This file is the FACADE. The implementation lives in `./sqlite/`:
19
+ *
20
+ * runtime.ts is node:sqlite present, and the memoised constructor
21
+ * errors.ts operational fault vs "nothing indexed here"
22
+ * schema.ts table definitions and the v1 -> v2 migration, as SQL text
23
+ * rows.ts row <-> domain mapping, and the byte accounting for it
24
+ * connection.ts open/close/cache, schema creation, migration, meta k/v
25
+ * meta.ts the optional meta fields, and the summary shape
26
+ * index-io.ts whole-index read and write — the paths that touch every row
27
+ * accessors.ts narrow reads that never materialise the index
28
+ *
29
+ * The path stays because 12 modules import it; keeping it as a re-export means the split is
30
+ * provably behaviour-preserving rather than an API change dressed as a refactor.
31
+ *
32
+ * Two invariants this arrangement rests on, both invisible to a type-check:
33
+ *
34
+ * - The memoised `node:sqlite` constructor lives ONLY in `runtime.ts`, and the open-connection
35
+ * cache ONLY in `connection.ts`. ESM gives one instance per module, so re-exporting is safe
36
+ * and re-DECLARING is not: a second copy of either forks the state, and the result is a
37
+ * `closeIndexDb` that closes a handle somebody else is still handing out.
38
+ * `tests/storage/sqlite-module-state.test.ts` fails on exactly that fork.
39
+ * - The re-exports below are an explicit list, not `export *`. Adding an export to a submodule
40
+ * should be a decision about this facade, not a side effect of writing a helper.
41
+ */
42
+ export { isSqliteAvailable, loadSqliteCtor, setSqliteCtorForTesting } from "./sqlite/runtime.js";
43
+ export { IndexStorageError, classifyStorageError, isIndexStorageError } from "./sqlite/errors.js";
44
+ export { SCHEMA_VERSION } from "./sqlite/schema.js";
45
+ export { closeAllIndexDbs, closeIndexDb, openIndexDb } from "./sqlite/connection.js";
46
+ export type { IndexSummary } from "./sqlite/meta.js";
47
+ export { importLegacyIndexIfEmpty, loadIndexSqlite, saveIndexSqlite, wasLossilyMigrated, } from "./sqlite/index-io.js";
48
+ export { getDataVersion, getFileEntrySqlite, getFileMtimeSqlite, getSymbolsForFileSqlite, loadIndexSummarySqlite, removeFileFromIndexSqlite, saveIncrementalSqlite, } from "./sqlite/accessors.js";
49
+ //# sourceMappingURL=sqlite-index-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-index-store.d.ts","sourceRoot":"","sources":["../../src/storage/sqlite-index-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEjG,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErF,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * SQLite backend for the per-repo index. See docs/adr/ADR-003-index-storage-format.md.
3
+ *
4
+ * The point of this module is NOT that SQL is nicer than JSON. It is that the JSON blob
5
+ * forced every write to cost the size of the whole repo: `saveIncremental` re-parsed and
6
+ * re-serialised 262 MB to record one edited file, and the PostToolUse hook — a fresh process
7
+ * per edit, so it can never batch — paid that on every single Write/Edit an agent made.
8
+ * Here a one-file re-index touches one row.
9
+ *
10
+ * Fidelity over elegance: hot fields get real columns (so a full load builds objects without
11
+ * parsing anything), and the rarely-populated tail (`tokens`, `decorators`, `extends`,
12
+ * `implements`, `meta`) is kept as one JSON `extras` column. That keeps the round-trip
13
+ * lossless for language-specific fields nobody here should have to know about, while the
14
+ * common symbol costs zero JSON.parse calls.
15
+ *
16
+ * ---------------------------------------------------------------------------
17
+ *
18
+ * This file is the FACADE. The implementation lives in `./sqlite/`:
19
+ *
20
+ * runtime.ts is node:sqlite present, and the memoised constructor
21
+ * errors.ts operational fault vs "nothing indexed here"
22
+ * schema.ts table definitions and the v1 -> v2 migration, as SQL text
23
+ * rows.ts row <-> domain mapping, and the byte accounting for it
24
+ * connection.ts open/close/cache, schema creation, migration, meta k/v
25
+ * meta.ts the optional meta fields, and the summary shape
26
+ * index-io.ts whole-index read and write — the paths that touch every row
27
+ * accessors.ts narrow reads that never materialise the index
28
+ *
29
+ * The path stays because 12 modules import it; keeping it as a re-export means the split is
30
+ * provably behaviour-preserving rather than an API change dressed as a refactor.
31
+ *
32
+ * Two invariants this arrangement rests on, both invisible to a type-check:
33
+ *
34
+ * - The memoised `node:sqlite` constructor lives ONLY in `runtime.ts`, and the open-connection
35
+ * cache ONLY in `connection.ts`. ESM gives one instance per module, so re-exporting is safe
36
+ * and re-DECLARING is not: a second copy of either forks the state, and the result is a
37
+ * `closeIndexDb` that closes a handle somebody else is still handing out.
38
+ * `tests/storage/sqlite-module-state.test.ts` fails on exactly that fork.
39
+ * - The re-exports below are an explicit list, not `export *`. Adding an export to a submodule
40
+ * should be a decision about this facade, not a side effect of writing a helper.
41
+ */
42
+ export { isSqliteAvailable, loadSqliteCtor, setSqliteCtorForTesting } from "./sqlite/runtime.js";
43
+ export { IndexStorageError, classifyStorageError, isIndexStorageError } from "./sqlite/errors.js";
44
+ export { SCHEMA_VERSION } from "./sqlite/schema.js";
45
+ export { closeAllIndexDbs, closeIndexDb, openIndexDb } from "./sqlite/connection.js";
46
+ export { importLegacyIndexIfEmpty, loadIndexSqlite, saveIndexSqlite, wasLossilyMigrated, } from "./sqlite/index-io.js";
47
+ export { getDataVersion, getFileEntrySqlite, getFileMtimeSqlite, getSymbolsForFileSqlite, loadIndexSummarySqlite, removeFileFromIndexSqlite, saveIncrementalSqlite, } from "./sqlite/accessors.js";
48
+ //# sourceMappingURL=sqlite-index-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-index-store.js","sourceRoot":"","sources":["../../src/storage/sqlite-index-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEjG,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAIrF,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/storage/telemetry/config.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD,oFAAoF;AACpF,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAM1C,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,IAAI,YAAY,CAS/C;AAiBD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,cAAc,CAatD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAcrE;AAMD;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAoB/C;AAED,sFAAsF;AACtF,wBAAgB,eAAe,IAAI;IAAE,KAAK,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAc3E"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/storage/telemetry/config.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD,oFAAoF;AACpF,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAM1C,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,IAAI,YAAY,CAS/C;AAiBD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,cAAc,CAatD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAcrE;AAMD;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CA8B/C;AAED,sFAAsF;AACtF,wBAAgB,eAAe,IAAI;IAAE,KAAK,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAc3E"}
@@ -103,9 +103,20 @@ export function maybePrintFirstRunNotice() {
103
103
  catch {
104
104
  /* not shown yet */
105
105
  }
106
- process.stderr.write("[codesift] Anonymous usage stats are ON (tool names, latencies, error/empty rates,\n" +
107
- " bucketed env — NO queries, paths, repo names or code). See exactly what is sent:\n" +
108
- " `codesift telemetry show`. Opt out: CODESIFT_TELEMETRY=off (or DO_NOT_TRACK=1).\n");
106
+ process.stderr.write(
107
+ // The enumeration is the consent. It is a CLOSED list, so anything the
108
+ // payload gains has to be added here BEFORE it ships — a user who read
109
+ // "tool names, latencies, error/empty rates, bucketed env" did not agree
110
+ // to skill-level or quality-gate telemetry, even though the negative
111
+ // claims below stayed true throughout. The retro rollup (ad605bd) is a
112
+ // different CATEGORY of data, not more of the same, which is why it gets
113
+ // its own clause rather than being folded into "usage stats".
114
+ "[codesift] Anonymous usage stats are ON (tool names, latencies, error/empty rates,\n" +
115
+ " bucketed env). If zuvo is installed, also anonymous per-skill rollups: which skill\n" +
116
+ " ran, friction category, whether the audit/adversarial gates produced a verdict or\n" +
117
+ " were skipped, and median effort — NO queries, paths, repo names, branches, commit\n" +
118
+ " hashes, free text or code. See exactly what is sent: `codesift telemetry show`.\n" +
119
+ " Opt out: CODESIFT_TELEMETRY=off (or DO_NOT_TRACK=1).\n");
109
120
  mkdirSync(dataDir(), { recursive: true });
110
121
  writeFileSync(marker, String(Date.now()) + "\n", "utf-8");
111
122
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/storage/telemetry/config.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6DAA6D;AAC7D,8CAA8C;AAC9C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIlC,oFAAoF;AACpF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAE1C,SAAS,OAAO;IACd,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AACxC,CAAC;AAMD,kEAAkE;AAClE,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,EAAE,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,MAAsB,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,oCAAoC;IACtC,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,cAAc,CAAC,CAAU;IAChC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC1E,IAAI,CAAC,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IAChC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,WAAW;QAAE,OAAO,MAAM,CAAC;IAChG,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,CAAqB;IACxC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,IAAI,CAAC;AAC9D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB;IACnC,IAAI,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAE3D,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAClE,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC,SAAS,CAAC;IAC5C,MAAM,SAAS,GAAG,cAAc,CAC9B,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CACtE,CAAC;IACF,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAEhC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAqB;IAC7D,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,IAAI,GAAG,GAA4B,EAAE,CAAC;IACtC,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QAChE,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,GAAG,GAAG,MAAiC,CAAC;IACpF,CAAC;IAAC,MAAM,CAAC;QACP,oCAAoC;IACtC,CAAC;IACD,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC;IAC7B,SAAS,CAAC,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC;IAC1B,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACjE,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,wBAAwB,CAAC,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB;IACtC,IAAI,CAAC;QACH,IAAI,qBAAqB,EAAE,KAAK,MAAM;YAAE,OAAO;QAC/C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC9B,OAAO,CAAC,gBAAgB;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sFAAsF;YACtF,sFAAsF;YACtF,sFAAsF,CACvF,CAAC;QACF,SAAS,CAAC,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,eAAe;IAC7B,IAAI,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;IAC7D,CAAC;IACD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAClE,IAAI,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,sBAAsB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,EAAE,CAAC;IAE1G,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC,SAAS,CAAC;IAC5C,MAAM,SAAS,GAAG,cAAc,CAC9B,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CACtE,CAAC;IACF,IAAI,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,yBAAyB,SAAS,EAAE,EAAE,CAAC;IAEzF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/storage/telemetry/config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../../src/storage/telemetry/payload.ts"],"names":[],"mappings":"AAKA,OAAO,EAAuC,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEzF;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,OAAO,CAAC,aAAa,CAAC,CAShG"}
1
+ {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../../src/storage/telemetry/payload.ts"],"names":[],"mappings":"AAKA,OAAO,EAAuC,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGzF;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,OAAO,CAAC,aAAa,CAAC,CAWhG"}
@@ -4,6 +4,7 @@ import { readLocalUsageEntries, aggregateToolMetrics, aggregateHintFunnel, aggre
4
4
  import { buildEnvProfile } from "./env-profile.js";
5
5
  import { getAnonId } from "./anon-id.js";
6
6
  import { buildLevel1Payload, assertSanitized } from "./sanitizer.js";
7
+ import { aggregateRetros } from "./retro-aggregator.js";
7
8
  /**
8
9
  * Build the exact Level-1 payload that would be sent right now, from the local
9
10
  * usage.jsonl. Repo dimensions are omitted here (added per-context at push
@@ -15,7 +16,9 @@ export async function buildCurrentLevel1Payload(now, sinceTs = 0) {
15
16
  const hints = aggregateHintFunnel(entries);
16
17
  const planTurn = aggregatePlanTurnFunnel(entries);
17
18
  const env = buildEnvProfile();
18
- const payload = buildLevel1Payload({ anonId: getAnonId(), env, tools, hints, planTurn, now });
19
+ // Absent when zuvo is not installed; never an error.
20
+ const retros = await aggregateRetros(sinceTs);
21
+ const payload = buildLevel1Payload({ anonId: getAnonId(), env, tools, hints, planTurn, retros, now });
19
22
  assertSanitized(payload); // throws if the allowlist was ever violated
20
23
  return payload;
21
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"payload.js","sourceRoot":"","sources":["../../../src/storage/telemetry/payload.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,kEAAkE;AAClE,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC5H,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAsB,MAAM,gBAAgB,CAAC;AAEzF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,GAAW,EAAE,OAAO,GAAG,CAAC;IACtE,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,kBAAkB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9F,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,4CAA4C;IACtE,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../../../src/storage/telemetry/payload.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,kEAAkE;AAClE,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC5H,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAsB,MAAM,gBAAgB,CAAC;AACzF,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,GAAW,EAAE,OAAO,GAAG,CAAC;IACtE,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,qDAAqD;IACrD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,kBAAkB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtG,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,4CAA4C;IACtE,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,27 @@
1
+ /** One day's worth of retros for one (skill, outcome-shape) combination. */
2
+ export interface RetroAggregate {
3
+ day: string;
4
+ skill: string;
5
+ code_type: string;
6
+ friction: string;
7
+ context_gap: string;
8
+ codesift: string;
9
+ routing: string;
10
+ count: number;
11
+ /** Medians, not sums: a total would leak how much work this install does. */
12
+ median_turns: number;
13
+ median_tool_calls: number;
14
+ median_files_read: number;
15
+ median_files_modified: number;
16
+ /** How many of these runs ran each safety gate to a real verdict. */
17
+ blind_audit_ran: number;
18
+ adversarial_ran: number;
19
+ }
20
+ /**
21
+ * Read and aggregate `~/.zuvo/retros.log`.
22
+ *
23
+ * Returns [] when zuvo is not installed, which is the common case for a codesift user — this must
24
+ * never be an error, only an absence.
25
+ */
26
+ export declare function aggregateRetros(sinceTs?: number, logPath?: string): Promise<RetroAggregate[]>;
27
+ //# sourceMappingURL=retro-aggregator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retro-aggregator.d.ts","sourceRoot":"","sources":["../../../src/storage/telemetry/retro-aggregator.ts"],"names":[],"mappings":"AA6CA,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qEAAqE;IACrE,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB;AAoDD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,SAAI,EACX,OAAO,SAAyC,GAC/C,OAAO,CAAC,cAAc,EAAE,CAAC,CAyF3B"}
@@ -0,0 +1,179 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ /**
5
+ * Anonymous rollup of zuvo retrospectives, so the install base can report WHERE WORK GOES WRONG —
6
+ * not just which tools were called.
7
+ *
8
+ * Why this rides the codesift payload instead of getting its own channel: the zuvo channel cannot
9
+ * collect from anyone. Its sender ships over SSH to a tailnet-only address, and the collector's
10
+ * public `/ingest/zuvo` requires a secret, deliberately — the collector's own comment says those
11
+ * namespaces "carry repo names and debt text". Measured 2026-08-06: `/ingest/zuvo` and
12
+ * `/ingest/backlog` hold exactly ONE anon_id each (this machine), while `/ingest/codesift` — open,
13
+ * anonymous, no token — has 11 external installs and 11,873 tool calls. The channel that works is
14
+ * the one to use.
15
+ *
16
+ * A retro line is 17 tab-separated fields, and 12 of them are already enums or counts. The other
17
+ * five identify: project, branch, commit sha, and a free-text "missing template" note. Those are
18
+ * NOT sanitised here — they are never read into the aggregate at all. Anonymity by omission
19
+ * survives someone later adding a field to the source format; anonymity by scrubbing does not.
20
+ */
21
+ /** Field positions in a canonical `retros.log` line (0-based, after the `RETRO: <ts>` field). */
22
+ const F = {
23
+ TS: 0,
24
+ SKILL: 1,
25
+ // 2 = project — identifies the repo
26
+ CODE_TYPE: 3,
27
+ FRICTION: 4,
28
+ // 5 = missing-template — free prose written by the agent
29
+ CONTEXT_GAP: 6,
30
+ TURNS: 7,
31
+ TOOL_CALLS: 8,
32
+ FILES_READ: 9,
33
+ FILES_MODIFIED: 10,
34
+ // 11 = branch — often names a ticket or a customer
35
+ // 12 = sha7 — a commit hash is a fingerprint of a specific repo
36
+ BLIND_AUDIT: 13,
37
+ ADVERSARIAL: 14,
38
+ CODESIFT: 15,
39
+ ROUTING: 16,
40
+ };
41
+ const FIELD_COUNT = 17;
42
+ /**
43
+ * Values that mean "this gate did not produce a verdict".
44
+ *
45
+ * `skipped` / `not_run` / `blocked*` are the answers worth counting SEPARATELY from a clean pass —
46
+ * a fleet where the adversarial gate is mostly skipped is a different product problem from one
47
+ * where it runs and finds nothing.
48
+ */
49
+ const GATE_NOT_RUN = new Set(["skipped", "not_run", "blocked", "blocked_infra", "-", ""]);
50
+ /**
51
+ * Collapse anything that is not a short, enum-shaped token to `"other"`.
52
+ *
53
+ * `append-retro` validates these columns against fixed case lists, so in practice they are already
54
+ * enums. In practice is not a guarantee: `retros.log` is a plain text file and a hand-appended or
55
+ * future-format line can put arbitrary prose at any position. Without this, one such line would
56
+ * carry a sentence — possibly naming a repo or a customer — onto an ANONYMOUS endpoint, and the
57
+ * whole basis for riding that endpoint would be gone.
58
+ *
59
+ * Bounded length and a conservative character class, so anonymity holds by construction rather
60
+ * than by trusting the writer.
61
+ */
62
+ const ENUMISH = /^[A-Za-z0-9][A-Za-z0-9_:.\/-]{0,31}$/;
63
+ function enumish(value) {
64
+ const v = (value ?? "").trim();
65
+ if (v === "")
66
+ return "";
67
+ return ENUMISH.test(v) ? v : "other";
68
+ }
69
+ function gateRan(value) {
70
+ const v = value.trim().toLowerCase();
71
+ return v.length > 0 && !GATE_NOT_RUN.has(v) && !v.startsWith("blocked");
72
+ }
73
+ function median(values) {
74
+ if (values.length === 0)
75
+ return 0;
76
+ const sorted = [...values].sort((a, b) => a - b);
77
+ const mid = Math.floor(sorted.length / 2);
78
+ return sorted.length % 2 === 0
79
+ ? Math.round(((sorted[mid - 1] ?? 0) + (sorted[mid] ?? 0)) / 2)
80
+ : (sorted[mid] ?? 0);
81
+ }
82
+ function dayOf(tsField) {
83
+ // `RETRO: 2026-08-05T23:46:44Z` — take the date, drop the clock. Time-of-day plus a repo-sized
84
+ // event count is enough to correlate one install's activity against a public commit history.
85
+ const match = tsField.match(/(\d{4}-\d{2}-\d{2})/);
86
+ return match?.[1] ?? null;
87
+ }
88
+ /**
89
+ * Read and aggregate `~/.zuvo/retros.log`.
90
+ *
91
+ * Returns [] when zuvo is not installed, which is the common case for a codesift user — this must
92
+ * never be an error, only an absence.
93
+ */
94
+ export async function aggregateRetros(sinceTs = 0, logPath = join(homedir(), ".zuvo", "retros.log")) {
95
+ let raw;
96
+ try {
97
+ raw = await readFile(logPath, "utf-8");
98
+ }
99
+ catch {
100
+ return []; // no zuvo on this machine
101
+ }
102
+ const buckets = new Map();
103
+ for (const line of raw.split(/\r?\n/)) {
104
+ if (!line.startsWith("RETRO:"))
105
+ continue;
106
+ const f = line.split("\t");
107
+ // Length is the format check. A drifted line (free prose, an older column count) is skipped
108
+ // rather than parsed by position — reading position 13 of a 9-field line would report whatever
109
+ // happened to be there as an audit verdict.
110
+ if (f.length !== FIELD_COUNT)
111
+ continue;
112
+ const day = dayOf(f[F.TS] ?? "");
113
+ if (!day)
114
+ continue;
115
+ if (sinceTs > 0) {
116
+ const at = Date.parse((f[F.TS] ?? "").replace(/^RETRO:\s*/, ""));
117
+ if (Number.isFinite(at) && at < sinceTs)
118
+ continue;
119
+ }
120
+ // Group on the NORMALISED values, not the raw ones: two lines whose prose differs both store
121
+ // `"other"`, so keying on the raw text would emit two aggregate rows with identical content.
122
+ const dims = {
123
+ skill: enumish(f[F.SKILL]),
124
+ code_type: enumish(f[F.CODE_TYPE]),
125
+ friction: enumish(f[F.FRICTION]),
126
+ context_gap: enumish(f[F.CONTEXT_GAP]),
127
+ codesift: enumish(f[F.CODESIFT]),
128
+ routing: enumish(f[F.ROUTING]),
129
+ };
130
+ // Joined on a separator that cannot occur in an enum-shaped token, so two different dimension
131
+ // tuples can never collide into one bucket.
132
+ const key = [day, ...Object.values(dims)].join("|");
133
+ let b = buckets.get(key);
134
+ if (!b) {
135
+ b = {
136
+ day,
137
+ ...dims,
138
+ blind_audit_ran: 0,
139
+ adversarial_ran: 0,
140
+ turns: [],
141
+ toolCalls: [],
142
+ filesRead: [],
143
+ filesModified: [],
144
+ };
145
+ buckets.set(key, b);
146
+ }
147
+ const num = (i) => {
148
+ const n = Number(f[i]);
149
+ return Number.isFinite(n) && n >= 0 ? n : 0;
150
+ };
151
+ b.turns.push(num(F.TURNS));
152
+ b.toolCalls.push(num(F.TOOL_CALLS));
153
+ b.filesRead.push(num(F.FILES_READ));
154
+ b.filesModified.push(num(F.FILES_MODIFIED));
155
+ if (gateRan(f[F.BLIND_AUDIT] ?? ""))
156
+ b.blind_audit_ran++;
157
+ if (gateRan(f[F.ADVERSARIAL] ?? ""))
158
+ b.adversarial_ran++;
159
+ }
160
+ return [...buckets.values()]
161
+ .map((b) => ({
162
+ day: b.day,
163
+ skill: b.skill,
164
+ code_type: b.code_type,
165
+ friction: b.friction,
166
+ context_gap: b.context_gap,
167
+ codesift: b.codesift,
168
+ routing: b.routing,
169
+ count: b.turns.length,
170
+ median_turns: median(b.turns),
171
+ median_tool_calls: median(b.toolCalls),
172
+ median_files_read: median(b.filesRead),
173
+ median_files_modified: median(b.filesModified),
174
+ blind_audit_ran: b.blind_audit_ran,
175
+ adversarial_ran: b.adversarial_ran,
176
+ }))
177
+ .sort((a, b) => (a.day === b.day ? a.skill.localeCompare(b.skill) : a.day.localeCompare(b.day)));
178
+ }
179
+ //# sourceMappingURL=retro-aggregator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retro-aggregator.js","sourceRoot":"","sources":["../../../src/storage/telemetry/retro-aggregator.ts"],"names":[],"mappings":"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"}