akm-cli 0.9.1 → 0.9.2-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +3 -1
  3. package/SECURITY.md +1 -1
  4. package/STABILITY.md +1 -1
  5. package/dist/akm +2 -2
  6. package/dist/akm-migrate +2 -2
  7. package/dist/assets/hints/cli-hints-full.md +14 -9
  8. package/dist/assets/improve-strategies/proactive-maintenance.json +1 -1
  9. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  10. package/dist/assets/models.json +35 -0
  11. package/dist/assets/tasks/core/extract.yml +6 -5
  12. package/dist/assets/tasks/core/improve.yml +6 -5
  13. package/dist/assets/tasks/core/index-refresh.yml +6 -5
  14. package/dist/assets/tasks/core/sync.yml +6 -5
  15. package/dist/assets/tasks/core/version-check.yml +6 -5
  16. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +6 -5
  17. package/dist/assets/tasks/improve/akm-improve-catchup.yml +6 -5
  18. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +6 -5
  19. package/dist/assets/tasks/improve/akm-improve-frequent.yml +6 -5
  20. package/dist/assets/tasks/improve/akm-improve-nightly.yml +6 -5
  21. package/dist/cli/confirm.js +2 -2
  22. package/dist/cli/parse-args.js +3 -24
  23. package/dist/cli/retired-commands.js +1 -1
  24. package/dist/cli/shared.js +2 -2
  25. package/dist/cli.js +11 -9
  26. package/dist/commands/agent/agent-dispatch.js +55 -89
  27. package/dist/commands/agent/contribute-cli.js +12 -45
  28. package/dist/commands/command/builtin-action.js +32 -0
  29. package/dist/commands/command/command-cli.js +99 -0
  30. package/dist/commands/command/command-execution.js +308 -0
  31. package/dist/commands/command/execution-source-loader.js +176 -0
  32. package/dist/commands/command/portable-template.js +60 -0
  33. package/dist/commands/config-cli.js +10 -4
  34. package/dist/commands/env/env.js +4 -2
  35. package/dist/commands/feedback-cli.js +1 -1
  36. package/dist/commands/health/checks.js +241 -29
  37. package/dist/commands/health/html-report.js +0 -14
  38. package/dist/commands/health/report-view-model.js +0 -1
  39. package/dist/commands/health/surfaces.js +6 -7
  40. package/dist/commands/health/types.js +0 -2
  41. package/dist/commands/health.js +63 -18
  42. package/dist/commands/improve/collapse-detector.js +2 -2
  43. package/dist/commands/improve/consolidate.js +251 -214
  44. package/dist/commands/improve/distill/promote-memory.js +71 -34
  45. package/dist/commands/improve/distill/quality-gate.js +17 -5
  46. package/dist/commands/improve/distill.js +232 -155
  47. package/dist/commands/improve/eligibility.js +112 -79
  48. package/dist/commands/improve/execution.js +57 -0
  49. package/dist/commands/improve/extract-cli.js +5 -5
  50. package/dist/commands/improve/extract.js +521 -342
  51. package/dist/commands/improve/improve-strategies.js +43 -14
  52. package/dist/commands/improve/improve.js +249 -29
  53. package/dist/commands/improve/loop-stages.js +11 -17
  54. package/dist/commands/improve/memory/memory-contradiction-detect.js +90 -66
  55. package/dist/commands/improve/outcome-loop.js +22 -38
  56. package/dist/commands/improve/planner.js +134 -0
  57. package/dist/commands/improve/preparation.js +730 -409
  58. package/dist/commands/improve/reflect.js +386 -223
  59. package/dist/commands/improve/run-context.js +3 -4
  60. package/dist/commands/improve/salience.js +6 -58
  61. package/dist/commands/improve/session-asset.js +12 -12
  62. package/dist/commands/lint/index.js +101 -29
  63. package/dist/commands/migrate-cli.js +11 -69
  64. package/dist/commands/migration-tool.js +6 -9
  65. package/dist/commands/models-cli.js +27 -0
  66. package/dist/commands/proposal/drain.js +258 -186
  67. package/dist/commands/proposal/proposal-cli.js +32 -10
  68. package/dist/commands/proposal/proposal.js +2 -5
  69. package/dist/commands/proposal/propose.js +192 -172
  70. package/dist/commands/proposal/repository.js +54 -91
  71. package/dist/commands/proposal/validators/proposal-validators.js +9 -7
  72. package/dist/commands/read/curate.js +10 -0
  73. package/dist/commands/read/registry-search.js +25 -9
  74. package/dist/commands/read/remember-cli.js +14 -2
  75. package/dist/commands/read/search.js +10 -4
  76. package/dist/commands/read/show.js +139 -153
  77. package/dist/commands/registry-cli.js +16 -7
  78. package/dist/commands/remember.js +33 -18
  79. package/dist/commands/sources/add-cli.js +19 -178
  80. package/dist/commands/sources/bundle-cli.js +15 -3
  81. package/dist/commands/sources/dangerous-env-audit.js +135 -0
  82. package/dist/commands/sources/info.js +2 -1
  83. package/dist/commands/sources/installed-stashes.js +835 -152
  84. package/dist/commands/sources/schema-repair.js +174 -95
  85. package/dist/commands/sources/self-update.js +30 -74
  86. package/dist/commands/sources/source-add.js +3 -5
  87. package/dist/commands/sources/sources-cli.js +2 -15
  88. package/dist/commands/sources/update-transaction.js +220 -0
  89. package/dist/commands/tasks/tasks-cli.js +3 -3
  90. package/dist/commands/tasks/tasks.js +736 -317
  91. package/dist/commands/workflow-cli.js +2 -2
  92. package/dist/core/adapter/adapters/agent-skills-adapter.js +3 -0
  93. package/dist/core/adapter/adapters/akm-adapter.js +83 -34
  94. package/dist/core/adapter/adapters/akm-lint.js +54 -39
  95. package/dist/core/adapter/adapters/akm-metadata.js +45 -45
  96. package/dist/core/adapter/adapters/akm-task-adapter.js +32 -49
  97. package/dist/core/adapter/adapters/akm-workflow-adapter.js +38 -23
  98. package/dist/core/adapter/adapters/dotenv-adapter.js +30 -1
  99. package/dist/core/adapter/adapters/generic-files-adapter.js +11 -0
  100. package/dist/core/adapter/adapters/index.js +0 -9
  101. package/dist/core/adapter/adapters/llm-wiki-adapter.js +4 -0
  102. package/dist/core/adapter/adapters/okf-adapter.js +4 -0
  103. package/dist/core/adapter/adapters/opencode-adapter.js +5 -8
  104. package/dist/core/adapter/adapters/tool-dir-shared.js +63 -6
  105. package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -0
  106. package/dist/core/adapter/execution-source.js +308 -0
  107. package/dist/core/adapter/recognize-match.js +36 -13
  108. package/dist/core/adapter/registry.js +0 -9
  109. package/dist/core/asset/stash-meta.js +94 -4
  110. package/dist/core/common.js +6 -11
  111. package/dist/core/config/config-io.js +3 -3
  112. package/dist/core/config/config-schema.js +18 -40
  113. package/dist/core/config/config-sources.js +11 -21
  114. package/dist/core/config/config-walker.js +31 -13
  115. package/dist/core/config/config.js +21 -20
  116. package/dist/core/config/schema/engines.js +8 -7
  117. package/dist/core/config/schema/improve-processes.js +29 -5
  118. package/dist/core/config/schema/primitives.js +1 -23
  119. package/dist/core/config/schema/sources-bundles.js +13 -16
  120. package/dist/core/errors.js +2 -0
  121. package/dist/core/events.js +68 -32
  122. package/dist/core/extra-params.js +1 -0
  123. package/dist/core/improve-result.js +315 -0
  124. package/dist/core/lesson-lint.js +0 -6
  125. package/dist/core/maintenance-barrier.js +4 -4
  126. package/dist/core/network-policy.js +152 -0
  127. package/dist/core/paths.js +1 -1
  128. package/dist/core/recognition-util.js +4 -4
  129. package/dist/core/registry-url.js +456 -0
  130. package/dist/core/state/migrations.js +161 -47
  131. package/dist/core/state-db.js +453 -80
  132. package/dist/core/system-error.js +32 -0
  133. package/dist/core/time.js +2 -12
  134. package/dist/core/write-source.js +0 -18
  135. package/dist/execution/directory-identity.js +52 -0
  136. package/dist/execution/executable-identity.js +107 -0
  137. package/dist/execution/guarded-source.js +398 -0
  138. package/dist/execution/json.js +95 -0
  139. package/dist/{commands/health/types-session-log.js → execution/limits.js} +2 -1
  140. package/dist/execution/record.js +55 -0
  141. package/dist/execution/resolved-request.js +730 -0
  142. package/dist/execution/source.js +320 -0
  143. package/dist/indexer/bundle-identity-guard.js +5 -4
  144. package/dist/indexer/db/graph-db.js +33 -0
  145. package/dist/indexer/graph/graph-boost.js +3 -4
  146. package/dist/indexer/graph/graph-extraction.js +562 -373
  147. package/dist/indexer/index-written-assets.js +65 -34
  148. package/dist/indexer/indexer.js +443 -222
  149. package/dist/indexer/installations.js +6 -0
  150. package/dist/indexer/lookup/adapter-concept-owner.js +283 -0
  151. package/dist/indexer/passes/memory-inference.js +227 -174
  152. package/dist/indexer/scan/doc-to-entry.js +7 -9
  153. package/dist/indexer/scan/drain-dir.js +51 -23
  154. package/dist/indexer/search/db-search.js +98 -22
  155. package/dist/indexer/search/search-fields.js +1 -1
  156. package/dist/indexer/search/search-hit-enrichers.js +1 -1
  157. package/dist/indexer/search/search-source.js +7 -16
  158. package/dist/indexer/search/semantic-status.js +10 -1
  159. package/dist/indexer/usage/show-usage.js +105 -0
  160. package/dist/indexer/usage/usage-events.js +7 -2
  161. package/dist/indexer/walk/matchers.js +40 -10
  162. package/dist/indexer/walk/path-resolver.js +5 -2
  163. package/dist/indexer/walk/walker.js +20 -2
  164. package/dist/integrations/agent/builder-shared.js +3 -6
  165. package/dist/integrations/agent/conversation-fallback.js +16 -0
  166. package/dist/integrations/agent/engine-resolution.js +87 -87
  167. package/dist/integrations/agent/execution-cascade.js +566 -0
  168. package/dist/integrations/agent/execution-definitions.js +211 -0
  169. package/dist/integrations/agent/execution-lowering.js +811 -0
  170. package/dist/integrations/agent/execution-preparation.js +67 -0
  171. package/dist/integrations/agent/index.js +0 -2
  172. package/dist/integrations/agent/inline-execution.js +74 -0
  173. package/dist/integrations/agent/model-map.js +515 -0
  174. package/dist/integrations/agent/persona-fallback.js +30 -0
  175. package/dist/integrations/agent/request-lowering.js +186 -0
  176. package/dist/integrations/agent/runner-dispatch.js +230 -37
  177. package/dist/integrations/agent/runner.js +12 -83
  178. package/dist/integrations/harnesses/aider/agent-builder.js +8 -0
  179. package/dist/integrations/harnesses/aider/index.js +0 -1
  180. package/dist/integrations/harnesses/amazonq/agent-builder.js +8 -0
  181. package/dist/integrations/harnesses/amazonq/index.js +0 -1
  182. package/dist/integrations/harnesses/claude/agent-builder.js +14 -1
  183. package/dist/integrations/harnesses/claude/index.js +1 -5
  184. package/dist/integrations/harnesses/claude/session-log.js +3 -33
  185. package/dist/integrations/harnesses/codex/agent-builder.js +8 -0
  186. package/dist/integrations/harnesses/codex/index.js +0 -1
  187. package/dist/integrations/harnesses/copilot/agent-builder.js +8 -0
  188. package/dist/integrations/harnesses/copilot/index.js +0 -1
  189. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -0
  190. package/dist/integrations/harnesses/gemini/index.js +0 -1
  191. package/dist/integrations/harnesses/index.js +4 -44
  192. package/dist/integrations/harnesses/opencode/agent-builder.js +16 -9
  193. package/dist/integrations/harnesses/opencode/index.js +0 -2
  194. package/dist/integrations/harnesses/opencode/session-log.js +14 -204
  195. package/dist/integrations/harnesses/opencode-sdk/harness.js +12 -1
  196. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +40 -42
  197. package/dist/integrations/harnesses/openhands/agent-builder.js +8 -0
  198. package/dist/integrations/harnesses/openhands/index.js +0 -1
  199. package/dist/integrations/harnesses/pi/agent-builder.js +8 -0
  200. package/dist/integrations/harnesses/pi/index.js +0 -1
  201. package/dist/integrations/harnesses/shared.js +0 -1
  202. package/dist/integrations/harnesses/types.js +1 -3
  203. package/dist/integrations/lockfile.js +82 -79
  204. package/dist/integrations/session-logs/index.js +6 -17
  205. package/dist/integrations/session-logs/provider-base.js +1 -29
  206. package/dist/llm/client.js +10 -5
  207. package/dist/llm/embedder.js +6 -7
  208. package/dist/llm/embedders/local.js +37 -88
  209. package/dist/llm/embedders/types.js +1 -1
  210. package/dist/llm/graph-extract.js +75 -50
  211. package/dist/llm/index-passes.js +43 -5
  212. package/dist/llm/memory-infer.js +8 -6
  213. package/dist/llm/metadata-enhance.js +5 -3
  214. package/dist/llm/structured-call.js +122 -25
  215. package/dist/output/format-exempt.js +1 -1
  216. package/dist/output/render-registry.js +0 -16
  217. package/dist/output/renderers.js +12 -7
  218. package/dist/output/shapes/curate.js +1 -0
  219. package/dist/output/shapes/helpers.js +10 -2
  220. package/dist/output/shapes/passthrough.js +2 -0
  221. package/dist/output/text/command-format.js +28 -32
  222. package/dist/output/text/health-format.js +1 -29
  223. package/dist/output/text/migrate.js +6 -56
  224. package/dist/output/text/proposal-format.js +16 -1
  225. package/dist/output/text/workflow-format.js +16 -0
  226. package/dist/registry/network.js +279 -0
  227. package/dist/registry/pinned-request-helper.js +247 -0
  228. package/dist/registry/pinned-transport.js +717 -0
  229. package/dist/registry/providers/skills-sh.js +18 -6
  230. package/dist/registry/providers/static-index.js +20 -7
  231. package/dist/registry/resolve.js +53 -28
  232. package/dist/scripts/akm-migrate-node.js +19122 -52218
  233. package/dist/scripts/akm-migrate.js +19064 -51567
  234. package/dist/setup/registry-stash-loader.js +64 -20
  235. package/dist/setup/semantic-assets.js +9 -34
  236. package/dist/setup/setup.js +12 -30
  237. package/dist/setup/source-identity.js +17 -0
  238. package/dist/setup/steps/sources.js +36 -15
  239. package/dist/setup/steps/tasks.js +39 -11
  240. package/dist/sources/providers/git-provider.js +3 -3
  241. package/dist/sources/providers/npm.js +2 -2
  242. package/dist/sources/providers/provider-utils.js +4 -3
  243. package/dist/sources/providers/website.js +11 -7
  244. package/dist/sources/snapshot-fetchers/host-guard.js +9 -136
  245. package/dist/sources/snapshot-fetchers/website-ingest.js +25 -109
  246. package/dist/sources/website-url.js +73 -0
  247. package/dist/storage/engines/sqlite-migrations.js +81 -26
  248. package/dist/storage/managed-db.js +27 -24
  249. package/dist/storage/repositories/events-repository.js +3 -0
  250. package/dist/storage/repositories/index-connection.js +42 -10
  251. package/dist/storage/repositories/index-entries-repository.js +167 -207
  252. package/dist/storage/repositories/index-entry-mapper.js +8 -12
  253. package/dist/storage/repositories/index-entry-schema.js +255 -0
  254. package/dist/storage/repositories/index-fts-repository.js +10 -10
  255. package/dist/storage/repositories/index-llm-cache-repository.js +8 -13
  256. package/dist/storage/repositories/index-meta-repository.js +0 -11
  257. package/dist/storage/repositories/index-schema.js +71 -342
  258. package/dist/storage/repositories/index-utility-repository.js +12 -17
  259. package/dist/storage/repositories/index-vec-repository.js +1 -1
  260. package/dist/storage/repositories/proposals-repository.js +4 -127
  261. package/dist/storage/repositories/registry-cache.js +2 -1
  262. package/dist/storage/repositories/task-history-repository.js +20 -40
  263. package/dist/storage/repositories/workflow-runs-repository.js +228 -129
  264. package/dist/storage/sqlite-read-snapshot.js +148 -0
  265. package/dist/tasks/backends/cron.js +170 -42
  266. package/dist/tasks/backends/index.js +1 -1
  267. package/dist/tasks/backends/launchd.js +787 -202
  268. package/dist/tasks/backends/schtasks.js +282 -83
  269. package/dist/tasks/embedded.js +7 -7
  270. package/dist/tasks/frozen-script.js +50 -0
  271. package/dist/tasks/resolve-akm-bin.js +5 -1
  272. package/dist/tasks/runner.js +239 -251
  273. package/dist/tasks/runtime-v3.js +281 -0
  274. package/dist/tasks/scheduler-binding.js +272 -0
  275. package/dist/tasks/scheduler-invocation.js +57 -43
  276. package/dist/tasks/scheduler-sync.js +654 -0
  277. package/dist/tasks/source-v3.js +752 -0
  278. package/dist/tasks/standalone-script-entry.js +5 -0
  279. package/dist/tasks/task-id.js +29 -0
  280. package/dist/workflows/authoring/authoring.js +15 -32
  281. package/dist/workflows/exec/dispatch-redaction.js +14 -8
  282. package/dist/workflows/exec/exec-unit.js +7 -28
  283. package/dist/workflows/exec/frozen-judge.js +57 -89
  284. package/dist/workflows/exec/lowering-notices.js +23 -0
  285. package/dist/workflows/exec/native-executor.js +301 -458
  286. package/dist/workflows/exec/param-secrets.js +4 -3
  287. package/dist/workflows/exec/run-workflow.js +26 -32
  288. package/dist/workflows/exec/step-work.js +105 -109
  289. package/dist/workflows/exec/unit-dispatch.js +103 -27
  290. package/dist/workflows/exec/unit-writer.js +3 -3
  291. package/dist/workflows/exec/worktree.js +2 -2
  292. package/dist/workflows/ir/compile.js +86 -72
  293. package/dist/workflows/ir/environment-v4.js +328 -0
  294. package/dist/workflows/ir/freeze-v4.js +122 -0
  295. package/dist/workflows/ir/plan-hash.js +13 -7
  296. package/dist/workflows/ir/schema-v4.js +525 -0
  297. package/dist/workflows/ir/schema.js +25 -284
  298. package/dist/workflows/ir/source-freeze-v4.js +506 -0
  299. package/dist/workflows/parser.js +27 -24
  300. package/dist/workflows/program/schema.js +1 -2
  301. package/dist/workflows/renderer.js +42 -29
  302. package/dist/workflows/resource-limits.js +4 -5
  303. package/dist/workflows/runtime/agent-identity.js +11 -13
  304. package/dist/workflows/runtime/plan-classifier.js +8 -8
  305. package/dist/workflows/runtime/runs.js +27 -43
  306. package/dist/workflows/runtime/workflow-asset-loader.js +45 -205
  307. package/dist/workflows/source-files.js +373 -0
  308. package/dist/workflows/source-ir/compile.js +196 -0
  309. package/dist/workflows/source-ir/github-yaml.js +577 -0
  310. package/dist/workflows/source-ir/ordering.js +38 -0
  311. package/dist/workflows/source-ir/program.js +50 -0
  312. package/dist/workflows/source-ir/result.js +26 -0
  313. package/dist/workflows/source-ir/schema.js +772 -0
  314. package/dist/workflows/source-ir/semantics.js +242 -0
  315. package/dist/workflows/source-ir/uses.js +14 -0
  316. package/docs/README.md +2 -0
  317. package/docs/migration/README.md +3 -1
  318. package/docs/migration/release-notes/0.9.2.md +55 -0
  319. package/docs/migration/release-notes/README.md +5 -0
  320. package/docs/migration/v0.8-to-v0.9.md +76 -1077
  321. package/docs/migration/v0.9.0-troubleshooting.md +104 -516
  322. package/docs/migration/v0.9.1-to-v0.9.2.md +150 -0
  323. package/docs/reference/README.md +1 -0
  324. package/docs/reference/cli.md +230 -98
  325. package/docs/reference/configuration.md +153 -27
  326. package/docs/reference/data-and-telemetry.md +19 -1
  327. package/docs/reference/supported-formats.md +23 -3
  328. package/docs/reference/tasks.md +182 -0
  329. package/docs/reference/workflow-schema.md +91 -40
  330. package/docs/reference/workflows.md +33 -6
  331. package/package.json +10 -6
  332. package/schemas/akm-config.json +372 -216
  333. package/schemas/akm-task.json +324 -80
  334. package/schemas/akm-workflow.json +6 -9
  335. package/dist/core/migration-operation.js +0 -75
  336. package/dist/integrations/agent/model-aliases.js +0 -74
  337. package/dist/tasks/parser.js +0 -380
  338. package/dist/tasks/schema.js +0 -123
  339. package/dist/tasks/validator.js +0 -80
  340. package/dist/workflows/ir/freeze.js +0 -320
  341. package/dist/workflows/runtime/document-cache.js +0 -13
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Centralizes the one canonical `entries` SELECT column list and the
8
8
  * JSON-parse-guarded row → {@link DbIndexedEntry} mapping that several queries
