akm-cli 0.9.0-rc.8 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (450) hide show
  1. package/CHANGELOG.md +1063 -44
  2. package/README.md +51 -25
  3. package/SECURITY.md +14 -1
  4. package/STABILITY.md +497 -0
  5. package/dist/akm +148 -35
  6. package/dist/{akm-migrate-storage → akm-migrate} +6 -9
  7. package/dist/assets/hints/cli-hints-full.md +223 -95
  8. package/dist/assets/hints/cli-hints-short.md +85 -22
  9. package/dist/assets/improve-strategies/default.json +1 -1
  10. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  11. package/dist/assets/prompts/memory-infer-user.md +2 -3
  12. package/dist/assets/stash-skeleton/README.md +6 -5
  13. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
  14. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
  15. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
  17. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
  18. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
  19. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
  20. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
  21. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
  22. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
  23. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
  24. package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
  25. package/dist/assets/tasks/core/extract.yml +1 -1
  26. package/dist/assets/tasks/core/version-check.yml +1 -1
  27. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  28. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  29. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  30. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  31. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  32. package/dist/assets/templates/html/health.html +1 -3
  33. package/dist/assets/workflows/workflow-template.md +32 -15
  34. package/dist/cli/invocation.js +40 -15
  35. package/dist/cli/parse-args.js +0 -22
  36. package/dist/cli/retired-commands.js +121 -0
  37. package/dist/cli/shared.js +154 -22
  38. package/dist/cli/unknown-flags.js +236 -0
  39. package/dist/cli-node.mjs +2 -1
  40. package/dist/cli.js +696 -258
  41. package/dist/commands/agent/agent-dispatch.js +14 -3
  42. package/dist/commands/agent/contribute-cli.js +73 -88
  43. package/dist/commands/completions.js +79 -22
  44. package/dist/commands/config-cli.js +17 -150
  45. package/dist/commands/env/env-cli.js +59 -143
  46. package/dist/commands/env/env.js +12 -163
  47. package/dist/commands/env/marker-path.js +6 -0
  48. package/dist/commands/env/secret-cli.js +36 -66
  49. package/dist/commands/env/secret.js +24 -57
  50. package/dist/commands/feedback-cli.js +141 -87
  51. package/dist/commands/health/accept-rate.js +58 -0
  52. package/dist/commands/health/advisories.js +3 -4
  53. package/dist/commands/health/checks.js +85 -23
  54. package/dist/commands/health/html-report.js +7 -10
  55. package/dist/commands/health/improve-metrics.js +25 -83
  56. package/dist/commands/health/md-report.js +5 -9
  57. package/dist/commands/health/metrics.js +62 -20
  58. package/dist/commands/health/renderers.js +47 -0
  59. package/dist/commands/health/report-view-model.js +4 -5
  60. package/dist/commands/health/stash-exposure.js +1 -1
  61. package/dist/commands/health/surfaces.js +3 -48
  62. package/dist/commands/health/task-runs.js +3 -67
  63. package/dist/commands/health/types-improve.js +7 -0
  64. package/dist/commands/health.js +99 -28
  65. package/dist/commands/improve/anti-collapse.js +2 -2
  66. package/dist/commands/improve/autonomy-gate.js +68 -0
  67. package/dist/commands/improve/collapse-detector.js +41 -40
  68. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  69. package/dist/commands/improve/consolidate/merge.js +4 -0
  70. package/dist/commands/improve/consolidate.js +140 -1000
  71. package/dist/commands/improve/distill/promote-memory.js +12 -12
  72. package/dist/commands/improve/distill/quality-gate.js +6 -6
  73. package/dist/commands/improve/distill.js +58 -69
  74. package/dist/commands/improve/eligibility.js +105 -57
  75. package/dist/commands/improve/extract-cli.js +14 -133
  76. package/dist/commands/improve/improve-cli.js +98 -114
  77. package/dist/commands/improve/improve-result-file.js +1 -28
  78. package/dist/commands/improve/improve-strategies.js +8 -5
  79. package/dist/commands/improve/improve.js +128 -91
  80. package/dist/commands/improve/loop-stages.js +182 -20
  81. package/dist/commands/improve/memory/derived-ref.js +45 -43
  82. package/dist/commands/improve/memory/memory-belief.js +1 -1
  83. package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
  84. package/dist/commands/improve/memory/memory-improve.js +6 -5
  85. package/dist/commands/improve/outcome-loop.js +22 -65
  86. package/dist/commands/improve/preparation.js +114 -123
  87. package/dist/commands/improve/proactive-maintenance.js +2 -5
  88. package/dist/commands/improve/reflect.js +56 -160
  89. package/dist/commands/improve/salience.js +11 -122
  90. package/dist/commands/improve/source-identity.js +10 -38
  91. package/dist/commands/lint/base-linter.js +20 -124
  92. package/dist/commands/lint/env-key-rules.js +31 -47
  93. package/dist/commands/lint/index.js +249 -43
  94. package/dist/commands/{events.js → log.js} +33 -38
  95. package/dist/commands/migrate-cli.js +92 -12
  96. package/dist/commands/migration-tool.js +46 -0
  97. package/dist/commands/observability-cli.js +70 -209
  98. package/dist/commands/proposal/drain.js +101 -29
  99. package/dist/commands/proposal/proposal-cli.js +76 -48
  100. package/dist/commands/proposal/proposal.js +54 -18
  101. package/dist/commands/proposal/propose-cli.js +88 -0
  102. package/dist/commands/proposal/propose.js +23 -15
  103. package/dist/commands/proposal/repository.js +701 -278
  104. package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
  105. package/dist/commands/proposal/validators/proposal-validators.js +55 -7
  106. package/dist/commands/proposal/validators/proposals.js +4 -7
  107. package/dist/commands/read/curate.js +34 -53
  108. package/dist/commands/read/knowledge.js +150 -95
  109. package/dist/commands/read/registry-search.js +2 -2
  110. package/dist/commands/read/remember-cli.js +42 -15
  111. package/dist/commands/read/search-cli.js +180 -78
  112. package/dist/commands/read/search.js +58 -43
  113. package/dist/commands/read/show.js +197 -141
  114. package/dist/commands/registry-cli.js +12 -51
  115. package/dist/commands/remember.js +14 -57
  116. package/dist/commands/sources/add-cli.js +100 -31
  117. package/dist/commands/sources/bundle-cli.js +166 -0
  118. package/dist/commands/sources/bundle-config-ops.js +7 -2
  119. package/dist/commands/sources/info.js +18 -5
  120. package/dist/commands/sources/init.js +12 -12
  121. package/dist/commands/sources/installed-stashes.js +382 -98
  122. package/dist/commands/sources/schema-repair.js +3 -2
  123. package/dist/commands/sources/self-update.js +131 -38
  124. package/dist/commands/sources/source-add.js +72 -17
  125. package/dist/commands/sources/source-clone.js +129 -45
  126. package/dist/commands/sources/source-manage.js +43 -23
  127. package/dist/commands/sources/sources-cli.js +57 -208
  128. package/dist/commands/sources/stash-cli.js +46 -53
  129. package/dist/commands/tasks/tasks-cli.js +91 -97
  130. package/dist/commands/tasks/tasks.js +276 -421
  131. package/dist/commands/workflow-cli.js +175 -450
  132. package/dist/core/adapter/adapters/akm-adapter.js +47 -28
  133. package/dist/core/adapter/adapters/akm-lint.js +42 -27
  134. package/dist/core/adapter/adapters/akm-metadata.js +15 -44
  135. package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
  136. package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
  137. package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
  138. package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
  139. package/dist/core/adapter/adapters/index.js +6 -6
  140. package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
  141. package/dist/core/adapter/adapters/okf-adapter.js +187 -19
  142. package/dist/core/adapter/adapters/shared.js +3 -19
  143. package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
  144. package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
  145. package/dist/core/adapter/detect-adapter.js +17 -0
  146. package/dist/core/adapter/recognize-match.js +6 -4
  147. package/dist/core/adapter/validate-context.js +214 -0
  148. package/dist/core/asset/akm-markdown.js +63 -0
  149. package/dist/core/asset/asset-placement.js +20 -6
  150. package/dist/core/asset/asset-ref.js +11 -9
  151. package/dist/core/asset/frontmatter-lint.js +30 -0
  152. package/dist/core/asset/frontmatter.js +37 -9
  153. package/dist/core/asset/markdown.js +40 -51
  154. package/dist/core/asset/resolve-ref.js +89 -18
  155. package/dist/core/asset/stash-meta.js +1 -1
  156. package/dist/core/bundle-id.js +51 -0
  157. package/dist/core/common.js +152 -38
  158. package/dist/core/config/config-io.js +12 -1
  159. package/dist/core/config/config-schema.js +35 -8
  160. package/dist/core/config/config-sources.js +55 -11
  161. package/dist/core/config/config-walker.js +25 -9
  162. package/dist/core/config/config.js +9 -48
  163. package/dist/core/config/experimental.js +21 -0
  164. package/dist/core/config/schema/embedding.js +5 -1
  165. package/dist/core/config/schema/experimental.js +30 -0
  166. package/dist/core/config/schema/improve-processes.js +0 -6
  167. package/dist/core/config/schema/improve.js +21 -3
  168. package/dist/core/config/schema/index-config.js +8 -15
  169. package/dist/core/config/schema/output.js +4 -1
  170. package/dist/core/config/schema/setup.js +9 -18
  171. package/dist/core/config/schema/sources-bundles.js +49 -33
  172. package/dist/core/config/schema/workflow.js +3 -3
  173. package/dist/core/env-secret-ref.js +76 -46
  174. package/dist/core/errors.js +18 -12
  175. package/dist/core/events.js +46 -128
  176. package/dist/core/file-change.js +6 -5
  177. package/dist/core/fs-txn.js +83 -7
  178. package/dist/core/git-message.js +2 -2
  179. package/dist/core/improve-result.js +1 -100
  180. package/dist/core/lesson-lint.js +1 -17
  181. package/dist/core/logs-db.js +2 -1
  182. package/dist/core/migration-operation.js +16 -0
  183. package/dist/core/mutation-target.js +78 -0
  184. package/dist/core/parse.js +4 -1
  185. package/dist/core/paths.js +17 -20
  186. package/dist/core/recognition-util.js +12 -14
  187. package/dist/core/redaction.js +34 -0
  188. package/dist/core/standards/resolve-standards-context.js +2 -14
  189. package/dist/core/standards/resolve-stash-standards.js +2 -2
  190. package/dist/core/standards/resolve-type-conventions.js +2 -2
  191. package/dist/core/state/migrations.js +41 -18
  192. package/dist/core/state-db.js +5 -14
  193. package/dist/core/structured.js +1 -1
  194. package/dist/core/subprocess.js +6 -4
  195. package/dist/core/text-truncation.js +9 -5
  196. package/dist/core/type-presentation.js +3 -3
  197. package/dist/core/warn.js +0 -3
  198. package/dist/core/write-source.js +771 -95
  199. package/dist/indexer/bundle-identity-guard.js +3 -2
  200. package/dist/indexer/db/graph-db.js +0 -24
  201. package/dist/indexer/ensure-index.js +1 -0
  202. package/dist/indexer/graph/graph-boost.js +9 -34
  203. package/dist/indexer/graph/graph-extraction.js +8 -5
  204. package/dist/indexer/index-writer-lock.js +53 -17
  205. package/dist/indexer/index-written-assets.js +16 -22
  206. package/dist/indexer/indexer.js +497 -239
  207. package/dist/indexer/installations.js +14 -96
  208. package/dist/indexer/passes/dir-staleness.js +16 -9
  209. package/dist/indexer/passes/memory-inference.js +11 -9
  210. package/dist/indexer/passes/metadata.js +113 -47
  211. package/dist/indexer/scan/doc-to-entry.js +38 -1
  212. package/dist/indexer/scan/drain-dir.js +13 -23
  213. package/dist/indexer/search/db-search.js +99 -54
  214. package/dist/indexer/search/fts-query.js +47 -24
  215. package/dist/indexer/search/ranking-contributors.js +42 -20
  216. package/dist/indexer/search/ranking.js +18 -99
  217. package/dist/indexer/search/search-fields.js +7 -2
  218. package/dist/indexer/search/search-source.js +82 -93
  219. package/dist/indexer/usage/usage-events.js +0 -89
  220. package/dist/indexer/walk/file-context.js +2 -1
  221. package/dist/indexer/walk/matchers.js +30 -43
  222. package/dist/indexer/walk/path-resolver.js +7 -2
  223. package/dist/indexer/walk/walker.js +38 -12
  224. package/dist/integrations/agent/builders.js +0 -6
  225. package/dist/integrations/agent/config.js +2 -2
  226. package/dist/integrations/agent/detect.js +49 -19
  227. package/dist/integrations/agent/engine-fallback.js +76 -0
  228. package/dist/integrations/agent/profiles.js +14 -0
  229. package/dist/integrations/agent/prompts.js +12 -8
  230. package/dist/integrations/agent/runner-dispatch.js +4 -2
  231. package/dist/integrations/agent/runner.js +0 -1
  232. package/dist/integrations/agent/spawn.js +5 -6
  233. package/dist/integrations/github.js +1 -1
  234. package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
  235. package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
  236. package/dist/integrations/harnesses/claude/session-log.js +0 -10
  237. package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
  238. package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
  239. package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
  240. package/dist/integrations/harnesses/index.js +3 -7
  241. package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
  242. package/dist/integrations/harnesses/opencode/session-log.js +0 -15
  243. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
  244. package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
  245. package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
  246. package/dist/integrations/lockfile.js +101 -6
  247. package/dist/integrations/session-logs/index.js +3 -28
  248. package/dist/llm/client.js +136 -100
  249. package/dist/llm/embedders/remote.js +13 -5
  250. package/dist/llm/feature-gate.js +4 -12
  251. package/dist/llm/graph-extract.js +5 -11
  252. package/dist/llm/memory-infer.js +144 -1
  253. package/dist/llm/metadata-enhance.js +5 -7
  254. package/dist/llm/structured-call.js +1 -1
  255. package/dist/llm/usage-persist.js +26 -5
  256. package/dist/llm/usage-telemetry.js +25 -2
  257. package/dist/output/cli-hints.js +1 -2
  258. package/dist/output/context.js +22 -7
  259. package/dist/output/format-exempt.js +80 -0
  260. package/dist/output/generic-render.js +259 -0
  261. package/dist/output/render-registry.js +57 -0
  262. package/dist/output/renderers.js +14 -36
  263. package/dist/output/shapes/curate.js +10 -1
  264. package/dist/output/shapes/events.js +12 -7
  265. package/dist/output/shapes/helpers.js +56 -83
  266. package/dist/output/shapes/migrate.js +8 -0
  267. package/dist/output/shapes/passthrough.js +7 -41
  268. package/dist/output/shapes/proposal/producer.js +15 -7
  269. package/dist/output/shapes.js +2 -9
  270. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  271. package/dist/output/text/bundle-show.js +7 -0
  272. package/dist/output/text/command-format.js +164 -96
  273. package/dist/output/text/env.js +1 -3
  274. package/dist/output/text/events.js +8 -7
  275. package/dist/output/text/health-format.js +103 -0
  276. package/dist/output/text/health.js +7 -0
  277. package/dist/output/text/helpers.js +10 -8
  278. package/dist/output/text/lint-format.js +43 -0
  279. package/dist/output/text/{save.js → lint.js} +2 -2
  280. package/dist/output/text/migrate.js +88 -0
  281. package/dist/output/text/proposal/producer.js +4 -2
  282. package/dist/output/text/proposal-format.js +44 -72
  283. package/dist/output/text/registry-commands.js +1 -2
  284. package/dist/output/text/show-directives.js +15 -7
  285. package/dist/output/text/status-list.js +32 -0
  286. package/dist/output/text/sync.js +5 -0
  287. package/dist/output/text/workflow-format.js +24 -203
  288. package/dist/output/text/workflow.js +1 -7
  289. package/dist/output/text.js +16 -17
  290. package/dist/registry/factory.js +4 -6
  291. package/dist/registry/origin-resolve.js +16 -27
  292. package/dist/registry/providers/skills-sh.js +3 -3
  293. package/dist/registry/providers/static-index.js +13 -23
  294. package/dist/registry/resolve.js +42 -7
  295. package/dist/registry/semver.js +34 -84
  296. package/dist/runtime.js +2 -23
  297. package/dist/scripts/akm-migrate-node.js +60290 -0
  298. package/dist/scripts/akm-migrate.js +59628 -0
  299. package/dist/setup/detect.js +42 -15
  300. package/dist/setup/registry-stash-loader.js +2 -2
  301. package/dist/setup/setup.js +236 -136
  302. package/dist/setup/steps/connection.js +7 -9
  303. package/dist/setup/steps/platforms.js +9 -9
  304. package/dist/setup/steps/semantic.js +15 -3
  305. package/dist/setup/steps/sources.js +12 -13
  306. package/dist/setup/steps/stashdir.js +2 -3
  307. package/dist/setup/steps/tasks.js +237 -120
  308. package/dist/sources/freshness.js +1 -1
  309. package/dist/sources/provider-factory.js +11 -17
  310. package/dist/sources/providers/filesystem.js +2 -3
  311. package/dist/sources/providers/git-install.js +278 -34
  312. package/dist/sources/providers/git-provider.js +25 -23
  313. package/dist/sources/providers/git-stash.js +395 -106
  314. package/dist/sources/providers/git.js +2 -2
  315. package/dist/sources/providers/npm.js +16 -19
  316. package/dist/sources/providers/provider-utils.js +7 -4
  317. package/dist/sources/providers/sync-from-ref.js +3 -9
  318. package/dist/sources/providers/website.js +6 -1
  319. package/dist/sources/resolve.js +6 -5
  320. package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
  321. package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
  322. package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
  323. package/dist/sources/snapshot-fetchers/github.js +100 -0
  324. package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
  325. package/dist/sources/snapshot-fetchers/registry.js +17 -1
  326. package/dist/sources/snapshot-fetchers/robots.js +348 -0
  327. package/dist/sources/snapshot-fetchers/rss.js +282 -0
  328. package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
  329. package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
  330. package/dist/sources/snapshot-fetchers/x.js +910 -0
  331. package/dist/storage/database.js +7 -0
  332. package/dist/storage/engines/sqlite-migrations.js +23 -111
  333. package/dist/storage/managed-db.js +2 -2
  334. package/dist/storage/repositories/canaries-repository.js +1 -1
  335. package/dist/storage/repositories/events-repository.js +27 -11
  336. package/dist/storage/repositories/improve-runs-repository.js +6 -12
  337. package/dist/storage/repositories/index-connection.js +17 -6
  338. package/dist/storage/repositories/index-entries-repository.js +151 -240
  339. package/dist/storage/repositories/index-entry-mapper.js +15 -11
  340. package/dist/storage/repositories/index-fts-repository.js +5 -2
  341. package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
  342. package/dist/storage/repositories/index-meta-repository.js +2 -3
  343. package/dist/storage/repositories/index-schema.js +10 -25
  344. package/dist/storage/repositories/index-utility-repository.js +15 -28
  345. package/dist/storage/repositories/index-vec-repository.js +6 -1
  346. package/dist/storage/repositories/outcome-repository.js +119 -0
  347. package/dist/storage/repositories/proposals-repository.js +296 -59
  348. package/dist/storage/repositories/registry-cache.js +19 -0
  349. package/dist/storage/repositories/salience-repository.js +172 -0
  350. package/dist/storage/repositories/task-history-repository.js +15 -13
  351. package/dist/storage/repositories/workflow-runs-repository.js +52 -40
  352. package/dist/tasks/backends/cron.js +105 -15
  353. package/dist/tasks/backends/index.js +1 -1
  354. package/dist/tasks/backends/launchd.js +85 -38
  355. package/dist/tasks/backends/schtasks.js +135 -15
  356. package/dist/tasks/embedded.js +56 -40
  357. package/dist/tasks/parser.js +7 -157
  358. package/dist/tasks/resolve-akm-bin.js +137 -59
  359. package/dist/tasks/runner.js +79 -42
  360. package/dist/tasks/scheduler-invocation.js +220 -10
  361. package/dist/tasks/schema.js +24 -1
  362. package/dist/tasks/task-id.js +1 -3
  363. package/dist/tasks/validator.js +20 -6
  364. package/dist/workflows/authoring/authoring.js +94 -143
  365. package/dist/workflows/authoring/scope-key.js +1 -1
  366. package/dist/workflows/exec/frozen-judge.js +28 -2
  367. package/dist/workflows/exec/native-executor.js +77 -57
  368. package/dist/workflows/exec/param-secrets.js +9 -9
  369. package/dist/workflows/exec/run-workflow.js +133 -79
  370. package/dist/workflows/exec/step-work.js +219 -346
  371. package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
  372. package/dist/workflows/ir/compile.js +141 -270
  373. package/dist/workflows/ir/freeze.js +40 -30
  374. package/dist/workflows/ir/params.js +135 -11
  375. package/dist/workflows/ir/plan-hash.js +1 -1
  376. package/dist/workflows/ir/schema.js +25 -26
  377. package/dist/workflows/parser.js +872 -307
  378. package/dist/workflows/program/expressions.js +20 -208
  379. package/dist/workflows/program/schema.js +7 -10
  380. package/dist/workflows/renderer.js +95 -68
  381. package/dist/workflows/resource-limits.js +2 -0
  382. package/dist/workflows/runtime/checkin.js +3 -3
  383. package/dist/workflows/runtime/plan-classifier.js +16 -75
  384. package/dist/workflows/runtime/runs.js +186 -127
  385. package/dist/workflows/runtime/unit-checkin.js +1 -1
  386. package/dist/workflows/runtime/unit-phases.js +2 -2
  387. package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
  388. package/dist/workflows/schema.js +1 -11
  389. package/dist/workflows/validate-summary.js +30 -36
  390. package/dist/workflows/validator.js +21 -62
  391. package/docs/README.md +68 -0
  392. package/docs/migration/README.md +8 -0
  393. package/docs/migration/release-notes/0.7.0.md +11 -11
  394. package/docs/migration/release-notes/0.9.0.md +208 -27
  395. package/docs/migration/v0.7-to-v0.8.md +46 -47
  396. package/docs/migration/v0.8-to-v0.9.md +564 -208
  397. package/docs/migration/v0.9.0-troubleshooting.md +561 -0
  398. package/docs/reference/README.md +12 -0
  399. package/docs/reference/cli.md +2253 -0
  400. package/docs/reference/configuration.md +358 -0
  401. package/docs/reference/data-and-telemetry.md +105 -42
  402. package/docs/reference/workflows.md +647 -0
  403. package/package.json +22 -11
  404. package/schemas/akm-asset-envelope.json +93 -0
  405. package/schemas/akm-config.json +81 -128
  406. package/schemas/akm-workflow.json +74 -73
  407. package/dist/assets/tasks/core/backup.yml +0 -5
  408. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  409. package/dist/cli/config-migrate.js +0 -1806
  410. package/dist/cli/config-validate.js +0 -41
  411. package/dist/commands/backup-cli.js +0 -56
  412. package/dist/commands/bundle/bundle-cli.js +0 -68
  413. package/dist/commands/bundle/bundle.js +0 -219
  414. package/dist/commands/graph/graph-cli.js +0 -124
  415. package/dist/commands/graph/graph.js +0 -489
  416. package/dist/commands/improve/extract-watch.js +0 -140
  417. package/dist/commands/mv-cli.js +0 -1221
  418. package/dist/commands/sources/history.js +0 -201
  419. package/dist/commands/tasks/default-tasks.js +0 -186
  420. package/dist/core/migration-backup.js +0 -1234
  421. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
  422. package/dist/llm/memory-infer-impl.js +0 -138
  423. package/dist/migrate/legacy/config-source-migration.js +0 -223
  424. package/dist/migrate/legacy/content-migration.js +0 -305
  425. package/dist/migrate/legacy/legacy-layout.js +0 -779
  426. package/dist/migrate/legacy/legacy-paths.js +0 -25
  427. package/dist/migrate/legacy/legacy-stash-json.js +0 -72
  428. package/dist/migrate/legacy/proposal-fs-import.js +0 -168
  429. package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
  430. package/dist/migrate/legacy/three-db-cutover.js +0 -841
  431. package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
  432. package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
  433. package/dist/migrate/legacy-ref-grammar.js +0 -214
  434. package/dist/output/shapes/distill.js +0 -14
  435. package/dist/output/shapes/history.js +0 -11
  436. package/dist/output/text/distill.js +0 -6
  437. package/dist/output/text/enable-disable.js +0 -8
  438. package/dist/output/text/history.js +0 -6
  439. package/dist/registry/build-index.js +0 -382
  440. package/dist/schemas/akm-config.json +0 -4704
  441. package/dist/schemas/akm-task.json +0 -87
  442. package/dist/schemas/akm-workflow.json +0 -372
  443. package/dist/scripts/migrate-storage.js +0 -3816
  444. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  445. package/dist/workflows/cli.js +0 -53
  446. package/dist/workflows/exec/brief.js +0 -481
  447. package/dist/workflows/exec/report.js +0 -1460
  448. package/dist/workflows/exec/watch.js +0 -116
  449. package/dist/workflows/program/parser.js +0 -813
  450. package/dist/workflows/program/project.js +0 -104
