akm-cli 0.9.0-rc.0 → 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 (598) hide show
  1. package/CHANGELOG.md +1283 -22
  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/prompts/workflow-unit-preamble.md +26 -0
  26. package/dist/assets/stash-skeleton/README.md +38 -10
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  38. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  39. package/dist/assets/tasks/core/extract.yml +3 -2
  40. package/dist/assets/tasks/core/improve.yml +2 -1
  41. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  42. package/dist/assets/tasks/core/sync.yml +1 -0
  43. package/dist/assets/tasks/core/version-check.yml +2 -1
  44. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  45. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  46. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  48. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  49. package/dist/assets/templates/html/health.html +5 -4
  50. package/dist/assets/workflows/workflow-template.md +31 -15
  51. package/dist/cli/invocation.js +279 -0
  52. package/dist/cli/parse-args.js +5 -90
  53. package/dist/cli/retired-commands.js +78 -0
  54. package/dist/cli/shared.js +158 -48
  55. package/dist/cli-node.mjs +2 -1
  56. package/dist/cli.js +747 -293
  57. package/dist/commands/agent/agent-dispatch.js +19 -18
  58. package/dist/commands/agent/agent-support.js +0 -24
  59. package/dist/commands/agent/contribute-cli.js +43 -97
  60. package/dist/commands/completions.js +80 -23
  61. package/dist/commands/config-cli.js +44 -281
  62. package/dist/commands/env/env-binding.js +99 -0
  63. package/dist/commands/env/env-cli.js +84 -224
  64. package/dist/commands/env/env.js +12 -163
  65. package/dist/commands/env/marker-path.js +6 -0
  66. package/dist/commands/env/secret-cli.js +45 -61
  67. package/dist/commands/env/secret.js +32 -62
  68. package/dist/commands/feedback-cli.js +179 -85
  69. package/dist/commands/health/accept-rate.js +58 -0
  70. package/dist/commands/health/advisories.js +7 -8
  71. package/dist/commands/health/checks.js +279 -94
  72. package/dist/commands/health/html-report.js +197 -578
  73. package/dist/commands/health/improve-metrics.js +277 -246
  74. package/dist/commands/health/llm-usage.js +19 -19
  75. package/dist/commands/health/md-report.js +16 -7
  76. package/dist/commands/health/metrics.js +67 -32
  77. package/dist/commands/health/renderers.js +47 -0
  78. package/dist/commands/health/report-view-model.js +508 -0
  79. package/dist/commands/health/stash-exposure.js +1 -1
  80. package/dist/commands/health/surfaces.js +16 -56
  81. package/dist/commands/health/task-runs.js +3 -67
  82. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  83. package/dist/commands/health/types-improve.js +29 -0
  84. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  85. package/dist/commands/health/types-result.js +7 -0
  86. package/dist/commands/health/types-runs.js +4 -0
  87. package/dist/commands/health/types-session-log.js +4 -0
  88. package/dist/commands/health/types-windows.js +4 -0
  89. package/dist/commands/health/types.js +26 -21
  90. package/dist/commands/health/windows.js +2 -3
  91. package/dist/commands/health.js +296 -167
  92. package/dist/commands/improve/anti-collapse.js +5 -5
  93. package/dist/commands/improve/autonomy-gate.js +68 -0
  94. package/dist/commands/improve/collapse-detector.js +65 -52
  95. package/dist/commands/improve/consolidate/chunking.js +9 -7
  96. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  97. package/dist/commands/improve/consolidate/merge.js +4 -0
  98. package/dist/commands/improve/consolidate.js +454 -1354
  99. package/dist/commands/improve/content-hash.js +39 -0
  100. package/dist/commands/improve/distill/content-repair.js +4 -10
  101. package/dist/commands/improve/distill/promote-memory.js +89 -64
  102. package/dist/commands/improve/distill/quality-gate.js +118 -42
  103. package/dist/commands/improve/distill-guards.js +1 -1
  104. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  105. package/dist/commands/improve/distill.js +607 -363
  106. package/dist/commands/improve/eligibility.js +165 -79
  107. package/dist/commands/improve/extract-cli.js +35 -126
  108. package/dist/commands/improve/extract-prompt.js +6 -35
  109. package/dist/commands/improve/extract.js +640 -391
  110. package/dist/commands/improve/feedback-valence.js +2 -12
  111. package/dist/commands/improve/improve-cli.js +134 -135
  112. package/dist/commands/improve/improve-result-file.js +30 -50
  113. package/dist/commands/improve/improve-run-types.js +4 -0
  114. package/dist/commands/improve/improve-strategies.js +135 -0
  115. package/dist/commands/improve/improve.js +904 -701
  116. package/dist/commands/improve/locks.js +64 -111
  117. package/dist/commands/improve/loop-stages.js +1110 -923
  118. package/dist/commands/improve/memory/derived-ref.js +124 -0
  119. package/dist/commands/improve/memory/memory-belief.js +79 -7
  120. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  121. package/dist/commands/improve/memory/memory-improve.js +25 -37
  122. package/dist/commands/improve/outcome-loop.js +25 -88
  123. package/dist/commands/improve/preparation.js +1034 -813
  124. package/dist/commands/improve/proactive-maintenance.js +34 -9
  125. package/dist/commands/improve/proposal-envelope.js +31 -0
  126. package/dist/commands/improve/reflect.js +983 -794
  127. package/dist/commands/improve/run-context.js +119 -0
  128. package/dist/commands/improve/salience.js +24 -127
  129. package/dist/commands/improve/session-asset.js +7 -3
  130. package/dist/commands/improve/shared.js +14 -34
  131. package/dist/commands/improve/source-identity.js +28 -0
  132. package/dist/commands/improve/triage.js +20 -17
  133. package/dist/commands/lint/base-linter.js +340 -313
  134. package/dist/commands/lint/env-key-rules.js +31 -47
  135. package/dist/commands/lint/index.js +185 -30
  136. package/dist/commands/{events.js → log.js} +28 -38
  137. package/dist/commands/migrate-cli.js +54 -0
  138. package/dist/commands/migration-tool.js +55 -0
  139. package/dist/commands/observability-cli.js +70 -208
  140. package/dist/commands/proposal/diff-format.js +50 -0
  141. package/dist/commands/proposal/drain-policies.js +0 -6
  142. package/dist/commands/proposal/drain.js +91 -40
  143. package/dist/commands/proposal/proposal-cli.js +134 -132
  144. package/dist/commands/proposal/proposal-types.js +56 -0
  145. package/dist/commands/proposal/proposal.js +83 -65
  146. package/dist/commands/proposal/propose-cli.js +88 -0
  147. package/dist/commands/proposal/propose.js +105 -88
  148. package/dist/commands/proposal/repository.js +1303 -278
  149. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  150. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  151. package/dist/commands/proposal/validators/proposals.js +6 -8
  152. package/dist/commands/read/curate.js +78 -73
  153. package/dist/commands/read/knowledge.js +510 -13
  154. package/dist/commands/read/registry-search.js +2 -2
  155. package/dist/commands/read/remember-cli.js +84 -15
  156. package/dist/commands/read/search-cli.js +203 -96
  157. package/dist/commands/read/search.js +126 -94
  158. package/dist/commands/read/show.js +226 -250
  159. package/dist/commands/registry-cli.js +34 -60
  160. package/dist/commands/remember.js +18 -57
  161. package/dist/commands/sources/add-cli.js +104 -49
  162. package/dist/commands/sources/bundle-cli.js +166 -0
  163. package/dist/commands/sources/bundle-config-ops.js +63 -0
  164. package/dist/commands/sources/info.js +27 -15
  165. package/dist/commands/sources/init.js +30 -40
  166. package/dist/commands/sources/installed-stashes.js +469 -172
  167. package/dist/commands/sources/migration-help.js +7 -4
  168. package/dist/commands/sources/schema-repair.js +10 -9
  169. package/dist/commands/sources/self-update.js +182 -121
  170. package/dist/commands/sources/source-add.js +169 -178
  171. package/dist/commands/sources/source-clone.js +144 -41
  172. package/dist/commands/sources/source-manage.js +94 -59
  173. package/dist/commands/sources/sources-cli.js +64 -205
  174. package/dist/commands/sources/stash-cli.js +91 -54
  175. package/dist/commands/sources/stash-skeleton.js +1 -1
  176. package/dist/commands/tasks/tasks-cli.js +106 -104
  177. package/dist/commands/tasks/tasks.js +445 -262
  178. package/dist/commands/workflow-cli.js +232 -121
  179. package/dist/core/action-contributors.js +1 -1
  180. package/dist/core/activation-policy.js +49 -0
  181. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  182. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  183. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  184. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  185. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  186. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  187. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  188. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  189. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  190. package/dist/core/adapter/adapters/index.js +80 -0
  191. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  192. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  193. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  194. package/dist/core/adapter/adapters/shared.js +286 -0
  195. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  196. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  197. package/dist/core/adapter/bundle-adapter.js +4 -0
  198. package/dist/core/adapter/detect-adapter.js +17 -0
  199. package/dist/core/adapter/recognize-match.js +44 -0
  200. package/dist/core/adapter/registry.js +56 -0
  201. package/dist/core/adapter/types.js +4 -0
  202. package/dist/core/asset/akm-markdown.js +30 -0
  203. package/dist/core/asset/asset-placement.js +243 -0
  204. package/dist/core/asset/asset-ref.js +110 -79
  205. package/dist/core/asset/asset-serialize.js +20 -0
  206. package/dist/core/asset/frontmatter.js +28 -12
  207. package/dist/core/asset/markdown.js +40 -51
  208. package/dist/core/asset/resolve-ref.js +274 -0
  209. package/dist/core/asset/stash-meta.js +2 -2
  210. package/dist/core/bundle-id.js +51 -0
  211. package/dist/core/common.js +281 -86
  212. package/dist/core/config/config-io.js +42 -128
  213. package/dist/core/config/config-schema.js +233 -834
  214. package/dist/core/config/config-sources.js +162 -39
  215. package/dist/core/config/config-types.js +16 -11
  216. package/dist/core/config/config-version.js +29 -0
  217. package/dist/core/config/config-walker.js +126 -37
  218. package/dist/core/config/config.js +154 -331
  219. package/dist/core/config/deep-merge.js +41 -0
  220. package/dist/core/config/engine-semantics.js +28 -0
  221. package/dist/core/config/experimental.js +21 -0
  222. package/dist/core/config/schema/embedding.js +38 -0
  223. package/dist/core/config/schema/engines.js +116 -0
  224. package/dist/core/config/schema/experimental.js +47 -0
  225. package/dist/core/config/schema/feedback.js +31 -0
  226. package/dist/core/config/schema/improve-processes.js +389 -0
  227. package/dist/core/config/schema/improve.js +94 -0
  228. package/dist/core/config/schema/index-config.js +176 -0
  229. package/dist/core/config/schema/output.js +18 -0
  230. package/dist/core/config/schema/primitives.js +94 -0
  231. package/dist/core/config/schema/search.js +30 -0
  232. package/dist/core/config/schema/setup.js +18 -0
  233. package/dist/core/config/schema/sources-bundles.js +169 -0
  234. package/dist/core/config/schema/workflow.js +29 -0
  235. package/dist/core/env-secret-ref.js +155 -20
  236. package/dist/core/errors.js +17 -15
  237. package/dist/core/events-types.js +4 -0
  238. package/dist/core/events.js +46 -128
  239. package/dist/core/extra-params.js +62 -0
  240. package/dist/core/file-change.js +17 -0
  241. package/dist/core/file-lock.js +202 -57
  242. package/dist/core/fs-txn.js +392 -0
  243. package/dist/core/git-message.js +59 -0
  244. package/dist/core/improve-result.js +167 -0
  245. package/dist/core/json-schema.js +142 -0
  246. package/dist/core/lesson-lint.js +1 -17
  247. package/dist/core/logs-db.js +1 -1
  248. package/dist/core/maintenance-barrier.js +135 -0
  249. package/dist/core/migration-operation.js +44 -0
  250. package/dist/core/mutation-target.js +78 -0
  251. package/dist/core/paths.js +22 -25
  252. package/dist/core/platform.js +10 -0
  253. package/dist/core/recognition-util.js +128 -0
  254. package/dist/core/redaction.js +392 -0
  255. package/dist/core/standards/resolve-standards-context.js +36 -65
  256. package/dist/core/standards/resolve-stash-standards.js +2 -2
  257. package/dist/core/standards/resolve-type-conventions.js +5 -5
  258. package/dist/core/state/migrations.js +242 -11
  259. package/dist/core/state-db.js +98 -10
  260. package/dist/core/structured.js +1 -1
  261. package/dist/core/subprocess.js +303 -0
  262. package/dist/core/text-truncation.js +9 -5
  263. package/dist/core/time.js +20 -0
  264. package/dist/core/type-presentation.js +130 -0
  265. package/dist/core/warn.js +0 -3
  266. package/dist/core/write-source.js +834 -118
  267. package/dist/indexer/bundle-identity-guard.js +92 -0
  268. package/dist/indexer/db/graph-db.js +1 -25
  269. package/dist/indexer/db/llm-cache.js +1 -1
  270. package/dist/indexer/ensure-index.js +30 -9
  271. package/dist/indexer/graph/graph-boost.js +9 -30
  272. package/dist/indexer/graph/graph-extraction.js +41 -27
  273. package/dist/indexer/graph/graph-types.js +4 -0
  274. package/dist/indexer/index-writer-lock.js +93 -49
  275. package/dist/indexer/index-written-assets.js +100 -53
  276. package/dist/indexer/indexer.js +746 -329
  277. package/dist/indexer/init.js +18 -25
  278. package/dist/indexer/installations.js +142 -0
  279. package/dist/indexer/passes/dir-staleness.js +18 -10
  280. package/dist/indexer/passes/memory-inference.js +25 -15
  281. package/dist/indexer/passes/metadata.js +412 -243
  282. package/dist/indexer/scan/doc-to-entry.js +160 -0
  283. package/dist/indexer/scan/drain-dir.js +134 -0
  284. package/dist/indexer/search/db-search.js +292 -108
  285. package/dist/indexer/search/fts-query.js +64 -0
  286. package/dist/indexer/search/ranking-contributors.js +145 -25
  287. package/dist/indexer/search/ranking-types.js +4 -0
  288. package/dist/indexer/search/ranking.js +28 -71
  289. package/dist/indexer/search/search-attribution.js +67 -0
  290. package/dist/indexer/search/search-fields.js +18 -3
  291. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  292. package/dist/indexer/search/search-source.js +157 -111
  293. package/dist/indexer/search/semantic-status.js +4 -1
  294. package/dist/indexer/usage/usage-events.js +10 -30
  295. package/dist/indexer/walk/file-context.js +3 -45
  296. package/dist/indexer/walk/matchers.js +42 -34
  297. package/dist/indexer/walk/path-resolver.js +11 -5
  298. package/dist/indexer/walk/walker.js +42 -14
  299. package/dist/integrations/agent/builder-shared.js +7 -0
  300. package/dist/integrations/agent/builders.js +5 -56
  301. package/dist/integrations/agent/config.js +3 -143
  302. package/dist/integrations/agent/detect.js +17 -2
  303. package/dist/integrations/agent/engine-resolution.js +231 -0
  304. package/dist/integrations/agent/index.js +1 -2
  305. package/dist/integrations/agent/model-aliases.js +16 -2
  306. package/dist/integrations/agent/profiles.js +36 -62
  307. package/dist/integrations/agent/prompts.js +46 -18
  308. package/dist/integrations/agent/runner-dispatch.js +93 -4
  309. package/dist/integrations/agent/runner.js +76 -208
  310. package/dist/integrations/agent/spawn.js +88 -196
  311. package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
  312. package/dist/integrations/harnesses/aider/index.js +48 -0
  313. package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
  314. package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
  315. package/dist/integrations/harnesses/amazonq/index.js +45 -0
  316. package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
  317. package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
  318. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  319. package/dist/integrations/harnesses/claude/index.js +24 -35
  320. package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
  321. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  322. package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
  323. package/dist/integrations/harnesses/codex/index.js +52 -0
  324. package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
  325. package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
  326. package/dist/integrations/harnesses/copilot/index.js +48 -0
  327. package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
  328. package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
  329. package/dist/integrations/harnesses/gemini/index.js +48 -0
  330. package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
  331. package/dist/integrations/harnesses/ids.js +24 -0
  332. package/dist/integrations/harnesses/index.js +54 -34
  333. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  334. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  335. package/dist/integrations/harnesses/opencode/index.js +14 -32
  336. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  337. package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
  338. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
  339. package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
  340. package/dist/integrations/harnesses/openhands/index.js +48 -0
  341. package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
  342. package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
  343. package/dist/integrations/harnesses/pi/index.js +45 -0
  344. package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
  345. package/dist/integrations/harnesses/shared.js +17 -0
  346. package/dist/integrations/harnesses/types.js +43 -32
  347. package/dist/integrations/lockfile.js +211 -24
  348. package/dist/integrations/session-logs/index.js +36 -39
  349. package/dist/integrations/session-logs/provider-base.js +113 -0
  350. package/dist/llm/client.js +182 -110
  351. package/dist/llm/embedders/deterministic.js +2 -2
  352. package/dist/llm/embedders/remote.js +21 -9
  353. package/dist/llm/feature-gate.js +17 -57
  354. package/dist/llm/graph-extract.js +12 -13
  355. package/dist/llm/index-passes.js +8 -42
  356. package/dist/llm/memory-infer.js +144 -1
  357. package/dist/llm/metadata-enhance.js +45 -30
  358. package/dist/llm/structured-call.js +16 -8
  359. package/dist/llm/usage-persist.js +30 -5
  360. package/dist/llm/usage-telemetry.js +59 -6
  361. package/dist/output/cli-hints.js +1 -2
  362. package/dist/output/command-registry.js +27 -0
  363. package/dist/output/context.js +22 -7
  364. package/dist/output/format-exempt.js +80 -0
  365. package/dist/output/generic-render.js +251 -0
  366. package/dist/output/html-render.js +11 -16
  367. package/dist/output/render-registry.js +57 -0
  368. package/dist/output/renderers.js +14 -279
  369. package/dist/output/shapes/curate.js +10 -1
  370. package/dist/output/shapes/events.js +12 -7
  371. package/dist/output/shapes/helpers.js +58 -84
  372. package/dist/output/shapes/passthrough.js +11 -39
  373. package/dist/output/shapes/proposal/producer.js +15 -7
  374. package/dist/output/shapes/registry.js +12 -6
  375. package/dist/output/shapes.js +0 -9
  376. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  377. package/dist/output/text/bundle-show.js +7 -0
  378. package/dist/output/text/command-format.js +562 -0
  379. package/dist/output/text/env.js +1 -3
  380. package/dist/output/text/events.js +8 -7
  381. package/dist/output/text/helpers.js +15 -1164
  382. package/dist/output/text/proposal/producer.js +4 -2
  383. package/dist/output/text/proposal-format.js +202 -0
  384. package/dist/output/text/registry-commands.js +1 -2
  385. package/dist/output/text/registry.js +12 -6
  386. package/dist/output/text/show-directives.js +117 -0
  387. package/dist/output/text/show-format.js +103 -0
  388. package/dist/output/text/sync.js +5 -0
  389. package/dist/output/text/workflow-format.js +332 -0
  390. package/dist/output/text/workflow.js +3 -2
  391. package/dist/output/text.js +10 -19
  392. package/dist/registry/factory.js +4 -6
  393. package/dist/registry/origin-resolve.js +16 -27
  394. package/dist/registry/providers/skills-sh.js +3 -3
  395. package/dist/registry/providers/static-index.js +15 -25
  396. package/dist/registry/resolve.js +43 -94
  397. package/dist/registry/semver.js +43 -0
  398. package/dist/runtime.js +81 -12
  399. package/dist/scripts/akm-migrate.js +35529 -0
  400. package/dist/setup/detect.js +5 -7
  401. package/dist/setup/detected-engines.js +136 -0
  402. package/dist/setup/engine-config.js +100 -0
  403. package/dist/setup/registry-stash-loader.js +3 -3
  404. package/dist/setup/semantic-assets.js +12 -9
  405. package/dist/setup/setup.js +444 -208
  406. package/dist/setup/steps/connection-shared.js +120 -0
  407. package/dist/setup/steps/connection.js +108 -305
  408. package/dist/setup/steps/platforms.js +13 -12
  409. package/dist/setup/steps/semantic.js +15 -3
  410. package/dist/setup/steps/sources.js +21 -15
  411. package/dist/setup/steps/stashdir.js +6 -4
  412. package/dist/setup/steps/tasks.js +236 -119
  413. package/dist/setup/steps.js +3 -2
  414. package/dist/sources/freshness.js +39 -0
  415. package/dist/sources/provider-factory.js +11 -17
  416. package/dist/sources/providers/filesystem.js +2 -3
  417. package/dist/sources/providers/git-install.js +278 -34
  418. package/dist/sources/providers/git-provider.js +54 -56
  419. package/dist/sources/providers/git-stash.js +420 -91
  420. package/dist/sources/providers/git.js +2 -2
  421. package/dist/sources/providers/npm.js +16 -19
  422. package/dist/sources/providers/provider-utils.js +47 -22
  423. package/dist/sources/providers/sync-from-ref.js +3 -9
  424. package/dist/sources/providers/website.js +2 -2
  425. package/dist/sources/resolve.js +11 -10
  426. package/dist/sources/snapshot-fetchers/types.js +4 -0
  427. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  428. package/dist/storage/database.js +60 -4
  429. package/dist/storage/engines/sqlite-migrations.js +156 -5
  430. package/dist/storage/locations.js +1 -2
  431. package/dist/storage/repositories/canaries-repository.js +1 -1
  432. package/dist/storage/repositories/events-repository.js +51 -11
  433. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  434. package/dist/storage/repositories/index-connection.js +79 -0
  435. package/dist/storage/repositories/index-db.js +4 -3
  436. package/dist/storage/repositories/index-entries-repository.js +863 -0
  437. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  438. package/dist/storage/repositories/index-entry-types.js +4 -0
  439. package/dist/storage/repositories/index-fts-repository.js +167 -0
  440. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  441. package/dist/storage/repositories/index-meta-repository.js +49 -0
  442. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  443. package/dist/storage/repositories/index-sql.js +12 -0
  444. package/dist/storage/repositories/index-utility-repository.js +356 -0
  445. package/dist/storage/repositories/index-vec-repository.js +250 -0
  446. package/dist/storage/repositories/outcome-repository.js +119 -0
  447. package/dist/storage/repositories/proposals-repository.js +317 -75
  448. package/dist/storage/repositories/registry-cache.js +1 -1
  449. package/dist/storage/repositories/salience-repository.js +172 -0
  450. package/dist/storage/repositories/task-history-repository.js +110 -3
  451. package/dist/storage/repositories/workflow-runs-repository.js +240 -19
  452. package/dist/tasks/backends/cron.js +169 -46
  453. package/dist/tasks/backends/exec-utils.js +76 -3
  454. package/dist/tasks/backends/index.js +6 -9
  455. package/dist/tasks/backends/launchd.js +292 -55
  456. package/dist/tasks/backends/schtasks.js +557 -70
  457. package/dist/tasks/backends/types.js +4 -0
  458. package/dist/tasks/command-executable.js +93 -0
  459. package/dist/tasks/embedded.js +56 -38
  460. package/dist/tasks/parser.js +156 -64
  461. package/dist/tasks/resolve-akm-bin.js +144 -51
  462. package/dist/tasks/runner.js +377 -209
  463. package/dist/tasks/schedule.js +108 -19
  464. package/dist/tasks/scheduler-invocation.js +296 -0
  465. package/dist/tasks/schema.js +1 -1
  466. package/dist/tasks/task-id.js +35 -0
  467. package/dist/tasks/validator.js +30 -16
  468. package/dist/text-import-hook.mjs +1 -1
  469. package/dist/workflows/authoring/authoring.js +104 -43
  470. package/dist/workflows/authoring/scope-key.js +1 -1
  471. package/dist/workflows/cli.js +0 -16
  472. package/dist/workflows/concurrency-policy.js +15 -0
  473. package/dist/workflows/exec/brief.js +450 -0
  474. package/dist/workflows/exec/frozen-judge.js +47 -0
  475. package/dist/workflows/exec/native-executor.js +1038 -0
  476. package/dist/workflows/exec/param-secrets.js +115 -0
  477. package/dist/workflows/exec/report.js +1460 -0
  478. package/dist/workflows/exec/run-workflow.js +602 -0
  479. package/dist/workflows/exec/scheduler.js +71 -0
  480. package/dist/workflows/exec/step-work.js +1190 -0
  481. package/dist/workflows/exec/unit-writer.js +23 -0
  482. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  483. package/dist/workflows/exec/worktree.js +171 -0
  484. package/dist/workflows/ir/compile.js +246 -0
  485. package/dist/workflows/ir/freeze.js +233 -0
  486. package/dist/workflows/ir/params.js +54 -0
  487. package/dist/workflows/ir/plan-hash.js +68 -0
  488. package/dist/workflows/ir/schema.js +540 -0
  489. package/dist/workflows/parser.js +878 -304
  490. package/dist/workflows/program/expressions.js +181 -0
  491. package/dist/workflows/program/schema.js +51 -0
  492. package/dist/workflows/renderer.js +100 -45
  493. package/dist/workflows/resource-limits.js +22 -0
  494. package/dist/workflows/runtime/agent-identity.js +59 -14
  495. package/dist/workflows/runtime/checkin.js +1 -1
  496. package/dist/workflows/runtime/plan-classifier.js +131 -0
  497. package/dist/workflows/runtime/runs.js +376 -119
  498. package/dist/workflows/runtime/unit-checkin.js +45 -0
  499. package/dist/workflows/runtime/unit-phases.js +20 -0
  500. package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
  501. package/dist/workflows/schema.js +1 -11
  502. package/dist/workflows/validate-summary.js +2 -3
  503. package/dist/workflows/validator.js +52 -30
  504. package/docs/README.md +42 -78
  505. package/docs/migration/README.md +8 -0
  506. package/docs/migration/release-notes/0.6.0.md +1 -1
  507. package/docs/migration/release-notes/0.7.0.md +9 -8
  508. package/docs/migration/release-notes/0.9.0.md +158 -14
  509. package/docs/migration/v0.7-to-v0.8.md +46 -47
  510. package/docs/migration/v0.8-to-v0.9.md +844 -0
  511. package/docs/reference/README.md +12 -0
  512. package/docs/reference/data-and-telemetry.md +333 -0
  513. package/package.json +21 -17
  514. package/schemas/akm-asset-envelope.json +93 -0
  515. package/schemas/akm-config.json +4636 -0
  516. package/schemas/akm-task.json +87 -0
  517. package/schemas/akm-workflow.json +373 -0
  518. package/dist/akm-migrate-storage +0 -38
  519. package/dist/assets/help/help-accept.md +0 -12
  520. package/dist/assets/help/help-improve.md +0 -84
  521. package/dist/assets/help/help-proposals.md +0 -17
  522. package/dist/assets/help/help-propose.md +0 -17
  523. package/dist/assets/help/help-reject.md +0 -11
  524. package/dist/assets/profiles/frequent.json +0 -13
  525. package/dist/assets/profiles/recombine-only.json +0 -21
  526. package/dist/assets/profiles/reflect-distill.json +0 -30
  527. package/dist/assets/profiles/synthesize.json +0 -15
  528. package/dist/assets/prompts/procedural-system.md +0 -44
  529. package/dist/assets/prompts/recombine-system.md +0 -40
  530. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  531. package/dist/assets/tasks/core/backup.yml +0 -4
  532. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  533. package/dist/assets/templates/html/default.html +0 -78
  534. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  535. package/dist/assets/wiki/index-template.md +0 -12
  536. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  537. package/dist/assets/wiki/log-template.md +0 -8
  538. package/dist/assets/wiki/schema-template.md +0 -61
  539. package/dist/cli/config-migrate.js +0 -150
  540. package/dist/cli/config-validate.js +0 -39
  541. package/dist/commands/graph/graph-cli.js +0 -124
  542. package/dist/commands/graph/graph.js +0 -487
  543. package/dist/commands/improve/calibration.js +0 -161
  544. package/dist/commands/improve/dedup.js +0 -482
  545. package/dist/commands/improve/extract-watch.js +0 -140
  546. package/dist/commands/improve/hot-probation.js +0 -45
  547. package/dist/commands/improve/improve-auto-accept.js +0 -276
  548. package/dist/commands/improve/improve-profiles.js +0 -168
  549. package/dist/commands/improve/procedural.js +0 -398
  550. package/dist/commands/improve/recombine.js +0 -818
  551. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  552. package/dist/commands/lint/agent-linter.js +0 -44
  553. package/dist/commands/lint/command-linter.js +0 -44
  554. package/dist/commands/lint/default-linter.js +0 -16
  555. package/dist/commands/lint/fact-linter.js +0 -39
  556. package/dist/commands/lint/knowledge-linter.js +0 -16
  557. package/dist/commands/lint/memory-linter.js +0 -61
  558. package/dist/commands/lint/registry.js +0 -41
  559. package/dist/commands/lint/skill-linter.js +0 -45
  560. package/dist/commands/lint/task-linter.js +0 -50
  561. package/dist/commands/lint/workflow-linter.js +0 -81
  562. package/dist/commands/proposal/legacy-import.js +0 -115
  563. package/dist/commands/sources/history.js +0 -196
  564. package/dist/commands/tasks/default-tasks.js +0 -186
  565. package/dist/commands/wiki-cli.js +0 -292
  566. package/dist/core/asset/asset-registry.js +0 -76
  567. package/dist/core/asset/asset-spec.js +0 -259
  568. package/dist/core/config/config-migration.js +0 -602
  569. package/dist/core/deep-merge.js +0 -38
  570. package/dist/core/eval/rank-metrics.js +0 -113
  571. package/dist/core/ripgrep/install.js +0 -163
  572. package/dist/core/ripgrep/resolve.js +0 -81
  573. package/dist/indexer/db/db.js +0 -1413
  574. package/dist/indexer/manifest.js +0 -170
  575. package/dist/indexer/passes/metadata-contributors.js +0 -31
  576. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  577. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
  578. package/dist/llm/call-ai.js +0 -62
  579. package/dist/llm/memory-infer-impl.js +0 -138
  580. package/dist/output/shapes/distill.js +0 -14
  581. package/dist/output/shapes/history.js +0 -11
  582. package/dist/output/text/distill.js +0 -6
  583. package/dist/output/text/enable-disable.js +0 -8
  584. package/dist/output/text/history.js +0 -6
  585. package/dist/output/text/wiki.js +0 -16
  586. package/dist/registry/build-index.js +0 -386
  587. package/dist/scripts/migrate-storage.js +0 -19108
  588. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
  589. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  590. package/dist/setup/legacy-config.js +0 -106
  591. package/dist/storage/repositories/consolidation-repository.js +0 -38
  592. package/dist/storage/repositories/recombine-repository.js +0 -213
  593. package/dist/wiki/wiki-templates.js +0 -15
  594. package/dist/wiki/wiki.js +0 -1012
  595. package/dist/workflows/db.js +0 -215
  596. package/docs/data-and-telemetry.md +0 -226
  597. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  598. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -1,36 +1,65 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ import { randomUUID } from "node:crypto";