9
- * used to reimplement. Corrupt `entry_json` rows are skipped (warn once) rather
9
+ * used to reimplement. Corrupt `document_json` rows are skipped (warn once) rather
10
10
  * than crashing the caller.
11
11
  *
12
12
  * Relocated from `src/indexer/db/entry-mapper.ts` (WI-5a): it now imports the
@@ -23,36 +23,32 @@ import { warn } from "../../core/warn.js";
23
23
  * Durable identity columns are surfaced here so every mapped entry carries
24
24
  * current indexed provenance.
25
25
  */
26
- export const ENTRY_COLUMNS = "id, entry_key, dir_path, file_path, stash_dir, entry_json, search_text, item_ref, concept_id, bundle_id, adapter_id";
26
+ export const ENTRY_COLUMNS = "id, item_ref, bundle_id, component_id, concept_id, adapter_id, type, file_path, content_hash, document_json, search_text";
27
27
  /**
28
- * Map one raw `entries` row to a {@link DbIndexedEntry}, parsing `entry_json`.
28
+ * Map one raw `entries` row to a {@link DbIndexedEntry}, parsing `document_json`.
29
29
  * Returns `null` (and warns, tagged with `context`) when the JSON is corrupt so
30
30
  * callers can skip the row instead of crashing.
31
31
  */
