akm-cli 0.9.1 → 0.9.2-alpha.2

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 (350) hide show
  1. package/CHANGELOG.md +103 -28
  2. package/README.md +3 -1
  3. package/SECURITY.md +1 -1
  4. package/STABILITY.md +1 -1
  5. package/dist/akm +2 -2
  6. package/dist/akm-migrate +2 -2
  7. package/dist/assets/hints/cli-hints-full.md +14 -9
  8. package/dist/assets/improve-strategies/proactive-maintenance.json +1 -1
  9. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  10. package/dist/assets/models.json +35 -0
  11. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +3 -4
  12. package/dist/assets/stash-skeleton/facts/conventions/organization.md +1 -3
  13. package/dist/assets/tasks/core/extract.yml +6 -5
  14. package/dist/assets/tasks/core/improve.yml +6 -5
  15. package/dist/assets/tasks/core/index-refresh.yml +6 -5
  16. package/dist/assets/tasks/core/sync.yml +6 -5
  17. package/dist/assets/tasks/core/version-check.yml +6 -5
  18. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +6 -5
  19. package/dist/assets/tasks/improve/akm-improve-catchup.yml +6 -5
  20. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +6 -5
  21. package/dist/assets/tasks/improve/akm-improve-frequent.yml +6 -5
  22. package/dist/assets/tasks/improve/akm-improve-nightly.yml +6 -5
  23. package/dist/cli/confirm.js +2 -2
  24. package/dist/cli/parse-args.js +3 -24
  25. package/dist/cli/retired-commands.js +1 -1
  26. package/dist/cli/shared.js +2 -2
  27. package/dist/cli.js +11 -9
  28. package/dist/commands/agent/agent-dispatch.js +55 -89
  29. package/dist/commands/agent/contribute-cli.js +12 -45
  30. package/dist/commands/command/builtin-action.js +32 -0
  31. package/dist/commands/command/command-cli.js +99 -0
  32. package/dist/commands/command/command-execution.js +308 -0
  33. package/dist/commands/command/execution-source-loader.js +176 -0
  34. package/dist/commands/command/portable-template.js +60 -0
  35. package/dist/commands/config-cli.js +10 -4
  36. package/dist/commands/env/env.js +4 -2
  37. package/dist/commands/feedback-cli.js +1 -1
  38. package/dist/commands/health/checks.js +241 -29
  39. package/dist/commands/health/html-report.js +0 -14
  40. package/dist/commands/health/report-view-model.js +0 -1
  41. package/dist/commands/health/surfaces.js +6 -7
  42. package/dist/commands/health/types.js +0 -2
  43. package/dist/commands/health.js +63 -18
  44. package/dist/commands/improve/collapse-detector.js +5 -6
  45. package/dist/commands/improve/consolidate.js +251 -214
  46. package/dist/commands/improve/distill/promote-memory.js +71 -34
  47. package/dist/commands/improve/distill/quality-gate.js +17 -5
  48. package/dist/commands/improve/distill.js +232 -155
  49. package/dist/commands/improve/eligibility.js +112 -79
  50. package/dist/commands/improve/execution.js +57 -0
  51. package/dist/commands/improve/extract-cli.js +5 -5
  52. package/dist/commands/improve/extract-prompt.js +64 -22
  53. package/dist/commands/improve/extract.js +608 -360
  54. package/dist/commands/improve/improve-strategies.js +43 -14
  55. package/dist/commands/improve/improve.js +249 -29
  56. package/dist/commands/improve/loop-stages.js +11 -17
  57. package/dist/commands/improve/memory/memory-contradiction-detect.js +90 -66
  58. package/dist/commands/improve/outcome-loop.js +22 -38
  59. package/dist/commands/improve/planner.js +134 -0
  60. package/dist/commands/improve/preparation.js +730 -409
  61. package/dist/commands/improve/reflect.js +386 -223
  62. package/dist/commands/improve/run-context.js +3 -4
  63. package/dist/commands/improve/salience.js +6 -58
  64. package/dist/commands/improve/session-asset.js +12 -12
  65. package/dist/commands/lint/index.js +101 -29
  66. package/dist/commands/migrate-cli.js +11 -69
  67. package/dist/commands/migration-tool.js +6 -9
  68. package/dist/commands/models-cli.js +27 -0
  69. package/dist/commands/proposal/drain.js +258 -186
  70. package/dist/commands/proposal/proposal-cli.js +32 -10
  71. package/dist/commands/proposal/proposal.js +2 -5
  72. package/dist/commands/proposal/propose.js +192 -172
  73. package/dist/commands/proposal/repository.js +54 -91
  74. package/dist/commands/proposal/validators/proposal-validators.js +9 -7
  75. package/dist/commands/read/curate.js +53 -22
  76. package/dist/commands/read/registry-search.js +25 -9
  77. package/dist/commands/read/remember-cli.js +14 -2
  78. package/dist/commands/read/search.js +10 -4
  79. package/dist/commands/read/show.js +139 -153
  80. package/dist/commands/registry-cli.js +16 -7
  81. package/dist/commands/remember.js +33 -18
  82. package/dist/commands/sources/add-cli.js +19 -178
  83. package/dist/commands/sources/bundle-cli.js +15 -3
  84. package/dist/commands/sources/dangerous-env-audit.js +135 -0
  85. package/dist/commands/sources/info.js +2 -1
  86. package/dist/commands/sources/installed-stashes.js +901 -177
  87. package/dist/commands/sources/schema-repair.js +174 -95
  88. package/dist/commands/sources/self-update.js +30 -74
  89. package/dist/commands/sources/source-add.js +3 -5
  90. package/dist/commands/sources/sources-cli.js +2 -15
  91. package/dist/commands/sources/update-transaction.js +220 -0
  92. package/dist/commands/tasks/tasks-cli.js +3 -3
  93. package/dist/commands/tasks/tasks.js +736 -317
  94. package/dist/commands/workflow-cli.js +2 -2
  95. package/dist/core/adapter/adapters/agent-skills-adapter.js +3 -0
  96. package/dist/core/adapter/adapters/akm-adapter.js +85 -35
  97. package/dist/core/adapter/adapters/akm-lint.js +54 -39
  98. package/dist/core/adapter/adapters/akm-metadata.js +45 -45
  99. package/dist/core/adapter/adapters/akm-task-adapter.js +32 -49
  100. package/dist/core/adapter/adapters/akm-workflow-adapter.js +38 -23
  101. package/dist/core/adapter/adapters/dotenv-adapter.js +30 -1
  102. package/dist/core/adapter/adapters/generic-files-adapter.js +11 -0
  103. package/dist/core/adapter/adapters/index.js +0 -9
  104. package/dist/core/adapter/adapters/llm-wiki-adapter.js +4 -0
  105. package/dist/core/adapter/adapters/okf-adapter.js +4 -0
  106. package/dist/core/adapter/adapters/opencode-adapter.js +5 -8
  107. package/dist/core/adapter/adapters/tool-dir-shared.js +63 -6
  108. package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -0
  109. package/dist/core/adapter/execution-source.js +308 -0
  110. package/dist/core/adapter/recognize-match.js +36 -13
  111. package/dist/core/adapter/registry.js +0 -9
  112. package/dist/core/asset/stash-meta.js +94 -4
  113. package/dist/core/common.js +6 -11
  114. package/dist/core/config/config-io.js +3 -3
  115. package/dist/core/config/config-schema.js +18 -40
  116. package/dist/core/config/config-sources.js +11 -21
  117. package/dist/core/config/config-walker.js +31 -13
  118. package/dist/core/config/config.js +23 -26
  119. package/dist/core/config/schema/engines.js +8 -7
  120. package/dist/core/config/schema/improve-processes.js +29 -5
  121. package/dist/core/config/schema/index-config.js +0 -27
  122. package/dist/core/config/schema/primitives.js +1 -23
  123. package/dist/core/config/schema/sources-bundles.js +13 -16
  124. package/dist/core/errors.js +2 -0
  125. package/dist/core/events.js +68 -32
  126. package/dist/core/extra-params.js +1 -0
  127. package/dist/core/improve-result.js +315 -0
  128. package/dist/core/lesson-lint.js +0 -6
  129. package/dist/core/maintenance-barrier.js +4 -4
  130. package/dist/core/network-policy.js +152 -0
  131. package/dist/core/paths.js +1 -1
  132. package/dist/core/recognition-util.js +4 -4
  133. package/dist/core/registry-url.js +456 -0
  134. package/dist/core/state/migrations.js +161 -47
  135. package/dist/core/state-db.js +453 -80
  136. package/dist/core/system-error.js +32 -0
  137. package/dist/core/time.js +2 -12
  138. package/dist/core/write-source.js +0 -18
  139. package/dist/execution/directory-identity.js +52 -0
  140. package/dist/execution/executable-identity.js +107 -0
  141. package/dist/execution/guarded-source.js +398 -0
  142. package/dist/execution/json.js +95 -0
  143. package/dist/{commands/health/types-session-log.js → execution/limits.js} +2 -1
  144. package/dist/execution/record.js +55 -0
  145. package/dist/execution/resolved-request.js +730 -0
  146. package/dist/execution/source.js +320 -0
  147. package/dist/indexer/bundle-identity-guard.js +5 -4
  148. package/dist/indexer/db/graph-db.js +33 -0
  149. package/dist/indexer/graph/graph-boost.js +3 -4
  150. package/dist/indexer/graph/graph-extraction.js +562 -373
  151. package/dist/indexer/index-written-assets.js +78 -39
  152. package/dist/indexer/indexer.js +471 -432
  153. package/dist/indexer/installations.js +6 -0
  154. package/dist/indexer/lookup/adapter-concept-owner.js +283 -0
  155. package/dist/indexer/materialize-embeddings.js +155 -0
  156. package/dist/indexer/passes/memory-inference.js +227 -174
  157. package/dist/indexer/passes/metadata.js +263 -118
  158. package/dist/indexer/scan/doc-to-entry.js +7 -10
  159. package/dist/indexer/scan/drain-dir.js +51 -23
  160. package/dist/indexer/search/db-search.js +156 -50
  161. package/dist/indexer/search/fts-query.js +40 -40
  162. package/dist/indexer/search/ranking.js +36 -1
  163. package/dist/indexer/search/search-attribution.js +3 -1
  164. package/dist/indexer/search/search-fields.js +23 -14
  165. package/dist/indexer/search/search-hit-enrichers.js +1 -1
  166. package/dist/indexer/search/search-source.js +7 -16
  167. package/dist/indexer/search/semantic-status.js +10 -1
  168. package/dist/indexer/usage/show-usage.js +105 -0
  169. package/dist/indexer/usage/usage-events.js +7 -2
  170. package/dist/indexer/walk/matchers.js +40 -10
  171. package/dist/indexer/walk/path-resolver.js +5 -2
  172. package/dist/indexer/walk/walker.js +20 -2
  173. package/dist/integrations/agent/builder-shared.js +3 -6
  174. package/dist/integrations/agent/conversation-fallback.js +16 -0
  175. package/dist/integrations/agent/engine-resolution.js +87 -87
  176. package/dist/integrations/agent/execution-cascade.js +566 -0
  177. package/dist/integrations/agent/execution-definitions.js +211 -0
  178. package/dist/integrations/agent/execution-lowering.js +811 -0
  179. package/dist/integrations/agent/execution-preparation.js +67 -0
  180. package/dist/integrations/agent/index.js +0 -2
  181. package/dist/integrations/agent/inline-execution.js +74 -0
  182. package/dist/integrations/agent/model-map.js +515 -0
  183. package/dist/integrations/agent/persona-fallback.js +30 -0
  184. package/dist/integrations/agent/request-lowering.js +186 -0
  185. package/dist/integrations/agent/runner-dispatch.js +230 -37
  186. package/dist/integrations/agent/runner.js +12 -83
  187. package/dist/integrations/harnesses/aider/agent-builder.js +8 -0
  188. package/dist/integrations/harnesses/aider/index.js +0 -1
  189. package/dist/integrations/harnesses/amazonq/agent-builder.js +8 -0
  190. package/dist/integrations/harnesses/amazonq/index.js +0 -1
  191. package/dist/integrations/harnesses/claude/agent-builder.js +14 -1
  192. package/dist/integrations/harnesses/claude/index.js +1 -5
  193. package/dist/integrations/harnesses/claude/session-log.js +3 -33
  194. package/dist/integrations/harnesses/codex/agent-builder.js +8 -0
  195. package/dist/integrations/harnesses/codex/index.js +0 -1
  196. package/dist/integrations/harnesses/copilot/agent-builder.js +8 -0
  197. package/dist/integrations/harnesses/copilot/index.js +0 -1
  198. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -0
  199. package/dist/integrations/harnesses/gemini/index.js +0 -1
  200. package/dist/integrations/harnesses/index.js +4 -44
  201. package/dist/integrations/harnesses/opencode/agent-builder.js +16 -9
  202. package/dist/integrations/harnesses/opencode/index.js +0 -2
  203. package/dist/integrations/harnesses/opencode/session-log.js +14 -204
  204. package/dist/integrations/harnesses/opencode-sdk/harness.js +12 -1
  205. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +40 -42
  206. package/dist/integrations/harnesses/openhands/agent-builder.js +8 -0
  207. package/dist/integrations/harnesses/openhands/index.js +0 -1
  208. package/dist/integrations/harnesses/pi/agent-builder.js +8 -0
  209. package/dist/integrations/harnesses/pi/index.js +0 -1
  210. package/dist/integrations/harnesses/shared.js +0 -1
  211. package/dist/integrations/harnesses/types.js +1 -3
  212. package/dist/integrations/lockfile.js +82 -79
  213. package/dist/integrations/session-logs/index.js +6 -17
  214. package/dist/integrations/session-logs/provider-base.js +1 -29
  215. package/dist/llm/client.js +10 -5
  216. package/dist/llm/embedder.js +6 -7
  217. package/dist/llm/embedders/local.js +37 -88
  218. package/dist/llm/embedders/types.js +1 -1
  219. package/dist/llm/graph-extract.js +75 -50
  220. package/dist/llm/index-passes.js +43 -5
  221. package/dist/llm/memory-infer.js +8 -6
  222. package/dist/llm/metadata-enhance.js +5 -3
  223. package/dist/llm/structured-call.js +122 -25
  224. package/dist/output/format-exempt.js +1 -1
  225. package/dist/output/render-registry.js +0 -16
  226. package/dist/output/renderers.js +12 -7
  227. package/dist/output/shapes/curate.js +1 -0
  228. package/dist/output/shapes/helpers.js +10 -2
  229. package/dist/output/shapes/passthrough.js +2 -0
  230. package/dist/output/text/command-format.js +31 -33
  231. package/dist/output/text/health-format.js +1 -29
  232. package/dist/output/text/migrate.js +6 -56
  233. package/dist/output/text/proposal-format.js +16 -1
  234. package/dist/output/text/workflow-format.js +16 -0
  235. package/dist/registry/network.js +279 -0
  236. package/dist/registry/pinned-request-helper.js +247 -0
  237. package/dist/registry/pinned-transport.js +717 -0
  238. package/dist/registry/providers/skills-sh.js +18 -6
  239. package/dist/registry/providers/static-index.js +20 -7
  240. package/dist/registry/resolve.js +53 -28
  241. package/dist/scripts/akm-migrate-node.js +19334 -52269
  242. package/dist/scripts/akm-migrate.js +19270 -51612
  243. package/dist/setup/registry-stash-loader.js +64 -20
  244. package/dist/setup/semantic-assets.js +9 -34
  245. package/dist/setup/setup.js +12 -30
  246. package/dist/setup/source-identity.js +17 -0
  247. package/dist/setup/steps/sources.js +36 -15
  248. package/dist/setup/steps/tasks.js +39 -11
  249. package/dist/sources/providers/git-provider.js +3 -3
  250. package/dist/sources/providers/npm.js +2 -2
  251. package/dist/sources/providers/provider-utils.js +4 -3
  252. package/dist/sources/providers/website.js +11 -7
  253. package/dist/sources/snapshot-fetchers/host-guard.js +9 -136
  254. package/dist/sources/snapshot-fetchers/website-ingest.js +25 -109
  255. package/dist/sources/website-url.js +73 -0
  256. package/dist/storage/engines/sqlite-migrations.js +81 -26
  257. package/dist/storage/managed-db.js +27 -24
  258. package/dist/storage/repositories/events-repository.js +3 -0
  259. package/dist/storage/repositories/index-connection.js +42 -10
  260. package/dist/storage/repositories/index-entries-repository.js +203 -229
  261. package/dist/storage/repositories/index-entry-mapper.js +8 -12
  262. package/dist/storage/repositories/index-entry-schema.js +255 -0
  263. package/dist/storage/repositories/index-fts-repository.js +64 -71
  264. package/dist/storage/repositories/index-llm-cache-repository.js +8 -13
  265. package/dist/storage/repositories/index-meta-repository.js +0 -11
  266. package/dist/storage/repositories/index-schema.js +74 -350
  267. package/dist/storage/repositories/index-utility-repository.js +12 -17
  268. package/dist/storage/repositories/index-vec-repository.js +56 -7
  269. package/dist/storage/repositories/proposals-repository.js +4 -127
  270. package/dist/storage/repositories/registry-cache.js +2 -1
  271. package/dist/storage/repositories/task-history-repository.js +20 -40
  272. package/dist/storage/repositories/workflow-runs-repository.js +228 -129
  273. package/dist/storage/sqlite-read-snapshot.js +148 -0
  274. package/dist/tasks/backends/cron.js +170 -42
  275. package/dist/tasks/backends/index.js +1 -1
  276. package/dist/tasks/backends/launchd.js +787 -202
  277. package/dist/tasks/backends/schtasks.js +282 -83
  278. package/dist/tasks/embedded.js +7 -7
  279. package/dist/tasks/frozen-script.js +50 -0
  280. package/dist/tasks/resolve-akm-bin.js +5 -1
  281. package/dist/tasks/runner.js +239 -251
  282. package/dist/tasks/runtime-v3.js +281 -0
  283. package/dist/tasks/scheduler-binding.js +272 -0
  284. package/dist/tasks/scheduler-invocation.js +57 -43
  285. package/dist/tasks/scheduler-sync.js +654 -0
  286. package/dist/tasks/source-v3.js +752 -0
  287. package/dist/tasks/standalone-script-entry.js +5 -0
  288. package/dist/tasks/task-id.js +29 -0
  289. package/dist/workflows/authoring/authoring.js +15 -32
  290. package/dist/workflows/exec/dispatch-redaction.js +14 -8
  291. package/dist/workflows/exec/exec-unit.js +7 -28
  292. package/dist/workflows/exec/frozen-judge.js +57 -89
  293. package/dist/workflows/exec/lowering-notices.js +23 -0
  294. package/dist/workflows/exec/native-executor.js +301 -458
  295. package/dist/workflows/exec/param-secrets.js +4 -3
  296. package/dist/workflows/exec/run-workflow.js +26 -32
  297. package/dist/workflows/exec/step-work.js +105 -109
  298. package/dist/workflows/exec/unit-dispatch.js +103 -27
  299. package/dist/workflows/exec/unit-writer.js +3 -3
  300. package/dist/workflows/exec/worktree.js +2 -2
  301. package/dist/workflows/ir/compile.js +86 -72
  302. package/dist/workflows/ir/environment-v4.js +328 -0
  303. package/dist/workflows/ir/freeze-v4.js +122 -0
  304. package/dist/workflows/ir/plan-hash.js +13 -7
  305. package/dist/workflows/ir/schema-v4.js +525 -0
  306. package/dist/workflows/ir/schema.js +25 -284
  307. package/dist/workflows/ir/source-freeze-v4.js +506 -0
  308. package/dist/workflows/parser.js +27 -24
  309. package/dist/workflows/program/schema.js +1 -2
  310. package/dist/workflows/renderer.js +42 -29
  311. package/dist/workflows/resource-limits.js +4 -5
  312. package/dist/workflows/runtime/agent-identity.js +11 -13
  313. package/dist/workflows/runtime/plan-classifier.js +8 -8
  314. package/dist/workflows/runtime/runs.js +27 -43
  315. package/dist/workflows/runtime/workflow-asset-loader.js +45 -205
  316. package/dist/workflows/source-files.js +373 -0
  317. package/dist/workflows/source-ir/compile.js +196 -0
  318. package/dist/workflows/source-ir/github-yaml.js +577 -0
  319. package/dist/workflows/source-ir/ordering.js +38 -0
  320. package/dist/workflows/source-ir/program.js +50 -0
  321. package/dist/workflows/source-ir/result.js +26 -0
  322. package/dist/workflows/source-ir/schema.js +772 -0
  323. package/dist/workflows/source-ir/semantics.js +242 -0
  324. package/dist/workflows/source-ir/uses.js +14 -0
  325. package/docs/README.md +2 -0
  326. package/docs/migration/README.md +3 -1
  327. package/docs/migration/release-notes/0.9.2.md +55 -0
  328. package/docs/migration/release-notes/README.md +5 -0
  329. package/docs/migration/v0.8-to-v0.9.md +76 -1077
  330. package/docs/migration/v0.9.0-troubleshooting.md +104 -516
  331. package/docs/migration/v0.9.1-to-v0.9.2.md +150 -0
  332. package/docs/reference/README.md +1 -0
  333. package/docs/reference/cli.md +230 -98
  334. package/docs/reference/configuration.md +159 -36
  335. package/docs/reference/data-and-telemetry.md +19 -1
  336. package/docs/reference/supported-formats.md +23 -3
  337. package/docs/reference/tasks.md +182 -0
  338. package/docs/reference/workflow-schema.md +91 -40
  339. package/docs/reference/workflows.md +33 -6
  340. package/package.json +10 -6
  341. package/schemas/akm-config.json +372 -224
  342. package/schemas/akm-task.json +324 -80
  343. package/schemas/akm-workflow.json +6 -9
  344. package/dist/core/migration-operation.js +0 -75
  345. package/dist/integrations/agent/model-aliases.js +0 -74
  346. package/dist/tasks/parser.js +0 -380
  347. package/dist/tasks/schema.js +0 -123
  348. package/dist/tasks/validator.js +0 -80
  349. package/dist/workflows/ir/freeze.js +0 -320
  350. package/dist/workflows/runtime/document-cache.js +0 -13