@@ -1,779 +0,0 @@
1
- // This Source Code Form is subject to the terms of the Mozilla Public
2
- // License, v. 2.0. If a copy of the MPL was not distributed with this
3
- // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- /**
5
- * @removeIn 0.10.0
6
- *
7
- * FROZEN copy of the pre-0.9.0 recognition/placement/ref-grammar/origin-
8
- * resolution surface — akm 0.9.0 chunk-1, WI-1.4, decision D1-6
9
- * (chunk-1 brief + anchors §D). Seeds Chunk 8's migrator: it walks the OLD
10
- * on-disk layout per source with THIS frozen resolver and builds the
11
- * complete old-ref -> new-id map before any re-layout happens (normative
12
- * spec §11.4; plan §3.4/§3.3 item 2).
13
- *
14
- * ## Why a copy, not a re-export (the #1 chunk-1 trap)
15
- *
16
- * A textual copy that still IMPORTS the live modules it freezes is NOT
17
- * frozen — it breaks the moment those modules change, which for two of them
18
- * is one/two chunks away:
19
- *
20
- * 1. `src/core/asset/asset-ref.ts` imports `{ isAssetType, AkmAssetType }`
21
- * from `../common`. `isAssetType` is a DYNAMIC check
22
- * (`Object.hasOwn(TYPE_DIRS, type)`) against the LIVE, evolving
23
- * `TYPE_DIRS` — and `common.ts:29-88` (the whole `ASSET_TYPES`/
24
- * `AkmAssetType`/`isAssetType` block) is deleted in Chunk 1.5, one
25
- * chunk after this one closes.
26
- * 2. `src/core/asset/asset-spec.ts` imports `buildWorkflowAction` from
27
- * `../../output/renderers` and `registerActionBuilder`/
28
- * `registerTypeRenderer` from `./asset-registry`; `ASSET_SPECS_INTERNAL`
29
- * carries `rendererName`/`actionBuilder` fields that call into that
30
- * registry. Both `asset-registry.ts` and `output/renderers.ts`'s
31
- * type-registry are deleted in Chunk 3.
32
- *
33
- * This file therefore imports NOTHING from `src/` — only Node builtins
34
- * (`node:fs`, `node:os`, `node:path`). Concretely (D1-6 a-d):
35
- *
36
- * (a) §"Type snapshot" below INLINES a private closed-union of the 14
37
- * type keys (`LEGACY_TYPE_KEYS`) instead of importing the live
38
- * `isAssetType`/`TYPE_DIRS`. This is a frozen SNAPSHOT of what the 14
39
- * built-in types were at this HEAD — it does NOT track types added
40
- * later via the live `registerAssetType` (out of scope: the old
41
- * on-disk layout this migrator walks never had dynamically-registered
42
- * types persisted into it).
43
- * (b) §"Narrowed AssetSpec" below drops `rendererName`/`actionBuilder`
44
- * from the copied `AssetSpec` shape — the migrator builds an old-ref
45
- * map, it never renders, so it has no need of the renderer registry
46
- * those two fields call into.
47
- * (c) §"Own extension constants" below is this file's OWN copy of
48
- * `SCRIPT_EXTENSIONS`/`WORKFLOW_EXTENSIONS`/`canonicalizeWorkflowName`,
49
- * independent of the live `core/recognition-util.ts` util home (WI-1.2)
50
- * — "so the live util home can evolve without touching the migrator"
51
- * (plan §3.4, architecture-plan.md:138).
52
- * (d) §"Ref grammar" and §"Origin -> source resolution" below copy the
53
- * bare/origin-qualified/`.derived` ref shapes and
54
- * `resolveSourcesForOrigin`/`isRemoteOrigin`/`parseRegistryRef`
55
- * self-contained, with a documented narrowing on the last one (see
56
- * that section's header comment) — it drops the LIVE network-fetching
57
- * artifact-resolution functions (`resolveNpmArtifact` et al.), keeping
58
- * only the pure ID-deriving parse logic `resolveSourcesForOrigin`
59
- * actually consumes.
60
- *
61
- * ## Provenance (D.2 census table, chunk-1 anchors.md §D.2)
62
- *
63
- * - `AssetSpec` interface + `ASSET_SPECS_INTERNAL` (all 14 types) +
64
- * `TYPE_DIRS` + `isRelevantAssetFile`/`deriveCanonicalAssetName`/
65
- * `deriveCanonicalAssetNameFromStashRoot`/`resolveAssetPathFromName` —
66
- * `src/core/asset/asset-spec.ts` (whole file), NARROWED per (b) above.
67
- * - `SCRIPT_EXTENSIONS`/`WORKFLOW_EXTENSIONS`/`canonicalizeWorkflowName` —
68
- * same file (moved to `core/recognition-util.ts` by WI-1.2; this copy
69
- * predates and is independent of that move, per (c) above).
70
- * - Ref grammar (bare + `.derived` key shapes) —
71
- * `src/core/asset/asset-ref.ts` (whole file) +
72
- * `src/commands/improve/memory/derived-ref.ts:37-83`
73
- * (`DERIVED_SUFFIX`/`isDerivedMemory`/`resolveParentRef`). The concrete
74
- * bare/origin-qualified/`.derived` pair algebra this resolver must
75
- * reproduce is demonstrated today by `rekeyStateDbForMove`
76
- * (`src/commands/mv-cli.ts:898-967`) — a good reference, not itself part
77
- * of the freeze.
78
- * - Origin -> source resolution — `src/registry/origin-resolve.ts` (whole
79
- * file) + the pure ID-deriving core of its `parseRegistryRef` dependency
80
- * (`src/registry/resolve.ts`), narrowed per (d) above.
81
- *
82
- * ## Deliberately NOT copied (out of WI-1.4 scope — chunk-1 anchors.md §D.1)
83
- *
84
- * `WORKFLOW_MIGRATIONS` (Chunk 8's frozen copy) and the pre-0.9 proposal
85
- * legacy-import fold (now `proposal-fs-import.ts`, the Chunk-5 fold completed
86
- * in Chunk 8) share this `migrate/legacy/` directory but were NOT this work
87
- * item's deliverable — they were added by their own owning chunks, not WI-1.4.
88
- *
89
- * ## Identifier names are intentionally UNCHANGED from their live sources
90
- *
91
- * The manifest's `grepGateScope` explicitly excludes `src/migrate/legacy/`
92
- * from every zero-count grep ("the frozen §3.4 copy retains dead
93
- * identifiers by design... do NOT rename identifiers inside the frozen copy
94
- * to appease greps"). Every exported name below (`AssetSpec`,
95
- * `ASSET_SPECS_INTERNAL`, `ASSET_SPECS`, `TYPE_DIRS`, `SCRIPT_EXTENSIONS`,
96
- * `WORKFLOW_EXTENSIONS`, `canonicalizeWorkflowName`, `DERIVED_SUFFIX`,
97
- * `AssetRef`, `makeAssetRef`, `parseAssetRef`, `isDerivedMemory`,
98
- * `resolveParentRef`, `resolveSourcesForOrigin`, `isRemoteOrigin`,
99
- * `parseRegistryRef`, ...) matches its live-module counterpart's name
100
- * exactly, by design.
101
- */
102
- import fs from "node:fs";
103
- import os from "node:os";
104
- import path from "node:path";
105
- import { fileURLToPath } from "node:url";
106
- // ═══════════════════════════════════════════════════════════════════════
107
- // Local, self-contained error type — replaces the live `UsageError`/
108
- // `NotFoundError` (`src/core/errors.ts`) so this file imports nothing from
109
- // `src/` at all, even a leaf that isn't currently delete-scheduled. Carries
110
- // an optional `.code` for parity with the messages/codes the live modules
111
- // threw, though the migrator only needs to catch-and-classify.
112
- // ═══════════════════════════════════════════════════════════════════════
113
- export class LegacyResolverError extends Error {
114
- code;
115
- constructor(message, code) {
116
- super(message);
117
- this.name = "LegacyResolverError";
118
- this.code = code;
119
- }
120
- }
121
- // ═══════════════════════════════════════════════════════════════════════
122
- // Type snapshot (D1-6a) — inlined closed union of the 14 built-in asset
123
- // type keys, replacing the live `isAssetType`/`AkmAssetType`
124
- // (`src/core/common.ts:29-88`, deleted Chunk 1.5). This is a frozen
125
- // SNAPSHOT, not a dynamic registry lookup.
126
- // ═══════════════════════════════════════════════════════════════════════
127
- export const LEGACY_TYPE_KEYS = [
128
- "skill",
129
- "command",
130
- "agent",
131
- "knowledge",
132
- "workflow",
133
- "script",
134
- "memory",
135
- "env",
136
- "secret",
137
- "wiki",
138
- "lesson",
139
- "task",
140
- "session",
141
- "fact",
142
- ];
143
- const LEGACY_TYPE_KEY_SET = new Set(LEGACY_TYPE_KEYS);
144
- /** Frozen-snapshot replacement for the live `isAssetType` (`core/common.ts:86-88`). */
145
- export function isAssetType(type) {
146
- return LEGACY_TYPE_KEY_SET.has(type);
147
- }
148
- // ═══════════════════════════════════════════════════════════════════════
149
- // Own extension constants (D1-6c) — independent copy of
150
- // `SCRIPT_EXTENSIONS`/`WORKFLOW_EXTENSIONS`/`canonicalizeWorkflowName`, not
151
- // imported from the live `core/recognition-util.ts` util home.
152
- // ═══════════════════════════════════════════════════════════════════════
153
- /** All recognized script extensions for the script asset type. */
154
- export const SCRIPT_EXTENSIONS = new Set([
155
- ".sh",
156
- ".ts",
157
- ".js",
158
- ".ps1",
159
- ".cmd",
160
- ".bat",
161
- ".py",
162
- ".rb",
163
- ".go",
164
- ".pl",
165
- ".php",
166
- ".lua",
167
- ".r",
168
- ".swift",
169
- ".kt",
170
- ".kts",
171
- ]);
172
- /**
173
- * Recognized workflow asset extensions, in resolution-priority order.
174
- * `.md` stays FIRST for back-compat; `.yaml`/`.yml` hold YAML workflow
175
- * programs.
176
- */
177
- export const WORKFLOW_EXTENSIONS = [".md", ".yaml", ".yml"];
178
- /**
179
- * Strip a recognized workflow extension (`.md`/`.yaml`/`.yml`) from a
180
- * workflow asset *name* so `foo`, `foo.yaml`, `foo.yml`, and `foo.md`
181
- * collapse to one canonical identity.
182
- */
183
- export function canonicalizeWorkflowName(name) {
184
- const lower = name.toLowerCase();
185
- for (const ext of WORKFLOW_EXTENSIONS) {
186
- if (lower.endsWith(ext))
187
- return name.slice(0, -ext.length);
188
- }
189
- return name;
190
- }
191
- /** Structural marker suffix for a derived (inferred) memory's canonical name. */
192
- export const DERIVED_SUFFIX = ".derived";
193
- function toPosix(input) {
194
- return input.replace(/\\/g, "/");
195
- }
196
- const workflowSpec = {
197
- isRelevantFile: (fileName) => WORKFLOW_EXTENSIONS.includes(path.extname(fileName).toLowerCase()),
198
- toCanonicalName: (typeRoot, filePath) => {
199
- const rel = toPosix(path.relative(typeRoot, filePath));
200
- for (const ext of WORKFLOW_EXTENSIONS) {
201
- if (rel.toLowerCase().endsWith(ext))
202
- return rel.slice(0, -ext.length);
203
- }
204
- return rel;
205
- },
206
- toAssetPath: (typeRoot, name) => {
207
- // Explicit extension wins (accepts refs like "release/ship.yaml").
208
- const lower = name.toLowerCase();
209
- for (const ext of WORKFLOW_EXTENSIONS) {
210
- if (lower.endsWith(ext))
211
- return path.join(typeRoot, name);
212
- }
213
- // Probe in priority order — `.md` first for back-compat — and fall back
214
- // to the markdown path so error messages keep naming the canonical file.
215
- for (const ext of WORKFLOW_EXTENSIONS) {
216
- const candidate = path.join(typeRoot, `${name}${ext}`);
217
- if (fs.existsSync(candidate))
218
- return candidate;
219
- }
220
- return path.join(typeRoot, `${name}.md`);
221
- },
222
- };
223
- const markdownSpec = {
224
- isRelevantFile: (fileName) => path.extname(fileName).toLowerCase() === ".md",
225
- toCanonicalName: (typeRoot, filePath) => {
226
- const rel = toPosix(path.relative(typeRoot, filePath));
227
- return rel.endsWith(".md") ? rel.slice(0, -3) : rel;
228
- },
229
- toAssetPath: (typeRoot, name) => {
230
- const withExt = name.endsWith(".md") ? name : `${name}.md`;
231
- return path.join(typeRoot, withExt);
232
- },
233
- };
234
- const scriptSpec = {
235
- isRelevantFile: (fileName) => SCRIPT_EXTENSIONS.has(path.extname(fileName).toLowerCase()),
236
- toCanonicalName: (typeRoot, filePath) => toPosix(path.relative(typeRoot, filePath)),
237
- toAssetPath: (typeRoot, name) => path.join(typeRoot, name),
238
- };
239
- export const ASSET_SPECS_INTERNAL = {
240
- skill: {
241
- stashDir: "skills",
242
- isRelevantFile: (fileName) => fileName === "SKILL.md",
243
- toCanonicalName: (typeRoot, filePath) => {
244
- const relDir = toPosix(path.dirname(path.relative(typeRoot, filePath)));
245
- if (!relDir || relDir === ".")
246
- return undefined;
247
- return relDir;
248
- },
249
- toAssetPath: (typeRoot, name) => path.join(typeRoot, name, "SKILL.md"),
250
- },
251
- command: { stashDir: "commands", ...markdownSpec },
252
- agent: { stashDir: "agents", ...markdownSpec },
253
- knowledge: { stashDir: "knowledge", ...markdownSpec },
254
- workflow: { stashDir: "workflows", ...workflowSpec },
255
- script: { stashDir: "scripts", ...scriptSpec },
256
- memory: { stashDir: "memories", ...markdownSpec },
257
- env: {
258
- stashDir: "env",
259
- isRelevantFile: (fileName) => fileName === ".env" || fileName.endsWith(".env"),
260
- toCanonicalName: (typeRoot, filePath) => {
261
- const rel = toPosix(path.relative(typeRoot, filePath));
262
- const fileName = path.basename(rel);
263
- // Treat ".env" as the "default" env; "<name>.env" → "<name>"
264
- if (fileName === ".env") {
265
- const dir = path.dirname(rel);
266
- return dir === "." || dir === "" ? "default" : `${dir}/default`;
267
- }
268
- const stripped = rel.endsWith(".env") ? rel.slice(0, -4) : rel;
269
- return stripped;
270
- },
271
- toAssetPath: (typeRoot, name) => {
272
- if (name === "default")
273
- return path.join(typeRoot, ".env");
274
- return path.join(typeRoot, name.endsWith(".env") ? name : `${name}.env`);
275
- },
276
- },
277
- secret: {
278
- stashDir: "secrets",
279
- isRelevantFile: (fileName) => !fileName.endsWith(".lock") && !fileName.endsWith(".sensitive"),
280
- toCanonicalName: (typeRoot, filePath) => toPosix(path.relative(typeRoot, filePath)),
281
- toAssetPath: (typeRoot, name) => path.join(typeRoot, name),
282
- },
283
- wiki: {
284
- stashDir: "wikis",
285
- ...markdownSpec,
286
- },
287
- lesson: {
288
- stashDir: "lessons",
289
- ...markdownSpec,
290
- },
291
- task: {
292
- stashDir: "tasks",
293
- isRelevantFile: (fileName) => path.extname(fileName).toLowerCase() === ".yml",
294
- toCanonicalName: (typeRoot, filePath) => {
295
- const rel = toPosix(path.relative(typeRoot, filePath));
296
- return rel.endsWith(".yml") ? rel.slice(0, -4) : rel;
297
- },
298
- toAssetPath: (typeRoot, name) => {
299
- const withExt = name.endsWith(".yml") ? name : `${name}.yml`;
300
- return path.join(typeRoot, withExt);
301
- },
302
- },
303
- session: {
304
- stashDir: "sessions",
305
- ...markdownSpec,
306
- },
307
- fact: {
308
- stashDir: "facts",
309
- ...markdownSpec,
310
- },
311
- };
312
- export const ASSET_SPECS = ASSET_SPECS_INTERNAL;
313
- export const TYPE_DIRS = Object.fromEntries(Object.entries(ASSET_SPECS_INTERNAL).map(([type, spec]) => [type, spec.stashDir]));
314
- export function isRelevantAssetFile(assetType, fileName) {
315
- return ASSET_SPECS[assetType]?.isRelevantFile(fileName) ?? false;
316
- }
317
- export function deriveCanonicalAssetName(assetType, typeRoot, filePath) {
318
- return ASSET_SPECS[assetType]?.toCanonicalName(typeRoot, filePath);
319
- }
320
- export function deriveCanonicalAssetNameFromStashRoot(assetType, stashRoot, filePath) {
321
- const relPath = toPosix(path.relative(stashRoot, filePath));
322
- const segments = relPath.split("/").filter(Boolean);
323
- const firstSegment = segments[0];
324
- const typeRoot = firstSegment !== undefined && firstSegment === TYPE_DIRS[assetType]
325
- ? path.join(stashRoot, firstSegment)
326
- : stashRoot;
327
- return deriveCanonicalAssetName(assetType, typeRoot, filePath);
328
- }
329
- export function resolveAssetPathFromName(assetType, typeRoot, name) {
330
- const spec = ASSET_SPECS[assetType];
331
- if (!spec)
332
- throw new Error(`Unknown asset type: "${assetType}"`);
333
- return spec.toAssetPath(typeRoot, name);
334
- }
335
- /** Accepted spelling aliases mapping to a canonical asset type. */
336
- const TYPE_ALIASES = {
337
- environment: "env",
338
- };
339
- /**
340
- * Build a ref string from components.
341
- *
342
- * Examples:
343
- * makeAssetRef("script", "deploy.sh") → "script:deploy.sh"
344
- * makeAssetRef("script", "deploy.sh", "npm:@scope/pkg") → "npm:@scope/pkg//script:deploy.sh"
345
- */
346
- export function makeAssetRef(type, name, origin) {
347
- validateName(name);
348
- const normalized = normalizeName(name);
349
- const asset = `${type}:${normalized}`;
350
- if (!origin)
351
- return asset;
352
- return `${origin}//${asset}`;
353
- }
354
- /** Serialize a parsed {@link AssetRef} back to its canonical `[origin//]type:name` string form. */
355
- export function refToString(ref) {
356
- return makeAssetRef(ref.type, ref.name, ref.origin);
357
- }
358
- /** Parse a ref string in the format `[origin//]type:name`. */
359
- export function parseAssetRef(ref) {
360
- const trimmed = ref.trim();
361
- if (!trimmed)
362
- throw new LegacyResolverError("Empty ref.", "MISSING_REQUIRED_ARGUMENT");
363
- let origin;
364
- let body = trimmed;
365
- const boundary = trimmed.indexOf("//");
366
- if (boundary >= 0) {
367
- origin = trimmed.slice(0, boundary);
368
- body = trimmed.slice(boundary + 2);
369
- if (!origin)
370
- throw new LegacyResolverError("Empty origin in ref.", "MISSING_REQUIRED_ARGUMENT");
371
- }
372
- const colon = body.indexOf(":");
373
- if (colon <= 0) {
374
- throw new LegacyResolverError(`Invalid ref "${trimmed}". Expected [origin//]type:name, e.g. skill:deploy or knowledge:guide.md`, "MISSING_REQUIRED_ARGUMENT");
375
- }
376
- const rawType = body.slice(0, colon);
377
- const rawName = body.slice(colon + 1);
378
- // The `vault` asset type was removed in 0.9.0. Point callers at its
379
- // replacements rather than failing with a generic unknown-type error.
380
- if (rawType === "vault") {
381
- throw new LegacyResolverError("The `vault` asset type was removed in 0.9.0 — use `env:` (whole .env config) or `secret:` (a single value).", "MISSING_REQUIRED_ARGUMENT");
382
- }
383
- // Type aliases: `environment:` is an accepted spelling of the canonical `env:` type.
384
- const resolvedType = TYPE_ALIASES[rawType] ?? rawType;
385
- if (!isAssetType(resolvedType)) {
386
- throw new LegacyResolverError(`Invalid asset type: "${rawType}".`, "MISSING_REQUIRED_ARGUMENT");
387
- }
388
- validateName(rawName);
389
- const name = normalizeName(rawName);
390
- return { type: resolvedType, name, origin: origin || undefined };
391
- }
392
- function validateName(name) {
393
- if (!name)
394
- throw new LegacyResolverError("Empty asset name.", "MISSING_REQUIRED_ARGUMENT");
395
- if (name.includes("\0"))
396
- throw new LegacyResolverError("Null byte in asset name.", "MISSING_REQUIRED_ARGUMENT");
397
- if (/^[A-Za-z]:/.test(name)) {
398
- throw new LegacyResolverError("Windows drive path in asset name.", "MISSING_REQUIRED_ARGUMENT");
399
- }
400
- const normalized = path.posix.normalize(name.replace(/\\/g, "/"));
401
- if (path.posix.isAbsolute(normalized)) {
402
- throw new LegacyResolverError("Absolute path in asset name.", "MISSING_REQUIRED_ARGUMENT");
403
- }
404
- if (normalized === ".." || normalized.startsWith("../")) {
405
- throw new LegacyResolverError("Path traversal in asset name.", "MISSING_REQUIRED_ARGUMENT");
406
- }
407
- const segments = normalized.split("/");
408
- if (segments.some((seg) => seg === "." || seg === "..")) {
409
- throw new LegacyResolverError("Asset name cannot contain relative path segments.", "MISSING_REQUIRED_ARGUMENT");
410
- }
411
- }
412
- function normalizeName(name) {
413
- return path.posix.normalize(name.replace(/\\/g, "/"));
414
- }
415
- // ═══════════════════════════════════════════════════════════════════════
416
- // `.derived` key shapes (D1-6d) — self-contained copy of
417
- // `derived-ref.ts:37-83`'s `DERIVED_SUFFIX`/`isDerivedMemory`/
418
- // `resolveParentRef`. `asNonEmptyString` is inlined (a two-line pure
419
- // helper from `core/common.ts:537-541`) rather than imported.
420
- // ═══════════════════════════════════════════════════════════════════════
421
- function asNonEmptyString(value) {
422
- if (typeof value !== "string")
423
- return undefined;
424
- const trimmed = value.trim();
425
- return trimmed.length > 0 ? trimmed : undefined;
426
- }
427
- /**
428
- * Normalise an arbitrary `source:`/edge string to a canonical `memory:<name>`
429
- * ref, or `undefined` when it is empty, unparseable, or not a memory ref.
430
- */
431
- function parseMemoryRef(value) {
432
- if (!value)
433
- return undefined;
434
- try {
435
- const parsed = parseAssetRef(value.trim());
436
- if (parsed.type !== "memory")
437
- return undefined;
438
- return makeAssetRef(parsed.type, parsed.name);
439
- }
440
- catch {
441
- return undefined;
442
- }
443
- }
444
- /**
445
- * True when the named memory is a derived/inferred child — either it carries
446
- * `inferred: true` in its frontmatter or its name ends with the structural
447
- * `.derived` suffix.
448
- */
449
- export function isDerivedMemory(name, frontmatter) {
450
- return frontmatter.inferred === true || name.endsWith(DERIVED_SUFFIX);
451
- }
452
- /**
453
- * Resolve the parent (source) memory ref for a derived memory, or
454
- * `undefined` when none can be determined. Precedence: `frontmatter.source`,
455
- * then `frontmatter.derivedFrom`, then the `.derived` name suffix stripped.
456
- */
457
- export function resolveParentRef(name, frontmatter) {
458
- const fromSource = parseMemoryRef(asNonEmptyString(frontmatter.source));
459
- if (fromSource)
460
- return fromSource;
461
- const derivedFrom = asNonEmptyString(frontmatter.derivedFrom);
462
- if (derivedFrom)
463
- return makeAssetRef("memory", derivedFrom);
464
- if (name.endsWith(DERIVED_SUFFIX)) {
465
- return makeAssetRef("memory", name.slice(0, -DERIVED_SUFFIX.length));
466
- }
467
- return undefined;
468
- }
469
- /**
470
- * Given an origin string (from an AssetRef) and the full list of stash
471
- * sources, return the subset of sources to search.
472
- *
473
- * Resolution order:
474
- * 1. undefined → all sources
475
- * 2. "local" → primary stash only (first entry)
476
- * 3. exact match → source whose registryId matches verbatim
477
- * 4. parsed match → parse origin as a registry ref, match by parsed ID
478
- * 5. path match → source whose resolved path matches the origin
479
- * 6. empty → indicates a remote/uninstalled origin (caller decides)
480
- */
481
- export function resolveSourcesForOrigin(origin, allSources) {
482
- if (!origin)
483
- return allSources;
484
- // "local" means the primary stash (first entry)
485
- if (origin === "local") {
486
- return allSources.length > 0 ? [allSources[0]] : [];
487
- }
488
- // Exact registryId match (e.g. origin is "npm:@scope/pkg")
489
- const byExactId = allSources.filter((s) => s.registryId !== undefined && s.registryId === origin);
490
- if (byExactId.length > 0)
491
- return byExactId;
492
- // Parse origin as a registry ref and match by parsed ID.
493
- try {
494
- const parsed = parseRegistryRef(origin);
495
- const byParsedId = allSources.filter((s) => s.registryId !== undefined && s.registryId === parsed.id);
496
- if (byParsedId.length > 0)
497
- return byParsedId;
498
- }
499
- catch {
500
- // Not a valid registry ref — continue to path matching
501
- }
502
- // Match by resolved path (any source, including installed)
503
- const resolvedOrigin = path.resolve(origin);
504
- const byPath = allSources.filter((s) => path.resolve(s.path) === resolvedOrigin);
505
- if (byPath.length > 0)
506
- return byPath;
507
- // No match — origin may be remote/uninstalled
508
- return [];
509
- }
510
- /**
511
- * Check whether an origin refers to something that could be fetched
512
- * remotely (i.e. it looks like a registry ref but isn't installed locally).
513
- */
514
- export function isRemoteOrigin(origin, allSources) {
515
- if (origin === "local")
516
- return false;
517
- return resolveSourcesForOrigin(origin, allSources).length === 0;
518
- }
519
- /**
520
- * Known prefixes `parseRegistryRef` handles as installable sources. Anything
521
- * with a colon that doesn't start with one of these is likely a registry
522
- * search result ID (e.g. `skills-sh:org/skills/name`).
523
- */
524
- const KNOWN_PREFIXES = ["npm:", "github:", "git+", "file:", "http://", "https://"];
525
- function detectRegistrySearchId(ref) {
526
- const colonIdx = ref.indexOf(":");
527
- if (colonIdx < 1)
528
- return undefined;
529
- for (const prefix of KNOWN_PREFIXES) {
530
- if (ref.startsWith(prefix))
531
- return undefined;
532
- }
533
- const prefix = ref.slice(0, colonIdx);
534
- if (!/^[a-z][a-z0-9-]*$/.test(prefix))
535
- return undefined;
536
- const rest = ref.slice(colonIdx + 1);
537
- const segments = rest.split("/").filter(Boolean);
538
- const suggestedRef = segments.length >= 2 ? `github:${segments[0]}/${segments[1]}` : undefined;
539
- const lines = [
540
- `"${ref}" looks like a registry search result ID, not an installable ref.`,
541
- `The "${prefix}:" prefix is a registry identifier and cannot be passed to \`akm add\`.`,
542
- "",
543
- ];
544
- if (suggestedRef) {
545
- lines.push(`Try installing the source repository directly:`, ` akm add ${suggestedRef}`, "");
546
- }
547
- lines.push("Or search for the installable ref:", ` akm search "${segments.length > 2 ? segments[segments.length - 1] : rest}" --source registry`, "Then install using the installRef value from the result:", " akm add github:owner/repo", " akm add npm:package-name");
548
- return lines.join("\n");
549
- }
550
- /** Parse an install/origin ref string, deriving its `{source, ref, id}` — the pure ID-deriving core of the live `parseRegistryRef`. */
551
- export function parseRegistryRef(rawRef) {
552
- const ref = rawRef.trim();
553
- if (!ref)
554
- throw new LegacyResolverError("Registry ref is required.");
555
- const registryIdHint = detectRegistrySearchId(ref);
556
- if (registryIdHint) {
557
- throw new LegacyResolverError(registryIdHint);
558
- }
559
- if (ref.startsWith("npm:")) {
560
- return parseNpmRef(ref.slice(4), ref);
561
- }
562
- if (ref.startsWith("github:")) {
563
- return parseGithubShorthand(ref.slice(7), ref);
564
- }
565
- if (ref.startsWith("git+")) {
566
- return parseGitUrl(stripGitTransport(ref), ref);
567
- }
568
- if (ref.startsWith("file:")) {
569
- return tryParseLocalRef(fileUriToPath(ref), true);
570
- }
571
- if (ref.startsWith("http://") || ref.startsWith("https://")) {
572
- return parseRemoteUrl(ref);
573
- }
574
- const localRef = tryParseLocalRef(ref, isPathLikeRef(ref));
575
- if (localRef) {
576
- return localRef;
577
- }
578
- if (ref.startsWith("@") || !looksLikeGithubOwnerRepo(ref)) {
579
- return parseNpmRef(ref, ref);
580
- }
581
- return parseGithubShorthand(ref, ref);
582
- }
583
- function parseNpmRef(input, originalRef) {
584
- const trimmed = input.trim();
585
- if (!trimmed)
586
- throw new LegacyResolverError("Invalid npm ref.");
587
- const parsed = splitNpmNameAndVersion(trimmed);
588
- validateNpmPackageName(parsed.packageName);
589
- return {
590
- source: "npm",
591
- ref: originalRef,
592
- id: `npm:${parsed.packageName}`,
593
- packageName: parsed.packageName,
594
- requestedVersionOrTag: parsed.requestedVersionOrTag,
595
- };
596
- }
597
- function parseGithubShorthand(input, originalRef) {
598
- const [repoPart, requestedRef] = splitRefSuffix(input.trim());
599
- const segments = repoPart.split("/").filter(Boolean);
600
- if (segments.length !== 2) {
601
- throw new LegacyResolverError("Invalid GitHub ref. Expected owner/repo or owner/repo#ref.");
602
- }
603
- const owner = segments[0];
604
- const repo = segments[1].replace(/\.git$/i, "");
605
- if (!owner || !repo) {
606
- throw new LegacyResolverError("Invalid GitHub ref. Expected owner/repo.");
607
- }
608
- return {
609
- source: "github",
610
- ref: originalRef,
611
- id: `github:${owner}/${repo}`,
612
- owner,
613
- repo,
614
- requestedRef,
615
- };
616
- }
617
- function parseRemoteUrl(rawUrl) {
618
- let url;
619
- try {
620
- url = new URL(rawUrl);
621
- }
622
- catch {
623
- throw new LegacyResolverError("Invalid registry URL.");
624
- }
625
- if (url.hostname === "github.com") {
626
- return parseGithubUrl(url, rawUrl);
627
- }
628
- return parseGitUrl(rawUrl, rawUrl);
629
- }
630
- function parseGithubUrl(url, rawUrl) {
631
- const segments = url.pathname.split("/").filter(Boolean);
632
- if (segments.length < 2) {
633
- throw new LegacyResolverError("Invalid GitHub URL. Expected https://github.com/owner/repo.");
634
- }
635
- const owner = segments[0];
636
- const repo = segments[1].replace(/\.git$/i, "");
637
- const requestedRef = url.hash ? decodeURIComponent(url.hash.slice(1)) : undefined;
638
- return {
639
- source: "github",
640
- ref: rawUrl,
641
- id: `github:${owner}/${repo}`,
642
- owner,
643
- repo,
644
- requestedRef,
645
- };
646
- }
647
- function parseGitUrl(input, originalRef) {
648
- const [urlPart, requestedRef] = splitRefSuffix(input.trim());
649
- if (!urlPart)
650
- throw new LegacyResolverError("Invalid git ref. A URL is required.");
651
- const normalized = urlPart.replace(/\.git$/i, "");
652
- return {
653
- source: "git",
654
- ref: originalRef,
655
- id: `git:${normalized}`,
656
- url: urlPart,
657
- requestedRef,
658
- };
659
- }
660
- function tryParseLocalRef(rawRef, explicitPath) {
661
- const resolvedPath = path.resolve(rawRef);
662
- let stat;
663
- try {
664
- stat = fs.statSync(resolvedPath);
665
- }
666
- catch {
667
- if (explicitPath) {
668
- throw new LegacyResolverError(`Local path not found: ${resolvedPath}`, "FILE_NOT_FOUND");
669
- }
670
- return undefined;
671
- }
672
- if (!stat.isDirectory()) {
673
- if (explicitPath) {
674
- throw new LegacyResolverError("Local add path must be a directory, but the provided path is not one.");
675
- }
676
- return undefined;
677
- }
678
- return {
679
- source: "local",
680
- ref: rawRef,
681
- id: `local:${toReadableLocalId(resolvedPath)}`,
682
- sourcePath: resolvedPath,
683
- };
684
- }
685
- function isPathLikeRef(ref) {
686
- if (ref.startsWith("@"))
687
- return false;
688
- if (ref === "." || ref === "..")
689
- return true;
690
- if (path.isAbsolute(ref))
691
- return true;
692
- if (ref.startsWith("./") || ref.startsWith("../") || ref.startsWith(".\\") || ref.startsWith("..\\")) {
693
- return true;
694
- }
695
- return ref.includes("/") || ref.includes("\\");
696
- }
697
- function splitNpmNameAndVersion(input) {
698
- if (input.startsWith("@")) {
699
- const secondAt = input.indexOf("@", 1);
700
- if (secondAt > 0) {
701
- return {
702
- packageName: input.slice(0, secondAt),
703
- requestedVersionOrTag: input.slice(secondAt + 1) || undefined,
704
- };
705
- }
706
- return { packageName: input };
707
- }
708
- const at = input.lastIndexOf("@");
709
- if (at > 0) {
710
- return {
711
- packageName: input.slice(0, at),
712
- requestedVersionOrTag: input.slice(at + 1) || undefined,
713
- };
714
- }
715
- return { packageName: input };
716
- }
717
- function validateNpmPackageName(name) {
718
- if (!name)
719
- throw new LegacyResolverError("Invalid npm package name: name is required.");
720
- if (name.length > 214)
721
- throw new LegacyResolverError(`Invalid npm package name: "${name}" exceeds 214 characters.`);
722
- if (name !== name.toLowerCase() && !name.startsWith("@")) {
723
- throw new LegacyResolverError(`Invalid npm package name: "${name}" must be lowercase.`);
724
- }
725
- if (name.startsWith(".") || name.startsWith("_")) {
726
- throw new LegacyResolverError(`Invalid npm package name: "${name}" cannot start with . or _.`);
727
- }
728
- if (/[~'!()*]/.test(name) ||
729
- name.includes(" ") ||
730
- encodeURIComponent(name)
731
- .replace(/%40/g, "@")
732
- .replace(/%2[Ff]/g, "/") !== name) {
733
- throw new LegacyResolverError(`Invalid npm package name: "${name}" contains invalid characters.`);
734
- }
735
- }
736
- function looksLikeGithubOwnerRepo(ref) {
737
- const [repoPart] = splitRefSuffix(ref);
738
- const parts = repoPart.split("/").filter(Boolean);
739
- return parts.length === 2;
740
- }
741
- function splitRefSuffix(value) {
742
- const hash = value.indexOf("#");
743
- if (hash < 0)
744
- return [value, undefined];
745
- return [value.slice(0, hash), value.slice(hash + 1) || undefined];
746
- }
747
- /** Strip the `git+` transport prefix from a ref, returning the inner URL. */
748
- function stripGitTransport(ref) {
749
- return ref.slice(4); // strip "git+"
750
- }
751
- /** Convert a `file:` URI to a local filesystem path. */
752
- function fileUriToPath(ref) {
753
- const after = ref.slice(5); // strip "file:"
754
- // Standard file:///absolute/path — delegate to Node's implementation
755
- if (after.startsWith("//")) {
756
- try {
757
- return fileURLToPath(ref);
758
- }
759
- catch {
760
- // Fall through to custom handling
761
- }
762
- }
763
- // Non-standard file:./relative or file:../relative or file:/absolute
764
- return after;
765
- }
766
- /**
767
- * Build a human-readable local ID from an absolute path.
768
- * /home/user/akm/skills → ~/akm/skills
769
- * /tmp/my-stash → /tmp/my-stash
770
- */
771
- function toReadableLocalId(absolutePath) {
772
- const home = os.homedir();
773
- if (absolutePath === home)
774
- return "~";
775
- if (absolutePath.startsWith(home + path.sep)) {
776
- return `~/${absolutePath.slice(home.length + 1)}`;
777
- }
778
- return absolutePath;
779
- }