32
32
  export function rowToIndexedEntry(row, context) {
33
33
  let entry;
34
34
  try {
35
- entry = JSON.parse(row.entry_json);
35
+ entry = JSON.parse(row.document_json);
36
36
  }
37
37
  catch {
38
- warn(`[db] ${context}: skipping entry id=${row.id} — corrupt entry_json`);
39
- return null;
40
- }
41
- if (!row.item_ref || !row.concept_id || !row.bundle_id || !row.adapter_id) {
42
- warn(`[db] ${context}: skipping entry id=${row.id} — missing indexed provenance`);
38
+ warn(`[db] ${context}: skipping entry id=${row.id} — corrupt document_json`);
43
39
  return null;
44
40
  }
45
41
  return {
46
42
  id: row.id,
47
- entryKey: row.entry_key,
48
- dirPath: row.dir_path,
49
43
  filePath: row.file_path,
50
- stashDir: row.stash_dir,
51
44
  entry,
52
45
  searchText: row.search_text,
53
46
  itemRef: row.item_ref,
54
47
  conceptId: row.concept_id,
55
48
  bundleId: row.bundle_id,
49
+ componentId: row.component_id,
56
50
  adapterId: row.adapter_id,
51
+ type: row.type,
52
+ ...(row.content_hash ? { contentHash: row.content_hash } : {}),
57
53
  };
58
54
  }
