akm-cli 0.9.17-alpha.3 → 0.9.17-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/CHANGELOG.md +731 -0
  2. package/dist/akm +94 -196
  3. package/dist/cli/shared.js +6 -2
  4. package/dist/cli.js +22 -9
  5. package/dist/commands/agent/agent-dispatch.js +1 -1
  6. package/dist/commands/command/command-execution.js +24 -62
  7. package/dist/commands/feedback-cli.js +0 -1
  8. package/dist/commands/health/accept-rate.js +2 -2
  9. package/dist/commands/health/checks.js +30 -75
  10. package/dist/commands/health/config-skew.js +38 -0
  11. package/dist/commands/health/egress.js +54 -0
  12. package/dist/commands/health/html-report.js +0 -38
  13. package/dist/commands/health/improve-metrics.js +123 -562
  14. package/dist/commands/health/plugin-staleness.js +53 -3
  15. package/dist/commands/health/renderers.js +12 -4
  16. package/dist/commands/health/report-view-model.js +11 -106
  17. package/dist/commands/health/types-improve.js +4 -19
  18. package/dist/commands/health/windows.js +64 -73
  19. package/dist/commands/health.js +122 -143
  20. package/dist/commands/improve/consolidate/chunking.js +25 -100
  21. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  22. package/dist/commands/improve/consolidate.js +538 -1075
  23. package/dist/commands/improve/content-hash.js +16 -24
  24. package/dist/commands/improve/distill/content-repair.js +18 -100
  25. package/dist/commands/improve/distill-guards.js +20 -81
  26. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  27. package/dist/commands/improve/distill.js +608 -1075
  28. package/dist/commands/improve/eligibility.js +126 -400
  29. package/dist/commands/improve/execution.js +3 -5
  30. package/dist/commands/improve/extract.js +487 -1046
  31. package/dist/commands/improve/feedback-valence.js +0 -25
  32. package/dist/commands/improve/improve-cli.js +29 -166
  33. package/dist/commands/improve/improve-result-file.js +10 -66
  34. package/dist/commands/improve/improve-strategies.js +12 -7
  35. package/dist/commands/improve/improve-usage-report.js +18 -64
  36. package/dist/commands/improve/improve.js +443 -1063
  37. package/dist/commands/improve/ledger.js +114 -0
  38. package/dist/commands/improve/locks.js +2 -8
  39. package/dist/commands/improve/loop-stages.js +459 -1172
  40. package/dist/commands/improve/memory/derived-ref.js +12 -77
  41. package/dist/commands/improve/memory/memory-belief.js +14 -118
  42. package/dist/commands/improve/memory/memory-improve.js +4 -3
  43. package/dist/commands/improve/outcome-loop.js +28 -156
  44. package/dist/commands/improve/planner.js +5 -10
  45. package/dist/commands/improve/preparation.js +851 -2339
  46. package/dist/commands/improve/proactive-maintenance.js +34 -101
  47. package/dist/commands/improve/reflect-noise.js +104 -280
  48. package/dist/commands/improve/reflect.js +621 -1367
  49. package/dist/commands/improve/salience.js +46 -232
  50. package/dist/commands/improve/session-asset.js +19 -100
  51. package/dist/commands/improve/stage.js +323 -0
  52. package/dist/commands/proposal/drain.js +251 -644
  53. package/dist/commands/proposal/proposal-cli.js +3 -18
  54. package/dist/commands/proposal/proposal-types.js +20 -41
  55. package/dist/commands/proposal/proposal.js +1 -2
  56. package/dist/commands/proposal/propose.js +134 -160
  57. package/dist/commands/proposal/repository.js +502 -1487
  58. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  59. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  60. package/dist/commands/proposal/validators/proposals.js +13 -89
  61. package/dist/commands/read/curate.js +63 -413
  62. package/dist/commands/read/search-cli.js +16 -33
  63. package/dist/commands/read/search.js +17 -23
  64. package/dist/commands/read/show.js +2 -13
  65. package/dist/commands/sources/bundle-cli.js +25 -2
  66. package/dist/commands/sources/bundle-config-ops.js +7 -0
  67. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  68. package/dist/commands/sources/info.js +2 -11
  69. package/dist/commands/sources/installed-stashes.js +197 -746
  70. package/dist/commands/sources/schema-repair.js +98 -129
  71. package/dist/commands/sources/source-add.js +62 -12
  72. package/dist/commands/sources/stash-cli.js +1 -1
  73. package/dist/commands/tasks/explain.js +10 -13
  74. package/dist/commands/tasks/tasks-cli.js +9 -8
  75. package/dist/commands/tasks/tasks.js +326 -930
  76. package/dist/commands/tasks/validate.js +42 -21
  77. package/dist/commands/workflow/plan.js +22 -29
  78. package/dist/commands/workflow-cli.js +4 -4
  79. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  80. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  81. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  82. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  83. package/dist/core/adapter/execution-source.js +17 -29
  84. package/dist/core/asset/resolve-ref.js +1 -1
  85. package/dist/core/bundle-id.js +42 -5
  86. package/dist/core/bundle-rename.js +291 -0
  87. package/dist/core/config/config-io.js +1 -2
  88. package/dist/core/config/config-schema.js +1 -33
  89. package/dist/core/config/config-walker.js +1 -1
  90. package/dist/core/config/config.js +163 -68
  91. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  92. package/dist/core/config/schema/embedding.js +20 -5
  93. package/dist/core/config/schema/engines.js +5 -0
  94. package/dist/core/config/schema/execution.js +1 -1
  95. package/dist/core/config/schema/experimental.js +1 -1
  96. package/dist/core/config/schema/improve-processes.js +21 -95
  97. package/dist/core/config/schema/improve.js +4 -42
  98. package/dist/core/config/schema/scheduler.js +12 -12
  99. package/dist/core/config/schema/search.js +6 -22
  100. package/dist/core/env-secret-ref.js +0 -1
  101. package/dist/core/errors.js +8 -9
  102. package/dist/core/file-lock.js +76 -173
  103. package/dist/core/logs-db.js +2 -2
  104. package/dist/core/paths.js +0 -27
  105. package/dist/core/redaction.js +109 -2
  106. package/dist/core/run-lock.js +2 -5
  107. package/dist/core/spawn-env.js +1 -1
  108. package/dist/core/state/migrations.js +108 -61
  109. package/dist/core/state-db-scope.js +2 -4
  110. package/dist/core/state-db.js +126 -692
  111. package/dist/core/type-presentation.js +1 -9
  112. package/dist/core/write-source.js +293 -1012
  113. package/dist/execution/input-contract.js +1 -1
  114. package/dist/execution/resolved-request.js +135 -689
  115. package/dist/execution/source.js +63 -257
  116. package/dist/execution/target-ref.js +1 -1
  117. package/dist/indexer/bundle-identity-guard.js +2 -2
  118. package/dist/indexer/db/graph-db.js +106 -46
  119. package/dist/indexer/ensure-index.js +44 -85
  120. package/dist/indexer/graph/graph-extraction.js +340 -562
  121. package/dist/indexer/graph/graph-related.js +130 -0
  122. package/dist/indexer/index-rebuild-lock.js +3 -11
  123. package/dist/indexer/index-writer-lock.js +8 -17
  124. package/dist/indexer/index-written-assets.js +139 -151
  125. package/dist/indexer/indexer.js +524 -846
  126. package/dist/indexer/materialize-embeddings.js +60 -397
  127. package/dist/indexer/passes/memory-inference.js +81 -90
  128. package/dist/indexer/passes/metadata.js +132 -200
  129. package/dist/indexer/read-preflight.js +0 -7
  130. package/dist/indexer/scan/doc-to-entry.js +1 -3
  131. package/dist/indexer/scan/drain-dir.js +1 -1
  132. package/dist/indexer/search/db-search.js +181 -590
  133. package/dist/indexer/search/fts-query.js +30 -41
  134. package/dist/indexer/search/ranking.js +28 -154
  135. package/dist/indexer/search/search-attribution.js +12 -32
  136. package/dist/indexer/search/search-fields.js +11 -15
  137. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  138. package/dist/indexer/search/search-source.js +1 -4
  139. package/dist/indexer/usage/usage-events.js +2 -7
  140. package/dist/integrations/agent/engine-fallback.js +23 -40
  141. package/dist/integrations/agent/engine-resolution.js +93 -183
  142. package/dist/integrations/agent/execution.js +507 -0
  143. package/dist/integrations/agent/model-map.js +28 -156
  144. package/dist/integrations/agent/request-lowering.js +66 -141
  145. package/dist/integrations/agent/runner-dispatch.js +143 -321
  146. package/dist/integrations/agent/runner.js +54 -14
  147. package/dist/integrations/lockfile.js +53 -101
  148. package/dist/llm/embedders/deterministic.js +2 -3
  149. package/dist/llm/embedders/profile.js +71 -0
  150. package/dist/llm/embedders/remote.js +10 -15
  151. package/dist/llm/graph-extract.js +3 -12
  152. package/dist/llm/index-passes.js +3 -5
  153. package/dist/llm/memory-infer.js +1 -2
  154. package/dist/llm/metadata-enhance.js +1 -2
  155. package/dist/llm/structured-call.js +5 -24
  156. package/dist/output/generic-render.js +23 -11
  157. package/dist/output/html-render.js +13 -10
  158. package/dist/output/render-registry.js +3 -32
  159. package/dist/output/shapes/helpers.js +2 -34
  160. package/dist/output/shapes/passthrough.js +1 -9
  161. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  162. package/dist/output/text/command-format.js +60 -23
  163. package/dist/output/text/helpers.js +1 -1
  164. package/dist/output/text/migrate.js +5 -14
  165. package/dist/output/text/proposal-format.js +1 -2
  166. package/dist/output/text/workflow-format.js +0 -32
  167. package/dist/output/text.js +2 -0
  168. package/dist/registry/factory.js +4 -19
  169. package/dist/registry/network.js +66 -220
  170. package/dist/registry/providers/index.js +0 -2
  171. package/dist/registry/providers/skills-sh.js +3 -14
  172. package/dist/registry/providers/static-index.js +24 -26
  173. package/dist/registry/resolve.js +55 -131
  174. package/dist/scripts/akm-migrate-node.js +43937 -93313
  175. package/dist/scripts/akm-migrate.js +43697 -93071
  176. package/dist/setup/registry-stash-loader.js +4 -13
  177. package/dist/setup/semantic-assets.js +3 -44
  178. package/dist/setup/setup.js +1 -1
  179. package/dist/setup/steps/tasks.js +25 -15
  180. package/dist/sources/provider-factory.js +17 -18
  181. package/dist/sources/providers/filesystem.js +2 -3
  182. package/dist/sources/providers/git-install.js +7 -1
  183. package/dist/sources/providers/git-provider.js +0 -3
  184. package/dist/sources/providers/git-stash.js +0 -17
  185. package/dist/sources/providers/npm.js +2 -4
  186. package/dist/sources/providers/provider-utils.js +5 -10
  187. package/dist/sources/providers/website.js +0 -2
  188. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  189. package/dist/sources/website-url.js +2 -2
  190. package/dist/storage/database.js +9 -35
  191. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  192. package/dist/storage/repositories/index-connection.js +34 -70
  193. package/dist/storage/repositories/index-entries-repository.js +69 -111
  194. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  195. package/dist/storage/repositories/index-entry-schema.js +83 -269
  196. package/dist/storage/repositories/index-fts-repository.js +86 -256
  197. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  198. package/dist/storage/repositories/index-meta-repository.js +6 -4
  199. package/dist/storage/repositories/index-schema.js +192 -220
  200. package/dist/storage/repositories/index-utility-repository.js +8 -29
  201. package/dist/storage/repositories/index-vec-repository.js +133 -414
  202. package/dist/storage/repositories/outcome-repository.js +2 -1
  203. package/dist/storage/repositories/proposals-repository.js +35 -0
  204. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  205. package/dist/storage/repositories/task-history-repository.js +26 -4
  206. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  207. package/dist/storage/sqlite-migrations.js +136 -0
  208. package/dist/storage/sqlite-pragmas.js +11 -9
  209. package/dist/storage/sqlite-transaction.js +170 -0
  210. package/dist/storage/state-db-integrity.js +34 -27
  211. package/dist/tasks/activation-config.js +134 -62
  212. package/dist/tasks/backends/cron.js +129 -277
  213. package/dist/tasks/backends/exec-utils.js +2 -5
  214. package/dist/tasks/backends/launchd.js +125 -745
  215. package/dist/tasks/backends/schtasks.js +101 -620
  216. package/dist/tasks/prepare/prepare-support.js +5 -15
  217. package/dist/tasks/prepare/prepare.js +0 -2
  218. package/dist/tasks/resolve-akm-bin.js +20 -79
  219. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  220. package/dist/tasks/scheduler-binding.js +18 -238
  221. package/dist/tasks/scheduler-invocation.js +52 -52
  222. package/dist/tasks/scheduler-lock.js +53 -0
  223. package/dist/tasks/scheduler-sync.js +361 -751
  224. package/dist/tasks/source/parse-task-source.js +160 -10
  225. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  226. package/dist/tasks/source/task-to-v4.js +2 -2
  227. package/dist/workflows/authoring/authoring.js +3 -12
  228. package/dist/workflows/compile.js +211 -0
  229. package/dist/workflows/concurrency-policy.js +13 -74
  230. package/dist/workflows/exec/child-invocation.js +3 -17
  231. package/dist/workflows/exec/child-workflow.js +32 -141
  232. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  233. package/dist/workflows/exec/environment.js +98 -0
  234. package/dist/workflows/exec/exec-unit.js +33 -140
  235. package/dist/workflows/exec/frozen-judge.js +7 -59
  236. package/dist/workflows/exec/native-executor.js +82 -341
  237. package/dist/workflows/exec/param-secrets.js +29 -47
  238. package/dist/workflows/exec/run-workflow.js +154 -387
  239. package/dist/workflows/exec/scheduler.js +9 -36
  240. package/dist/workflows/exec/step-work.js +127 -430
  241. package/dist/workflows/exec/unit-dispatch.js +11 -63
  242. package/dist/workflows/exec/unit-writer.js +8 -52
  243. package/dist/workflows/exec/worktree.js +39 -273
  244. package/dist/workflows/freeze/child-output-references.js +4 -15
  245. package/dist/workflows/freeze/environment.js +99 -92
  246. package/dist/workflows/freeze/freeze.js +172 -0
  247. package/dist/workflows/freeze/step-values.js +19 -21
  248. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  249. package/dist/workflows/freeze/targets/command.js +10 -33
  250. package/dist/workflows/freeze/targets/script.js +5 -12
  251. package/dist/workflows/freeze/targets/shell.js +3 -6
  252. package/dist/workflows/freeze/targets/task.js +25 -80
  253. package/dist/workflows/freeze/task-bindings.js +20 -67
  254. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  255. package/dist/workflows/ir/params.js +6 -51
  256. package/dist/workflows/ir/plan-hash.js +2 -34
  257. package/dist/workflows/parser.js +140 -43
  258. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  259. package/dist/workflows/renderer.js +36 -69
  260. package/dist/workflows/resource-limits.js +12 -120
  261. package/dist/workflows/runtime/agent-identity.js +8 -40
  262. package/dist/workflows/runtime/run-outputs.js +3 -6
  263. package/dist/workflows/runtime/run-plan.js +316 -0
  264. package/dist/workflows/runtime/runs.js +48 -200
  265. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  266. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  267. package/dist/workflows/validate-summary.js +2 -7
  268. package/docs/integration/bundling-akm.md +49 -42
  269. package/docs/migration/README.md +1 -0
  270. package/docs/migration/release-notes/0.9.17.md +41 -0
  271. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  272. package/docs/reference/cli.md +182 -125
  273. package/docs/reference/configuration.md +49 -56
  274. package/docs/reference/data-and-telemetry.md +19 -20
  275. package/docs/reference/tasks.md +86 -38
  276. package/docs/reference/workflow-schema.md +14 -18
  277. package/docs/reference/workflows.md +6 -9
  278. package/package.json +1 -1
  279. package/schemas/akm-config.json +87 -406
  280. package/dist/commands/health/advisories.js +0 -150
  281. package/dist/commands/health/metrics.js +0 -329
  282. package/dist/commands/health/surfaces.js +0 -102
  283. package/dist/commands/improve/anti-collapse.js +0 -83
  284. package/dist/commands/improve/collapse-detector.js +0 -432
  285. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  286. package/dist/commands/improve/consolidate/merge.js +0 -146
  287. package/dist/commands/improve/distill/promote-memory.js +0 -329
  288. package/dist/commands/improve/distill/quality-gate.js +0 -500
  289. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  290. package/dist/commands/improve/proposal-envelope.js +0 -31
  291. package/dist/commands/improve/run-context.js +0 -123
  292. package/dist/commands/improve/shared.js +0 -21
  293. package/dist/commands/improve/source-identity.js +0 -28
  294. package/dist/commands/improve/triage.js +0 -96
  295. package/dist/commands/proposal/drain-policies.js +0 -151
  296. package/dist/commands/sources/update-transaction.js +0 -220
  297. package/dist/core/action-contributors.js +0 -28
  298. package/dist/core/config/config-version-shim.js +0 -101
  299. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  300. package/dist/core/fs-txn.js +0 -405
  301. package/dist/core/lexical-score.js +0 -25
  302. package/dist/core/maintenance-barrier.js +0 -167
  303. package/dist/execution/executable-identity.js +0 -105
  304. package/dist/execution/guarded-source.js +0 -441
  305. package/dist/indexer/graph/graph-boost.js +0 -427
  306. package/dist/indexer/graph/graph-dedup.js +0 -95
  307. package/dist/indexer/search/name-match.js +0 -35
  308. package/dist/indexer/search/ranking-contributors.js +0 -515
  309. package/dist/indexer/walk/project-context.js +0 -192
  310. package/dist/integrations/agent/execution-cascade.js +0 -566
  311. package/dist/integrations/agent/execution-definitions.js +0 -202
  312. package/dist/integrations/agent/execution-lowering.js +0 -841
  313. package/dist/integrations/agent/execution-preparation.js +0 -98
  314. package/dist/integrations/agent/inline-execution.js +0 -74
  315. package/dist/registry/create-provider-registry.js +0 -29
  316. package/dist/registry/pinned-request-helper.js +0 -247
  317. package/dist/registry/pinned-transport.js +0 -717
  318. package/dist/sources/providers/index.js +0 -14
  319. package/dist/storage/engines/sqlite-migrations.js +0 -271
  320. package/dist/storage/repositories/canaries-repository.js +0 -107
  321. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  322. package/dist/storage/repositories/registry-cache.js +0 -113
  323. package/dist/tasks/scheduler-sync-preview.js +0 -52
  324. package/dist/workflows/freeze/resolve-steps.js +0 -86
  325. package/dist/workflows/freeze/source-freeze.js +0 -64
  326. package/dist/workflows/ir/compile.js +0 -321
  327. package/dist/workflows/ir/environment-v4.js +0 -330
  328. package/dist/workflows/ir/freeze-v4.js +0 -153
  329. package/dist/workflows/ir/schema-v4.js +0 -745
  330. package/dist/workflows/ir/schema.js +0 -354
  331. package/dist/workflows/program/schema.js +0 -78
  332. package/dist/workflows/runtime/checkin.js +0 -57
  333. package/dist/workflows/runtime/plan-classifier.js +0 -196
  334. package/dist/workflows/runtime/unit-checkin.js +0 -45
  335. package/dist/workflows/runtime/unit-phases.js +0 -20
  336. package/dist/workflows/schema.js +0 -4
  337. package/dist/workflows/source-ir/compile.js +0 -200
  338. package/dist/workflows/source-ir/program.js +0 -50
  339. package/dist/workflows/source-ir/result.js +0 -26
  340. package/dist/workflows/source-ir/schema.js +0 -786
  341. package/dist/workflows/source-ir/triggers.js +0 -79
  342. package/dist/workflows/source-ir/uses.js +0 -40
  343. package/dist/workflows/validator.js +0 -60
