akm-cli 0.9.0-rc.1 → 0.9.0-rc.13

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 (587) hide show
  1. package/CHANGELOG.md +1190 -52
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/stash-skeleton/README.md +38 -10
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  38. package/dist/assets/tasks/core/extract.yml +3 -2
  39. package/dist/assets/tasks/core/improve.yml +2 -1
  40. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  41. package/dist/assets/tasks/core/sync.yml +1 -0
  42. package/dist/assets/tasks/core/version-check.yml +2 -1
  43. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  44. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  45. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  46. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  48. package/dist/assets/templates/html/health.html +5 -4
  49. package/dist/assets/workflows/workflow-template.md +31 -15
  50. package/dist/cli/invocation.js +279 -0
  51. package/dist/cli/parse-args.js +5 -90
  52. package/dist/cli/retired-commands.js +78 -0
  53. package/dist/cli/shared.js +158 -48
  54. package/dist/cli-node.mjs +2 -1
  55. package/dist/cli.js +747 -293
  56. package/dist/commands/agent/agent-dispatch.js +19 -18
  57. package/dist/commands/agent/agent-support.js +0 -24
  58. package/dist/commands/agent/contribute-cli.js +43 -97
  59. package/dist/commands/completions.js +80 -23
  60. package/dist/commands/config-cli.js +44 -281
  61. package/dist/commands/env/env-binding.js +13 -9
  62. package/dist/commands/env/env-cli.js +76 -159
  63. package/dist/commands/env/env.js +12 -163
  64. package/dist/commands/env/marker-path.js +6 -0
  65. package/dist/commands/env/secret-cli.js +45 -61
  66. package/dist/commands/env/secret.js +32 -62
  67. package/dist/commands/feedback-cli.js +179 -85
  68. package/dist/commands/health/accept-rate.js +58 -0
  69. package/dist/commands/health/advisories.js +7 -8
  70. package/dist/commands/health/checks.js +279 -94
  71. package/dist/commands/health/html-report.js +197 -578
  72. package/dist/commands/health/improve-metrics.js +277 -246
  73. package/dist/commands/health/llm-usage.js +19 -19
  74. package/dist/commands/health/md-report.js +16 -7
  75. package/dist/commands/health/metrics.js +67 -32
  76. package/dist/commands/health/renderers.js +47 -0
  77. package/dist/commands/health/report-view-model.js +508 -0
  78. package/dist/commands/health/stash-exposure.js +1 -1
  79. package/dist/commands/health/surfaces.js +16 -56
  80. package/dist/commands/health/task-runs.js +3 -67
  81. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  82. package/dist/commands/health/types-improve.js +29 -0
  83. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  84. package/dist/commands/health/types-result.js +7 -0
  85. package/dist/commands/health/types-runs.js +4 -0
  86. package/dist/commands/health/types-session-log.js +4 -0
  87. package/dist/commands/health/types-windows.js +4 -0
  88. package/dist/commands/health/types.js +26 -21
  89. package/dist/commands/health/windows.js +2 -3
  90. package/dist/commands/health.js +296 -167
  91. package/dist/commands/improve/anti-collapse.js +5 -5
  92. package/dist/commands/improve/autonomy-gate.js +68 -0
  93. package/dist/commands/improve/collapse-detector.js +65 -52
  94. package/dist/commands/improve/consolidate/chunking.js +9 -7
  95. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  96. package/dist/commands/improve/consolidate/merge.js +4 -0
  97. package/dist/commands/improve/consolidate.js +454 -1354
  98. package/dist/commands/improve/content-hash.js +39 -0
  99. package/dist/commands/improve/distill/content-repair.js +4 -10
  100. package/dist/commands/improve/distill/promote-memory.js +89 -64
  101. package/dist/commands/improve/distill/quality-gate.js +118 -42
  102. package/dist/commands/improve/distill-guards.js +1 -1
  103. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  104. package/dist/commands/improve/distill.js +607 -363
  105. package/dist/commands/improve/eligibility.js +165 -79
  106. package/dist/commands/improve/extract-cli.js +35 -126
  107. package/dist/commands/improve/extract-prompt.js +6 -35
  108. package/dist/commands/improve/extract.js +640 -391
  109. package/dist/commands/improve/feedback-valence.js +2 -12
  110. package/dist/commands/improve/improve-cli.js +134 -135
  111. package/dist/commands/improve/improve-result-file.js +30 -50
  112. package/dist/commands/improve/improve-run-types.js +4 -0
  113. package/dist/commands/improve/improve-strategies.js +135 -0
  114. package/dist/commands/improve/improve.js +904 -701
  115. package/dist/commands/improve/locks.js +64 -111
  116. package/dist/commands/improve/loop-stages.js +1110 -923
  117. package/dist/commands/improve/memory/derived-ref.js +124 -0
  118. package/dist/commands/improve/memory/memory-belief.js +79 -7
  119. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  120. package/dist/commands/improve/memory/memory-improve.js +25 -37
  121. package/dist/commands/improve/outcome-loop.js +25 -88
  122. package/dist/commands/improve/preparation.js +1034 -813
  123. package/dist/commands/improve/proactive-maintenance.js +34 -9
  124. package/dist/commands/improve/proposal-envelope.js +31 -0
  125. package/dist/commands/improve/reflect.js +983 -794
  126. package/dist/commands/improve/run-context.js +119 -0
  127. package/dist/commands/improve/salience.js +24 -127
  128. package/dist/commands/improve/session-asset.js +7 -3
  129. package/dist/commands/improve/shared.js +14 -34
  130. package/dist/commands/improve/source-identity.js +28 -0
  131. package/dist/commands/improve/triage.js +20 -17
  132. package/dist/commands/lint/base-linter.js +340 -313
  133. package/dist/commands/lint/env-key-rules.js +31 -47
  134. package/dist/commands/lint/index.js +185 -30
  135. package/dist/commands/{events.js → log.js} +28 -38
  136. package/dist/commands/migrate-cli.js +54 -0
  137. package/dist/commands/migration-tool.js +55 -0
  138. package/dist/commands/observability-cli.js +70 -208
  139. package/dist/commands/proposal/diff-format.js +50 -0
  140. package/dist/commands/proposal/drain-policies.js +0 -6
  141. package/dist/commands/proposal/drain.js +91 -40
  142. package/dist/commands/proposal/proposal-cli.js +134 -132
  143. package/dist/commands/proposal/proposal-types.js +56 -0
  144. package/dist/commands/proposal/proposal.js +83 -65
  145. package/dist/commands/proposal/propose-cli.js +88 -0
  146. package/dist/commands/proposal/propose.js +105 -88
  147. package/dist/commands/proposal/repository.js +1303 -278
  148. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  149. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  150. package/dist/commands/proposal/validators/proposals.js +6 -8
  151. package/dist/commands/read/curate.js +78 -73
  152. package/dist/commands/read/knowledge.js +510 -13
  153. package/dist/commands/read/registry-search.js +2 -2
  154. package/dist/commands/read/remember-cli.js +84 -15
  155. package/dist/commands/read/search-cli.js +203 -96
  156. package/dist/commands/read/search.js +126 -94
  157. package/dist/commands/read/show.js +226 -250
  158. package/dist/commands/registry-cli.js +34 -60
  159. package/dist/commands/remember.js +18 -57
  160. package/dist/commands/sources/add-cli.js +104 -49
  161. package/dist/commands/sources/bundle-cli.js +166 -0
  162. package/dist/commands/sources/bundle-config-ops.js +63 -0
  163. package/dist/commands/sources/info.js +27 -15
  164. package/dist/commands/sources/init.js +30 -40
  165. package/dist/commands/sources/installed-stashes.js +469 -172
  166. package/dist/commands/sources/schema-repair.js +10 -9
  167. package/dist/commands/sources/self-update.js +182 -121
  168. package/dist/commands/sources/source-add.js +169 -178
  169. package/dist/commands/sources/source-clone.js +144 -41
  170. package/dist/commands/sources/source-manage.js +94 -59
  171. package/dist/commands/sources/sources-cli.js +64 -205
  172. package/dist/commands/sources/stash-cli.js +91 -54
  173. package/dist/commands/sources/stash-skeleton.js +1 -1
  174. package/dist/commands/tasks/tasks-cli.js +106 -104
  175. package/dist/commands/tasks/tasks.js +445 -262
  176. package/dist/commands/workflow-cli.js +75 -228
  177. package/dist/core/action-contributors.js +1 -1
  178. package/dist/core/activation-policy.js +49 -0
  179. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  180. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  181. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  182. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  183. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  184. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  185. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  186. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  187. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  188. package/dist/core/adapter/adapters/index.js +80 -0
  189. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  190. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  191. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  192. package/dist/core/adapter/adapters/shared.js +286 -0
  193. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  194. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  195. package/dist/core/adapter/bundle-adapter.js +4 -0
  196. package/dist/core/adapter/detect-adapter.js +17 -0
  197. package/dist/core/adapter/recognize-match.js +44 -0
  198. package/dist/core/adapter/registry.js +56 -0
  199. package/dist/core/adapter/types.js +4 -0
  200. package/dist/core/asset/akm-markdown.js +30 -0
  201. package/dist/core/asset/asset-placement.js +243 -0
  202. package/dist/core/asset/asset-ref.js +110 -79
  203. package/dist/core/asset/asset-serialize.js +20 -0
  204. package/dist/core/asset/frontmatter.js +28 -12
  205. package/dist/core/asset/markdown.js +40 -51
  206. package/dist/core/asset/resolve-ref.js +274 -0
  207. package/dist/core/asset/stash-meta.js +2 -2
  208. package/dist/core/bundle-id.js +51 -0
  209. package/dist/core/common.js +281 -86
  210. package/dist/core/config/config-io.js +42 -128
  211. package/dist/core/config/config-schema.js +233 -855
  212. package/dist/core/config/config-sources.js +162 -39
  213. package/dist/core/config/config-types.js +16 -11
  214. package/dist/core/config/config-version.js +29 -0
  215. package/dist/core/config/config-walker.js +126 -37
  216. package/dist/core/config/config.js +154 -331
  217. package/dist/core/config/deep-merge.js +41 -0
  218. package/dist/core/config/engine-semantics.js +28 -0
  219. package/dist/core/config/experimental.js +21 -0
  220. package/dist/core/config/schema/embedding.js +38 -0
  221. package/dist/core/config/schema/engines.js +116 -0
  222. package/dist/core/config/schema/experimental.js +47 -0
  223. package/dist/core/config/schema/feedback.js +31 -0
  224. package/dist/core/config/schema/improve-processes.js +389 -0
  225. package/dist/core/config/schema/improve.js +94 -0
  226. package/dist/core/config/schema/index-config.js +176 -0
  227. package/dist/core/config/schema/output.js +18 -0
  228. package/dist/core/config/schema/primitives.js +94 -0
  229. package/dist/core/config/schema/search.js +30 -0
  230. package/dist/core/config/schema/setup.js +18 -0
  231. package/dist/core/config/schema/sources-bundles.js +169 -0
  232. package/dist/core/config/schema/workflow.js +29 -0
  233. package/dist/core/env-secret-ref.js +155 -20
  234. package/dist/core/errors.js +17 -15
  235. package/dist/core/events-types.js +4 -0
  236. package/dist/core/events.js +46 -128
  237. package/dist/core/extra-params.js +62 -0
  238. package/dist/core/file-change.js +17 -0
  239. package/dist/core/file-lock.js +202 -57
  240. package/dist/core/fs-txn.js +392 -0
  241. package/dist/core/git-message.js +59 -0
  242. package/dist/core/improve-result.js +167 -0
  243. package/dist/core/lesson-lint.js +1 -17
  244. package/dist/core/logs-db.js +1 -1
  245. package/dist/core/maintenance-barrier.js +135 -0
  246. package/dist/core/migration-operation.js +44 -0
  247. package/dist/core/mutation-target.js +78 -0
  248. package/dist/core/paths.js +22 -25
  249. package/dist/core/platform.js +10 -0
  250. package/dist/core/recognition-util.js +128 -0
  251. package/dist/core/redaction.js +392 -0
  252. package/dist/core/standards/resolve-standards-context.js +36 -65
  253. package/dist/core/standards/resolve-stash-standards.js +2 -2
  254. package/dist/core/standards/resolve-type-conventions.js +5 -5
  255. package/dist/core/state/migrations.js +242 -11
  256. package/dist/core/state-db.js +98 -10
  257. package/dist/core/structured.js +1 -1
  258. package/dist/core/subprocess.js +303 -0
  259. package/dist/core/text-truncation.js +9 -5
  260. package/dist/core/time.js +20 -0
  261. package/dist/core/type-presentation.js +130 -0
  262. package/dist/core/warn.js +0 -3
  263. package/dist/core/write-source.js +834 -118
  264. package/dist/indexer/bundle-identity-guard.js +92 -0
  265. package/dist/indexer/db/graph-db.js +1 -25
  266. package/dist/indexer/db/llm-cache.js +1 -1
  267. package/dist/indexer/ensure-index.js +30 -9
  268. package/dist/indexer/graph/graph-boost.js +9 -30
  269. package/dist/indexer/graph/graph-extraction.js +41 -27
  270. package/dist/indexer/graph/graph-types.js +4 -0
  271. package/dist/indexer/index-writer-lock.js +93 -49
  272. package/dist/indexer/index-written-assets.js +100 -53
  273. package/dist/indexer/indexer.js +746 -329
  274. package/dist/indexer/init.js +18 -25
  275. package/dist/indexer/installations.js +142 -0
  276. package/dist/indexer/passes/dir-staleness.js +18 -10
  277. package/dist/indexer/passes/memory-inference.js +25 -15
  278. package/dist/indexer/passes/metadata.js +412 -243
  279. package/dist/indexer/scan/doc-to-entry.js +160 -0
  280. package/dist/indexer/scan/drain-dir.js +134 -0
  281. package/dist/indexer/search/db-search.js +292 -108
  282. package/dist/indexer/search/fts-query.js +64 -0
  283. package/dist/indexer/search/ranking-contributors.js +145 -25
  284. package/dist/indexer/search/ranking-types.js +4 -0
  285. package/dist/indexer/search/ranking.js +28 -71
  286. package/dist/indexer/search/search-attribution.js +67 -0
  287. package/dist/indexer/search/search-fields.js +18 -3
  288. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  289. package/dist/indexer/search/search-source.js +157 -111
  290. package/dist/indexer/search/semantic-status.js +4 -1
  291. package/dist/indexer/usage/usage-events.js +10 -30
  292. package/dist/indexer/walk/file-context.js +3 -45
  293. package/dist/indexer/walk/matchers.js +42 -73
  294. package/dist/indexer/walk/path-resolver.js +11 -5
  295. package/dist/indexer/walk/walker.js +42 -14
  296. package/dist/integrations/agent/builder-shared.js +7 -0
  297. package/dist/integrations/agent/builders.js +5 -58
  298. package/dist/integrations/agent/config.js +3 -143
  299. package/dist/integrations/agent/detect.js +17 -2
  300. package/dist/integrations/agent/engine-resolution.js +231 -0
  301. package/dist/integrations/agent/index.js +1 -2
  302. package/dist/integrations/agent/model-aliases.js +8 -3
  303. package/dist/integrations/agent/profiles.js +6 -99
  304. package/dist/integrations/agent/prompts.js +46 -18
  305. package/dist/integrations/agent/runner-dispatch.js +78 -13
  306. package/dist/integrations/agent/runner.js +76 -208
  307. package/dist/integrations/agent/spawn.js +48 -279
  308. package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
  309. package/dist/integrations/harnesses/aider/index.js +2 -12
  310. package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
  311. package/dist/integrations/harnesses/amazonq/index.js +3 -17
  312. package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
  313. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  314. package/dist/integrations/harnesses/claude/index.js +1 -14
  315. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  316. package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
  317. package/dist/integrations/harnesses/codex/index.js +2 -13
  318. package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
  319. package/dist/integrations/harnesses/copilot/index.js +1 -13
  320. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
  321. package/dist/integrations/harnesses/gemini/index.js +1 -13
  322. package/dist/integrations/harnesses/ids.js +24 -0
  323. package/dist/integrations/harnesses/index.js +31 -33
  324. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  325. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  326. package/dist/integrations/harnesses/opencode/index.js +1 -18
  327. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  328. package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
  329. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
  330. package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
  331. package/dist/integrations/harnesses/openhands/index.js +2 -12
  332. package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
  333. package/dist/integrations/harnesses/pi/index.js +3 -16
  334. package/dist/integrations/harnesses/shared.js +17 -0
  335. package/dist/integrations/harnesses/types.js +38 -34
  336. package/dist/integrations/lockfile.js +211 -24
  337. package/dist/integrations/session-logs/index.js +24 -40
  338. package/dist/integrations/session-logs/provider-base.js +113 -0
  339. package/dist/llm/client.js +182 -110
  340. package/dist/llm/embedders/deterministic.js +2 -2
  341. package/dist/llm/embedders/remote.js +21 -9
  342. package/dist/llm/feature-gate.js +17 -57
  343. package/dist/llm/graph-extract.js +12 -13
  344. package/dist/llm/index-passes.js +8 -42
  345. package/dist/llm/memory-infer.js +144 -1
  346. package/dist/llm/metadata-enhance.js +45 -30
  347. package/dist/llm/structured-call.js +16 -8
  348. package/dist/llm/usage-persist.js +30 -5
  349. package/dist/llm/usage-telemetry.js +59 -6
  350. package/dist/output/cli-hints.js +1 -2
  351. package/dist/output/command-registry.js +27 -0
  352. package/dist/output/context.js +22 -7
  353. package/dist/output/format-exempt.js +80 -0
  354. package/dist/output/generic-render.js +251 -0
  355. package/dist/output/html-render.js +11 -16
  356. package/dist/output/render-registry.js +57 -0
  357. package/dist/output/renderers.js +15 -281
  358. package/dist/output/shapes/curate.js +10 -1
  359. package/dist/output/shapes/events.js +12 -7
  360. package/dist/output/shapes/helpers.js +58 -84
  361. package/dist/output/shapes/passthrough.js +8 -40
  362. package/dist/output/shapes/proposal/producer.js +15 -7
  363. package/dist/output/shapes/registry.js +12 -6
  364. package/dist/output/shapes.js +0 -9
  365. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  366. package/dist/output/text/bundle-show.js +7 -0
  367. package/dist/output/text/command-format.js +562 -0
  368. package/dist/output/text/env.js +1 -3
  369. package/dist/output/text/events.js +8 -7
  370. package/dist/output/text/helpers.js +15 -1375
  371. package/dist/output/text/proposal/producer.js +4 -2
  372. package/dist/output/text/proposal-format.js +202 -0
  373. package/dist/output/text/registry-commands.js +1 -2
  374. package/dist/output/text/registry.js +12 -6
  375. package/dist/output/text/show-directives.js +117 -0
  376. package/dist/output/text/show-format.js +103 -0
  377. package/dist/output/text/sync.js +5 -0
  378. package/dist/output/text/workflow-format.js +332 -0
  379. package/dist/output/text/workflow.js +1 -2
  380. package/dist/output/text.js +10 -19
  381. package/dist/registry/factory.js +4 -6
  382. package/dist/registry/origin-resolve.js +16 -27
  383. package/dist/registry/providers/skills-sh.js +3 -3
  384. package/dist/registry/providers/static-index.js +15 -25
  385. package/dist/registry/resolve.js +43 -94
  386. package/dist/registry/semver.js +43 -0
  387. package/dist/runtime.js +81 -12
  388. package/dist/scripts/akm-migrate.js +35529 -0
  389. package/dist/setup/detect.js +5 -7
  390. package/dist/setup/detected-engines.js +136 -0
  391. package/dist/setup/engine-config.js +100 -0
  392. package/dist/setup/registry-stash-loader.js +3 -3
  393. package/dist/setup/semantic-assets.js +12 -9
  394. package/dist/setup/setup.js +444 -208
  395. package/dist/setup/steps/connection-shared.js +120 -0
  396. package/dist/setup/steps/connection.js +108 -305
  397. package/dist/setup/steps/platforms.js +13 -12
  398. package/dist/setup/steps/semantic.js +15 -3
  399. package/dist/setup/steps/sources.js +21 -15
  400. package/dist/setup/steps/stashdir.js +6 -4
  401. package/dist/setup/steps/tasks.js +236 -119
  402. package/dist/setup/steps.js +3 -2
  403. package/dist/sources/freshness.js +39 -0
  404. package/dist/sources/provider-factory.js +11 -17
  405. package/dist/sources/providers/filesystem.js +2 -3
  406. package/dist/sources/providers/git-install.js +278 -34
  407. package/dist/sources/providers/git-provider.js +54 -56
  408. package/dist/sources/providers/git-stash.js +420 -91
  409. package/dist/sources/providers/git.js +2 -2
  410. package/dist/sources/providers/npm.js +16 -19
  411. package/dist/sources/providers/provider-utils.js +47 -22
  412. package/dist/sources/providers/sync-from-ref.js +3 -9
  413. package/dist/sources/providers/website.js +2 -2
  414. package/dist/sources/resolve.js +11 -10
  415. package/dist/sources/snapshot-fetchers/types.js +4 -0
  416. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  417. package/dist/storage/database.js +60 -4
  418. package/dist/storage/engines/sqlite-migrations.js +156 -5
  419. package/dist/storage/locations.js +1 -2
  420. package/dist/storage/repositories/canaries-repository.js +1 -1
  421. package/dist/storage/repositories/events-repository.js +51 -11
  422. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  423. package/dist/storage/repositories/index-connection.js +79 -0
  424. package/dist/storage/repositories/index-db.js +4 -3
  425. package/dist/storage/repositories/index-entries-repository.js +863 -0
  426. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  427. package/dist/storage/repositories/index-entry-types.js +4 -0
  428. package/dist/storage/repositories/index-fts-repository.js +167 -0
  429. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  430. package/dist/storage/repositories/index-meta-repository.js +49 -0
  431. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  432. package/dist/storage/repositories/index-sql.js +12 -0
  433. package/dist/storage/repositories/index-utility-repository.js +356 -0
  434. package/dist/storage/repositories/index-vec-repository.js +250 -0
  435. package/dist/storage/repositories/outcome-repository.js +119 -0
  436. package/dist/storage/repositories/proposals-repository.js +317 -75
  437. package/dist/storage/repositories/registry-cache.js +1 -1
  438. package/dist/storage/repositories/salience-repository.js +172 -0
  439. package/dist/storage/repositories/task-history-repository.js +110 -3
  440. package/dist/storage/repositories/workflow-runs-repository.js +68 -35
  441. package/dist/tasks/backends/cron.js +169 -46
  442. package/dist/tasks/backends/exec-utils.js +76 -3
  443. package/dist/tasks/backends/index.js +6 -9
  444. package/dist/tasks/backends/launchd.js +292 -55
  445. package/dist/tasks/backends/schtasks.js +557 -70
  446. package/dist/tasks/backends/types.js +4 -0
  447. package/dist/tasks/command-executable.js +93 -0
  448. package/dist/tasks/embedded.js +56 -38
  449. package/dist/tasks/parser.js +156 -64
  450. package/dist/tasks/resolve-akm-bin.js +144 -51
  451. package/dist/tasks/runner.js +377 -209
  452. package/dist/tasks/schedule.js +108 -19
  453. package/dist/tasks/scheduler-invocation.js +296 -0
  454. package/dist/tasks/schema.js +1 -1
  455. package/dist/tasks/task-id.js +35 -0
  456. package/dist/tasks/validator.js +30 -16
  457. package/dist/workflows/authoring/authoring.js +96 -148
  458. package/dist/workflows/authoring/scope-key.js +1 -1
  459. package/dist/workflows/cli.js +0 -20
  460. package/dist/workflows/concurrency-policy.js +15 -0
  461. package/dist/workflows/exec/brief.js +25 -59
  462. package/dist/workflows/exec/frozen-judge.js +47 -0
  463. package/dist/workflows/exec/native-executor.js +157 -94
  464. package/dist/workflows/exec/report.js +365 -200
  465. package/dist/workflows/exec/run-workflow.js +46 -40
  466. package/dist/workflows/exec/scheduler.js +12 -41
  467. package/dist/workflows/exec/step-work.js +239 -205
  468. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  469. package/dist/workflows/ir/compile.js +141 -283
  470. package/dist/workflows/ir/freeze.js +233 -0
  471. package/dist/workflows/ir/plan-hash.js +40 -5
  472. package/dist/workflows/ir/schema.js +537 -1
  473. package/dist/workflows/parser.js +878 -306
  474. package/dist/workflows/program/expressions.js +20 -208
  475. package/dist/workflows/program/schema.js +7 -10
  476. package/dist/workflows/renderer.js +99 -121
  477. package/dist/workflows/resource-limits.js +22 -0
  478. package/dist/workflows/runtime/checkin.js +1 -1
  479. package/dist/workflows/runtime/plan-classifier.js +131 -0
  480. package/dist/workflows/runtime/runs.js +200 -113
  481. package/dist/workflows/runtime/unit-checkin.js +1 -1
  482. package/dist/workflows/runtime/unit-phases.js +20 -0
  483. package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
  484. package/dist/workflows/schema.js +1 -11
  485. package/dist/workflows/validate-summary.js +4 -26
  486. package/dist/workflows/validator.js +52 -30
  487. package/docs/README.md +42 -78
  488. package/docs/migration/README.md +8 -0
  489. package/docs/migration/release-notes/0.6.0.md +1 -1
  490. package/docs/migration/release-notes/0.7.0.md +9 -8
  491. package/docs/migration/release-notes/0.9.0.md +158 -14
  492. package/docs/migration/v0.7-to-v0.8.md +46 -47
  493. package/docs/migration/v0.8-to-v0.9.md +844 -0
  494. package/docs/reference/README.md +12 -0
  495. package/docs/reference/data-and-telemetry.md +333 -0
  496. package/package.json +21 -17
  497. package/schemas/akm-asset-envelope.json +93 -0
  498. package/schemas/akm-config.json +4636 -0
  499. package/schemas/akm-task.json +87 -0
  500. package/{dist/schemas → schemas}/akm-workflow.json +127 -82
  501. package/dist/akm-migrate-storage +0 -38
  502. package/dist/assets/help/help-accept.md +0 -12
  503. package/dist/assets/help/help-improve.md +0 -84
  504. package/dist/assets/help/help-proposals.md +0 -17
  505. package/dist/assets/help/help-propose.md +0 -17
  506. package/dist/assets/help/help-reject.md +0 -11
  507. package/dist/assets/profiles/frequent.json +0 -13
  508. package/dist/assets/profiles/recombine-only.json +0 -21
  509. package/dist/assets/profiles/reflect-distill.json +0 -30
  510. package/dist/assets/profiles/synthesize.json +0 -15
  511. package/dist/assets/prompts/procedural-system.md +0 -44
  512. package/dist/assets/prompts/recombine-system.md +0 -40
  513. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  514. package/dist/assets/tasks/core/backup.yml +0 -4
  515. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  516. package/dist/assets/templates/html/default.html +0 -78
  517. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  518. package/dist/assets/wiki/index-template.md +0 -12
  519. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  520. package/dist/assets/wiki/log-template.md +0 -8
  521. package/dist/assets/wiki/schema-template.md +0 -61
  522. package/dist/cli/config-migrate.js +0 -150
  523. package/dist/cli/config-validate.js +0 -39
  524. package/dist/commands/graph/graph-cli.js +0 -124
  525. package/dist/commands/graph/graph.js +0 -487
  526. package/dist/commands/improve/calibration.js +0 -161
  527. package/dist/commands/improve/dedup.js +0 -482
  528. package/dist/commands/improve/extract-watch.js +0 -140
  529. package/dist/commands/improve/hot-probation.js +0 -45
  530. package/dist/commands/improve/improve-auto-accept.js +0 -276
  531. package/dist/commands/improve/improve-profiles.js +0 -168
  532. package/dist/commands/improve/procedural.js +0 -398
  533. package/dist/commands/improve/recombine.js +0 -818
  534. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  535. package/dist/commands/lint/agent-linter.js +0 -44
  536. package/dist/commands/lint/command-linter.js +0 -44
  537. package/dist/commands/lint/default-linter.js +0 -16
  538. package/dist/commands/lint/fact-linter.js +0 -39
  539. package/dist/commands/lint/knowledge-linter.js +0 -16
  540. package/dist/commands/lint/memory-linter.js +0 -61
  541. package/dist/commands/lint/registry.js +0 -41
  542. package/dist/commands/lint/skill-linter.js +0 -45
  543. package/dist/commands/lint/task-linter.js +0 -50
  544. package/dist/commands/lint/workflow-linter.js +0 -81
  545. package/dist/commands/proposal/legacy-import.js +0 -115
  546. package/dist/commands/sources/history.js +0 -196
  547. package/dist/commands/tasks/default-tasks.js +0 -186
  548. package/dist/commands/wiki-cli.js +0 -292
  549. package/dist/core/asset/asset-registry.js +0 -76
  550. package/dist/core/asset/asset-spec.js +0 -316
  551. package/dist/core/config/config-migration.js +0 -602
  552. package/dist/core/deep-merge.js +0 -38
  553. package/dist/core/eval/rank-metrics.js +0 -113
  554. package/dist/core/ripgrep/install.js +0 -163
  555. package/dist/core/ripgrep/resolve.js +0 -81
  556. package/dist/indexer/db/db.js +0 -1414
  557. package/dist/indexer/manifest.js +0 -170
  558. package/dist/indexer/passes/metadata-contributors.js +0 -31
  559. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  560. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  561. package/dist/llm/call-ai.js +0 -62
  562. package/dist/llm/memory-infer-impl.js +0 -138
  563. package/dist/output/shapes/distill.js +0 -14
  564. package/dist/output/shapes/history.js +0 -11
  565. package/dist/output/text/distill.js +0 -6
  566. package/dist/output/text/enable-disable.js +0 -8
  567. package/dist/output/text/history.js +0 -6
  568. package/dist/output/text/wiki.js +0 -16
  569. package/dist/registry/build-index.js +0 -386
  570. package/dist/schemas/akm-config.json +0 -14225
  571. package/dist/scripts/migrate-storage.js +0 -13169
  572. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
  573. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  574. package/dist/setup/legacy-config.js +0 -106
  575. package/dist/storage/repositories/consolidation-repository.js +0 -38
  576. package/dist/storage/repositories/recombine-repository.js +0 -213
  577. package/dist/wiki/wiki-templates.js +0 -15
  578. package/dist/wiki/wiki.js +0 -1012
  579. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  580. package/dist/workflows/db.js +0 -350
  581. package/dist/workflows/exec/watch.js +0 -116
  582. package/dist/workflows/program/parser.js +0 -760
  583. package/dist/workflows/program/project.js +0 -105
  584. package/docs/data-and-telemetry.md +0 -227
  585. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  586. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  587. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -3,118 +3,85 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