@@ -0,0 +1,255 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * The single canonical contract for the derived `entries` generation.
6
+ *
7
+ * `index.db` is regenerable, so callers compare one normalized PRAGMA
8
+ * fingerprint and discard any generation that differs. This module owns both
9
+ * the DDL and its expected fingerprint so schema creation, writable opens,
10
+ * serving preflights, and read-only evaluator tooling cannot drift into
11
+ * separate definitions of "current".
12
+ */
13
+ export const CANONICAL_INDEX_DB_VERSION = 21;
14
+ export const CANONICAL_ENTRY_SCHEMA_SQL = `
15
+ CREATE TABLE IF NOT EXISTS entries (
16
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
17
+ item_ref TEXT NOT NULL UNIQUE,
18
+ bundle_id TEXT NOT NULL,
19
+ component_id TEXT NOT NULL,
20
+ concept_id TEXT NOT NULL,
21
+ adapter_id TEXT NOT NULL,
22
+ type TEXT NOT NULL,
23
+ file_path TEXT NOT NULL,
24
+ content_hash TEXT,
25
+ document_json TEXT NOT NULL,
26
+ search_text TEXT NOT NULL,
27
+ derived_from TEXT
28
+ );
29
+
30
+ CREATE INDEX IF NOT EXISTS idx_entries_bundle ON entries(bundle_id);
31
+ CREATE INDEX IF NOT EXISTS idx_entries_type ON entries(type);
32
+ CREATE INDEX IF NOT EXISTS idx_entries_file_path ON entries(file_path);
33
+ CREATE INDEX IF NOT EXISTS idx_entries_derived_from ON entries(derived_from);
34
+ `;
35
+ const CANONICAL_ENTRY_SCHEMA_FINGERPRINT = {
36
+ tableSql: "CREATE TABLE entries ( id INTEGER PRIMARY KEY AUTOINCREMENT, item_ref TEXT NOT NULL UNIQUE, bundle_id TEXT NOT NULL, component_id TEXT NOT NULL, concept_id TEXT NOT NULL, adapter_id TEXT NOT NULL, type TEXT NOT NULL, file_path TEXT NOT NULL, content_hash TEXT, document_json TEXT NOT NULL, search_text TEXT NOT NULL, derived_from TEXT )",
37
+ sqliteSequenceTable: true,
38
+ sqliteSequenceValid: true,
39
+ columns: [
40
+ { cid: 0, name: "id", type: "INTEGER", notNull: 0, defaultValue: null, primaryKeyPosition: 1, hidden: 0 },
41
+ {
42
+ cid: 1,
43
+ name: "item_ref",
44
+ type: "TEXT",
45
+ notNull: 1,
46
+ defaultValue: null,
47
+ primaryKeyPosition: 0,
48
+ hidden: 0,
49
+ },
50
+ {
51
+ cid: 2,
52
+ name: "bundle_id",
53
+ type: "TEXT",
54
+ notNull: 1,
55
+ defaultValue: null,
56
+ primaryKeyPosition: 0,
57
+ hidden: 0,
58
+ },
59
+ {
60
+ cid: 3,
61
+ name: "component_id",
62
+ type: "TEXT",
63
+ notNull: 1,
64
+ defaultValue: null,
65
+ primaryKeyPosition: 0,
66
+ hidden: 0,
67
+ },
68
+ {
69
+ cid: 4,
70
+ name: "concept_id",
71
+ type: "TEXT",
72
+ notNull: 1,
73
+ defaultValue: null,
74
+ primaryKeyPosition: 0,
75
+ hidden: 0,
76
+ },
77
+ {
78
+ cid: 5,
79
+ name: "adapter_id",
80
+ type: "TEXT",
81
+ notNull: 1,
82
+ defaultValue: null,
83
+ primaryKeyPosition: 0,
84
+ hidden: 0,
85
+ },
86
+ { cid: 6, name: "type", type: "TEXT", notNull: 1, defaultValue: null, primaryKeyPosition: 0, hidden: 0 },
87
+ {
88
+ cid: 7,
89
+ name: "file_path",
90
+ type: "TEXT",
91
+ notNull: 1,
92
+ defaultValue: null,
93
+ primaryKeyPosition: 0,
94
+ hidden: 0,
95
+ },
96
+ {
97
+ cid: 8,
98
+ name: "content_hash",
99
+ type: "TEXT",
100
+ notNull: 0,
101
+ defaultValue: null,
102
+ primaryKeyPosition: 0,
103
+ hidden: 0,
104
+ },
105
+ {
106
+ cid: 9,
107
+ name: "document_json",
108
+ type: "TEXT",
109
+ notNull: 1,
110
+ defaultValue: null,
111
+ primaryKeyPosition: 0,
112
+ hidden: 0,
113
+ },
114
+ {
115
+ cid: 10,
116
+ name: "search_text",
117
+ type: "TEXT",
118
+ notNull: 1,
119
+ defaultValue: null,
120
+ primaryKeyPosition: 0,
121
+ hidden: 0,
122
+ },
123
+ {
124
+ cid: 11,
125
+ name: "derived_from",
126
+ type: "TEXT",
127
+ notNull: 0,
128
+ defaultValue: null,
129
+ primaryKeyPosition: 0,
130
+ hidden: 0,
131
+ },
132
+ ],
133
+ indexes: [
134
+ {
135
+ name: "idx_entries_bundle",
136
+ unique: 0,
137
+ origin: "c",
138
+ partial: 0,
139
+ columns: [
140
+ { sequence: 0, cid: 2, name: "bundle_id", descending: 0, collation: "BINARY", key: 1 },
141
+ { sequence: 1, cid: -1, name: null, descending: 0, collation: "BINARY", key: 0 },
142
+ ],
143
+ },
144
+ {
145
+ name: "idx_entries_derived_from",
146
+ unique: 0,
147
+ origin: "c",
148
+ partial: 0,
149
+ columns: [
150
+ { sequence: 0, cid: 11, name: "derived_from", descending: 0, collation: "BINARY", key: 1 },
151
+ { sequence: 1, cid: -1, name: null, descending: 0, collation: "BINARY", key: 0 },
152
+ ],
153
+ },
154
+ {
155
+ name: "idx_entries_file_path",
156
+ unique: 0,
157
+ origin: "c",
158
+ partial: 0,
159
+ columns: [
160
+ { sequence: 0, cid: 7, name: "file_path", descending: 0, collation: "BINARY", key: 1 },
161
+ { sequence: 1, cid: -1, name: null, descending: 0, collation: "BINARY", key: 0 },
162
+ ],
163
+ },
164
+ {
165
+ name: "idx_entries_type",
166
+ unique: 0,
167
+ origin: "c",
168
+ partial: 0,
169
+ columns: [
170
+ { sequence: 0, cid: 6, name: "type", descending: 0, collation: "BINARY", key: 1 },
171
+ { sequence: 1, cid: -1, name: null, descending: 0, collation: "BINARY", key: 0 },
172
+ ],
173
+ },
174
+ {
175
+ name: "sqlite_autoindex_entries_1",
176
+ unique: 1,
177
+ origin: "u",
178
+ partial: 0,
179
+ columns: [
180
+ { sequence: 0, cid: 1, name: "item_ref", descending: 0, collation: "BINARY", key: 1 },
181
+ { sequence: 1, cid: -1, name: null, descending: 0, collation: "BINARY", key: 0 },
182
+ ],
183
+ },
184
+ ],
185
+ };
186
+ function sqlString(value) {
187
+ return `'${value.replaceAll("'", "''")}'`;
188
+ }
189
+ function normalizeSchemaSql(value) {
190
+ if (value == null)
191
+ return null;
192
+ return value.replace(/\s+/g, " ").trim();
193
+ }
194
+ export function readEntrySchemaFingerprint(db) {
195
+ const tableRow = db.prepare("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'entries'").get();
196
+ const sqliteSequenceTable = db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = 'sqlite_sequence'").get() !=
197
+ null;
198
+ const maxId = Number(db.prepare("SELECT COALESCE(MAX(id), 0) AS maxId FROM entries").get().maxId);
199
+ const sequenceRow = sqliteSequenceTable
200
+ ? db.prepare("SELECT seq FROM sqlite_sequence WHERE name = 'entries'").get()
201
+ : undefined;
202
+ const sqliteSequenceValid = sqliteSequenceTable &&
203
+ (maxId === 0 ? sequenceRow == null || Number(sequenceRow.seq) >= 0 : Number(sequenceRow?.seq) >= maxId);
204
+ const columns = db.prepare("PRAGMA table_xinfo(entries)").all().map((column) => ({
205
+ cid: Number(column.cid),
206
+ name: column.name,
207
+ type: column.type.trim().toUpperCase(),
208
+ notNull: Number(column.notnull),
209
+ defaultValue: column.dflt_value === null ? null : String(column.dflt_value),
210
+ primaryKeyPosition: Number(column.pk),
211
+ hidden: Number(column.hidden),
212
+ }));
213
+ const indexes = db.prepare("PRAGMA index_list(entries)").all()
214
+ .map((index) => ({
215
+ name: index.name,
216
+ unique: Number(index.unique),
217
+ origin: index.origin,
218
+ partial: Number(index.partial),
219
+ columns: db.prepare(`PRAGMA index_xinfo(${sqlString(index.name)})`).all()
220
+ .sort((left, right) => Number(left.seqno) - Number(right.seqno))
221
+ .map((column) => ({
222
+ sequence: Number(column.seqno),
223
+ cid: Number(column.cid),
224
+ name: column.name,
225
+ descending: Number(column.desc),
226
+ collation: column.coll,
227
+ key: Number(column.key),
228
+ })),
229
+ }))
230
+ .sort((left, right) => left.name.localeCompare(right.name));
231
+ return {
232
+ tableSql: normalizeSchemaSql(tableRow?.sql),
233
+ sqliteSequenceTable,
234
+ sqliteSequenceValid,
235
+ columns,
236
+ indexes,
237
+ };
238
+ }
239
+ export function hasCanonicalEntrySchema(db) {
240
+ try {
241
+ return JSON.stringify(readEntrySchemaFingerprint(db)) === JSON.stringify(CANONICAL_ENTRY_SCHEMA_FINGERPRINT);
242
+ }
243
+ catch {
244
+ return false;
245
+ }
246
+ }
247
+ export function isCanonicalIndexGeneration(db) {
248
+ try {
249
+ const row = db.prepare("SELECT value FROM index_meta WHERE key = 'version'").get();
250
+ return row?.value === String(CANONICAL_INDEX_DB_VERSION) && hasCanonicalEntrySchema(db);
251
+ }
252
+ catch {
253
+ return false;
254
+ }
255
+ }
@@ -34,7 +34,7 @@ function runFtsQuery(db, ftsQuery, limit, entryType, excludeTypes) {
34
34
  // exclusion is redundant there. An empty list skips the clause entirely
35
35
  // (never emit `NOT IN ()`, which is a SQL error / always-false).
36
36
  const excludes = excludeTypes && excludeTypes.length > 0 ? excludeTypes : [];
37
- // The typed and untyped paths differ ONLY by one WHERE clause (an entry_type
37
+ // The typed and untyped paths differ only by one `type` WHERE clause
38
38
  // equality vs. an optional NOT IN exclusion) and their param order — the
39
39
  // SELECT/JOIN/ORDER/LIMIT is shared, so build it once. Join on integer
40
40
  // entry_id directly (no CAST; we store integer). bm25() per-column weights:
@@ -42,16 +42,16 @@ function runFtsQuery(db, ftsQuery, limit, entryType, excludeTypes) {
42
42
  let filterClause;
43
43
  let params;
44
44
  if (entryType && entryType !== "any") {
45
- filterClause = "AND e.entry_type = ?";
45
+ filterClause = "AND e.type = ?";
46
46
  params = [ftsQuery, entryType, limit];
47
47
  }
48
48
  else {
49
- filterClause = excludes.length > 0 ? `AND e.entry_type NOT IN (${excludes.map(() => "?").join(", ")})` : "";
49
+ filterClause = excludes.length > 0 ? `AND e.type NOT IN (${excludes.map(() => "?").join(", ")})` : "";
50
50
  // Param order: MATCH, then the NOT IN values, then LIMIT.
51
51
  params = [ftsQuery, ...excludes, limit];
52
52
  }
53
53
  const sql = `
54
- SELECT e.id, e.file_path AS filePath, e.entry_json, e.search_text AS searchText,
54
+ SELECT e.id, e.file_path AS filePath, e.document_json AS documentJson, e.search_text AS searchText,
55
55
  e.item_ref AS itemRef, e.bundle_id AS bundleId, e.concept_id AS conceptId, e.adapter_id AS adapterId,
56
56
  bm25(entries_fts, 0, 10.0, 5.0, 3.0, 2.0, 1.0) AS bm25Score
57
57
  FROM entries_fts f
@@ -68,10 +68,10 @@ function runFtsQuery(db, ftsQuery, limit, entryType, excludeTypes) {
68
68
  for (const row of rows) {
69
69
  let entry;
70
70
  try {
71
- entry = JSON.parse(row.entry_json);
71
+ entry = JSON.parse(row.documentJson);
72
72
  }
73
73
  catch {
74
- warn(`[db] searchFts: skipping entry id=${row.id} — corrupt entry_json`);
74
+ warn(`[db] searchFts: skipping entry id=${row.id} — corrupt document_json`);
75
75
  continue;
76
76
  }
77
77
  results.push({
@@ -116,7 +116,7 @@ export function rebuildFts(db, options) {
116
116
  // Then drop the matching rows from entries_fts so the INSERT below
117
117
  // doesn't double-up. The dirty list is drained at the end.
118
118
  rows = db
119
- .prepare(`SELECT e.id AS id, e.entry_json AS entry_json
119
+ .prepare(`SELECT e.id AS id, e.document_json AS document_json
120
120
  FROM entries_fts_dirty d
121
121
  JOIN entries e ON e.id = d.entry_id`)
122
122
  .all();
@@ -134,7 +134,7 @@ export function rebuildFts(db, options) {
134
134
  else {
135
135
  // Full path: wipe and re-read every row.
136
136
  db.exec("DELETE FROM entries_fts");
137
- rows = db.prepare("SELECT id, entry_json FROM entries").all();
137
+ rows = db.prepare("SELECT id, document_json FROM entries").all();
138
138
  }
139
139
  const insertStmt = db.prepare("INSERT INTO entries_fts (entry_id, name, description, tags, hints, content) VALUES (?, ?, ?, ?, ?, ?)");
140
140
  let skipped = 0;
@@ -142,7 +142,7 @@ export function rebuildFts(db, options) {
142
142
  let entry;
143
143
  let fields;
144
144
  try {
145
- entry = JSON.parse(row.entry_json);
145
+ entry = JSON.parse(row.document_json);
146
146
  fields = buildSearchFields(entry);
147
147
  }
148
148
  catch {
@@ -152,7 +152,7 @@ export function rebuildFts(db, options) {
152
152
  insertStmt.run(row.id, fields.name, fields.description, fields.tags, fields.hints, fields.content);
153
153
  }
154
154
  if (skipped > 0) {
155
- warn(`[db] rebuildFts: skipped ${skipped} entr${skipped === 1 ? "y" : "ies"} with invalid entry_json`);
155
+ warn(`[db] rebuildFts: skipped ${skipped} entr${skipped === 1 ? "y" : "ies"} with invalid document_json`);
156
156
  }
157
157
  // Always drain the dirty queue — both paths converge here. The
158
158
  // incremental path drains it because we just consumed every dirty row;
@@ -7,7 +7,6 @@
7
7
  * Owns the raw SQL for `llm_enrichment_cache` — the body-hash-keyed cache that
8
8
  * lets `akm index --enrich` skip the LLM call when a file's body is unchanged.
9
9
  */
10
- import { bestEffort } from "../../core/best-effort.js";
11
10
  import { sha256Hex } from "../../runtime.js";
12
11
  import { SQLITE_CHUNK_SIZE } from "./index-sql.js";
13
12
  /**
@@ -83,20 +82,16 @@ export function upsertLlmCacheEntry(db, assetRef, bodyHash, resultJson, cacheVar
83
82
  * `entries` table. Should be called during the cleanup phase of each index
84
83
  * run to prevent the cache from growing unboundedly as assets are removed.
85
84
  *
86
- * The join uses a LIKE match against the entries `file_path` column because
87
- * graph/memory cache refs are absolute file paths, while enrichment cache
88
- * refs are entry_key strings — we preserve any entry that still has a
89
- * corresponding row in either the entries table (by entry_key) or that
90
- * matches a live file_path.
85
+ * Graph/memory cache refs are absolute file paths, while metadata-enrichment
86
+ * refs use canonical `item_ref`; preserve a cache row that matches either
87
+ * current identity.
91
88
  */
92
89
  export function clearStaleCacheEntries(db) {
93
- bestEffort(() => {
94
- db.exec(`
95
- DELETE FROM llm_enrichment_cache
96
- WHERE asset_ref NOT IN (SELECT file_path FROM entries)
97
- AND asset_ref NOT IN (SELECT entry_key FROM entries)
98
- `);
99
- }, "llm_enrichment_cache may not exist in very old DBs opened without ensureSchema");
90
+ db.exec(`
91
+ DELETE FROM llm_enrichment_cache
92
+ WHERE asset_ref NOT IN (SELECT file_path FROM entries)
93
+ AND asset_ref NOT IN (SELECT item_ref FROM entries)
94
+ `);
100
95
  }
101
96
  /**
102
97
  * Compute a stable SHA-256 hex digest of a UTF-8 string. Used as the body_hash
@@ -1,14 +1,6 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- /**
5
- * `index.db` meta + per-directory index-state repository.
6
- *
7
- * Owns the raw SQL for `index_meta` (the key/value stamp table) and
8
- * `index_dir_state` (incremental-index bookkeeping). Lives in the storage
9
- * layer, not the indexer, so the storage layer owns these primitives.
10
- */
11
- import path from "node:path";
12
4
  // ── Meta helpers ────────────────────────────────────────────────────────────
13
5
  export function getMeta(db, key) {
14
6
  const row = db.prepare("SELECT value FROM index_meta WHERE key = ?").get(key);
@@ -55,6 +47,3 @@ export function upsertIndexDirState(db, state) {
55
47
  export function deleteIndexDirState(db, dirPath) {
56
48
  db.prepare("DELETE FROM index_dir_state WHERE dir_path = ?").run(dirPath);
57
49
  }
58
- export function deleteIndexDirStatesByStashDir(db, stashDir) {
59
- db.prepare("DELETE FROM index_dir_state WHERE dir_path = ? OR dir_path LIKE ?").run(stashDir, `${stashDir}${path.sep}%`);
60
- }