4
5
  import fs from "node:fs";
5
6
  import path from "node:path";
6
- import { makeAssetRef, parseAssetRef } from "../../core/asset/asset-ref.js";
7
- import { TYPE_DIRS } from "../../core/asset/asset-spec.js";
8
- import { NotFoundError, UsageError } from "../../core/errors.js";
9
- import { findSourceForPath, getPrimarySource, resolveSourceEntries, } from "../../indexer/search/search-source.js";
10
- import { isRemoteOrigin, resolveSourcesForOrigin } from "../../registry/origin-resolve.js";
7
+ import { stashDirFor } from "../../core/asset/asset-placement.js";
8
+ import { isBundleSlug } from "../../core/asset/asset-ref.js";
9
+ import { displayRef, parseQualifiedRefInput } from "../../core/asset/resolve-ref.js";
10
+ import { loadConfig } from "../../core/config/config.js";
11
+ import { ConfigError, NotFoundError, UsageError } from "../../core/errors.js";
12
+ import { defaultBundleForTarget } from "../../core/mutation-target.js";
13
+ import { warn } from "../../core/warn.js";
14
+ import { commitWriteTargetBoundary, prepareWriteTargetForMutation, resolveWriteTarget, } from "../../core/write-source.js";
15
+ import { withAssetMutationLease } from "../../indexer/index-writer-lock.js";
16
+ import { indexWrittenAssets } from "../../indexer/index-written-assets.js";
17
+ import { findSourceForPath, resolveSourceEntries } from "../../indexer/search/search-source.js";
18
+ import { isRemoteOrigin, resolveSourcesForLocator, resolveSourcesForOrigin } from "../../registry/origin-resolve.js";
11
19
  import { syncFromRef } from "../../sources/providers/sync-from-ref.js";