6
+ import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
7
+ import { isBundleSlug } from "../../core/asset/asset-ref.js";
6
8
  import { isHttpUrl, resolveStashDir } from "../../core/common.js";
7
- import { getSources, loadConfig, loadUserConfig, saveConfig } from "../../core/config/config.js";
9
+ import { bundleEntryToSourceEntry, getSources, installedSourceDescriptor, loadConfig, mutateConfig, } from "../../core/config/config.js";
8
10
  import { ConfigError, UsageError } from "../../core/errors.js";
9
11
  import { akmIndex } from "../../indexer/indexer.js";
10
- import { upsertLockEntry } from "../../integrations/lockfile.js";
12
+ import { deriveBundleId } from "../../indexer/installations.js";
13
+ import { readLockfile, removeLockEntry, upsertLockEntry } from "../../integrations/lockfile.js";
11
14
  import { parseRegistryRef } from "../../registry/resolve.js";
12
15
  import { detectStashRoot } from "../../sources/providers/provider-utils.js";
13
16
  import { syncFromRef } from "../../sources/providers/sync-from-ref.js";
14
- import { ensureWebsiteMirror, shouldAllowPrivateWebsiteUrlForTests, validateWebsiteInputUrl, } from "../../sources/website-ingest.js";
15
- import { ensureWikiNameAvailable, validateWikiName } from "../../wiki/wiki.js";
16
- const VALID_OVERRIDE_TYPES = new Set(["wiki"]);
17
+ import { ensureWebsiteMirror, shouldAllowPrivateWebsiteUrlForTests, validateWebsiteInputUrl, } from "../../sources/snapshot-fetchers/website-ingest.js";
18
+ import { bundleKeyForPath, bundleKeyForUrl, nextBundleKey } from "./bundle-config-ops.js";
17
19
  export async function akmAdd(input) {
18
20
  const ref = input.ref.trim();
19
21
  if (!ref)
20
22
  throw new UsageError("Install ref or local directory is required. " +
21
- "Examples: `akm add @scope/stash`, `akm add github:owner/repo`, `akm add ./local/path`");
22
- // Validate and resolve wiki name when --type wiki is used
23
- let wikiName;
24
- if (input.overrideType) {
25
- if (!VALID_OVERRIDE_TYPES.has(input.overrideType)) {
26
- throw new UsageError(`Invalid --type value: "${input.overrideType}". Supported types: ${[...VALID_OVERRIDE_TYPES].join(", ")}`);
27
- }
28
- if (input.overrideType === "wiki") {
29
- const derived = input.name ?? deriveWikiNameFromRef(ref);
30
- validateWikiName(derived);
31
- wikiName = derived;
32
- }
33
- }
23
+ "Examples: `akm bundle add @scope/stash`, `akm bundle add github:owner/repo`, `akm bundle add ./local/path`");
34
24
  const stashDir = resolveStashDir();
