akm-cli 0.9.0-rc.8 → 0.9.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 (450) hide show
  1. package/CHANGELOG.md +1063 -44
  2. package/README.md +51 -25
  3. package/SECURITY.md +14 -1
  4. package/STABILITY.md +497 -0
  5. package/dist/akm +148 -35
  6. package/dist/{akm-migrate-storage → akm-migrate} +6 -9
  7. package/dist/assets/hints/cli-hints-full.md +223 -95
  8. package/dist/assets/hints/cli-hints-short.md +85 -22
  9. package/dist/assets/improve-strategies/default.json +1 -1
  10. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  11. package/dist/assets/prompts/memory-infer-user.md +2 -3
  12. package/dist/assets/stash-skeleton/README.md +6 -5
  13. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
  14. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
  15. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
  17. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
  18. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
  19. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
  20. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
  21. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
  22. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
  23. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
  24. package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
  25. package/dist/assets/tasks/core/extract.yml +1 -1
  26. package/dist/assets/tasks/core/version-check.yml +1 -1
  27. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  28. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  29. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  30. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  31. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  32. package/dist/assets/templates/html/health.html +1 -3
  33. package/dist/assets/workflows/workflow-template.md +32 -15
  34. package/dist/cli/invocation.js +40 -15
  35. package/dist/cli/parse-args.js +0 -22
  36. package/dist/cli/retired-commands.js +121 -0
  37. package/dist/cli/shared.js +154 -22
  38. package/dist/cli/unknown-flags.js +236 -0
  39. package/dist/cli-node.mjs +2 -1
  40. package/dist/cli.js +696 -258
  41. package/dist/commands/agent/agent-dispatch.js +14 -3
  42. package/dist/commands/agent/contribute-cli.js +73 -88
  43. package/dist/commands/completions.js +79 -22
  44. package/dist/commands/config-cli.js +17 -150
  45. package/dist/commands/env/env-cli.js +59 -143
  46. package/dist/commands/env/env.js +12 -163
  47. package/dist/commands/env/marker-path.js +6 -0
  48. package/dist/commands/env/secret-cli.js +36 -66
  49. package/dist/commands/env/secret.js +24 -57
  50. package/dist/commands/feedback-cli.js +141 -87
  51. package/dist/commands/health/accept-rate.js +58 -0
  52. package/dist/commands/health/advisories.js +3 -4
  53. package/dist/commands/health/checks.js +85 -23
  54. package/dist/commands/health/html-report.js +7 -10
  55. package/dist/commands/health/improve-metrics.js +25 -83
  56. package/dist/commands/health/md-report.js +5 -9
  57. package/dist/commands/health/metrics.js +62 -20
  58. package/dist/commands/health/renderers.js +47 -0
  59. package/dist/commands/health/report-view-model.js +4 -5
  60. package/dist/commands/health/stash-exposure.js +1 -1
  61. package/dist/commands/health/surfaces.js +3 -48
  62. package/dist/commands/health/task-runs.js +3 -67
  63. package/dist/commands/health/types-improve.js +7 -0
  64. package/dist/commands/health.js +99 -28
  65. package/dist/commands/improve/anti-collapse.js +2 -2
  66. package/dist/commands/improve/autonomy-gate.js +68 -0
  67. package/dist/commands/improve/collapse-detector.js +41 -40
  68. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  69. package/dist/commands/improve/consolidate/merge.js +4 -0
  70. package/dist/commands/improve/consolidate.js +140 -1000
  71. package/dist/commands/improve/distill/promote-memory.js +12 -12
  72. package/dist/commands/improve/distill/quality-gate.js +6 -6
  73. package/dist/commands/improve/distill.js +58 -69
  74. package/dist/commands/improve/eligibility.js +105 -57
  75. package/dist/commands/improve/extract-cli.js +14 -133
  76. package/dist/commands/improve/improve-cli.js +98 -114
  77. package/dist/commands/improve/improve-result-file.js +1 -28
  78. package/dist/commands/improve/improve-strategies.js +8 -5
  79. package/dist/commands/improve/improve.js +128 -91
  80. package/dist/commands/improve/loop-stages.js +182 -20
  81. package/dist/commands/improve/memory/derived-ref.js +45 -43
  82. package/dist/commands/improve/memory/memory-belief.js +1 -1
  83. package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
  84. package/dist/commands/improve/memory/memory-improve.js +6 -5
  85. package/dist/commands/improve/outcome-loop.js +22 -65
  86. package/dist/commands/improve/preparation.js +114 -123
  87. package/dist/commands/improve/proactive-maintenance.js +2 -5
  88. package/dist/commands/improve/reflect.js +56 -160
  89. package/dist/commands/improve/salience.js +11 -122
  90. package/dist/commands/improve/source-identity.js +10 -38
  91. package/dist/commands/lint/base-linter.js +20 -124
  92. package/dist/commands/lint/env-key-rules.js +31 -47
  93. package/dist/commands/lint/index.js +249 -43
  94. package/dist/commands/{events.js → log.js} +33 -38
  95. package/dist/commands/migrate-cli.js +92 -12
  96. package/dist/commands/migration-tool.js +46 -0
  97. package/dist/commands/observability-cli.js +70 -209
  98. package/dist/commands/proposal/drain.js +101 -29
  99. package/dist/commands/proposal/proposal-cli.js +76 -48
  100. package/dist/commands/proposal/proposal.js +54 -18
  101. package/dist/commands/proposal/propose-cli.js +88 -0
  102. package/dist/commands/proposal/propose.js +23 -15
  103. package/dist/commands/proposal/repository.js +701 -278
  104. package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
  105. package/dist/commands/proposal/validators/proposal-validators.js +55 -7
  106. package/dist/commands/proposal/validators/proposals.js +4 -7
  107. package/dist/commands/read/curate.js +34 -53
  108. package/dist/commands/read/knowledge.js +150 -95
  109. package/dist/commands/read/registry-search.js +2 -2
  110. package/dist/commands/read/remember-cli.js +42 -15
  111. package/dist/commands/read/search-cli.js +180 -78
  112. package/dist/commands/read/search.js +58 -43
  113. package/dist/commands/read/show.js +197 -141
  114. package/dist/commands/registry-cli.js +12 -51
  115. package/dist/commands/remember.js +14 -57
  116. package/dist/commands/sources/add-cli.js +100 -31
  117. package/dist/commands/sources/bundle-cli.js +166 -0
  118. package/dist/commands/sources/bundle-config-ops.js +7 -2
  119. package/dist/commands/sources/info.js +18 -5
  120. package/dist/commands/sources/init.js +12 -12
  121. package/dist/commands/sources/installed-stashes.js +382 -98
  122. package/dist/commands/sources/schema-repair.js +3 -2
  123. package/dist/commands/sources/self-update.js +131 -38
  124. package/dist/commands/sources/source-add.js +72 -17
  125. package/dist/commands/sources/source-clone.js +129 -45
  126. package/dist/commands/sources/source-manage.js +43 -23
  127. package/dist/commands/sources/sources-cli.js +57 -208
  128. package/dist/commands/sources/stash-cli.js +46 -53
  129. package/dist/commands/tasks/tasks-cli.js +91 -97
  130. package/dist/commands/tasks/tasks.js +276 -421
  131. package/dist/commands/workflow-cli.js +175 -450
  132. package/dist/core/adapter/adapters/akm-adapter.js +47 -28
  133. package/dist/core/adapter/adapters/akm-lint.js +42 -27
  134. package/dist/core/adapter/adapters/akm-metadata.js +15 -44
  135. package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
  136. package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
  137. package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
  138. package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
  139. package/dist/core/adapter/adapters/index.js +6 -6
  140. package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
  141. package/dist/core/adapter/adapters/okf-adapter.js +187 -19
  142. package/dist/core/adapter/adapters/shared.js +3 -19
  143. package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
  144. package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
  145. package/dist/core/adapter/detect-adapter.js +17 -0
  146. package/dist/core/adapter/recognize-match.js +6 -4
  147. package/dist/core/adapter/validate-context.js +214 -0
  148. package/dist/core/asset/akm-markdown.js +63 -0
  149. package/dist/core/asset/asset-placement.js +20 -6
  150. package/dist/core/asset/asset-ref.js +11 -9
  151. package/dist/core/asset/frontmatter-lint.js +30 -0
  152. package/dist/core/asset/frontmatter.js +37 -9
  153. package/dist/core/asset/markdown.js +40 -51
  154. package/dist/core/asset/resolve-ref.js +89 -18
  155. package/dist/core/asset/stash-meta.js +1 -1
  156. package/dist/core/bundle-id.js +51 -0
  157. package/dist/core/common.js +152 -38
  158. package/dist/core/config/config-io.js +12 -1
  159. package/dist/core/config/config-schema.js +35 -8
  160. package/dist/core/config/config-sources.js +55 -11
  161. package/dist/core/config/config-walker.js +25 -9
  162. package/dist/core/config/config.js +9 -48
  163. package/dist/core/config/experimental.js +21 -0
  164. package/dist/core/config/schema/embedding.js +5 -1
  165. package/dist/core/config/schema/experimental.js +30 -0
  166. package/dist/core/config/schema/improve-processes.js +0 -6
  167. package/dist/core/config/schema/improve.js +21 -3
  168. package/dist/core/config/schema/index-config.js +8 -15
  169. package/dist/core/config/schema/output.js +4 -1
  170. package/dist/core/config/schema/setup.js +9 -18
  171. package/dist/core/config/schema/sources-bundles.js +49 -33
  172. package/dist/core/config/schema/workflow.js +3 -3
  173. package/dist/core/env-secret-ref.js +76 -46
  174. package/dist/core/errors.js +18 -12
  175. package/dist/core/events.js +46 -128
  176. package/dist/core/file-change.js +6 -5
  177. package/dist/core/fs-txn.js +83 -7
  178. package/dist/core/git-message.js +2 -2
  179. package/dist/core/improve-result.js +1 -100
  180. package/dist/core/lesson-lint.js +1 -17
  181. package/dist/core/logs-db.js +2 -1
  182. package/dist/core/migration-operation.js +16 -0
  183. package/dist/core/mutation-target.js +78 -0
  184. package/dist/core/parse.js +4 -1
  185. package/dist/core/paths.js +17 -20
  186. package/dist/core/recognition-util.js +12 -14
  187. package/dist/core/redaction.js +34 -0
  188. package/dist/core/standards/resolve-standards-context.js +2 -14
  189. package/dist/core/standards/resolve-stash-standards.js +2 -2
  190. package/dist/core/standards/resolve-type-conventions.js +2 -2
  191. package/dist/core/state/migrations.js +41 -18
  192. package/dist/core/state-db.js +5 -14
  193. package/dist/core/structured.js +1 -1
  194. package/dist/core/subprocess.js +6 -4
  195. package/dist/core/text-truncation.js +9 -5
  196. package/dist/core/type-presentation.js +3 -3
  197. package/dist/core/warn.js +0 -3
  198. package/dist/core/write-source.js +771 -95
  199. package/dist/indexer/bundle-identity-guard.js +3 -2
  200. package/dist/indexer/db/graph-db.js +0 -24
  201. package/dist/indexer/ensure-index.js +1 -0
  202. package/dist/indexer/graph/graph-boost.js +9 -34
  203. package/dist/indexer/graph/graph-extraction.js +8 -5
  204. package/dist/indexer/index-writer-lock.js +53 -17
  205. package/dist/indexer/index-written-assets.js +16 -22
  206. package/dist/indexer/indexer.js +497 -239
  207. package/dist/indexer/installations.js +14 -96
  208. package/dist/indexer/passes/dir-staleness.js +16 -9
  209. package/dist/indexer/passes/memory-inference.js +11 -9
  210. package/dist/indexer/passes/metadata.js +113 -47
  211. package/dist/indexer/scan/doc-to-entry.js +38 -1
  212. package/dist/indexer/scan/drain-dir.js +13 -23
  213. package/dist/indexer/search/db-search.js +99 -54
  214. package/dist/indexer/search/fts-query.js +47 -24
  215. package/dist/indexer/search/ranking-contributors.js +42 -20
  216. package/dist/indexer/search/ranking.js +18 -99
  217. package/dist/indexer/search/search-fields.js +7 -2
  218. package/dist/indexer/search/search-source.js +82 -93
  219. package/dist/indexer/usage/usage-events.js +0 -89
  220. package/dist/indexer/walk/file-context.js +2 -1
  221. package/dist/indexer/walk/matchers.js +30 -43
  222. package/dist/indexer/walk/path-resolver.js +7 -2
  223. package/dist/indexer/walk/walker.js +38 -12
  224. package/dist/integrations/agent/builders.js +0 -6
  225. package/dist/integrations/agent/config.js +2 -2
  226. package/dist/integrations/agent/detect.js +49 -19
  227. package/dist/integrations/agent/engine-fallback.js +76 -0
  228. package/dist/integrations/agent/profiles.js +14 -0
  229. package/dist/integrations/agent/prompts.js +12 -8
  230. package/dist/integrations/agent/runner-dispatch.js +4 -2
  231. package/dist/integrations/agent/runner.js +0 -1
  232. package/dist/integrations/agent/spawn.js +5 -6
  233. package/dist/integrations/github.js +1 -1
  234. package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
  235. package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
  236. package/dist/integrations/harnesses/claude/session-log.js +0 -10
  237. package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
  238. package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
  239. package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
  240. package/dist/integrations/harnesses/index.js +3 -7
  241. package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
  242. package/dist/integrations/harnesses/opencode/session-log.js +0 -15
  243. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
  244. package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
  245. package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
  246. package/dist/integrations/lockfile.js +101 -6
  247. package/dist/integrations/session-logs/index.js +3 -28
  248. package/dist/llm/client.js +136 -100
  249. package/dist/llm/embedders/remote.js +13 -5
  250. package/dist/llm/feature-gate.js +4 -12
  251. package/dist/llm/graph-extract.js +5 -11
  252. package/dist/llm/memory-infer.js +144 -1
  253. package/dist/llm/metadata-enhance.js +5 -7
  254. package/dist/llm/structured-call.js +1 -1
  255. package/dist/llm/usage-persist.js +26 -5
  256. package/dist/llm/usage-telemetry.js +25 -2
  257. package/dist/output/cli-hints.js +1 -2
  258. package/dist/output/context.js +22 -7
  259. package/dist/output/format-exempt.js +80 -0
  260. package/dist/output/generic-render.js +259 -0
  261. package/dist/output/render-registry.js +57 -0
  262. package/dist/output/renderers.js +14 -36
  263. package/dist/output/shapes/curate.js +10 -1
  264. package/dist/output/shapes/events.js +12 -7
  265. package/dist/output/shapes/helpers.js +56 -83
  266. package/dist/output/shapes/migrate.js +8 -0
  267. package/dist/output/shapes/passthrough.js +7 -41
  268. package/dist/output/shapes/proposal/producer.js +15 -7
  269. package/dist/output/shapes.js +2 -9
  270. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  271. package/dist/output/text/bundle-show.js +7 -0
  272. package/dist/output/text/command-format.js +164 -96
  273. package/dist/output/text/env.js +1 -3
  274. package/dist/output/text/events.js +8 -7
  275. package/dist/output/text/health-format.js +103 -0
  276. package/dist/output/text/health.js +7 -0
  277. package/dist/output/text/helpers.js +10 -8
  278. package/dist/output/text/lint-format.js +43 -0
  279. package/dist/output/text/{save.js → lint.js} +2 -2
  280. package/dist/output/text/migrate.js +88 -0
  281. package/dist/output/text/proposal/producer.js +4 -2
  282. package/dist/output/text/proposal-format.js +44 -72
  283. package/dist/output/text/registry-commands.js +1 -2
  284. package/dist/output/text/show-directives.js +15 -7
  285. package/dist/output/text/status-list.js +32 -0
  286. package/dist/output/text/sync.js +5 -0
  287. package/dist/output/text/workflow-format.js +24 -203
  288. package/dist/output/text/workflow.js +1 -7
  289. package/dist/output/text.js +16 -17
  290. package/dist/registry/factory.js +4 -6
  291. package/dist/registry/origin-resolve.js +16 -27
  292. package/dist/registry/providers/skills-sh.js +3 -3
  293. package/dist/registry/providers/static-index.js +13 -23
  294. package/dist/registry/resolve.js +42 -7
  295. package/dist/registry/semver.js +34 -84
  296. package/dist/runtime.js +2 -23
  297. package/dist/scripts/akm-migrate-node.js +60290 -0
  298. package/dist/scripts/akm-migrate.js +59628 -0
  299. package/dist/setup/detect.js +42 -15
  300. package/dist/setup/registry-stash-loader.js +2 -2
  301. package/dist/setup/setup.js +236 -136
  302. package/dist/setup/steps/connection.js +7 -9
  303. package/dist/setup/steps/platforms.js +9 -9
  304. package/dist/setup/steps/semantic.js +15 -3
  305. package/dist/setup/steps/sources.js +12 -13
  306. package/dist/setup/steps/stashdir.js +2 -3
  307. package/dist/setup/steps/tasks.js +237 -120
  308. package/dist/sources/freshness.js +1 -1
  309. package/dist/sources/provider-factory.js +11 -17
  310. package/dist/sources/providers/filesystem.js +2 -3
  311. package/dist/sources/providers/git-install.js +278 -34
  312. package/dist/sources/providers/git-provider.js +25 -23
  313. package/dist/sources/providers/git-stash.js +395 -106
  314. package/dist/sources/providers/git.js +2 -2
  315. package/dist/sources/providers/npm.js +16 -19
  316. package/dist/sources/providers/provider-utils.js +7 -4
  317. package/dist/sources/providers/sync-from-ref.js +3 -9
  318. package/dist/sources/providers/website.js +6 -1
  319. package/dist/sources/resolve.js +6 -5
  320. package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
  321. package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
  322. package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
  323. package/dist/sources/snapshot-fetchers/github.js +100 -0
  324. package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
  325. package/dist/sources/snapshot-fetchers/registry.js +17 -1
  326. package/dist/sources/snapshot-fetchers/robots.js +348 -0
  327. package/dist/sources/snapshot-fetchers/rss.js +282 -0
  328. package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
  329. package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
  330. package/dist/sources/snapshot-fetchers/x.js +910 -0
  331. package/dist/storage/database.js +7 -0
  332. package/dist/storage/engines/sqlite-migrations.js +23 -111
  333. package/dist/storage/managed-db.js +2 -2
  334. package/dist/storage/repositories/canaries-repository.js +1 -1
  335. package/dist/storage/repositories/events-repository.js +27 -11
  336. package/dist/storage/repositories/improve-runs-repository.js +6 -12
  337. package/dist/storage/repositories/index-connection.js +17 -6
  338. package/dist/storage/repositories/index-entries-repository.js +151 -240
  339. package/dist/storage/repositories/index-entry-mapper.js +15 -11
  340. package/dist/storage/repositories/index-fts-repository.js +5 -2
  341. package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
  342. package/dist/storage/repositories/index-meta-repository.js +2 -3
  343. package/dist/storage/repositories/index-schema.js +10 -25
  344. package/dist/storage/repositories/index-utility-repository.js +15 -28
  345. package/dist/storage/repositories/index-vec-repository.js +6 -1
  346. package/dist/storage/repositories/outcome-repository.js +119 -0
  347. package/dist/storage/repositories/proposals-repository.js +296 -59
  348. package/dist/storage/repositories/registry-cache.js +19 -0
  349. package/dist/storage/repositories/salience-repository.js +172 -0
  350. package/dist/storage/repositories/task-history-repository.js +15 -13
  351. package/dist/storage/repositories/workflow-runs-repository.js +52 -40
  352. package/dist/tasks/backends/cron.js +105 -15
  353. package/dist/tasks/backends/index.js +1 -1
  354. package/dist/tasks/backends/launchd.js +85 -38
  355. package/dist/tasks/backends/schtasks.js +135 -15
  356. package/dist/tasks/embedded.js +56 -40
  357. package/dist/tasks/parser.js +7 -157
  358. package/dist/tasks/resolve-akm-bin.js +137 -59
  359. package/dist/tasks/runner.js +79 -42
  360. package/dist/tasks/scheduler-invocation.js +220 -10
  361. package/dist/tasks/schema.js +24 -1
  362. package/dist/tasks/task-id.js +1 -3
  363. package/dist/tasks/validator.js +20 -6
  364. package/dist/workflows/authoring/authoring.js +94 -143
  365. package/dist/workflows/authoring/scope-key.js +1 -1
  366. package/dist/workflows/exec/frozen-judge.js +28 -2
  367. package/dist/workflows/exec/native-executor.js +77 -57
  368. package/dist/workflows/exec/param-secrets.js +9 -9
  369. package/dist/workflows/exec/run-workflow.js +133 -79
  370. package/dist/workflows/exec/step-work.js +219 -346
  371. package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
  372. package/dist/workflows/ir/compile.js +141 -270
  373. package/dist/workflows/ir/freeze.js +40 -30
  374. package/dist/workflows/ir/params.js +135 -11
  375. package/dist/workflows/ir/plan-hash.js +1 -1
  376. package/dist/workflows/ir/schema.js +25 -26
  377. package/dist/workflows/parser.js +872 -307
  378. package/dist/workflows/program/expressions.js +20 -208
  379. package/dist/workflows/program/schema.js +7 -10
  380. package/dist/workflows/renderer.js +95 -68
  381. package/dist/workflows/resource-limits.js +2 -0
  382. package/dist/workflows/runtime/checkin.js +3 -3
  383. package/dist/workflows/runtime/plan-classifier.js +16 -75
  384. package/dist/workflows/runtime/runs.js +186 -127
  385. package/dist/workflows/runtime/unit-checkin.js +1 -1
  386. package/dist/workflows/runtime/unit-phases.js +2 -2
  387. package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
  388. package/dist/workflows/schema.js +1 -11
  389. package/dist/workflows/validate-summary.js +30 -36
  390. package/dist/workflows/validator.js +21 -62
  391. package/docs/README.md +68 -0
  392. package/docs/migration/README.md +8 -0
  393. package/docs/migration/release-notes/0.7.0.md +11 -11
  394. package/docs/migration/release-notes/0.9.0.md +208 -27
  395. package/docs/migration/v0.7-to-v0.8.md +46 -47
  396. package/docs/migration/v0.8-to-v0.9.md +564 -208
  397. package/docs/migration/v0.9.0-troubleshooting.md +561 -0
  398. package/docs/reference/README.md +12 -0
  399. package/docs/reference/cli.md +2253 -0
  400. package/docs/reference/configuration.md +358 -0
  401. package/docs/reference/data-and-telemetry.md +105 -42
  402. package/docs/reference/workflows.md +647 -0
  403. package/package.json +22 -11
  404. package/schemas/akm-asset-envelope.json +93 -0
  405. package/schemas/akm-config.json +81 -128
  406. package/schemas/akm-workflow.json +74 -73
  407. package/dist/assets/tasks/core/backup.yml +0 -5
  408. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  409. package/dist/cli/config-migrate.js +0 -1806
  410. package/dist/cli/config-validate.js +0 -41
  411. package/dist/commands/backup-cli.js +0 -56
  412. package/dist/commands/bundle/bundle-cli.js +0 -68
  413. package/dist/commands/bundle/bundle.js +0 -219
  414. package/dist/commands/graph/graph-cli.js +0 -124
  415. package/dist/commands/graph/graph.js +0 -489
  416. package/dist/commands/improve/extract-watch.js +0 -140
  417. package/dist/commands/mv-cli.js +0 -1221
  418. package/dist/commands/sources/history.js +0 -201
  419. package/dist/commands/tasks/default-tasks.js +0 -186
  420. package/dist/core/migration-backup.js +0 -1234
  421. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
  422. package/dist/llm/memory-infer-impl.js +0 -138
  423. package/dist/migrate/legacy/config-source-migration.js +0 -223
  424. package/dist/migrate/legacy/content-migration.js +0 -305
  425. package/dist/migrate/legacy/legacy-layout.js +0 -779
  426. package/dist/migrate/legacy/legacy-paths.js +0 -25
  427. package/dist/migrate/legacy/legacy-stash-json.js +0 -72
  428. package/dist/migrate/legacy/proposal-fs-import.js +0 -168
  429. package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
  430. package/dist/migrate/legacy/three-db-cutover.js +0 -841
  431. package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
  432. package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
  433. package/dist/migrate/legacy-ref-grammar.js +0 -214
  434. package/dist/output/shapes/distill.js +0 -14
  435. package/dist/output/shapes/history.js +0 -11
  436. package/dist/output/text/distill.js +0 -6
  437. package/dist/output/text/enable-disable.js +0 -8
  438. package/dist/output/text/history.js +0 -6
  439. package/dist/registry/build-index.js +0 -382
  440. package/dist/schemas/akm-config.json +0 -4704
  441. package/dist/schemas/akm-task.json +0 -87
  442. package/dist/schemas/akm-workflow.json +0 -372
  443. package/dist/scripts/migrate-storage.js +0 -3816
  444. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  445. package/dist/workflows/cli.js +0 -53
  446. package/dist/workflows/exec/brief.js +0 -481
  447. package/dist/workflows/exec/report.js +0 -1460
  448. package/dist/workflows/exec/watch.js +0 -116
  449. package/dist/workflows/program/parser.js +0 -813
  450. package/dist/workflows/program/project.js +0 -104