12
20
  import { resolveAssetPath } from "../../sources/resolve.js";
21
+ function destinationRef(config, target, type, name) {
22
+ if (!config || !target)
23
+ return undefined;
24
+ return displayRef({ type, name, bundleId: target.source.name }, defaultBundleForTarget(config));
25
+ }
13
26
  export async function akmClone(options) {
14
- const parsed = parseAssetRef(options.sourceRef);
15
- // When --dest is provided, the working stash is optional
27
+ const unmanagedDest = options.dest;
28
+ const hasUnmanagedDest = unmanagedDest !== undefined;
29
+ if (hasUnmanagedDest && options.target !== undefined) {
30
+ throw new UsageError("--dest and --bundle cannot be used together; choose an unmanaged path or a managed bundle.");
31
+ }
32
+ // F1b/F4b: accept the 0.9.0 conceptId spelling (`akm clone scripts/deploy.sh`).
33
+ // F5 origin split (parseQualifiedRefInput): `akm clone` also accepts a NON-slug
34
+ // clone SOURCE as the `origin//conceptId` prefix — a registry ref
35
+ // (`npm:@scope/pkg`), a bare path, or a URL — resolved by
36
+ // resolveSourcesForOrigin's registry-id / path matching + the remote-fetch
37
+ // fallback below (the strict new-grammar parser rejects such origins as they
38
+ // are not bundle slugs).
39
+ const parsed = parseQualifiedRefInput(options.sourceRef);
40
+ const config = hasUnmanagedDest ? undefined : loadConfig();
41
+ const resolvedWriteTarget = config ? resolveWriteTarget(config, options.target) : undefined;
42
+ const writeTarget = resolvedWriteTarget ? prepareWriteTargetForMutation(resolvedWriteTarget) : undefined;
43
+ // An unmanaged --dest does not require any configured write target.
16
44
  let allSources;
17
45
  try {
18
46
  allSources = resolveSourceEntries();
19
47
  }
20
48
  catch (err) {
21
- if (options.dest) {
49
+ if (hasUnmanagedDest) {
22
50
  allSources = [];
23
51
  }
24
52
  else {
25
53
  throw err;
26
54
  }
27
55
  }
28
- const primarySource = getPrimarySource(allSources);
29
- const destRoot = options.dest ? path.resolve(options.dest) : primarySource?.path;
56
+ const destRoot = unmanagedDest !== undefined ? path.resolve(unmanagedDest) : writeTarget?.source.path;
30
57
  if (!destRoot) {
31
- throw new Error("No working stash configured and no --dest provided. Run `akm init` or pass --dest.");
58
+ throw new ConfigError("No writable source configured and no --dest provided. Run `akm bundle create` or pass --dest.", "STASH_DIR_NOT_FOUND");
32
59
  }
33
- let searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
60
+ let searchSources = parsed.origin && !isBundleSlug(parsed.origin)
61
+ ? resolveSourcesForLocator(parsed.origin, allSources)
62
+ : resolveSourcesForOrigin(parsed.origin, allSources);
34
63
  // Remote fetch fallback: if no local source matched and origin looks remote, fetch it
35
64
  let remoteFetched;
36
65
  if (searchSources.length === 0 && parsed.origin && isRemoteOrigin(parsed.origin, allSources)) {
@@ -66,9 +95,9 @@ export async function akmClone(options) {
66
95
  }
67
96
  const sourceSource = findSourceForPath(sourcePath, allSources);
68
97
  const destName = options.newName ?? parsed.name;
69
- const typeDir = TYPE_DIRS[parsed.type];
98
+ const typeDir = stashDirFor(parsed.type);
70
99
  // Validate destName to prevent path traversal (parsed.name is already
71
- // validated by parseAssetRef, but newName comes directly from user input).
100
+ // validated by the ref parser, but newName comes directly from user input).
72
101
  // Run whenever newName is provided, including empty string.
73
102
  if (options.newName !== undefined) {
74
103
  if (destName === "") {
@@ -92,7 +121,11 @@ export async function akmClone(options) {
92
121
  throw new UsageError(`Unsafe clone name "${destName}": resolves outside the target type directory.`);
93
122
  }
94
123
  }
95
- const destLabel = options.dest ? "at destination" : "in working stash";
124
+ const destLabel = hasUnmanagedDest
125
+ ? "at destination"
126
+ : writeTarget?.selector
127
+ ? `in target "${writeTarget.selector}"`
128
+ : "in working stash";
96
129
  // Guard against self-clone
97
130
  if (parsed.type === "skill") {
98
131
  const sourceSkillDir = path.resolve(path.dirname(sourcePath));
@@ -110,39 +143,109 @@ export async function akmClone(options) {
110
143
  throw new Error(`Source and destination are the same path. Use --name to provide a new name for the clone.`);
111
144
  }
112
145
  }
113
- let destPath;
114
- if (parsed.type === "skill") {
115
- const sourceSkillDir = path.dirname(sourcePath);
116
- const destSkillDir = path.join(destRoot, typeDir, destName);
117
- const overwritten = fs.existsSync(destSkillDir);
118
- if (overwritten && !options.force) {
119
- throw new Error(`Asset already exists ${destLabel}: ${destSkillDir}. Use --force to overwrite.`);
146
+ return withAssetMutationLease("clone", async () => {
147
+ let destPath;
148
+ let overwritten;
149
+ let operationPaths;
150
+ if (parsed.type === "skill") {
151
+ const sourceSkillDir = path.dirname(sourcePath);
152
+ const destSkillDir = path.join(destRoot, typeDir, destName);
153
+ assertNoDestinationSymlinkParent(destRoot, destSkillDir);
154
+ const existing = lstatIfExists(destSkillDir);
155
+ overwritten = existing !== undefined;
156
+ if (overwritten && !options.force) {
157
+ throw new UsageError(`Asset already exists ${destLabel}: ${destSkillDir}. Use --force to overwrite.`, "RESOURCE_ALREADY_EXISTS");
158
+ }
159
+ const replacedPaths = existing?.isDirectory() && !existing.isSymbolicLink() ? listTreeFiles(destSkillDir) : [];
160
+ // Stage first so a failed source copy leaves the old entry untouched. A
161
+ // final symlink is removed as an entry, never traversed.
162
+ const stagingDir = `${destSkillDir}.tmp-${randomUUID()}`;
163
+ try {
164
+ fs.cpSync(sourceSkillDir, stagingDir, { recursive: true, errorOnExist: true, force: false });
165
+ if (overwritten)
166
+ fs.rmSync(destSkillDir, { recursive: true, force: true });
167
+ fs.renameSync(stagingDir, destSkillDir);
168
+ }
169
+ catch (err) {
170
+ fs.rmSync(stagingDir, { recursive: true, force: true });
171
+ throw err;
172
+ }
173
+ destPath = path.join(destSkillDir, "SKILL.md");
174
+ operationPaths = [...new Set([...replacedPaths, ...listTreeFiles(destSkillDir)])];
120
175
  }
121
- if (overwritten) {
122
- fs.rmSync(destSkillDir, { recursive: true, force: true });
176
+ else {
177
+ destPath = path.join(destRoot, typeDir, destName);
178
+ assertNoDestinationSymlinkParent(destRoot, destPath);
179
+ const existing = lstatIfExists(destPath);
180
+ overwritten = existing !== undefined;
181
+ if (overwritten && !options.force) {
182
+ throw new UsageError(`Asset already exists ${destLabel}: ${destPath}. Use --force to overwrite.`, "RESOURCE_ALREADY_EXISTS");
183
+ }
184
+ fs.mkdirSync(path.dirname(destPath), { recursive: true });
185
+ const stagingPath = `${destPath}.tmp-${randomUUID()}`;
186
+ try {
187
+ fs.copyFileSync(sourcePath, stagingPath, fs.constants.COPYFILE_EXCL);
188
+ if (overwritten)
189
+ fs.rmSync(destPath, { recursive: true, force: true });
190
+ fs.renameSync(stagingPath, destPath);
191
+ }
192
+ catch (err) {
193
+ fs.rmSync(stagingPath, { force: true });
194
+ throw err;
195
+ }
196
+ operationPaths = [destPath];
197
+ }
198
+ const ref = destinationRef(config, writeTarget, parsed.type, destName);
199
+ if (writeTarget) {
200
+ const commitRoot = writeTarget.source.repoPath ?? writeTarget.source.path;
201
+ const commitPaths = operationPaths.map((filePath) => path.relative(commitRoot, filePath).replaceAll(path.sep, "/"));
202
+ commitWriteTargetBoundary(writeTarget, `Clone ${ref}`, { paths: commitPaths });
203
+ if (!(await indexWrittenAssets(writeTarget.source.path, [destPath], { bundleId: writeTarget.source.name }))) {
204
+ warn(`Clone ${ref} succeeded, but its targeted index update failed; run \`akm index\` to refresh it.`);
205
+ }
123
206
  }
124
- fs.cpSync(sourceSkillDir, destSkillDir, { recursive: true });
125
- destPath = path.join(destSkillDir, "SKILL.md");
126
- const ref = makeAssetRef(parsed.type, destName, "local");
127
207
  return {
128
208
  source: { path: sourcePath, registryId: sourceSource?.registryId },
129
- destination: { path: destPath, ref },
209
+ destination: { path: destPath, ...(ref ? { ref } : {}) },
130
210
  overwritten,
131
211
  ...(remoteFetched ? { remoteFetched } : {}),
132
212
  };
213
+ });
214
+ }
215
+ function lstatIfExists(filePath) {
216
+ try {
217
+ return fs.lstatSync(filePath);
133
218
  }
134
- destPath = path.join(destRoot, typeDir, destName);
135
- const overwritten = fs.existsSync(destPath);
136
- if (overwritten && !options.force) {
137
- throw new Error(`Asset already exists ${destLabel}: ${destPath}. Use --force to overwrite.`);
219
+ catch (error) {
220
+ if (error.code === "ENOENT")
221
+ return undefined;
222
+ throw error;
223
+ }
224
+ }
225
+ function assertNoDestinationSymlinkParent(root, destination) {
226
+ const resolvedRoot = path.resolve(root);
227
+ const relativeParent = path.relative(resolvedRoot, path.dirname(path.resolve(destination)));
228
+ if (relativeParent === "" || relativeParent === ".")
229
+ return;
230
+ if (relativeParent.startsWith("..") || path.isAbsolute(relativeParent)) {
231
+ throw new UsageError(`Clone destination escapes the selected target: ${destination}.`, "PATH_ESCAPE_VIOLATION");
232
+ }
233
+ let current = resolvedRoot;
234
+ for (const segment of relativeParent.split(path.sep)) {
235
+ current = path.join(current, segment);
236
+ if (lstatIfExists(current)?.isSymbolicLink()) {
237
+ throw new UsageError(`Clone destination has a symbolic-link parent outside the selected target boundary: ${current}.`, "PATH_ESCAPE_VIOLATION");
238
+ }
239
+ }
240
+ }
241
+ function listTreeFiles(root) {
242
+ const files = [];
243
+ for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
244
+ const entryPath = path.join(root, entry.name);
245
+ if (entry.isDirectory())
246
+ files.push(...listTreeFiles(entryPath));
247
+ else
248
+ files.push(entryPath);
138
249
  }
139
- fs.mkdirSync(path.dirname(destPath), { recursive: true });
140
- fs.copyFileSync(sourcePath, destPath);
141
- const ref = makeAssetRef(parsed.type, destName, "local");
142
- return {
143
- source: { path: sourcePath, registryId: sourceSource?.registryId },
144
- destination: { path: destPath, ref },
145
- overwritten,
146
- ...(remoteFetched ? { remoteFetched } : {}),
147
- };
250
+ return files;
148
251
  }
@@ -2,10 +2,11 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import path from "node:path";
5
+ import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
5
6
  import { isRemoteUrl } from "../../core/common.js";
6
- import { getSources, loadConfig, loadUserConfig, saveConfig } from "../../core/config/config.js";
7
+ import { bundleEntryToSourceEntry, bundlesToSourceEntries, getSources, mutateConfig } from "../../core/config/config.js";
7
8
  import { ConfigError, UsageError } from "../../core/errors.js";
8
- import { resolveSourceEntries } from "../../indexer/search/search-source.js";
9
+ import { bundleKeyForPath, bundleKeyForUrl, nextBundleKey } from "./bundle-config-ops.js";
9
10
  // ── Operations ──────────────────────────────────────────────────────────────
10
11
  /**
11
12
  * Add a stash source (filesystem path or remote provider URL) to config.
@@ -22,72 +23,106 @@ export function addStash(opts) {
22
23
  if (writable === true && providerType && providerType !== "filesystem" && providerType !== "git") {
23
24
  throw new ConfigError("writable: true is only supported on filesystem and git sources", "INVALID_CONFIG_FILE");
24
25
  }
25
- const config = loadUserConfig();
26
- const sources = [...getSources(config)];
27
- let entry;
28
- if (isRemoteUrl(target)) {
29
- if (!providerType) {
30
- throw new UsageError("--provider is required for URL sources (e.g. --provider git --provider website)");
31
- }
32
- // Deduplicate by URL
33
- if (sources.some((s) => s.url === target)) {
34
- return { sources, added: false, message: "Source URL already configured" };
35
- }
36
- entry = { type: providerType, url: target };
37
- if (name)
38
- entry.name = name;
39
- if (writable)
40
- entry.writable = true;
41
- if (providerOptions)
42
- entry.options = providerOptions;
26
+ let result;
27
+ const targetIsUrl = isRemoteUrl(target);
28
+ if (targetIsUrl && !providerType) {
29
+ throw new UsageError("--provider is required for URL sources (e.g. --provider git --provider website)");
43
30
  }
44
- else {
45
- // Filesystem path
46
- const resolvedPath = path.resolve(target);
47
- if (sources.some((s) => s.path && path.resolve(s.path) === resolvedPath)) {
48
- return { sources, added: false, message: "Source path already configured" };
31
+ // R-013: `--provider npm` names an npm package SPEC (e.g. "lodash",
32
+ // "@scope/pkg@^2"), never a URL — a tarball URL is not installable as a
33
+ // package spec and would only fail much later, at first sync, with a
34
+ // confusing "Invalid npm package name" error. Reject it loudly here instead.
35
+ if (providerType === "npm" && targetIsUrl) {
36
+ throw new UsageError(`--provider npm expects a package spec (e.g. "lodash" or "@scope/pkg@^2"), not a URL: "${target}". ` +
37
+ "Drop --provider npm and re-run `akm bundle add <package>` to add an npm source.");
38
+ }
39
+ // A bare (non-URL) target with --provider npm is a declarative npm source
40
+ // add — the same "locator, not a URL" descriptor path used for git/website
41
+ // URL sources below. Without this, a non-URL target fell through to the
42
+ // filesystem branch below and `--provider npm` was silently ignored,
43
+ // creating a bogus filesystem bundle for the current working directory
44
+ // (R-013).
45
+ const useDescriptorPath = targetIsUrl || providerType === "npm";
46
+ mutateConfig((config) => {
47
+ const bundles = { ...(config.bundles ?? {}) };
48
+ let key;
49
+ if (useDescriptorPath) {
50
+ if (bundleKeyForUrl(config, target)) {
51
+ const already = targetIsUrl ? "Source URL already configured" : "Source already configured";
52
+ result = { sources: getSources(config), added: false, message: already };
53
+ return config;
54
+ }
55
+ key = nextBundleKey(bundles, name, target);
56
+ bundles[key] = urlBundleDescriptor(providerType, target, providerOptions, writable === true);
57
+ }
58
+ else {
59
+ const resolvedPath = path.resolve(target);
60
+ if (bundleKeyForPath(config, resolvedPath)) {
61
+ result = { sources: getSources(config), added: false, message: "Source path already configured" };
62
+ return config;
63
+ }
64
+ key = nextBundleKey(bundles, name, resolvedPath);
65
+ bundles[key] = {
66
+ path: resolvedPath,
67
+ ...(writable === true ? { writable: true } : {}),
68
+ components: {
69
+ main: { root: ".", adapter: detectAdapterId(resolvedPath), writable: writable ?? true },
70
+ },
71
+ };
49
72
  }
50
- entry = { type: "filesystem", path: resolvedPath };
51
- if (name)
52
- entry.name = name;
73
+ const next = { ...config, bundles };
74
+ const entry = bundleEntryToSourceEntry(key, bundles[key]);
75
+ result = { sources: bundlesToSourceEntries(next) ?? [], added: true, entry };
76
+ return next;
77
+ });
78
+ return result;
79
+ }
80
+ /**
81
+ * Build the 0.9.0 bundle descriptor for a declarative (non-filesystem) source
82
+ * (spec §10.1). `locator` is a URL for git/website; for npm it is a bare
83
+ * package spec (e.g. "lodash", "@scope/pkg@^2") — never a URL (R-013,
84
+ * rejected earlier in {@link addStash}).
85
+ */
86
+ function urlBundleDescriptor(providerType, locator, options, writable) {
87
+ if (providerType === "website") {
88
+ // Website provider options ride on the (passthrough) website descriptor and
89
+ // round-trip back to `entry.options` via bundleEntryToSourceEntry.
90
+ return {
91
+ website: { url: locator, ...(options ?? {}) },
92
+ components: { main: { root: ".", adapter: "website-snapshot", writable: false } },
93
+ };
53
94
  }
54
- sources.push(entry);
55
- saveConfig({ ...config, sources });
56
- return { sources, added: true, entry };
95
+ if (providerType === "npm")
96
+ return { npm: locator };
97
+ if (providerType === "git")
98
+ return { git: locator, ...(writable ? { writable: true } : {}) };
99
+ throw new ConfigError(`unsupported source type "${providerType}"; expected filesystem, git, website, or npm`, "INVALID_CONFIG_FILE");
57
100
  }
58
101
  /**
59
102
  * Remove a stash source by URL, path, or name.
60
103
  * Match priority: URL > path > name (most specific first).
61
104
  */
62
105
  export function removeStash(target) {
63
- const config = loadUserConfig();
64
- const sources = [...getSources(config)];
65
106
  const isUrlTarget = isRemoteUrl(target);
66
107
  const resolvedPath = !isUrlTarget ? path.resolve(target) : undefined;
67
- // Try URL match first, then path, then name (most specific → least specific)
68
- let idx = -1;
69
- if (isUrlTarget) {
70
- idx = sources.findIndex((s) => s.url === target);
71
- }
72
- if (idx === -1 && resolvedPath) {
73
- idx = sources.findIndex((s) => s.path && path.resolve(s.path) === resolvedPath);
74
- }
75
- if (idx === -1) {
76
- idx = sources.findIndex((s) => s.name === target);
77
- }
78
- if (idx === -1) {
79
- return { sources, removed: false, message: "No matching source found" };
80
- }
81
- const removed = sources.splice(idx, 1)[0];
82
- saveConfig({ ...config, sources });
83
- return { sources, removed: true, entry: removed };
84
- }
85
- /**
86
- * List all stash sources (local filesystem + configured stashes).
87
- */
88
- export function listStashes() {
89
- const config = loadConfig();
90
- const localSources = resolveSourceEntries();
91
- const sources = getSources(config);
92
- return { localSources, sources };
108
+ let result;
109
+ mutateConfig((config) => {
110
+ const bundles = { ...(config.bundles ?? {}) };
111
+ // Match priority: URL > path > bundle key (name).
112
+ let key = isUrlTarget ? bundleKeyForUrl(config, target) : undefined;
113
+ if (!key && resolvedPath)
114
+ key = bundleKeyForPath(config, resolvedPath);
115
+ if (!key && target in bundles)
116
+ key = target;
117
+ if (!key) {
118
+ result = { sources: getSources(config), removed: false, message: "No matching source found" };
119
+ return config;
120
+ }
121
+ const removed = bundleEntryToSourceEntry(key, bundles[key]);
122
+ delete bundles[key];
123
+ const next = { ...config, bundles: Object.keys(bundles).length > 0 ? bundles : undefined };
124
+ result = { sources: bundlesToSourceEntries(next) ?? [], removed: true, entry: removed };
125
+ return next;
126
+ });
127
+ return result;
93
128
  }