35
25
  if (shouldAddAsWebsiteUrl(ref)) {
36
- return addWebsiteSource(ref, stashDir, input.name ?? wikiName, input.options, wikiName);
26
+ return addWebsiteSource(ref, stashDir, input.name, input.options);
37
27
  }
38
28
  // Detect local directory refs and route them to stashes[] instead of installed[]
39
29
  try {
40
30
  const parsed = parseRegistryRef(ref);
41
31
  if (parsed.source === "local") {
42
- return addLocalSource(ref, parsed.sourcePath, stashDir, wikiName, input.name);
32
+ return addLocalSource(ref, parsed.sourcePath, stashDir, input.name);
43
33
  }
44
34
  }
45
35
  catch {
46
36
  // Not a local ref — fall through to registry install
47
37
  }
48
- return addRegistryStash(ref, stashDir, input.writable, wikiName);
49
- }
50
- export async function registerWikiSource(input) {
51
- const stashDir = resolveStashDir();
52
- const name = input.name ?? deriveWikiNameFromRef(input.ref);
53
- validateWikiName(name);
54
- ensureWikiNameAvailable(stashDir, name);
55
- return akmAdd({
56
- ref: input.ref,
57
- name,
58
- overrideType: "wiki",
59
- options: input.options,
60
- writable: input.writable,
61
- });
38
+ return addRegistryStash(ref, stashDir, input.writable);
62
39
  }