@@ -1,95 +0,0 @@
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
- * One-time, read-only guard for un-migrated `vaults/` directories (0.9.0).
6
- *
7
- * Background: 0.8.0 introduced the `env` asset type and a `vaults/` → `env/`
8
- * copy migration (run by `akm-migrate-storage`). 0.9.0 removed the `vault`
9
- * asset type entirely, and the indexer now unconditionally SKIPS `vaults/`
10
- * (the `akm` adapter's `recognize` abstains on it — see `akmStashAbstains` in
11
- * `core/adapter/adapters/akm-adapter.ts`). A user who upgrades straight
12
- * to 0.9.0 without ever running the storage migration therefore has the `.env`
13
- * data in their `vaults/` directory silently dropped from the index — it was
14
- * never copied to `env/`, and `vaults/` is no longer scanned.
15
- *
16
- * This guard detects exactly that state on a stash and emits ONE clear warning
17
- * pointing at `akm-migrate-storage`. It is:
18
- * - Non-destructive: it never reads `.env` contents, never writes, never
19
- * deletes, and never moves anything. It only stats directory entries.
20
- * - Idempotent: the warning is emitted at most once per process per stash
21
- * directory (deduped in-memory).
22
- *
23
- * It deliberately does NOT auto-run the copy: filesystem mutation + chmod of
24
- * secret material stays in the dedicated `akm-migrate-storage` bin, behind the
25
- * user's explicit invocation, never as a side effect of a normal `akm` command.
26
- */
27
- import fs from "node:fs";
28
- import path from "node:path";
29
- import { warn } from "../../core/warn.js";
30
- /**
31
- * Marker filename the `vaults/` → `env/` migration drops inside `vaults/` after
32
- * a successful copy. Single source of truth shared with
33
- * `scripts/migrate-storage.ts` (which writes it) and this guard (which reads
34
- * it). Its presence means the data already lives under `env/` (or was a no-op
35
- * fresh install).
36
- */
37
- export const MIGRATED_MARKER = ".migrated";
38
- /** Stashes already warned about in this process — keyed by absolute stash dir. */
39
- const warnedStashDirs = new Set();
40
- /** True when `dir` contains at least one `*.env` / `.env` file (recursively). */
41
- function hasEnvFilesRecursive(dir) {
42
- let entries;
43
- try {
44
- entries = fs.readdirSync(dir, { withFileTypes: true });
45
- }
46
- catch {
47
- return false;
48
- }
49
- for (const entry of entries) {
50
- const full = path.join(dir, entry.name);
51
- if (entry.isDirectory()) {
52
- if (hasEnvFilesRecursive(full))
53
- return true;
54
- }
55
- else if (entry.name === ".env" || entry.name.endsWith(".env")) {
56
- return true;
57
- }
58
- }
59
- return false;
60
- }
61
- /**
62
- * Warn (once) when `<stashDir>/vaults/` holds `.env` data that was never
63
- * migrated to `env/`. No-op when there is no `vaults/` dir, when the
64
- * `vaults/.migrated` marker is present, or when `vaults/` has no `.env` files.
65
- *
66
- * @returns `true` when a warning was emitted, `false` otherwise. The return is
67
- * primarily for tests; callers can ignore it.
68
- */
69
- export function warnOnUnmigratedVaults(stashDir) {
70
- const resolved = path.resolve(stashDir);
71
- if (warnedStashDirs.has(resolved))
72
- return false;
73
- const vaultsDir = path.join(resolved, "vaults");
74
- if (!fs.existsSync(vaultsDir))
75
- return false;
76
- // The migration writes this marker after a successful copy. Its presence
77
- // means the data already lives under env/ (or was a no-op fresh install).
78
- if (fs.existsSync(path.join(vaultsDir, MIGRATED_MARKER)))
79
- return false;
80
- if (!hasEnvFilesRecursive(vaultsDir))
81
- return false;
82
- // Mark before emitting so a throw in `warn` can't cause a re-warn loop.
83
- warnedStashDirs.add(resolved);
84
- warn(`[akm] WARNING: found un-migrated secrets in ${vaultsDir}.\n` +
85
- ` The 'vault' asset type was removed in 0.9.0 and 'vaults/' is no longer indexed,\n` +
86
- ` so this data will NOT appear under 'env:' until you migrate it. Run:\n` +
87
- ` akm-migrate-storage --yes\n` +
88
- ` This copies 'vaults/' -> 'env/' (non-destructive — your 'vaults/' dir is left intact).\n` +
89
- ` See docs/migration/v0.8-to-v0.9.md.`);
90
- return true;
91
- }
92
- /** Test-only: clear the per-process dedup set. */
93
- export function _resetUnmigratedVaultsGuardForTests() {
94
- warnedStashDirs.clear();
95
- }
@@ -1,138 +0,0 @@
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
- * LLM helper for the `akm index` memory-inference pass (#201).
6
- *
7
- * Compresses a single memory body into one higher-signal derived memory. The
8
- * pass itself (in `src/indexer/memory-inference.ts`) is responsible for
9
- * deciding which memories are pending, persisting the derived memory with the
10
- * correct frontmatter (`inferred: true`, `source: <parent-ref>`), and marking
11
- * the parent as processed for idempotency.
12
- *
13
- * This module is intentionally tiny and stateless so tests can stub it via
14
- * `mock.module("../src/llm/memory-infer", ...)` without hitting a network.
15
- *
16
- * Locked v1 contract (#208): the LLM connection always comes from the
17
- * selected named LLM engine. Callers obtain
18
- * the connection via `resolveIndexPassLLM("memory", config)` and pass it
19
- * straight through.
20
- */
21
- import memoryInferSystemPrompt from "../assets/prompts/memory-infer-system.md" with { type: "text" };
22
- import memoryInferUserPrompt from "../assets/prompts/memory-infer-user.md" with { type: "text" };
23
- import { toErrorMessage } from "../core/common.js";
24
- import { warn } from "../core/warn.js";
25
- import { parseEmbeddedJsonResponse } from "./client.js";
26
- import { callStructured } from "./structured-call.js";
27
- /** Hard cap on body chars sent to the model — pragmatic and matches `runLlmEnrich`. */
28
- const MAX_BODY_CHARS = 4000;
29
- const SYSTEM_PROMPT = memoryInferSystemPrompt;
30
- const USER_PROMPT_PREFIX = memoryInferUserPrompt;
31
- /**
32
- * Strict JSON Schema for the derived-memory payload. Sent to providers that
33
- * opt in via `LlmConnectionConfig.supportsJsonSchema = true`; the client
34
- * silently drops the schema for providers that don't.
35
- *
36
- * Extends the responseSchema lift (PR 1, asset-writers-investigation §5) to
37
- * the memory-inference path. Mirrors the validation gate below
38
- * (title/description/content + non-empty tags/searchHints) so a
39
- * schema-compliant response is guaranteed to pass the downstream check
40
- * — no more "incomplete derived memory payload from LLM; skipping memory"
41
- * for shape-only failures.
42
- */
43
- const DERIVED_MEMORY_JSON_SCHEMA = {
44
- type: "object",
45
- properties: {
46
- title: { type: "string", minLength: 1 },
47
- description: { type: "string", minLength: 1 },
48
- content: { type: "string", minLength: 1 },
49
- tags: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 8 },
50
- searchHints: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 6 },
51
- },
52
- required: ["title", "description", "content", "tags", "searchHints"],
53
- additionalProperties: false,
54
- };
55
- /**
56
- * Compress a single memory body into one derived memory via the configured LLM.
57
- *
58
- * Returns `undefined` on any failure (timeout, invalid JSON, empty response).
59
- * Errors are logged via `warn()` but never thrown — a failed split for one memory
60
- * must not abort the rest of the index pass.
61
- *
62
- * Routes through `callStructured({ feature: "memory_inference", ... })` so the
63
- * feature gate, error classification, and onFallback hook are honoured uniformly
64
- * (Fix C5).
65
- */
66
- export async function compressMemoryToDerivedMemory(llmConfig, body, signal, akmConfig, onFallback, telemetry, onRetryAttempt) {
67
- const trimmedBody = body.trim();
68
- if (!trimmedBody)
69
- return undefined;
70
- const userPrompt = `${USER_PROMPT_PREFIX}${trimmedBody.slice(0, MAX_BODY_CHARS)}`;
71
- // Memory-inference is ALWAYS gated: no `akmConfig` ⇒ gate closed (no chat,
72
- // `disabled` fallback), never the seam's ungated/propagate path (which is for
73
- // direct callers like `enhanceMetadata`). This is the gate-closed branch
74
- // `tryLlmFeature(_, undefined, _)` took before the migration.
75
- if (!akmConfig) {
76
- onFallback?.({ feature: "memory_inference", reason: "disabled" });
77
- return undefined;
78
- }
79
- return callStructured({
80
- feature: "memory_inference",
81
- akmConfig,
82
- config: llmConfig,
83
- messages: [
84
- { role: "system", content: SYSTEM_PROMPT },
85
- { role: "user", content: userPrompt },
86
- ],
87
- request: {
88
- temperature: 0.1,
89
- timeoutMs: llmConfig.timeoutMs,
90
- signal,
91
- responseSchema: DERIVED_MEMORY_JSON_SCHEMA,
92
- onRetryAttempt,
93
- },
94
- parse: (raw) => {
95
- if (!raw)
96
- return undefined;
97
- const parsed = parseEmbeddedJsonResponse(raw);
98
- if (!parsed) {
99
- warn("memory inference: invalid JSON response from LLM; skipping memory.");
100
- return undefined;
101
- }
102
- const title = typeof parsed.title === "string" ? parsed.title.trim() : "";
103
- const description = typeof parsed.description === "string" ? parsed.description.trim() : "";
104
- const content = typeof parsed.content === "string" ? parsed.content.trim() : "";
105
- const tags = Array.isArray(parsed.tags)
106
- ? parsed.tags
107
- .filter((t) => typeof t === "string")
108
- .map((t) => t.trim())
109
- .filter(Boolean)
110
- .slice(0, 8)
111
- : [];
112
- const searchHints = Array.isArray(parsed.searchHints)
113
- ? parsed.searchHints
114
- .filter((h) => typeof h === "string")
115
- .map((h) => h.trim())
116
- .filter(Boolean)
117
- .slice(0, 6)
118
- : [];
119
- if (!title || !description || !content || tags.length === 0 || searchHints.length === 0) {
120
- warn("memory inference: incomplete derived memory payload from LLM; skipping memory.");
121
- return undefined;
122
- }
123
- return { title, description, tags, searchHints, content };
124
- },
125
- onError: (cls, err) => {
126
- if (cls === "html") {
127
- if (telemetry)
128
- telemetry.htmlErrorCount = (telemetry.htmlErrorCount ?? 0) + 1;
129
- warn(`memory inference: provider returned HTML instead of JSON; skipping memory: ${toErrorMessage(err)}`);
130
- return undefined;
131
- }
132
- warn(`memory inference failed: ${toErrorMessage(err)}`);
133
- return undefined;
134
- },
135
- fallback: undefined,
136
- onFallback,
137
- });
138
- }
@@ -1,223 +0,0 @@
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
- * @removeIn next-minor — Chunk-8 config-shape migration (WI-8.4).
6
- *
7
- * Translates the pre-cutover source configuration
8
- * (`stashDir` / `sources[]` / `installed[]`) into the 0.9.0 `bundles` +
9
- * `defaultBundle` shape (spec §10.1). Runs as a pure pre-validation transform in
10
- * the migrator's config-applied phase (`cli/config-migrate.ts`): the old keys
11
- * are removed and the emitted `bundles` map is keyed by exactly what
12
- * `deriveInstallations` derives for each source at runtime (D-R5 no-identity
13
- * shift), because BOTH sides call the ONE shared {@link deriveBundleId} helper.
14
- *
15
- * `defaultBundle` is the primary stash's derived id — the source marked
16
- * `primary: true`, else the synthetic entry built from top-level `stashDir`.
17
- *
18
- * Ordering mirrors the transitional runtime resolvers (primary first, then
19
- * `sources[]` in declared order, then `installed[]`) so the emitted map's
20
- * insertion order reproduces the runtime installation-priority order after the
21
- * migration.
22
- *
23
- * WI-8.5 desired/resolved split (spec §10.2): an `installed[]` entry is emitted
24
- * as its DESIRED source descriptor — a git/npm bundle carrying the re-installable
25
- * LOCATOR (`{ git: ref }` / `{ npm: ref }`), NOT the materialized cache root. The
26
- * resolved root lives exclusively in the lock (`localRoot`), emitted by
27
- * {@link migratedLockEntries} keyed by the same derived bundle id, from which the
28
- * runtime ({@link import("../../indexer/search/search-source.js").resolveSourceEntries})
29
- * resolves the git/npm bundle's content dir. A local/filesystem install still
30
- * emits `{ path: stashRoot }` (a real path, no cache to re-materialize). The
31
- * original registry id is preserved in the entry's `registryId` locator so
32
- * nothing is lost.
33
- */
34
- import os from "node:os";
35
- import path from "node:path";
36
- import { installedSourceDescriptor } from "../../core/config/config-sources.js";
37
- import { deriveBundleId } from "../../indexer/installations.js";
38
- /** The pre-cutover source keys this transform consumes and removes. */
39
- const OLD_SOURCE_KEYS = ["stashDir", "sources", "installed"];
40
- /** True when a raw config object carries any pre-cutover source key. */
41
- export function hasOldSourceShape(raw) {
42
- return OLD_SOURCE_KEYS.some((k) => k in raw && raw[k] !== undefined);
43
- }
44
- /** Expand a leading `~` against the home directory (config paths may use it). */
45
- function expandTilde(p) {
46
- if (p === "~")
47
- return os.homedir();
48
- if (p.startsWith("~/") || p.startsWith("~\\"))
49
- return path.join(os.homedir(), p.slice(2));
50
- return p;
51
- }
52
- function readString(value) {
53
- return typeof value === "string" && value.length > 0 ? value : undefined;
54
- }
55
- /** Build the 0.9.0 source descriptor for one pre-cutover `sources[]` entry. */
56
- function sourceEntryDescriptor(entry) {
57
- const type = readString(entry.type) ?? "filesystem";
58
- const entryPath = readString(entry.path);
59
- const url = readString(entry.url);
60
- const options = entry.options ?? undefined;
61
- const maxPages = typeof options?.maxPages === "number" ? options.maxPages : undefined;
62
- switch (type) {
63
- case "filesystem":
64
- return entryPath ? { path: entryPath } : undefined;
65
- case "git":
66
- return url ? { git: url } : undefined;
67
- case "website":
68
- return url ? { website: { url, ...(maxPages !== undefined ? { maxPages } : {}) } } : undefined;
69
- case "npm":
70
- // Today's npm source carries the package spec in `path` (parseSourceSpec).
71
- return entryPath ? { npm: entryPath } : undefined;
72
- default:
73
- return entryPath ? { path: entryPath } : undefined;
74
- }
75
- }
76
- /**
77
- * Extract the ordered pre-cutover source list from a raw config object, mirroring
78
- * the runtime resolution order: primary first, then `sources[]`, then
79
- * `installed[]`.
80
- */
81
- export function oldConfigMigratableSources(raw) {
82
- const out = [];
83
- const sources = Array.isArray(raw.sources) ? raw.sources : [];
84
- const installed = Array.isArray(raw.installed) ? raw.installed : [];
85
- const stashDir = readString(raw.stashDir);
86
- // Primary: an explicit `primary: true` source wins; otherwise the top-level
87
- // `stashDir` (a synthetic writable filesystem primary).
88
- const primaryEntry = sources.find((entry) => entry.primary === true);
89
- if (primaryEntry) {
90
- const descriptor = sourceEntryDescriptor(primaryEntry);
91
- const p = readString(primaryEntry.path);
92
- if (descriptor) {
93
- out.push({
94
- derivationPath: p ? path.resolve(expandTilde(p)) : (readString(primaryEntry.url) ?? ""),
95
- registryId: readString(primaryEntry.name),
96
- writable: primaryEntry.writable === true,
97
- primary: true,
98
- descriptor,
99
- });
100
- }
101
- }
102
- else if (stashDir) {
103
- out.push({
104
- derivationPath: path.resolve(expandTilde(stashDir)),
105
- writable: true,
106
- primary: true,
107
- descriptor: { path: stashDir },
108
- });
109
- }
110
- for (const entry of sources) {
111
- if (entry === primaryEntry)
112
- continue;
113
- const descriptor = sourceEntryDescriptor(entry);
114
- if (!descriptor)
115
- continue;
116
- const p = readString(entry.path);
117
- out.push({
118
- derivationPath: p ? path.resolve(expandTilde(p)) : (readString(entry.url) ?? ""),
119
- registryId: readString(entry.name),
120
- writable: entry.writable === true,
121
- descriptor,
122
- });
123
- }
124
- for (const entry of installed) {
125
- const stashRoot = readString(entry.stashRoot);
126
- if (!stashRoot)
127
- continue;
128
- const source = readString(entry.source);
129
- const ref = readString(entry.ref);
130
- // WI-8.5 desired/resolved split: emit the DESIRED source descriptor (git/npm
131
- // locator), NOT the materialized cache root. The resolved root belongs in the
132
- // lock (`localRoot`), keyed by the derived bundle id — see {@link migratedLockEntries}.
133
- const descriptor = source ? installedSourceDescriptor(source, ref, stashRoot) : { path: stashRoot };
134
- const resolvedRoot = path.resolve(expandTilde(stashRoot));
135
- // A git/npm descriptor carries a locator, so the runtime resolves its content
136
- // dir from the lock's localRoot; record that resolved state for the lock.
137
- const needsLock = ("git" in descriptor || "npm" in descriptor) && !!source && !!ref;
138
- out.push({
139
- derivationPath: resolvedRoot,
140
- registryId: readString(entry.id),
141
- writable: entry.writable === true,
142
- descriptor,
143
- ...(needsLock ? { lock: { source: source, ref: ref, localRoot: resolvedRoot } } : {}),
144
- });
145
- }
146
- return out;
147
- }
148
- /**
149
- * Derive the §10.2 lock entries the config-shape migration produces for
150
- * `installed[]` entries whose desired descriptor is a git/npm LOCATOR. Each
151
- * entry is keyed by the SAME derived bundle id as {@link migrateConfigSourcesToBundles}
152
- * (both share {@link oldConfigMigratableSources} + {@link deriveBundleId} over
153
- * the same ordered list), so the runtime resolves the git/npm bundle's content
154
- * dir from `localRoot`. Filesystem/local bundles resolve directly from their
155
- * config `path` and get no lock entry. Returns `[]` for an already-migrated or
156
- * old-shape-free config (idempotent, side-effect free).
157
- */
158
- export function migratedLockEntries(raw) {
159
- if ("bundles" in raw)
160
- return [];
161
- if (!hasOldSourceShape(raw))
162
- return [];
163
- const usedIds = new Set();
164
- const entries = [];
165
- for (const src of oldConfigMigratableSources(raw)) {
166
- const id = deriveBundleId(src.registryId, src.derivationPath, usedIds);
167
- if (src.lock) {
168
- entries.push({ id, source: src.lock.source, ref: src.lock.ref, localRoot: src.lock.localRoot });
169
- }
170
- }
171
- return entries;
172
- }
173
- /**
174
- * The SearchSource[] view of the pre-cutover config — the exact input a "direct
175
- * `deriveInstallations` run over the old source list" consumes for the D-R5
176
- * no-identity-shift proof.
177
- */
178
- export function oldConfigToSearchSources(raw) {
179
- return oldConfigMigratableSources(raw).map((src) => ({
180
- path: src.derivationPath,
181
- ...(src.registryId ? { registryId: src.registryId } : {}),
182
- ...(src.writable ? { writable: true } : {}),
183
- }));
184
- }
185
- /**
186
- * Translate the pre-cutover source shape into `bundles` + `defaultBundle`,
187
- * removing `stashDir`/`sources`/`installed`. Idempotent: a config with no old
188
- * source keys (already migrated, or none configured) is returned unchanged, so
189
- * the transform is safe to run over any migration target.
190
- */
191
- export function migrateConfigSourcesToBundles(raw) {
192
- // Already migrated (or half-migrated — the schema rejects that): leave as-is.
193
- if ("bundles" in raw)
194
- return raw;
195
- if (!hasOldSourceShape(raw))
196
- return raw;
197
- const migratable = oldConfigMigratableSources(raw);
198
- const usedIds = new Set();
199
- const bundles = {};
200
- let defaultBundle;
201
- for (const src of migratable) {
202
- // The ONE shared derivation, so the emitted key equals the runtime
203
- // installation id by construction (D-R5).
204
- const id = deriveBundleId(src.registryId, src.derivationPath, usedIds);
205
- const entry = { ...src.descriptor };
206
- if (src.writable)
207
- entry.writable = true;
208
- // Preserve the original registry id when the slug-legal key differs from it
209
- // (a non-slug-legal id like `github:owner/repo`), so the locator is not lost.
210
- if (src.registryId && src.registryId !== id)
211
- entry.registryId = src.registryId;
212
- bundles[id] = entry;
213
- if (src.primary)
214
- defaultBundle = id;
215
- }
216
- const out = { ...raw };
217
- for (const key of OLD_SOURCE_KEYS)
218
- delete out[key];
219
- out.bundles = bundles;
220
- if (defaultBundle !== undefined)
221
- out.defaultBundle = defaultBundle;
222
- return out;
223
- }