@@ -42,7 +42,6 @@ import fs from "node:fs";
42
42
  import path from "node:path";
43
43
  import { resolveStashDir } from "../../core/common.js";
44
44
  import { recordWrittenPath } from "../../core/write-provenance.js";
45
- import { chatCompletion } from "../../llm/client.js";
46
45
  /**
47
46
  * Build a `RunContext` over the given carriers with the supplied memo (or `null`
48
47
  * for the non-memoizing base context). Kept private so the only way to obtain a
@@ -56,7 +55,7 @@ function buildRunContext(carriers, memo) {
56
55
  eventsCtx: carriers.eventsCtx,
57
56
  proposalsCtx: carriers.proposalsCtx,
58
57
  chat: carriers.chat,
59
- getLlmConfig: carriers.getLlmConfig,
58
+ getLlmRunner: carriers.getLlmRunner,
60
59
  sourceRun: carriers.sourceRun,
61
60
  dryRun: carriers.dryRun,
62
61
  signal: carriers.signal,
@@ -99,8 +98,8 @@ export function createRunContext(init) {
99
98
  config: init.config,
100
99
  eventsCtx: init.eventsCtx,
101
100
  proposalsCtx: init.proposalsCtx,
102
- chat: init.chat ?? chatCompletion,
103
- getLlmConfig: init.getLlmConfig,
101
+ chat: init.chat,
102
+ getLlmRunner: init.getLlmRunner ?? (() => null),
104
103
  sourceRun: init.sourceRun,
105
104
  dryRun: init.dryRun,
106
105
  signal: init.signal,
@@ -1,52 +1,6 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- /**
5
- * WS-1 — Unified SALIENCE model (S1 seam).
6
- *
7
- * Replaces the three competing attention formulas that existed across:
8
- * - proactive-maintenance.ts:186 — `importance × log(1+freq) × recencyDecay / log10(size)`
9
- * - feedback-valence.ts:111 — `combinedEligibilityScore = utility·0.7 + valence·0.3`
10
- * - getUtilityScoresByIds — MemRL utility EMA (#386)
11
- *
12
- * ## Salience vector (three independently-stored, independently-decayable sub-scores)
13
- *
14
- * | Sub-score | Brain analogy | Source |
15
- * |-------------------|------------------------|---------------------------------|
16
- * | `encodingSalience`| Amygdala tagging (Gap 1)| Set at extract; v1 = type weight|
17
- * | `outcomeSalience` | Dopaminergic outcome | WS-2 (0 until that lands) |
18
- * | `retrievalSalience`| Hippocampal frequency+recency | usage_events + utility_scores |
19
- *
20
- * ## Projection
21
- *
22
- * `rankScore = (w_e·encoding + w_o·outcome + w_r·retrieval) × sizePenalty`, normalized [0,1].
23
- *
24
- * **WS-2 default-ON (R1 loop closure):**
25
- * `w_o = 0.15` is applied by default now that `outcome_score` saturates at
26
- * `OUTCOME_SCORE_MAX` (G2). Operators can opt out via
27
- * `improve.salience.outcomeWeightEnabled: false`, which restores the WS-1
28
- * parity weights `w_e=0.30, w_r=0.70, w_o=0`. `outcomeSalience` is populated
29
- * from `asset_outcome.outcome_score` regardless of the flag.
30
- *
31
- * ## Plasticity
32
- *
33
- * `consecutive_no_ops` (INTEGER column in `asset_salience`) dampens CONSOLIDATION-
34
- * SELECTION only — it is intentionally NOT applied to `rankScore`, so a stable
35
- * asset stays fully retrievable while no longer consuming repeated LLM merge
36
- * attempts. See `getConsecutiveNoOps` / `recordNoOp` / `resetConsecutiveNoOps`.
37
- *
38
- * ## Canonical store
39
- *
40
- * The three sub-scores live in `state.db :: asset_salience` (canonical).
41
- * An optional frontmatter mirror of the stable `encodingSalience` is allowed for
42
- * portability (issue #608 may write it there), but state.db is the source of truth
43
- * for ranking. This prevents the frontmatter-vs-state.db split that issue #608
44
- * would otherwise create (#608 pull-forward decision from Part VI).
45
- *
46
- * @module salience
47
- */
48
- import path from "node:path";
49
- import { conceptIdFromTypeName } from "../../core/asset/resolve-ref.js";
50
4
  import { getAllEntries } from "../../storage/repositories/index-entries-repository.js";