63
40
  /**
64
- * Add a local directory as a filesystem stash source.
65
- * Creates a stashes[] entry instead of an installed[] entry.
41
+ * Add a local directory as a filesystem bundle (spec §10.1) — replaces the
42
+ * retired `sources[]` filesystem entry.
66
43
  */
67
- async function addLocalSource(ref, sourcePath, stashDir, wikiName, explicitName) {
44
+ async function addLocalSource(ref, sourcePath, stashDir, explicitName) {
68
45
  const stashRoot = detectStashRoot(sourcePath);
69
46
  const resolvedPath = path.resolve(stashRoot);
70
- const config = loadUserConfig();
71
- // Derive the canonical name: explicit --name wins, then wiki name, then readable path.
72
- const derivedName = explicitName ?? wikiName ?? toReadableId(resolvedPath);
73
- // Check for duplicates in sources[]
74
- const sources = [...getSources(config)];
75
- const existing = sources.find((s) => s.type === "filesystem" && s.path && path.resolve(s.path) === resolvedPath);
76
- let persistedEntry;
77
- if (!existing) {
78
- persistedEntry = {
79
- type: "filesystem",
47
+ let bundleKey = explicitName ?? toReadableId(resolvedPath);
48
+ mutateConfig((config) => {
49
+ const existing = bundleKeyForPath(config, resolvedPath);
50
+ if (existing) {
51
+ bundleKey = existing;
52
+ const current = config.bundles?.[existing];
53
+ if (current?.components)
54
+ return config;
55
+ const bundles = { ...(config.bundles ?? {}) };
56
+ bundles[existing] = {
57
+ ...current,
58
+ path: resolvedPath,
59
+ components: { main: { root: ".", adapter: detectAdapterId(resolvedPath) } },
60
+ };
61
+ return { ...config, bundles };
62
+ }
63
+ const bundles = { ...(config.bundles ?? {}) };
64
+ bundleKey = nextBundleKey(bundles, explicitName, resolvedPath);
65
+ bundles[bundleKey] = {
80
66
  path: resolvedPath,
81
- name: derivedName,
82
- ...(wikiName ? { wikiName } : {}),
67
+ components: { main: { root: ".", adapter: detectAdapterId(resolvedPath) } },
83
68
  };
84
- sources.push(persistedEntry);
85
- saveConfig({ ...config, sources });
86
- }
87
- else {
88
- let changed = false;
89
- // If --name was explicitly supplied, update the persisted name.
90
- if (explicitName && existing.name !== explicitName) {
91
- existing.name = explicitName;
92
- changed = true;
93
- }
94
- if (wikiName && existing.wikiName !== wikiName) {
95
- existing.wikiName = wikiName;
96
- changed = true;
97
- }
98
- if (changed)
99
- saveConfig({ ...config, sources });
100
- persistedEntry = existing;
101
- }
69
+ return { ...config, bundles };
70
+ });
102
71
  const index = await akmIndex({ stashDir });
103
72
  const updatedConfig = loadConfig();
104
73
  return {
105
74
  schemaVersion: 1,
106
- stashDir,
107
- ref: wikiName ?? ref,
75
+ bundleDir: stashDir,
76
+ ref,
108
77
  sourceAdded: {
109
78
  type: "filesystem",
110
79
  path: resolvedPath,
111
- name: persistedEntry.name ?? toReadableId(resolvedPath),
80
+ name: bundleKey,
112
81
  stashRoot: resolvedPath,
113
- ...(persistedEntry.wikiName ? { wiki: persistedEntry.wikiName } : {}),
114
82
  },
115
83
  config: {
116
84
  sourceCount: getSources(updatedConfig).length,
117
- installedKitCount: updatedConfig.installed?.length ?? 0,
118
85
  },
119
86
  index: {
120
87
  mode: index.mode,
@@ -125,36 +92,29 @@ async function addLocalSource(ref, sourcePath, stashDir, wikiName, explicitName)
125
92
  },
126
93
  };
127
94
  }
128
- async function addWebsiteSource(ref, stashDir, name, options, wikiName) {
95
+ async function addWebsiteSource(ref, stashDir, name, options) {
129
96
  const allowPrivateHosts = shouldAllowPrivateWebsiteUrlForTests(ref);
130
97
  const normalizedUrl = validateWebsiteInputUrl(ref, { allowPrivateHosts });
131
- const config = loadUserConfig();
132
- const sources = [...getSources(config)];
133
- let entry = sources.find((stash) => stash.type === "website" && stash.url === normalizedUrl);
134
- if (!entry) {
135
- entry = {
136
- type: "website",
137
- url: normalizedUrl,
138
- name: name ?? toWebsiteName(normalizedUrl),
139
- ...(options && Object.keys(options).length > 0 ? { options } : {}),
140
- ...(wikiName ? { wikiName } : {}),
98
+ const maxPages = typeof options?.maxPages === "number" ? options.maxPages : undefined;
99
+ let entry;
100
+ mutateConfig((config) => {
101
+ const bundles = { ...(config.bundles ?? {}) };
102
+ const existingKey = bundleKeyForUrl(config, normalizedUrl);
103
+ const key = existingKey ?? nextBundleKey(bundles, name ?? toWebsiteName(normalizedUrl), normalizedUrl);
104
+ const website = { url: normalizedUrl, ...(maxPages !== undefined ? { maxPages } : {}) };
105
+ const nextBundle = {
106
+ ...(existingKey ? bundles[key] : {}),
107
+ website,
108
+ components: { main: { root: ".", adapter: "website-snapshot", writable: false } },
141
109
  };
142
- sources.push(entry);
143
- saveConfig({ ...config, sources });
144
- }
145
- else {
146
- let changed = false;
147
- if (options && Object.keys(options).length > 0) {
148
- entry.options = { ...entry.options, ...options };
149
- changed = true;
150
- }
151
- if (wikiName && entry.wikiName !== wikiName) {
152
- entry.wikiName = wikiName;
153
- changed = true;
110
+ if (JSON.stringify(bundles[key]) === JSON.stringify(nextBundle)) {
111
+ entry = bundleEntryToSourceEntry(key, bundles[key]);
112
+ return config;
154
113
  }
155
- if (changed)
156
- saveConfig({ ...config, sources });
157
- }
114
+ bundles[key] = nextBundle;
115
+ entry = bundleEntryToSourceEntry(key, nextBundle);
116
+ return { ...config, bundles };
117
+ });
158
118
  const cachePaths = await ensureWebsiteMirror(entry, {
159
119
  requireStashDir: true,
160
120
  ...(allowPrivateHosts ? { allowPrivateHosts: true } : {}),
@@ -163,18 +123,16 @@ async function addWebsiteSource(ref, stashDir, name, options, wikiName) {
163
123
  const updatedConfig = loadConfig();
164
124
  return {
165
125
  schemaVersion: 1,
166
- stashDir,
167
- ref: wikiName ?? ref,
126
+ bundleDir: stashDir,
127
+ ref,
168
128
  sourceAdded: {
169
129
  type: "website",
170
130
  url: normalizedUrl,
171
- name: entry.name,
131
+ name: entry?.name,
172
132
  stashRoot: cachePaths.stashDir,
173
- ...(entry.wikiName ? { wiki: entry.wikiName } : {}),
174
133
  },
175
134
  config: {
176
135
  sourceCount: getSources(updatedConfig).length,
177
- installedKitCount: updatedConfig.installed?.length ?? 0,
178
136
  },
179
137
  index: {
180
138
  mode: index.mode,
@@ -189,14 +147,26 @@ async function addWebsiteSource(ref, stashDir, name, options, wikiName) {
189
147
  * Install a stash from a registry (npm, github, git) by dispatching to the
190
148
  * matching syncable provider and persisting the lock entry.
191
149
  */
192
- async function addRegistryStash(ref, stashDir, writable, wikiName) {
150
+ async function addRegistryStash(ref, stashDir, writable) {
193
151
  const parsedRef = parseRegistryRef(ref);
194
- if (writable === true && parsedRef.source !== "git") {
152
+ if (writable === true && parsedRef.source !== "git" && parsedRef.source !== "github") {
195
153
  throw new ConfigError("writable: true is only supported on filesystem and git sources", "INVALID_CONFIG_FILE");
196
154
  }
197
- const synced = await syncFromRef(ref, { writable });
198
- const replaced = (loadConfig().installed ?? []).find((entry) => entry.id === synced.id);
199
- const updatedConfig = upsertInstalledRegistryEntry({
155
+ const currentConfig = loadConfig();
156
+ const existingBundleKey = findInstalledBundleKey(currentConfig.bundles ?? {}, parsedRef.id);
157
+ const existingBundle = existingBundleKey ? currentConfig.bundles?.[existingBundleKey] : undefined;
158
+ const priorLock = existingBundleKey ? readLockfile().find((entry) => entry.id === existingBundleKey) : undefined;
159
+ const existingWritable = Object.values(existingBundle?.components ?? {})[0]?.writable ?? existingBundle?.writable === true;
160
+ const effectiveWritable = writable === true || existingWritable;
161
+ const requiredRoots = priorLock?.localRoot
162
+ ? Object.values(existingBundle?.components ?? {}).map((component) => path.resolve(priorLock.localRoot, component.root ?? "."))
163
+ : [];
164
+ const synced = await syncFromRef(ref, {
165
+ writable: effectiveWritable,
166
+ ...(effectiveWritable && priorLock?.localRoot ? { writableRoot: priorLock.localRoot } : {}),
167
+ ...(requiredRoots.length > 0 ? { writableRequiredRoots: requiredRoots } : {}),
168
+ });
169
+ const { config: updatedConfig, bundleId } = upsertInstalledRegistryEntry({
200
170
  id: synced.id,
201
171
  source: synced.source,
202
172
  ref: synced.ref,
@@ -207,20 +177,25 @@ async function addRegistryStash(ref, stashDir, writable, wikiName) {
207
177
  cacheDir: synced.cacheDir,
208
178
  installedAt: synced.syncedAt,
209
179
  writable: synced.writable,
210
- ...(wikiName ? { wikiName } : {}),
211
180
  });
181
+ // The prior materialized root (if this is a re-install) — read BEFORE the lock
182
+ // upsert overwrites it, so a moved cache root can be cleaned afterwards.
183
+ const priorLocalRoot = priorLock?.localRoot;
212
184
  await upsertLockEntry({
213
- id: synced.id,
185
+ id: bundleId,
214
186
  source: synced.source,
215
187
  ref: synced.ref,
216
188
  resolvedVersion: synced.resolvedVersion,
217
189
  resolvedRevision: synced.resolvedRevision,
218
190
  integrity: synced.integrity,
191
+ // §10.2 resolved lock state the install flow has on hand.
192
+ localRoot: synced.contentDir,
193
+ installedAt: synced.syncedAt,
219
194
  });
220
- // Clean up old cache directory on re-install
221
- if (replaced && replaced.cacheDir !== synced.cacheDir) {
195
+ // Clean up the old materialized root on re-install (moved cache).
196
+ if (!effectiveWritable && priorLocalRoot && path.resolve(priorLocalRoot) !== path.resolve(synced.contentDir)) {
222
197
  try {
223
- fs.rmSync(replaced.cacheDir, { recursive: true, force: true });
198
+ fs.rmSync(priorLocalRoot, { recursive: true, force: true });
224
199
  }
225
200
  catch {
226
201
  // Best-effort cleanup only.
@@ -229,7 +204,7 @@ async function addRegistryStash(ref, stashDir, writable, wikiName) {
229
204
  const index = await akmIndex({ stashDir });
230
205
  return {
231
206
  schemaVersion: 1,
232
- stashDir,
207
+ bundleDir: stashDir,
233
208
  ref,
234
209
  installed: {
235
210
  id: synced.id,
@@ -245,7 +220,6 @@ async function addRegistryStash(ref, stashDir, writable, wikiName) {
245
220
  },
246
221
  config: {
247
222
  sourceCount: getSources(updatedConfig).length,
248
- installedKitCount: updatedConfig.installed?.length ?? 0,
249
223
  },
250
224
  index: {
251
225
  mode: index.mode,
@@ -256,34 +230,89 @@ async function addRegistryStash(ref, stashDir, writable, wikiName) {
256
230
  },
257
231
  };
258
232
  }
259
- /** Persist or replace an installed stash entry in the user config. */
233
+ /**
234
+ * Persist or replace a registry-installed source as a 0.9.0 `bundles` entry
235
+ * (spec §10.1 / §10.2 desired/resolved split). The bundle carries ONLY the
236
+ * desired descriptor (git/npm locator + preserved `registryId` + `writable`);
237
+ * the resolved cache root belongs exclusively in the lock (written by callers
238
+ * via {@link upsertLockEntry} with the returned `bundleId`). Returns the config
239
+ * plus the derived bundle id so the caller keys its lock entry identically.
240
+ */
260
241
  export function upsertInstalledRegistryEntry(entry) {
261
- const current = loadUserConfig();
262
- const currentInstalled = current.installed ?? [];
263
- const withoutExisting = currentInstalled.filter((item) => item.id !== entry.id);
264
- const nextInstalled = [...withoutExisting, normalizeInstalledEntry(entry)];
265
- const nextConfig = { ...current, installed: nextInstalled };
266
- saveConfig(nextConfig);
267
- return nextConfig;
242
+ let bundleId = entry.id;
243
+ const config = mutateConfig((current) => {
244
+ const bundles = { ...(current.bundles ?? {}) };
245
+ bundleId = resolveInstalledBundleKey(bundles, entry.id, entry.stashRoot);
246
+ const existingComponents = bundles[bundleId]?.components;
247
+ const components = existingComponents
248
+ ? Object.fromEntries(Object.entries(existingComponents).map(([id, component]) => [
249
+ id,
250
+ { ...component, writable: entry.writable === true },
251
+ ]))
252
+ : {
253
+ main: {
254
+ root: ".",
255
+ adapter: detectAdapterId(path.resolve(entry.stashRoot)),
256
+ writable: entry.writable === true,
257
+ },
258
+ };
259
+ const descriptor = installedSourceDescriptor(entry.source, entry.ref, path.resolve(entry.stashRoot));
260
+ bundles[bundleId] = {
261
+ ...descriptor,
262
+ ...(entry.writable === true ? { writable: true } : {}),
263
+ ...(entry.id !== bundleId ? { registryId: entry.id } : {}),
264
+ components: components,
265
+ };
266
+ return { ...current, bundles };
267
+ }).config;
268
+ return { config, bundleId };
268
269
  }
269
- /** Remove an installed stash entry from the user config. */
270
- export function removeInstalledRegistryEntry(id) {
271
- const current = loadUserConfig();
272
- const currentInstalled = current.installed ?? [];
273
- const nextInstalled = currentInstalled.filter((item) => item.id !== id);
274
- const nextConfig = {
275
- ...current,
276
- installed: nextInstalled.length > 0 ? nextInstalled : undefined,
277
- };
278
- saveConfig(nextConfig);
279
- return nextConfig;
270
+ /**
271
+ * Remove a registry-installed source: delete its `bundles` entry and its lock
272
+ * entry (spec §10.2). Matches the bundle by preserved `registryId` or by a
273
+ * slug-legal install id used verbatim as the key. Idempotent.
274
+ */
275
+ export async function removeInstalledRegistryEntry(id) {
276
+ let removedKey;
277
+ const config = mutateConfig((current) => {
278
+ const bundles = { ...(current.bundles ?? {}) };
279
+ const key = findInstalledBundleKey(bundles, id);
280
+ if (!key)
281
+ return current;
282
+ removedKey = key;
283
+ delete bundles[key];
284
+ return { ...current, bundles: Object.keys(bundles).length > 0 ? bundles : undefined };
285
+ }).config;
286
+ if (removedKey)
287
+ await removeLockEntry(removedKey);
288
+ return config;
280
289
  }
281
- function normalizeInstalledEntry(entry) {
282
- return {
283
- ...entry,
284
- stashRoot: path.resolve(entry.stashRoot),
285
- cacheDir: path.resolve(entry.cacheDir),
286
- };
290
+ /**
291
+ * The bundle key that maps to a registry install id, or `undefined` when no
292
+ * bundle currently represents it. A non-slug-legal install id (e.g.
293
+ * `github:owner/repo`) is preserved verbatim on the bundle's `registryId`; a
294
+ * slug-legal id is used directly as the key.
295
+ */
296
+ function findInstalledBundleKey(bundles, installId) {
297
+ for (const [key, bundle] of Object.entries(bundles)) {
298
+ if (bundle.registryId === installId)
299
+ return key;
300
+ }
301
+ if (isBundleSlug(installId) && installId in bundles)
302
+ return installId;
303
+ return undefined;
304
+ }
305
+ /**
306
+ * The stable bundle key for a registry install: reuse the existing bundle for
307
+ * this install id (so re-installs keep the same key), otherwise derive a
308
+ * batch-unique key via the shared {@link deriveBundleId} (D-R5), unique against
309
+ * the currently-configured bundle keys.
310
+ */
311
+ function resolveInstalledBundleKey(bundles, installId, stashRoot) {
312
+ const existing = findInstalledBundleKey(bundles, installId);
313
+ if (existing)
314
+ return existing;
315
+ return deriveBundleId(installId, path.resolve(stashRoot), new Set(Object.keys(bundles)));
287
316
  }
288
317
  function toReadableId(resolvedPath) {
289
318
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
@@ -315,41 +344,3 @@ function toWebsiteName(siteUrl) {
315
344
  return siteUrl;
316
345
  }
317
346
  }
318
- /**
319
- * Derive a wiki name from a ref string when --name is not provided.
320
- * Lowercases and slugifies the most meaningful identifier segment.
321
- */
322
- export function deriveWikiNameFromRef(ref) {
323
- let candidate = ref;
324
- // github:owner/repo or github:owner/repo@ref
325
- if (/^github:/i.test(ref)) {
326
- const repoPath = ref.replace(/^github:/i, "").split("@")[0];
327
- candidate = repoPath.split("/").pop() ?? repoPath;
328
- }
329
- // npm:pkg or @scope/pkg
330
- else if (/^npm:/i.test(ref) || ref.startsWith("@")) {
331
- candidate = ref
332
- .replace(/^npm:/i, "")
333
- .replace(/^@[^/]+\//, "")
334
- .split("@")[0];
335
- }
336
- // git URLs or HTTPS git URLs
337
- else if (/^(git:|https?:\/\/)/.test(ref)) {
338
- try {
339
- candidate = new URL(ref).pathname.split("/").pop() ?? candidate;
340
- }
341
- catch {
342
- candidate = ref.split("/").pop() ?? ref;
343
- }
344
- candidate = candidate.replace(/\.git$/, "");
345
- }
346
- // Local paths
347
- else {
348
- candidate = path.basename(ref.replace(/\/+$/, ""));
349
- }
350
- return candidate
351
- .toLowerCase()
352
- .replace(/[^a-z0-9]+/g, "-")
353
- .replace(/^-+|-+$/g, "")
354
- .slice(0, 64);
355
- }