@@ -12,9 +12,8 @@
12
12
  * target below so a configured registry cannot preselect a different source
13
13
  * merely by reusing a trusted display ID.
14
14
  */
15
- import { jsonWithByteCap } from "../core/common.js";
16
15
  import { hasRegistryUrlCredentials } from "../core/registry-url.js";
17
- import { allowPrivateRegistryFixtureForTests, cancelRegistryResponse, fetchRegistryResponse, } from "../registry/network.js";
16
+ import { fetchRegistryJson } from "../registry/network.js";
18
17
  import { parseRegistryRef } from "../registry/resolve.js";
19
18
  // ── Default selections ──────────────────────────────────────────────────────
20
19
  const AUTHENTICATED_DEFAULT_TARGETS = {
@@ -74,20 +73,12 @@ export async function loadSetupStashes(registryUrl, timeoutMs = 4000) {
74
73
  }
75
74
  async function loadSetupStashesReal(registryUrl, timeoutMs = 4000) {
76
75
  try {
77
- const response = await fetchRegistryResponse(registryUrl, { headers: { Accept: "application/json" } }, {
78
- policy: { kind: "public-registry" },
76
+ const raw = await fetchRegistryJson(registryUrl, {
77
+ headers: { Accept: "application/json" },
79
78
  timeoutMs,
80
79
  retries: 0,
81
- allowPrivateHostsForTesting: allowPrivateRegistryFixtureForTests(registryUrl),
82
80
  });
83
- if (!response.ok) {
84
- await cancelRegistryResponse(response);
85
- return FALLBACK_STASHES;
86
- }
87
- const raw = await jsonWithByteCap(response, 10 * 1024 * 1024, {
88
- bodyTimeoutMs: timeoutMs,
89
- });
90
- if (!Array.isArray(raw.stashes) || raw.stashes.length === 0)
81
+ if (!Array.isArray(raw?.stashes) || raw.stashes.length === 0)
91
82
  return FALLBACK_STASHES;
92
83
  const entries = raw.stashes.flatMap((item) => {
93
84
  if (!item || typeof item !== "object")
@@ -4,21 +4,13 @@
4
4
  /**
5
5
  * Semantic-search asset preparation for the setup wizard. Transformers.js is
6
6
  * a normal external package dependency; setup never mutates the installed CLI.
7
- * This module only prepares the model and probes sqlite-vec.
7
+ * This module only prepares the model.
8
8
  */
9
- import fs from "node:fs";
10
- import os from "node:os";
11
- import path from "node:path";
12
9
  import * as p from "../cli/clack.js";
13
10
  import { isHttpUrl } from "../core/common.js";
14
11
  import { checkEmbeddingAvailability, DEFAULT_LOCAL_MODEL, isTransformersAvailable } from "../llm/embedder.js";
15
- import { closeDatabase, openIndexDatabase } from "../storage/repositories/index-connection.js";
16
- import { isVecAvailable } from "../storage/repositories/index-vec-repository.js";
17
- // Approximate first-download sizes used in the setup note.
18
- // LOCAL_MODEL_APPROX_SIZE_MB tracks the default local model (DEFAULT_LOCAL_MODEL).
12
+ // Approximate first-download size of the default local model (DEFAULT_LOCAL_MODEL), used in the setup note.
19
13
  const LOCAL_MODEL_APPROX_SIZE_MB = 130;
20
- // SQLITE_VEC_APPROX_SIZE_MB reflects the optional sqlite-vec install footprint.
21
- const SQLITE_VEC_APPROX_SIZE_MB = 5;
22
14
  export function isRemoteEmbeddingConfig(embedding) {
23
15
  return isHttpUrl(embedding?.endpoint);
24
16
  }
@@ -27,14 +19,10 @@ export function isRemoteEmbeddingConfig(embedding) {
27
19
  */
28
20
  export function describeSemanticSearchAssets(embedding) {
29
21
  if (isRemoteEmbeddingConfig(embedding)) {
30
- return [
31
- `• Embedding endpoint: ${embedding?.provider ?? "custom"} / ${embedding?.model} (no local model download)`,
32
- `• sqlite-vec acceleration: optional native extension (~${SQLITE_VEC_APPROX_SIZE_MB} MB when installed separately)`,
33
- ];
22
+ return [`• Embedding endpoint: ${embedding?.provider ?? "custom"} / ${embedding?.model} (no local model download)`];
34
23
  }
35
24
  return [
36
25
  `• Local embedding model: ${embedding?.localModel ?? DEFAULT_LOCAL_MODEL} (~${LOCAL_MODEL_APPROX_SIZE_MB} MB download on first use)`,
37
- `• sqlite-vec acceleration: optional native extension (~${SQLITE_VEC_APPROX_SIZE_MB} MB when installed separately)`,
38
26
  ];
39
27
  }
40
28
  export async function prepareSemanticSearchAssets(config) {
@@ -69,34 +57,5 @@ export async function prepareSemanticSearchAssets(config) {
69
57
  }
70
58
  }
71
59
  spin.stop(remote ? "Remote embedding endpoint is ready." : "Local embedding model downloaded and ready.");
72
- let db;
73
- let probeDir;
74
- try {
75
- probeDir = fs.mkdtempSync(path.join(os.tmpdir(), "akm-setup-vec-probe-"));
76
- db = openIndexDatabase(path.join(probeDir, "probe.db"), config.embedding?.dimension ? { embeddingDim: config.embedding.dimension } : undefined);
77
- if (isVecAvailable(db)) {
78
- p.log.info("sqlite-vec is available for fast vector search.");
79
- }
80
- else {
81
- p.log.info("sqlite-vec is not available. Semantic search will use the JS fallback until the optional extension is installed.");
82
- }
83
- }
84
- catch (error) {
85
- const message = error instanceof Error ? error.message : String(error);
86
- p.log.warn(`Could not open the local database or check for sqlite-vec. Semantic search will use the JS fallback. (${message})\n` +
87
- "Check file permissions and available disk space in the cache directory, or run `akm index --full --verbose` to diagnose.");
88
- }
89
- finally {
90
- if (db)
91
- closeDatabase(db);
92
- if (probeDir) {
93
- try {
94
- fs.rmSync(probeDir, { recursive: true, force: true });
95
- }
96
- catch {
97
- /* ignore cleanup failure */
98
- }
99
- }
100
- }
101
60
  return { ok: true };
102
61
  }
@@ -117,7 +117,7 @@ export function assertSetupConfigPreflight() {
117
117
  catch (error) {
118
118
  if (!(error instanceof ConfigError))
119
119
  throw error;
120
- if (error.code !== "UNSUPPORTED_CONFIG_VERSION" && error.code !== "INVALID_CONFIG_FILE")
120
+ if (error.code !== "INVALID_CONFIG_FILE")
121
121
  throw error;
122
122
  throw new ConfigError(`\`akm setup\` cannot run: the config at ${configPath} did not load (${error.message}). ` +
123
123
  "It was left untouched — setup never writes over a config it cannot first read cleanly.", error.code, "Rewrite the file using the current config schema, or move it aside to start fresh " +
@@ -9,11 +9,11 @@ import { parse as yamlParse, stringify as yamlStringify } from "yaml";
9
9
  import * as p from "../../cli/clack.js";
10
10
  import { akmTasksSync } from "../../commands/tasks/tasks.js";
11
11
  import { makeBundleRef } from "../../core/asset/asset-ref.js";
12
- import { loadConfig, mutateConfig } from "../../core/config/config.js";
12
+ import { loadConfig, mutateConfig, resetConfigCache } from "../../core/config/config.js";
13
13
  import { UsageError } from "../../core/errors.js";
14
14
  import { commitWriteTargetBoundary, deleteAssetFromSource, prepareWriteTargetForMutation, resolveWriteTarget, writeAssetToSource, } from "../../core/write-source.js";
15
- import { schedulerActivationSourceId, schedulerActivations } from "../../tasks/activation-config.js";
16
- import { backendNameForPlatform } from "../../tasks/backends/index.js";
15
+ import { enabledRefsFromInstalled, isSchedulerBundleActive, schedulerEnabledRefs } from "../../tasks/activation-config.js";
16
+ import { backendNameForPlatform, selectBackend } from "../../tasks/backends/index.js";
17
17
  import { listEmbeddedTasks } from "../../tasks/embedded.js";
18
18
  import { parseSchedule } from "../../tasks/schedule.js";
19
19
  import { parseTaskSource } from "../../tasks/source/parse-task-source.js";
@@ -77,9 +77,7 @@ export function listSetupTaskDefinitions() {
77
77
  const config = loadConfig();
78
78
  const target = resolveWriteTarget(config, config.defaultBundle, { requireWritable: false });
79
79
  const taskDir = path.join(target.source.path, "tasks");
80
- const enabledRefs = new Set(schedulerActivations(config)
81
- .filter((activation) => activation.kind === "task")
82
- .map((activation) => activation.ref));
80
+ const enabledRefs = new Set(schedulerEnabledRefs(config) ?? []);
83
81
  if (!fs.existsSync(taskDir))
84
82
  return [];
85
83
  const tasks = [];
@@ -178,17 +176,14 @@ export async function prepareSetupTaskDefinitions(tasks, deps = {}) {
178
176
  const selected = new Set(tasks.filter((plan) => plan.enabled).map((plan) => makeBundleRef(target.source.name, `tasks/${plan.task.id}`)));
179
177
  const managed = new Set(tasks.map((plan) => makeBundleRef(target.source.name, `tasks/${plan.task.id}`)));
180
178
  mutateConfig((current) => {
181
- const existing = schedulerActivations(current);
182
- const next = existing.filter((activation) => activation.kind !== "task" || !managed.has(activation.ref));
183
- const sourceId = schedulerActivationSourceId(current, target.source.name);
184
- if (selected.size > 0 && !sourceId) {
179
+ const existing = schedulerEnabledRefs(current) ?? [];
180
+ const next = existing.filter((ref) => !managed.has(ref));
181
+ if (selected.size > 0 && !isSchedulerBundleActive(current, target.source.name)) {
185
182
  throw new UsageError(`Cannot activate setup tasks from disabled bundle ${JSON.stringify(target.source.name)}.`);
186
183
  }
187
- for (const ref of selected) {
188
- next.push({ kind: "task", ref, sourceId: sourceId });
189
- }
190
- next.sort((left, right) => left.ref.localeCompare(right.ref) || left.kind.localeCompare(right.kind));
191
- if (JSON.stringify(existing) === JSON.stringify(next))
184
+ next.push(...selected);
185
+ next.sort((left, right) => left.localeCompare(right));
186
+ if (current.scheduler?.enabled !== undefined && JSON.stringify([...existing]) === JSON.stringify(next))
192
187
  return current;
193
188
  return { ...current, scheduler: { ...current.scheduler, enabled: next } };
194
189
  });
@@ -198,6 +193,7 @@ const DEFAULT_SCHEDULED_TASKS_DEPS = {
198
193
  list: listSetupTaskDefinitions,
199
194
  prepare: prepareSetupTaskDefinitions,
200
195
  sync: akmTasksSync,
196
+ inspectInstalled: async () => ({ installed: await selectBackend().list() }),
201
197
  };
202
198
  export async function stepScheduledTasks(deps = DEFAULT_SCHEDULED_TASKS_DEPS, options = {}) {
203
199
  if (options.nonInteractive || isCiEnvironment()) {
@@ -212,6 +208,20 @@ export async function stepScheduledTasks(deps = DEFAULT_SCHEDULED_TASKS_DEPS, op
212
208
  const embedded = listEmbeddedTasks();
213
209
  if (embedded.length === 0)
214
210
  return;
211
+ // A config that predates `scheduler.enabled` means "keep what is installed":
212
+ // make that explicit before the review below reads and edits the list.
213
+ if (schedulerEnabledRefs(loadConfig()) === undefined) {
214
+ try {
215
+ const inspection = await deps.inspectInstalled();
216
+ const refs = enabledRefsFromInstalled(inspection.installed, loadConfig());
217
+ mutateConfig((current) => ({ ...current, scheduler: { ...current.scheduler, enabled: [...refs] } }));
218
+ resetConfigCache();
219
+ }
220
+ catch (cause) {
221
+ const message = cause instanceof Error ? cause.message : String(cause);
222
+ p.log.warn(`Native scheduler bindings could not be inspected: ${message}`);
223
+ }
224
+ }
215
225
  const installed = await deps.list();
216
226
  const byId = new Map();
217
227
  for (const task of installed)
@@ -1,23 +1,22 @@
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
- * Source provider factory map.
6
- *
7
- * Maps source kind identifiers (e.g. "filesystem", "git", "website", "npm")
8
- * to factory functions that build {@link SourceProvider} instances from a
9
- * {@link SourceConfigEntry}.
10
- *
11
- * Distinct from the registry-discovery factory (`registry/factory.ts`).
12
- * Both share `create-provider-registry.ts` for the underlying string→factory
13
- * map.
14
- */
15
- import { createProviderRegistry } from "../registry/create-provider-registry.js";
16
- // ── Factory map ─────────────────────────────────────────────────────────────
17
- const registry = createProviderRegistry();
18
- export function registerSourceProvider(type, factory) {
19
- registry.register(type, factory);
20
- }
4
+ import { createFilesystemProvider } from "./providers/filesystem.js";
5
+ import { GitSourceProvider } from "./providers/git-provider.js";
6
+ import { NpmSourceProvider } from "./providers/npm.js";
7
+ import { createWebsiteProvider } from "./providers/website.js";
8
+ /** The factory for a configured source kind, or null for a kind akm does not support. */
21
9
  export function resolveSourceProviderFactory(type) {
22
- return registry.resolve(type);
10
+ switch (type) {
11
+ case "filesystem":
12
+ return createFilesystemProvider;
13
+ case "git":
14
+ return (config) => new GitSourceProvider(config);
15
+ case "npm":
16
+ return (config) => new NpmSourceProvider(config);
17
+ case "website":
18
+ return createWebsiteProvider;
19
+ default:
20
+ return null;
21
+ }
23
22
  }
@@ -3,14 +3,13 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import { resolveStashDir } from "../../core/common.js";
5
5
  import { ConfigError } from "../../core/errors.js";
6
- import { registerSourceProvider } from "../provider-factory.js";
7
6
  /**
8
7
  * Filesystem source — points at a directory the user already manages.
9
8
  *
10
9
  * Implements {@link SourceProvider} with `{ name, kind, path }`. No `sync()`:
11
10
  * content is the user's own directory, never refreshed by akm.
12
11
  */
13
- registerSourceProvider("filesystem", (entry) => {
12
+ export function createFilesystemProvider(entry) {
14
13
  if (entry.type !== "filesystem") {
15
14
  throw new ConfigError(`filesystem source invoked with type="${entry.type}"`);
16
15
  }
@@ -26,4 +25,4 @@ registerSourceProvider("filesystem", (entry) => {
26
25
  return stashDir;
27
26
  },
28
27
  };
29
- });
28
+ }
@@ -114,8 +114,14 @@ function normalizeRemoteUrl(value) {
114
114
  .replace(/\/+$/, "")
115
115
  .replace(/\.git$/i, "");
116
116
  }
117
- function replaceDirectory(stagedDir, destination) {
117
+ /**
118
+ * Move a fully materialized directory into place. POSIX cannot rename over a
119
+ * non-empty directory, so the old one is renamed aside first and restored if
120
+ * the second rename fails; the destination is missing for one syscall at most.
121
+ */
122
+ export function replaceDirectory(stagedDir, destination) {
118
123
  const backup = `${destination}.backup-${randomBytes(4).toString("hex")}`;
124
+ fs.mkdirSync(path.dirname(destination), { recursive: true });
119
125
  const hadDestination = fs.existsSync(destination);
120
126
  if (hadDestination)
121
127
  fs.renameSync(destination, backup);
@@ -11,7 +11,6 @@ import { ConfigError, UsageError } from "../../core/errors.js";
11
11
  import { getRegistryIndexCacheDir } from "../../core/paths.js";
12
12
  import { validateGitUrl } from "../../registry/resolve.js";
13
13
  import { withFreshnessCache } from "../freshness.js";
14
- import { registerSourceProvider } from "../provider-factory.js";
15
14
  import { assertNoIgnoredPathOverwrite, cloneRepo, inspectGitUpstream, runGit } from "./git-install.js";
16
15
  import { sanitizeString } from "./provider-utils.js";
17
16
  /** Cache TTL before refreshing the mirrored repo (12 hours). */
@@ -60,8 +59,6 @@ function resolveGitContentDir(config) {
60
59
  }
61
60
  throw new ConfigError("git source entry must have either `path` or `url`");
62
61
  }
63
- // ── Self-register ───────────────────────────────────────────────────────────
64
- registerSourceProvider("git", (config) => new GitSourceProvider(config));
65
62
  // ── Cache management ────────────────────────────────────────────────────────
66
63
  export function getCachePaths(repoUrl, cacheRootOverride) {
67
64
  const key = createHash("sha256").update(repoUrl).digest("hex").slice(0, 16);
@@ -204,9 +204,6 @@ export function saveGitStash(name, message, writableOverride, options) {
204
204
  }
205
205
  assertNoIgnoredExactPaths(repoDir, requestedPaths);
206
206
  const baseHead = readOptionalHead(repoDir);
207
- if (options?.expectedBaseHead !== undefined && (baseHead ?? null) !== options.expectedBaseHead) {
208
- throw new Error(`Git target advanced before its exact-path commit could be created.`);
209
- }
210
207
  const remoteResult = runGit(["-C", repoDir, "remote"]);
211
208
  if (remoteResult.status !== 0) {
212
209
  throw new Error(`git remote failed: ${remoteResult.stderr?.trim() || "unknown error"}`);
@@ -300,20 +297,6 @@ export function assertNoIgnoredExactPaths(repoDir, paths) {
300
297
  throw new UsageError(`Exact Git publication path is ignored: ${ignored[0]}. Update .gitignore or choose a tracked destination before writing.`);
301
298
  }
302
299
  }
303
- /** Reject exact staged/unstaged paths before an AKM filesystem mutation. */
304
- export function assertGitExactPathsClean(repoDir, paths) {
305
- const normalized = normalizeExactPaths(repoDir, paths);
306
- assertNoIgnoredExactPaths(repoDir, normalized);
307
- for (const result of runExactPathChunks(repoDir, ["status", "--porcelain=v1", "-z", "--untracked-files=all"], normalized)) {
308
- if (result.status !== 0) {
309
- throw new Error(`git status failed: ${result.stderr.trim() || "unknown error"}`);
310
- }
311
- if (result.stdout.length > 0) {
312
- const record = result.stdout.split("\0").find(Boolean) ?? "";
313
- throw new UsageError(`Exact Git operation path has staged or unstaged work: ${record.slice(3)}. Commit, stash, or discard that path before retrying.`);
314
- }
315
- }
316
- }
317
300
  function readOptionalHead(repoDir) {
318
301
  const result = runGit(["-C", repoDir, "rev-parse", "--verify", "HEAD"]);
319
302
  return result.status === 0 && result.stdout.trim() ? result.stdout.trim() : undefined;
@@ -13,8 +13,7 @@ import fs from "node:fs";
13
13
  import path from "node:path";
14
14
  import { ConfigError, UsageError } from "../../core/errors.js";
15
15
  import { getRegistryCacheDir } from "../../core/paths.js";
16
- import { npmArtifactNetworkPolicy, parseRegistryRef, resolveRegistryArtifact } from "../../registry/resolve.js";
17
- import { registerSourceProvider } from "../provider-factory.js";
16
+ import { parseRegistryRef, resolveRegistryArtifact } from "../../registry/resolve.js";
18
17
  import { applyAkmIncludeConfig, buildInstallCacheDir, computeFileHash, detectStashRoot, downloadArchive, isDirectory, } from "./provider-utils.js";
19
18
  import { extractTarGzSecure, verifyArchiveIntegrity } from "./tar-utils.js";
20
19
  /**
@@ -45,7 +44,6 @@ class NpmSourceProvider {
45
44
  await syncNpmRef(ref, { force: options?.force });
46
45
  }
47
46
  }
48
- registerSourceProvider("npm", (config) => new NpmSourceProvider(config));
49
47
  function npmRefFromConfig(config) {
50
48
  const candidate = config.path;
51
49
  if (typeof candidate !== "string" || !candidate) {
@@ -108,7 +106,7 @@ async function doSyncNpm(parsed, options) {
108
106
  let installRoot;
109
107
  let stashRoot;
110
108
  try {
111
- await downloadArchive(resolved.artifactUrl, archivePath, npmArtifactNetworkPolicy(resolved));
109
+ await downloadArchive(resolved.artifactUrl, archivePath);
112
110
  verifyArchiveIntegrity(archivePath, resolved.resolvedRevision, resolved.source);
113
111
  integrity = await computeFileHash(archivePath);
114
112
  extractTarGzSecure(archivePath, extractedDir);
@@ -6,7 +6,7 @@ import fs from "node:fs";
6
6
  import path from "node:path";
7
7
  import { getAdapters } from "../../core/adapter/registry.js";
8
8
  import { stashDirNames } from "../../core/asset/asset-placement.js";
9
- import { cancelRegistryResponse, fetchRegistryResponse } from "../../registry/network.js";
9
+ import { fetchRegistry } from "../../registry/network.js";
10
10
  import { writeResponseToFileCapped } from "../../runtime.js";
11
11
  import { copyIncludedPaths, findNearestIncludeConfig } from "../include.js";
12
12
  const REGISTRY_STASH_DIR_NAMES = new Set(stashDirNames());
@@ -99,15 +99,10 @@ export function applyAkmIncludeConfig(sourceRoot, cacheDir, searchRoot = sourceR
99
99
  return selectedDir;
100
100
  }
101
101
  /** Stream a remote archive to disk via the runtime boundary's response writer. */
102
- export async function downloadArchive(url, destination, networkPolicy) {
103
- const response = await fetchRegistryResponse(url, undefined, { policy: networkPolicy, timeoutMs: 120_000 });
104
- if (!response.ok) {
105
- await cancelRegistryResponse(response);
106
- throw new Error(`Failed to download archive (${response.status}) from ${url}`);
107
- }
108
- // Stream to disk with an explicit byte cap + body-read deadline: the fetch
109
- // timeout above bounds only the connection/header phase, so an unbounded or
110
- // dribbling body could otherwise fill the disk or hang the install forever.
102
+ export async function downloadArchive(url, destination) {
103
+ const response = await fetchRegistry(url, { timeoutMs: 120_000 });
104
+ // Stream to disk with an explicit byte cap + body-read deadline so an
105
+ // unbounded or dribbling body cannot fill the disk or hang the install.
111
106
  await writeResponseToFileCapped(destination, response);
112
107
  }
113
108
  /** SHA-256 of a file, returned as `sha256:<hex>`. */
@@ -2,7 +2,6 @@
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
4
  import { ConfigError } from "../../core/errors.js";
5
- import { registerSourceProvider } from "../provider-factory.js";
6
5
  import { getWebsiteCachePaths, shouldAllowPrivateWebsiteUrlForTests, validateWebsiteUrl } from "../website-url.js";
7
6
  /** Website source provider — URL-derived path plus an injected mirror refresh. */
8
7
  export function createWebsiteProvider(config) {
@@ -33,4 +32,3 @@ export function createWebsiteProvider(config) {
33
32
  },
34
33
  };
35
34
  }
36
- registerSourceProvider("website", createWebsiteProvider);
@@ -76,7 +76,7 @@ function resolveFetcherStashDir(explicitStashDir) {
76
76
  export async function ensureWebsiteMirror(config, options) {
77
77
  const rawUrl = config.url ?? "";
78
78
  const normalizedUrl = validateWebsiteUrl(rawUrl, { allowPrivateHosts: options?.allowPrivateHosts });
79
- const cachePaths = getWebsiteCachePaths(normalizedUrl, options?.cacheRootDir);
79
+ const cachePaths = getWebsiteCachePaths(normalizedUrl);
80
80
  const requireStashDir = options?.requireStashDir === true;
81
81
  await withFreshnessCache({
82
82
  markerPath: cachePaths.manifestPath,
@@ -35,9 +35,9 @@ export function shouldAllowPrivateWebsiteUrlForTests(rawUrl) {
35
35
  }
36
36
  return true;
37
37
  }
38
- export function getWebsiteCachePaths(siteUrl, cacheRootOverride) {
38
+ export function getWebsiteCachePaths(siteUrl) {
39
39
  const key = createHash("sha256").update(normalizeSiteUrl(siteUrl)).digest("hex").slice(0, 16);
40
- const rootDir = path.join(cacheRootOverride ?? getRegistryIndexCacheDir(), `website-${key}`);
40
+ const rootDir = path.join(getRegistryIndexCacheDir(), `website-${key}`);
41
41
  return {
42
42
  rootDir,
43
43
  stashDir: path.join(rootDir, "stash"),
@@ -23,7 +23,8 @@
23
23
  * This file is intentionally NOT an adapter/DI/ports-and-adapters layer. It is
24
24
  * a plain module: a structural type plus a factory function. The handle it
25
25
  * returns is the real underlying driver instance (so e.g. `sqlite-vec`'s
26
- * `load(db)` receives the genuine driver handle and works unchanged).
26
+ * `load(db)`, used to drop the retired `entries_vec` table, receives the
27
+ * genuine driver handle and works unchanged).
27
28
  *
28
29
  * @module storage/database
29
30
  */
@@ -35,39 +36,13 @@ const isBun = !!process.versions?.bun;
35
36
  // Bun built-in, unresolvable on Node) nor `better-sqlite3` (an optional native
36
37
  // dep, possibly absent under Bun) is statically imported.
37
38
  const nodeRequire = createRequire(import.meta.url);
38
- // bun:sqlite — Bun built-in, no native build. Cannot run on Node.
39
- const bunSqliteProvider = {
40
- name: "bun:sqlite",
41
- supported: () => isBun,
42
- open: openBunDatabase,
43
- };
44
- // better-sqlite3 — native Node driver. Cannot run on Bun (oven-sh/bun#4290).
45
- const nodeSqliteProvider = {
46
- name: "better-sqlite3",
47
- supported: () => !isBun,
48
- open: openNodeDatabase,
49
- };
50
39
  /**
51
- * Ordered provider registry. The factory selects the first supported provider.
52
- * A future Postgres provider is appended here — and only here. Both SQLite
53
- * engines are kept as distinct providers (not collapsed) because no single
54
- * SQLite driver runs on both Bun and Node today.
55
- */
56
- const PROVIDERS = [bunSqliteProvider, nodeSqliteProvider];
57
- /** Select the provider for the current runtime. */
58
- function selectProvider() {
59
- const provider = PROVIDERS.find((p) => p.supported());
60
- if (!provider) {
61
- throw new Error(`No storage provider supports the current runtime (${isBun ? "Bun" : "Node"}).`);
62
- }
63
- return provider;
64
- }
65
- /**
66
- * Open a SQLite database handle at `path` via the active {@link StorageProvider}.
67
- * Returns a handle conforming to the structural {@link Database} type.
40
+ * Open a SQLite database handle at `path` on the current runtime's driver
41
+ * (`bun:sqlite` on Bun, `better-sqlite3` on Node). Returns a handle conforming
42
+ * to the structural {@link Database} type.
68
43
  */
69
44
  export function openDatabase(path, opts) {
70
- return selectProvider().open(path, opts);
45
+ return isBun ? openBunDatabase(path, opts) : openNodeDatabase(path, opts);
71
46
  }
72
47
  /**
73
48
  * {@link openDatabase} with a finalize-on-close guard (issue #720).
@@ -90,7 +65,7 @@ export function openDatabase(path, opts) {
90
65
  * force-finalizing under them changes behavior they were built on.
91
66
  */
92
67
  export function openDatabaseFinalizing(path, opts) {
93
- const db = selectProvider().open(path, opts);
68
+ const db = openDatabase(path, opts);
94
69
  const tracked = new Set();
95
70
  const origPrepare = db.prepare.bind(db);
96
71
  const origClose = db.close.bind(db);
@@ -251,9 +226,8 @@ function openNodeDatabase(path, opts) {
251
226
  // bun:sqlite also provides db.run(). Normalize the latter at the provider
252
227
  // boundary so callers and maintenance wrappers can rely on one contract.
253
228
  run: (sql, ...params) => db.prepare(sql).run(...params),
254
- // sqlite-vec's load(db) calls db.loadExtension(). Without forwarding it the
255
- // extension could never load on Node, so the vector fast path was dead
256
- // across the entire npm distribution even when sqlite-vec was installed.
229
+ // sqlite-vec's load(db) calls db.loadExtension(); without forwarding it the
230
+ // extension could never load on Node.
257
231
  loadExtension: db.loadExtension.bind(db),
258
232
  transaction: db.transaction.bind(db),
259
233
  get inTransaction() {