51
5
  import { getUtilityScoresByIds } from "../../storage/repositories/index-utility-repository.js";
52
6
  import { WARM_START_CAP } from "./outcome-loop.js";
@@ -313,24 +267,18 @@ export function buildRankChangeReport(oldRanks, newRanks, oldTopN = 200, forgett
313
267
  * map should be treated as never retrieved (lastUseMs = 0).
314
268
  *
315
269
  * @param indexDb - An open read-capable index database connection.
316
- * @param refs - The set of asset refs to look up.
270
+ * @param candidates - Planned refs carrying their canonical durable item_ref.
317
271
  */
318
- export function getLastUseMsByRef(indexDb, refs, stashDir) {
272
+ export function getLastUseMsByRef(indexDb, candidates) {
319
273
  const result = new Map();
320
- if (refs.length === 0)
274
+ if (candidates.length === 0)
321
275
  return result;
322
- const refSet = new Set(refs);
276
+ const refByItemRef = new Map(candidates.flatMap((candidate) => (candidate.itemRef ? [[candidate.itemRef, candidate.ref]] : [])));
323
277
  const allEntries = getAllEntries(indexDb);
324
- const selectedRoot = stashDir ? path.resolve(stashDir) : undefined;
325
278
  const idToRef = new Map();
326
279
  for (const indexed of allEntries) {
327
- if (selectedRoot && path.resolve(indexed.stashDir) !== selectedRoot)
328
- continue;
329
- // In-memory correlation key, NOT a durable write: it must match the caller's
330
- // `refs` (the `ImproveEligibleRef.ref`, now the SHORT conceptId — Chunk-8
331
- // WI-8.5c flipped the candidate-ref spelling to match the display flip).
332
- const ref = conceptIdFromTypeName(indexed.entry.type, indexed.entry.name);
333
- if (refSet.has(ref))
280
+ const ref = refByItemRef.get(indexed.itemRef);
281
+ if (ref)
334
282
  idToRef.set(indexed.id, ref);
335
283
  }
336
284
  const ids = [...idToRef.keys()];
@@ -27,7 +27,6 @@ import { stashDirFor } from "../../core/asset/asset-placement.js";
27
27
  import { assembleAsset } from "../../core/asset/asset-serialize.js";
28
28
  import { conceptIdFromTypeName } from "../../core/asset/resolve-ref.js";
29
29
  import { recordWrittenPath } from "../../core/write-provenance.js";
30
- import { normalizeHarnessId } from "../../integrations/harnesses/index.js";
31
30
  /**
32
31
  * JSON Schema for the session-summary LLM call. Strict so providers that
33
32
  * support schema enforcement constrain the output upstream; the parser only
@@ -151,11 +150,11 @@ export function sessionMeetsDurationGate(data, minDurationMinutes) {
151
150
  *
152
151
  * Documented convention (#561, checklist item "Document `access` field
153
152
  * convention per harness"): the string tells a downstream agent exactly how to
154
- * read and parse the log at `log_path`. New harnesses fall back to a generic
155
- * `cat <log_path>` hint, which is always correct for a file-backed log.
153
+ * read and parse the source at `log_path`. New harnesses fall back to a generic
154
+ * `cat <log_path>` hint for file-backed logs.
156
155
  */
157
- export function buildSessionAccessInstructions(harness, logPath) {
158
- const canonical = normalizeHarnessId(harness);
156
+ export function buildSessionAccessInstructions(harness, logPath, sessionId) {
157
+ const canonical = harness;
159
158
  if (canonical === "claude") {
160
159
  return [
161
160
  `Read with: cat ${logPath}`,
@@ -164,8 +163,9 @@ export function buildSessionAccessInstructions(harness, logPath) {
164
163
  }
165
164
  if (canonical === "opencode") {
166
165
  return [
167
- `Read with: cat ${logPath}`,
168
- `The log is opencode session storage (JSON). Inspect with: jq '.' ${logPath}`,
166
+ `Open the SQLite database at ${JSON.stringify(logPath)} in read-only mode.`,
167
+ "Query: SELECT m.data, p.data FROM message AS m JOIN part AS p ON p.message_id = m.id WHERE m.session_id = ? AND p.session_id = ? ORDER BY m.time_created, p.time_created;",
168
+ `Bind both parameters to ${JSON.stringify(sessionId)}.`,
169
169
  ].join("\n");
170
170
  }
171
171
  // Generic fallback — file-backed logs are always readable with cat.
@@ -177,7 +177,7 @@ function isoOrUndefined(ms) {
177
177
  }
178
178
  /** Default session-name slug: `<harness>-session-<yyyy-mm-dd>-<shortId>`. */
179
179
  export function buildSessionAssetName(harness, sessionId, startedAtMs) {
180
- const canonical = normalizeHarnessId(harness);
180
+ const canonical = harness;
181
181
  const datePart = isoOrUndefined(startedAtMs)?.slice(0, 10) ?? "unknown-date";
182
182
  const shortId = sessionId.slice(0, 8);
183
183
  return `${canonical}-session-${datePart}-${shortId}`;
@@ -193,7 +193,7 @@ export function buildSessionAssetContent(data, summary) {
193
193
  const endedAt = isoOrUndefined(ref.endedAt);
194
194
  const name = buildSessionAssetName(harness, ref.sessionId, ref.startedAt);
195
195
  const logPath = ref.filePath;
196
- const baseTags = ["session", normalizeHarnessId(harness)];
196
+ const baseTags = ["session", harness];
197
197
  const extraTags = (summary.tags ?? []).filter((t) => typeof t === "string" && t.trim().length > 0);
198
198
  const tags = Array.from(new Set([...baseTags, ...extraTags]));
199
199
  const frontmatter = {
@@ -205,7 +205,7 @@ export function buildSessionAssetContent(data, summary) {
205
205
  ...(endedAt ? { ended_at: endedAt } : {}),
206
206
  ...(ref.projectHint ? { project: ref.projectHint } : {}),
207
207
  log_path: logPath,
208
- access: buildSessionAccessInstructions(harness, logPath),
208
+ access: buildSessionAccessInstructions(harness, logPath, ref.sessionId),
209
209
  tags,
210
210
  };
211
211
  const topics = summary.keyTopics
@@ -221,7 +221,7 @@ export function buildSessionAssetContent(data, summary) {
221
221
  /** Resolve `<stash>/sessions/<harness>/<session-id>.md`. */
222
222
  export function resolveSessionAssetPath(stashDir, harness, sessionId) {
223
223
  const dir = stashDirFor("session") ?? "sessions";
224
- return path.join(stashDir, dir, normalizeHarnessId(harness), `${sessionId}.md`);
224
+ return path.join(stashDir, dir, harness, `${sessionId}.md`);
225
225
  }
226
226
  /**
227
227
  * Generate (via the injected summarizer) and write a session asset to the stash.
@@ -250,7 +250,7 @@ export async function writeSessionAsset(data, stashDir, generate) {
250
250
  // Canonical 0.9.0 conceptId (`sessions/<harness>/<id>`, D-R3) — the same
251
251
  // spelling the xrefs / usage-event readers now expect. Historical
252
252
  // `session:<harness>/<id>` rows persist un-migrated and are tolerated.
253
- ref: conceptIdFromTypeName("session", `${normalizeHarnessId(harness)}/${sessionId}`),
253
+ ref: conceptIdFromTypeName("session", `${harness}/${sessionId}`),
254
254
  logPath: data.ref.filePath,
255
255
  };
256
256
  }
@@ -3,7 +3,7 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
6
- import { factDiagnostics, matchWorkflowPlaceholder, memoryOrphanStubApplies, nameOrTypeDiagnostics, ORPHANED_STUB_DETAIL, taskDiagnostics, workflowFrontendDiagnostics, } from "../../core/adapter/adapters/akm-lint.js";
6
+ import { factDiagnostics, matchWorkflowPlaceholder, memoryOrphanStubApplies, nameOrTypeDiagnostics, ORPHANED_STUB_DETAIL, taskDiagnostics, workflowFrontendDiagnostics, workflowYamlSourceDiagnostics, } from "../../core/adapter/adapters/akm-lint.js";
7
7
  import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
8
8
  import { adapterForId } from "../../core/adapter/registry.js";
9
9
  import { createValidateContext } from "../../core/adapter/validate-context.js";
@@ -16,7 +16,9 @@ import { loadConfig, primaryBundlePath } from "../../core/config/config.js";
16
16
  import { UsageError } from "../../core/errors.js";
17
17
  import { warn } from "../../core/warn.js";
18
18
  import { resolveSourceEntries } from "../../indexer/search/search-source.js";
19
- import { parseTaskYaml, TASK_EXTENSION, TASK_NEAR_MISS_EXTENSION, taskExtensionDetail, taskYamlParseDetail, } from "../../tasks/schema.js";
19
+ import { TASK_EXTENSION, TASK_NEAR_MISS_EXTENSION, taskExtensionDetail } from "../../tasks/source-v3.js";
20
+ import { resolveWorkflowSourceDomains } from "../../workflows/source-files.js";
21
+ import { compareWorkflowSourceCodePoints } from "../../workflows/source-ir/ordering.js";
20
22
  import { runBaseChecks } from "./base-linter.js";
21
23
  import { checkEnvForDangerousKeys } from "./env-key-rules.js";
22
24
  import { isAdvisoryLintIssue } from "./types.js";
@@ -78,6 +80,63 @@ function collectMarkdownFiles(dir, caseInsensitive = false) {
78
80
  }
79
81
  return results;
80
82
  }
83
+ function isCachedLintPath(filePath) {
84
+ const posixPath = filePath.replace(/\\/g, "/");
85
+ return posixPath.includes("/.cache/") || posixPath.includes("/registry/");
86
+ }
87
+ /** Peer workflow sources accepted by the source-IR compiler; `.yaml` remains unsupported. */
88
+ function collectWorkflowFiles(dir) {
89
+ if (!fs.existsSync(dir))
90
+ return [];
91
+ const results = [];
92
+ for (const entry of fs
93
+ .readdirSync(dir, { withFileTypes: true })
94
+ .sort((left, right) => compareWorkflowSourceCodePoints(left.name, right.name))) {
95
+ if (entry.name === ".git")
96
+ continue;
97
+ const full = path.join(dir, entry.name);
98
+ if (entry.isDirectory()) {
99
+ if (entry.name === ".cache" || entry.name === "registry")
100
+ continue;
101
+ results.push(...collectWorkflowFiles(full));
102
+ continue;
103
+ }
104
+ if (!entry.isFile() && !entry.isSymbolicLink())
105
+ continue;
106
+ const extension = path.extname(entry.name).toLowerCase();
107
+ if (extension === ".md" || extension === ".yml")
108
+ results.push(full);
109
+ }
110
+ return results.sort(compareWorkflowSourceCodePoints);
111
+ }
112
+ /**
113
+ * Resolve the already-enumerated candidates through the same workflow-source
114
+ * authority used by index/show/run. The bulk surface inspects every canonical
115
+ * domain without re-reading its parent directory once per workflow. A rejected
116
+ * domain produces one deterministic finding and none of its sources is parsed.
117
+ */
118
+ function resolveWorkflowLintOwnership(stashRoot, files) {
119
+ const ownedFiles = [];
120
+ const issues = [];
121
+ for (const resolution of resolveWorkflowSourceDomains(stashRoot, "akm", files)) {
122
+ if (resolution.source) {
123
+ ownedFiles.push(resolution.source.path);
124
+ continue;
125
+ }
126
+ if (!resolution.rejection)
127
+ continue;
128
+ const representative = resolution.sourcePaths[0];
129
+ if (!representative)
130
+ continue;
131
+ issues.push({
132
+ file: representative,
133
+ issue: "invalid-workflow-structure",
134
+ detail: resolution.rejection.message,
135
+ fixed: false,
136
+ });
137
+ }
138
+ return { files: ownedFiles.sort(compareWorkflowSourceCodePoints), issues };
139
+ }
81
140
  // ── Non-akm adapter dispatch (real `adapter.validate()`, not a re-implementation) ──
82
141
  //
83
142
  // akm 0.9.0 lint/adapter-dispatch wiring: `akm lint` used to special-case
@@ -92,9 +151,9 @@ function collectMarkdownFiles(dir, caseInsensitive = false) {
92
151
  // its OWN configured/detected adapter's `validate()` — the single definition
93
152
  // of that format's rules, shared with the (now also wired, advisory-only)
94
153
  // change-transaction pre-commit gate in `commands/proposal/repository.ts`.
95
- // This is intentionally the ONLY branch this module adds: the `akm` sweep
96
- // below is completely untouched (pinned by the goldens/test suite
97
- // CRITICAL: akm findings/`--fix` must not move).
154
+ // The adapter-dispatch work intentionally stays outside the `akm` sweep below.
155
+ // The sweep's workflow branch separately supports authoritative peer `.md` and
156
+ // `.yml` sources while preserving the pinned Markdown findings/`--fix` bytes.
98
157
  /**
99
158
  * Case-insensitive SUFFIX match against an adapter's declared `extensions`
100
159
  * hint. Deliberately NOT `path.extname()`: Node's `extname(".env")` is `""`
@@ -165,6 +224,7 @@ const KNOWN_ADAPTER_ISSUE_TYPES = new Set([
165
224
  "missing-description",
166
225
  "broken-xref",
167
226
  "broken-source",
227
+ "invalid-workflow-structure",
168
228
  "workflow-warning",
169
229
  ]);
170
230
  /** Map one adapter {@link Diagnostic} onto a {@link LintIssue} — see `types.ts`'s `"adapter-diagnostic"` doc comment for the open→closed reconciliation. */
@@ -444,7 +504,7 @@ export function lintAssetFile(ctx, subdir) {
444
504
  issues.push(...factDiagnostics(ctx.relPath, ctx.data));
445
505
  break;
446
506
  case "tasks":
447
- issues.push(...taskDiagnostics(ctx.relPath, ctx.data));
507
+ issues.push(...taskDiagnostics(ctx.relPath, ctx.raw, ctx.stashRoot));
448
508
  break;
449
509
  case "memories":
450
510
  appendMemoryStubIssue(ctx, issues);
@@ -477,10 +537,20 @@ function lintAkmSweep(stashRoot, extraStashRoots, cfg, sources, options) {
477
537
  const dirsToScan = options.typeFilter ? STASH_SUBDIRS.filter((d) => d === options.typeFilter) : STASH_SUBDIRS;
478
538
  for (const subdir of dirsToScan) {
479
539
  const dirPath = path.join(stashRoot, subdir);
480
- // Tasks are .yml files; everything else (including workflows, one
481
- // markdown format now) is .md
482
- const files = subdir === "tasks" ? collectTaskFiles(dirPath) : collectMarkdownFiles(dirPath, true);
483
- const assetFiles = subdir === "workflows" ? files.filter((file) => path.basename(file).toLowerCase() !== "readme.md") : files;
540
+ // Tasks have their own `.yml` plus near-miss collector. Workflows accept
541
+ // peer `.md`/`.yml` sources; every remaining AKM subdir is Markdown.
542
+ const files = subdir === "tasks"
543
+ ? collectTaskFiles(dirPath)
544
+ : subdir === "workflows"
545
+ ? collectWorkflowFiles(dirPath)
546
+ : collectMarkdownFiles(dirPath, true);
547
+ let assetFiles = subdir === "workflows" ? files.filter((file) => path.basename(file).toLowerCase() !== "readme.md") : files;
548
+ if (subdir === "workflows") {
549
+ assetFiles = assetFiles.filter((file) => !isCachedLintPath(file));
550
+ const ownership = resolveWorkflowLintOwnership(stashRoot, assetFiles);
551
+ assetFiles = ownership.files;
552
+ flagged.push(...ownership.issues);
553
+ }
484
554
  // Directory-level check: skills require a SKILL.md entry point (was
485
555
  // SkillLinter.lintDirectory). Run once per direct subdirectory before the
486
556
  // per-file loop.
@@ -505,8 +575,7 @@ function lintAkmSweep(stashRoot, extraStashRoots, cfg, sources, options) {
505
575
  // Compare on a separator-normalized copy: on Windows these paths carry
506
576
  // backslashes, so the forward-slash substring never matched and --fix
507
577
  // rewrote files inside the registry cache.
508
- const posixPath = filePath.replace(/\\/g, "/");
509
- if (posixPath.includes("/.cache/") || posixPath.includes("/registry/"))
578
+ if (isCachedLintPath(filePath))
510
579
  continue;
511
580
  const relPath = path.relative(stashRoot, filePath);
512
581
  let raw;
@@ -516,6 +585,21 @@ function lintAkmSweep(stashRoot, extraStashRoots, cfg, sources, options) {
516
585
  catch {
517
586
  continue;
518
587
  }
588
+ // GitHub-shaped YAML is a peer workflow source, not a Markdown document:
589
+ // no frontmatter/base/stub checks and no `--fix` mutation apply. Compile
590
+ // once through the shared source-IR frontend and route its findings.
591
+ if (subdir === "workflows" && path.extname(filePath).toLowerCase() === ".yml") {
592
+ const frontend = workflowYamlSourceDiagnostics(relPath, raw, filePath, stashRoot);
593
+ for (const finding of [...frontend.errors, ...frontend.warnings]) {
594
+ if (isAdvisoryLintIssue(finding)) {
595
+ warnings.push(finding);
596
+ }
597
+ else {
598
+ flagged.push(finding);
599
+ }
600
+ }
601
+ continue;
602
+ }
519
603
  let data;
520
604
  let body;
521
605
  let frontmatter;
@@ -523,21 +607,9 @@ function lintAkmSweep(stashRoot, extraStashRoots, cfg, sources, options) {
523
607
  // the FILE (its extension, whether it parsed at all), not its fields.
524
608
  const fileIssues = [];
525
609
  if (subdir === "tasks") {
526
- // Task files are pure YAML parseFrontmatter returns empty data for them.
527
- const parsed = parseTaskYaml(raw);
528
- data = parsed.data;
529
- if (!parsed.ok) {
530
- // A parse failure used to fall through as `data = {}`, and every task
531
- // rule short-circuits on an empty mapping — so an unparseable task
532
- // file reported a CLEAN scan. Report the parse failure itself
533
- // (issue #760).
534
- fileIssues.push({
535
- file: relPath,
536
- issue: "invalid-task-yaml",
537
- detail: taskYamlParseDetail(parsed.error),
538
- fixed: false,
539
- });
540
- }
610
+ // Task files are pure YAML. The canonical task-v3 parser runs once in
611
+ // taskDiagnostics below; base checks need no parsed frontmatter data.
612
+ data = {};
541
613
  if (isNearMissTaskFileName(relPath)) {
542
614
  fileIssues.push({
543
615
  file: relPath,
@@ -603,8 +675,8 @@ function lintAkmSweep(stashRoot, extraStashRoots, cfg, sources, options) {
603
675
  // `ADVISORY_LINT_ISSUES`, never by which half of the pass produced it, so
604
676
  // a future compile-warning kind carrying a fatal code cannot slip past
605
677
  // `--fail-on-flagged`.
606
- // NB: the CLI passes the ABSOLUTE filePath to parseWorkflow (matching the
607
- // old WorkflowLinter), whereas the adapter passes the change relPath.
678
+ // The CLI passes the absolute filePath to the shared source-IR frontend,
679
+ // whereas the adapter passes the change relPath.
608
680
  if (subdir === "workflows") {
609
681
  const frontend = workflowFrontendDiagnostics(relPath, raw, filePath);
610
682
  for (const finding of [...frontend.errors, ...frontend.warnings]) {
@@ -3,58 +3,20 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import { defineGroupCommand, defineJsonCommand, output } from "../cli/shared.js";
5
5
  import { runMigrationTool } from "./migration-tool.js";
6
- const configArg = {
7
- type: "string",
8
- description: "Complete operator-prepared current config; optional when the active config is current",
9
- };
10
6
  /**
11
- * Split the standalone `akm-migrate` tool's captured stdout into its
12
- * progress-event lines (if any — `apply` prints one JSON line per completed
13
- * sub-step, e.g. content migration / proposal-ref repair) and its final
14
- * result line. `status` and `apply --dry-run` never print progress, so
15
- * `progress` is empty for them; `apply` may print zero or more.
16
- *
17
- * Each `console.log` call in the child produces exactly one `\n`-terminated
18
- * line, so splitting on `\n` and dropping the trailing empty entry from the
19
- * final newline recovers exactly the lines it printed, in order.
20
- */
21
- function splitToolStdout(stdout) {
22
- const lines = stdout.split("\n");
23
- if (lines.length > 0 && lines.at(-1) === "")
24
- lines.pop();
25
- if (lines.length === 0)
26
- return { progress: [] };
27
- return { progress: lines.slice(0, -1), resultLine: lines.at(-1) };
28
- }
29
- /**
30
- * Runs the standalone `akm-migrate` tool and renders its result through the
31
- * normal `--format` pipeline (D7) instead of a fixed JSON passthrough.
32
- *
33
- * The child's progress-event lines (if any) are not part of the result
34
- * envelope — they print as-is, in order, regardless of `--format`, the same
35
- * way `apply` always printed them before this change. Only the final result
36
- * line — always a well-formed `MigrationPlan` JSON object — is parsed and
37
- * handed to `output()`, so `text`/`md`/`html`/`yaml` render a real
38
- * (registered or generic) rendering of it instead of silently staying JSON.
39
- * `--format json` (the default) is therefore the only format whose BYTES can
40
- * change here (pretty-printed via `output()` instead of the child's compact
41
- * `JSON.stringify`) — every value stays identical, which is what the
42
- * migration-lifecycle integration tests assert via `JSON.parse`.
7
+ * Run the task-only migrator and render its one JSON plan through the normal
8
+ * output pipeline.
43
9
  */
44
10
  async function runMigrateSubcommand(command, args) {
45
11
  const result = await runMigrationTool(args);
46
12
  if (result.stderr)
47
13
  process.stderr.write(result.stderr);
48
- const { progress, resultLine } = splitToolStdout(result.stdout);
49
- for (const line of progress)
50
- console.log(line);
51
- if (resultLine !== undefined) {
14
+ const resultLine = result.stdout.trim();
15
+ if (resultLine) {
52
16
  try {
53
17
  output(command, JSON.parse(resultLine));
54
18
  }
55
19
  catch {
56
- // The child is expected to always print one well-formed JSON result
57
- // line; if it somehow didn't, don't lose the line, just don't reshape it.
58
20
  console.log(resultLine);
59
21
  }
60
22
  }
@@ -67,45 +29,25 @@ async function runMigrateSubcommand(command, args) {
67
29
  }
68
30
  }
69
31
  export const migrateCommand = defineGroupCommand({
70
- // S11 originally hid this from `--help`/completions as an internal,
71
- // self-update-only surface. That made it undiscoverable even though the
72
- // 0.9.0 upgrade instructions tell users to run it first (`akm migrate
73
- // status`, `akm migrate apply`) — the one command those instructions
74
- // depend on was invisible. Listed in the SYSTEM section of HELP_SECTIONS
75
- // (src/cli.ts) and in shell completions now; `akm migrate status`/`apply`
76
- // always executed regardless of `hidden`.
77
- meta: { name: "migrate", description: "Inspect or apply config and durable database migrations" },
32
+ meta: { name: "migrate", description: "Inspect or apply task-v2 to task-v3 migrations" },
78
33
  subCommands: {
79
34
  status: defineJsonCommand({
80
- meta: { name: "status", description: "Read-only cross-artifact migration eligibility check" },
81
- args: { config: configArg },
82
- run({ args }) {
83
- return runMigrateSubcommand("migrate-status", ["status", ...(args.config ? ["--config", args.config] : [])]);
35
+ meta: { name: "status", description: "Read-only task-v2 migration check" },
36
+ run() {
37
+ return runMigrateSubcommand("migrate-status", ["status"]);
84
38
  },
85
39
  }),
86
40
  apply: defineJsonCommand({
87
- meta: { name: "apply", description: "Create a verified backup and atomically apply pending migrations" },
41
+ meta: { name: "apply", description: "Back up and atomically convert task-v2 files to task v3" },
88
42
  args: {
89
- config: configArg,
90
- // R-062: canonical spelling is kebab-case, matching every other
91
- // multi-word flag in the CLI. `--dryRun` (the pre-rename spelling)
92
- // is kept as an explicit, documented alias — citty registers BOTH
93
- // the camelCase and kebab-case spelling of any declared flag name
94
- // automatically, so this is a rename, not a breaking change: both
95
- // spellings already worked, and both keep working.
96
43
  "dry-run": {
97
44
  type: "boolean",
98
- alias: "dryRun",
99
45
  default: false,
100
- description: "Run the same eligibility checks without mutation. Alias: --dryRun.",
46
+ description: "Run the same eligibility checks without mutation.",
101
47
  },
102
48
  },
103
49
  run({ args }) {
104
- return runMigrateSubcommand("migrate-apply", [
105
- "apply",
106
- ...(args.config ? ["--config", args.config] : []),
107
- ...(args.dryRun ? ["--dry-run"] : []),
108
- ]);
50
+ return runMigrateSubcommand("migrate-apply", ["apply", ...(args.dryRun ? ["--dry-run"] : [])]);
109
51
  },
110
52
  }),
111
53
  },
@@ -14,10 +14,9 @@ function migrationEntryPoint() {
14
14
  }
15
15
  /**
16
16
  * Spawns the standalone `akm-migrate` tool and returns its captured exit
17
- * status plus stdout/stderr — never writes them itself. `migrate-cli.ts`'s
18
- * `status`/`apply` commands use this to reshape the child's final JSON result
19
- * line through the normal `--format` pipeline (D7) while any earlier
20
- * progress-event lines the child printed still go through verbatim.
17
+ * status plus stdout/stderr — never writes them itself. `migrate-cli.ts` uses
18
+ * this packaging boundary to render the task-only plan through the normal
19
+ * output pipeline.
21
20
  */
22
21
  export async function runMigrationTool(args) {
23
22
  const entry = migrationEntryPoint();
@@ -28,11 +27,9 @@ export async function runMigrationTool(args) {
28
27
  throw new NotFoundError("This binary was built without the embedded akm-migrate tool.", "FILE_NOT_FOUND", "Rebuild from scripts/akm-standalone.ts, or run akm-migrate from a source/npm install.");
29
28
  }
30
29
  // Compiled standalone: no scripts/ tree exists on disk (`import.meta.url`
31
- // resolves inside the binary's virtual filesystem), so the documented
32
- // `./akm-<ver> migrate status/apply` path used to dead-end with
33
- // FILE_NOT_FOUND. Release binaries are compiled from
34
- // `scripts/akm-standalone.ts`, which embeds the migrator and dispatches to
35
- // it when `AKM_MIGRATE_ENTRY=1` — so re-exec ourselves with the marker.
30
+ // resolves inside the binary's virtual filesystem). Release binaries embed
31
+ // the task migrator in `scripts/akm-standalone.ts` and re-exec themselves
32
+ // with the internal marker.
36
33
  // (src must not import scripts/: the dist build's tsc has `rootDir: src`.)
37
34
  const result = spawnSync(process.execPath, entry ? [entry, ...args] : [...args], {
38
35
  encoding: "utf8",
@@ -0,0 +1,27 @@
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
+ import { defineGroupCommand, defineJsonCommand, output } from "../cli/shared.js";
5
+ import { copyDefaultModelMap } from "../integrations/agent/model-map.js";
6
+ /** Operator-owned model-map lifecycle commands. Alias expansion is consumed through the runtime API. */
7
+ export const modelsCommand = defineGroupCommand({
8
+ meta: { name: "models", description: "Inspect and customize model intent alias defaults" },
9
+ subCommands: {
10
+ "copy-defaults": defineJsonCommand({
11
+ meta: {
12
+ name: "copy-defaults",
13
+ description: "Copy AKM's installed models.json into the user configuration directory",
14
+ },
15
+ args: {
16
+ overwrite: {
17
+ type: "boolean",
18
+ default: false,
19
+ description: "Confirm replacing an existing regular user models.json file",
20
+ },
21
+ },
22
+ run({ args }) {
23
+ output("models", copyDefaultModelMap({ overwrite: args.overwrite === true }));
24
+ },
25
+ }),
26
+ },
27
+ });