akm-cli 0.9.1 → 0.9.2-alpha.1

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 (341) hide show
  1. package/CHANGELOG.md +88 -0
  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/tasks/core/extract.yml +6 -5
  12. package/dist/assets/tasks/core/improve.yml +6 -5
  13. package/dist/assets/tasks/core/index-refresh.yml +6 -5
  14. package/dist/assets/tasks/core/sync.yml +6 -5
  15. package/dist/assets/tasks/core/version-check.yml +6 -5
  16. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +6 -5
  17. package/dist/assets/tasks/improve/akm-improve-catchup.yml +6 -5
  18. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +6 -5
  19. package/dist/assets/tasks/improve/akm-improve-frequent.yml +6 -5
  20. package/dist/assets/tasks/improve/akm-improve-nightly.yml +6 -5
  21. package/dist/cli/confirm.js +2 -2
  22. package/dist/cli/parse-args.js +3 -24
  23. package/dist/cli/retired-commands.js +1 -1
  24. package/dist/cli/shared.js +2 -2
  25. package/dist/cli.js +11 -9
  26. package/dist/commands/agent/agent-dispatch.js +55 -89
  27. package/dist/commands/agent/contribute-cli.js +12 -45
  28. package/dist/commands/command/builtin-action.js +32 -0
  29. package/dist/commands/command/command-cli.js +99 -0
  30. package/dist/commands/command/command-execution.js +308 -0
  31. package/dist/commands/command/execution-source-loader.js +176 -0
  32. package/dist/commands/command/portable-template.js +60 -0
  33. package/dist/commands/config-cli.js +10 -4
  34. package/dist/commands/env/env.js +4 -2
  35. package/dist/commands/feedback-cli.js +1 -1
  36. package/dist/commands/health/checks.js +241 -29
  37. package/dist/commands/health/html-report.js +0 -14
  38. package/dist/commands/health/report-view-model.js +0 -1
  39. package/dist/commands/health/surfaces.js +6 -7
  40. package/dist/commands/health/types.js +0 -2
  41. package/dist/commands/health.js +63 -18
  42. package/dist/commands/improve/collapse-detector.js +2 -2
  43. package/dist/commands/improve/consolidate.js +251 -214
  44. package/dist/commands/improve/distill/promote-memory.js +71 -34
  45. package/dist/commands/improve/distill/quality-gate.js +17 -5
  46. package/dist/commands/improve/distill.js +232 -155
  47. package/dist/commands/improve/eligibility.js +112 -79
  48. package/dist/commands/improve/execution.js +57 -0
  49. package/dist/commands/improve/extract-cli.js +5 -5
  50. package/dist/commands/improve/extract.js +521 -342
  51. package/dist/commands/improve/improve-strategies.js +43 -14
  52. package/dist/commands/improve/improve.js +249 -29
  53. package/dist/commands/improve/loop-stages.js +11 -17
  54. package/dist/commands/improve/memory/memory-contradiction-detect.js +90 -66
  55. package/dist/commands/improve/outcome-loop.js +22 -38
  56. package/dist/commands/improve/planner.js +134 -0
  57. package/dist/commands/improve/preparation.js +730 -409
  58. package/dist/commands/improve/reflect.js +386 -223
  59. package/dist/commands/improve/run-context.js +3 -4
  60. package/dist/commands/improve/salience.js +6 -58
  61. package/dist/commands/improve/session-asset.js +12 -12
  62. package/dist/commands/lint/index.js +101 -29
  63. package/dist/commands/migrate-cli.js +11 -69
  64. package/dist/commands/migration-tool.js +6 -9
  65. package/dist/commands/models-cli.js +27 -0
  66. package/dist/commands/proposal/drain.js +258 -186
  67. package/dist/commands/proposal/proposal-cli.js +32 -10
  68. package/dist/commands/proposal/proposal.js +2 -5
  69. package/dist/commands/proposal/propose.js +192 -172
  70. package/dist/commands/proposal/repository.js +54 -91
  71. package/dist/commands/proposal/validators/proposal-validators.js +9 -7
  72. package/dist/commands/read/curate.js +10 -0
  73. package/dist/commands/read/registry-search.js +25 -9
  74. package/dist/commands/read/remember-cli.js +14 -2
  75. package/dist/commands/read/search.js +10 -4
  76. package/dist/commands/read/show.js +139 -153
  77. package/dist/commands/registry-cli.js +16 -7
  78. package/dist/commands/remember.js +33 -18
  79. package/dist/commands/sources/add-cli.js +19 -178
  80. package/dist/commands/sources/bundle-cli.js +15 -3
  81. package/dist/commands/sources/dangerous-env-audit.js +135 -0
  82. package/dist/commands/sources/info.js +2 -1
  83. package/dist/commands/sources/installed-stashes.js +835 -152
  84. package/dist/commands/sources/schema-repair.js +174 -95
  85. package/dist/commands/sources/self-update.js +30 -74
  86. package/dist/commands/sources/source-add.js +3 -5
  87. package/dist/commands/sources/sources-cli.js +2 -15
  88. package/dist/commands/sources/update-transaction.js +220 -0
  89. package/dist/commands/tasks/tasks-cli.js +3 -3
  90. package/dist/commands/tasks/tasks.js +736 -317
  91. package/dist/commands/workflow-cli.js +2 -2
  92. package/dist/core/adapter/adapters/agent-skills-adapter.js +3 -0
  93. package/dist/core/adapter/adapters/akm-adapter.js +83 -34
  94. package/dist/core/adapter/adapters/akm-lint.js +54 -39
  95. package/dist/core/adapter/adapters/akm-metadata.js +45 -45
  96. package/dist/core/adapter/adapters/akm-task-adapter.js +32 -49
  97. package/dist/core/adapter/adapters/akm-workflow-adapter.js +38 -23
  98. package/dist/core/adapter/adapters/dotenv-adapter.js +30 -1
  99. package/dist/core/adapter/adapters/generic-files-adapter.js +11 -0
  100. package/dist/core/adapter/adapters/index.js +0 -9
  101. package/dist/core/adapter/adapters/llm-wiki-adapter.js +4 -0
  102. package/dist/core/adapter/adapters/okf-adapter.js +4 -0
  103. package/dist/core/adapter/adapters/opencode-adapter.js +5 -8
  104. package/dist/core/adapter/adapters/tool-dir-shared.js +63 -6
  105. package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -0
  106. package/dist/core/adapter/execution-source.js +308 -0
  107. package/dist/core/adapter/recognize-match.js +36 -13
  108. package/dist/core/adapter/registry.js +0 -9
  109. package/dist/core/asset/stash-meta.js +94 -4
  110. package/dist/core/common.js +6 -11
  111. package/dist/core/config/config-io.js +3 -3
  112. package/dist/core/config/config-schema.js +18 -40
  113. package/dist/core/config/config-sources.js +11 -21
  114. package/dist/core/config/config-walker.js +31 -13
  115. package/dist/core/config/config.js +21 -20
  116. package/dist/core/config/schema/engines.js +8 -7
  117. package/dist/core/config/schema/improve-processes.js +29 -5
  118. package/dist/core/config/schema/primitives.js +1 -23
  119. package/dist/core/config/schema/sources-bundles.js +13 -16
  120. package/dist/core/errors.js +2 -0
  121. package/dist/core/events.js +68 -32
  122. package/dist/core/extra-params.js +1 -0
  123. package/dist/core/improve-result.js +315 -0
  124. package/dist/core/lesson-lint.js +0 -6
  125. package/dist/core/maintenance-barrier.js +4 -4
  126. package/dist/core/network-policy.js +152 -0
  127. package/dist/core/paths.js +1 -1
  128. package/dist/core/recognition-util.js +4 -4
  129. package/dist/core/registry-url.js +456 -0
  130. package/dist/core/state/migrations.js +161 -47
  131. package/dist/core/state-db.js +453 -80
  132. package/dist/core/system-error.js +32 -0
  133. package/dist/core/time.js +2 -12
  134. package/dist/core/write-source.js +0 -18
  135. package/dist/execution/directory-identity.js +52 -0
  136. package/dist/execution/executable-identity.js +107 -0
  137. package/dist/execution/guarded-source.js +398 -0
  138. package/dist/execution/json.js +95 -0
  139. package/dist/{commands/health/types-session-log.js → execution/limits.js} +2 -1
  140. package/dist/execution/record.js +55 -0
  141. package/dist/execution/resolved-request.js +730 -0
  142. package/dist/execution/source.js +320 -0
  143. package/dist/indexer/bundle-identity-guard.js +5 -4
  144. package/dist/indexer/db/graph-db.js +33 -0
  145. package/dist/indexer/graph/graph-boost.js +3 -4
  146. package/dist/indexer/graph/graph-extraction.js +562 -373
  147. package/dist/indexer/index-written-assets.js +65 -34
  148. package/dist/indexer/indexer.js +443 -222
  149. package/dist/indexer/installations.js +6 -0
  150. package/dist/indexer/lookup/adapter-concept-owner.js +283 -0
  151. package/dist/indexer/passes/memory-inference.js +227 -174
  152. package/dist/indexer/scan/doc-to-entry.js +7 -9
  153. package/dist/indexer/scan/drain-dir.js +51 -23
  154. package/dist/indexer/search/db-search.js +98 -22
  155. package/dist/indexer/search/search-fields.js +1 -1
  156. package/dist/indexer/search/search-hit-enrichers.js +1 -1
  157. package/dist/indexer/search/search-source.js +7 -16
  158. package/dist/indexer/search/semantic-status.js +10 -1
  159. package/dist/indexer/usage/show-usage.js +105 -0
  160. package/dist/indexer/usage/usage-events.js +7 -2
  161. package/dist/indexer/walk/matchers.js +40 -10
  162. package/dist/indexer/walk/path-resolver.js +5 -2
  163. package/dist/indexer/walk/walker.js +20 -2
  164. package/dist/integrations/agent/builder-shared.js +3 -6
  165. package/dist/integrations/agent/conversation-fallback.js +16 -0
  166. package/dist/integrations/agent/engine-resolution.js +87 -87
  167. package/dist/integrations/agent/execution-cascade.js +566 -0
  168. package/dist/integrations/agent/execution-definitions.js +211 -0
  169. package/dist/integrations/agent/execution-lowering.js +811 -0
  170. package/dist/integrations/agent/execution-preparation.js +67 -0
  171. package/dist/integrations/agent/index.js +0 -2
  172. package/dist/integrations/agent/inline-execution.js +74 -0
  173. package/dist/integrations/agent/model-map.js +515 -0
  174. package/dist/integrations/agent/persona-fallback.js +30 -0
  175. package/dist/integrations/agent/request-lowering.js +186 -0
  176. package/dist/integrations/agent/runner-dispatch.js +230 -37
  177. package/dist/integrations/agent/runner.js +12 -83
  178. package/dist/integrations/harnesses/aider/agent-builder.js +8 -0
  179. package/dist/integrations/harnesses/aider/index.js +0 -1
  180. package/dist/integrations/harnesses/amazonq/agent-builder.js +8 -0
  181. package/dist/integrations/harnesses/amazonq/index.js +0 -1
  182. package/dist/integrations/harnesses/claude/agent-builder.js +14 -1
  183. package/dist/integrations/harnesses/claude/index.js +1 -5
  184. package/dist/integrations/harnesses/claude/session-log.js +3 -33
  185. package/dist/integrations/harnesses/codex/agent-builder.js +8 -0
  186. package/dist/integrations/harnesses/codex/index.js +0 -1
  187. package/dist/integrations/harnesses/copilot/agent-builder.js +8 -0
  188. package/dist/integrations/harnesses/copilot/index.js +0 -1
  189. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -0
  190. package/dist/integrations/harnesses/gemini/index.js +0 -1
  191. package/dist/integrations/harnesses/index.js +4 -44
  192. package/dist/integrations/harnesses/opencode/agent-builder.js +16 -9
  193. package/dist/integrations/harnesses/opencode/index.js +0 -2
  194. package/dist/integrations/harnesses/opencode/session-log.js +14 -204
  195. package/dist/integrations/harnesses/opencode-sdk/harness.js +12 -1
  196. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +40 -42
  197. package/dist/integrations/harnesses/openhands/agent-builder.js +8 -0
  198. package/dist/integrations/harnesses/openhands/index.js +0 -1
  199. package/dist/integrations/harnesses/pi/agent-builder.js +8 -0
  200. package/dist/integrations/harnesses/pi/index.js +0 -1
  201. package/dist/integrations/harnesses/shared.js +0 -1
  202. package/dist/integrations/harnesses/types.js +1 -3
  203. package/dist/integrations/lockfile.js +82 -79
  204. package/dist/integrations/session-logs/index.js +6 -17
  205. package/dist/integrations/session-logs/provider-base.js +1 -29
  206. package/dist/llm/client.js +10 -5
  207. package/dist/llm/embedder.js +6 -7
  208. package/dist/llm/embedders/local.js +37 -88
  209. package/dist/llm/embedders/types.js +1 -1
  210. package/dist/llm/graph-extract.js +75 -50
  211. package/dist/llm/index-passes.js +43 -5
  212. package/dist/llm/memory-infer.js +8 -6
  213. package/dist/llm/metadata-enhance.js +5 -3
  214. package/dist/llm/structured-call.js +122 -25
  215. package/dist/output/format-exempt.js +1 -1
  216. package/dist/output/render-registry.js +0 -16
  217. package/dist/output/renderers.js +12 -7
  218. package/dist/output/shapes/curate.js +1 -0
  219. package/dist/output/shapes/helpers.js +10 -2
  220. package/dist/output/shapes/passthrough.js +2 -0
  221. package/dist/output/text/command-format.js +28 -32
  222. package/dist/output/text/health-format.js +1 -29
  223. package/dist/output/text/migrate.js +6 -56
  224. package/dist/output/text/proposal-format.js +16 -1
  225. package/dist/output/text/workflow-format.js +16 -0
  226. package/dist/registry/network.js +279 -0
  227. package/dist/registry/pinned-request-helper.js +247 -0
  228. package/dist/registry/pinned-transport.js +717 -0
  229. package/dist/registry/providers/skills-sh.js +18 -6
  230. package/dist/registry/providers/static-index.js +20 -7
  231. package/dist/registry/resolve.js +53 -28
  232. package/dist/scripts/akm-migrate-node.js +19122 -52218
  233. package/dist/scripts/akm-migrate.js +19064 -51567
  234. package/dist/setup/registry-stash-loader.js +64 -20
  235. package/dist/setup/semantic-assets.js +9 -34
  236. package/dist/setup/setup.js +12 -30
  237. package/dist/setup/source-identity.js +17 -0
  238. package/dist/setup/steps/sources.js +36 -15
  239. package/dist/setup/steps/tasks.js +39 -11
  240. package/dist/sources/providers/git-provider.js +3 -3
  241. package/dist/sources/providers/npm.js +2 -2
  242. package/dist/sources/providers/provider-utils.js +4 -3
  243. package/dist/sources/providers/website.js +11 -7
  244. package/dist/sources/snapshot-fetchers/host-guard.js +9 -136
  245. package/dist/sources/snapshot-fetchers/website-ingest.js +25 -109
  246. package/dist/sources/website-url.js +73 -0
  247. package/dist/storage/engines/sqlite-migrations.js +81 -26
  248. package/dist/storage/managed-db.js +27 -24
  249. package/dist/storage/repositories/events-repository.js +3 -0
  250. package/dist/storage/repositories/index-connection.js +42 -10
  251. package/dist/storage/repositories/index-entries-repository.js +167 -207
  252. package/dist/storage/repositories/index-entry-mapper.js +8 -12
  253. package/dist/storage/repositories/index-entry-schema.js +255 -0
  254. package/dist/storage/repositories/index-fts-repository.js +10 -10
  255. package/dist/storage/repositories/index-llm-cache-repository.js +8 -13
  256. package/dist/storage/repositories/index-meta-repository.js +0 -11
  257. package/dist/storage/repositories/index-schema.js +71 -342
  258. package/dist/storage/repositories/index-utility-repository.js +12 -17
  259. package/dist/storage/repositories/index-vec-repository.js +1 -1
  260. package/dist/storage/repositories/proposals-repository.js +4 -127
  261. package/dist/storage/repositories/registry-cache.js +2 -1
  262. package/dist/storage/repositories/task-history-repository.js +20 -40
  263. package/dist/storage/repositories/workflow-runs-repository.js +228 -129
  264. package/dist/storage/sqlite-read-snapshot.js +148 -0
  265. package/dist/tasks/backends/cron.js +170 -42
  266. package/dist/tasks/backends/index.js +1 -1
  267. package/dist/tasks/backends/launchd.js +787 -202
  268. package/dist/tasks/backends/schtasks.js +282 -83
  269. package/dist/tasks/embedded.js +7 -7
  270. package/dist/tasks/frozen-script.js +50 -0
  271. package/dist/tasks/resolve-akm-bin.js +5 -1
  272. package/dist/tasks/runner.js +239 -251
  273. package/dist/tasks/runtime-v3.js +281 -0
  274. package/dist/tasks/scheduler-binding.js +272 -0
  275. package/dist/tasks/scheduler-invocation.js +57 -43
  276. package/dist/tasks/scheduler-sync.js +654 -0
  277. package/dist/tasks/source-v3.js +752 -0
  278. package/dist/tasks/standalone-script-entry.js +5 -0
  279. package/dist/tasks/task-id.js +29 -0
  280. package/dist/workflows/authoring/authoring.js +15 -32
  281. package/dist/workflows/exec/dispatch-redaction.js +14 -8
  282. package/dist/workflows/exec/exec-unit.js +7 -28
  283. package/dist/workflows/exec/frozen-judge.js +57 -89
  284. package/dist/workflows/exec/lowering-notices.js +23 -0
  285. package/dist/workflows/exec/native-executor.js +301 -458
  286. package/dist/workflows/exec/param-secrets.js +4 -3
  287. package/dist/workflows/exec/run-workflow.js +26 -32
  288. package/dist/workflows/exec/step-work.js +105 -109
  289. package/dist/workflows/exec/unit-dispatch.js +103 -27
  290. package/dist/workflows/exec/unit-writer.js +3 -3
  291. package/dist/workflows/exec/worktree.js +2 -2
  292. package/dist/workflows/ir/compile.js +86 -72
  293. package/dist/workflows/ir/environment-v4.js +328 -0
  294. package/dist/workflows/ir/freeze-v4.js +122 -0
  295. package/dist/workflows/ir/plan-hash.js +13 -7
  296. package/dist/workflows/ir/schema-v4.js +525 -0
  297. package/dist/workflows/ir/schema.js +25 -284
  298. package/dist/workflows/ir/source-freeze-v4.js +506 -0
  299. package/dist/workflows/parser.js +27 -24
  300. package/dist/workflows/program/schema.js +1 -2
  301. package/dist/workflows/renderer.js +42 -29
  302. package/dist/workflows/resource-limits.js +4 -5
  303. package/dist/workflows/runtime/agent-identity.js +11 -13
  304. package/dist/workflows/runtime/plan-classifier.js +8 -8
  305. package/dist/workflows/runtime/runs.js +27 -43
  306. package/dist/workflows/runtime/workflow-asset-loader.js +45 -205
  307. package/dist/workflows/source-files.js +373 -0
  308. package/dist/workflows/source-ir/compile.js +196 -0
  309. package/dist/workflows/source-ir/github-yaml.js +577 -0
  310. package/dist/workflows/source-ir/ordering.js +38 -0
  311. package/dist/workflows/source-ir/program.js +50 -0
  312. package/dist/workflows/source-ir/result.js +26 -0
  313. package/dist/workflows/source-ir/schema.js +772 -0
  314. package/dist/workflows/source-ir/semantics.js +242 -0
  315. package/dist/workflows/source-ir/uses.js +14 -0
  316. package/docs/README.md +2 -0
  317. package/docs/migration/README.md +3 -1
  318. package/docs/migration/release-notes/0.9.2.md +55 -0
  319. package/docs/migration/release-notes/README.md +5 -0
  320. package/docs/migration/v0.8-to-v0.9.md +76 -1077
  321. package/docs/migration/v0.9.0-troubleshooting.md +104 -516
  322. package/docs/migration/v0.9.1-to-v0.9.2.md +150 -0
  323. package/docs/reference/README.md +1 -0
  324. package/docs/reference/cli.md +230 -98
  325. package/docs/reference/configuration.md +153 -27
  326. package/docs/reference/data-and-telemetry.md +19 -1
  327. package/docs/reference/supported-formats.md +23 -3
  328. package/docs/reference/tasks.md +182 -0
  329. package/docs/reference/workflow-schema.md +91 -40
  330. package/docs/reference/workflows.md +33 -6
  331. package/package.json +10 -6
  332. package/schemas/akm-config.json +372 -216
  333. package/schemas/akm-task.json +324 -80
  334. package/schemas/akm-workflow.json +6 -9
  335. package/dist/core/migration-operation.js +0 -75
  336. package/dist/integrations/agent/model-aliases.js +0 -74
  337. package/dist/tasks/parser.js +0 -380
  338. package/dist/tasks/schema.js +0 -123
  339. package/dist/tasks/validator.js +0 -80
  340. package/dist/workflows/ir/freeze.js +0 -320
  341. package/dist/workflows/runtime/document-cache.js +0 -13
@@ -1,67 +1,59 @@
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
- * `akm agent [--engine <name>] [--prompt <text>] [--command <ref>] [--workflow <ref>] [args...]`
6
- *
7
- * Dispatch an agent by named engine, optionally injecting a prompt from
8
- * inline text, a stash command: asset, or a stash workflow: asset.
9
- *
10
- * When none of --prompt, --command, or --workflow are given, the agent is
11
- * launched interactively (no injected prompt).
12
- *
13
- * Template placeholders (`{{0}}`, `{{1}}`, ...) in the loaded asset body are
14
- * filled from the extra positional args in order.
15
- */
16
- import fs from "node:fs";
17
- import { parseRefInput } from "../../core/asset/resolve-ref.js";
18
- import { NotFoundError, UsageError } from "../../core/errors.js";
4
+ import { UsageError } from "../../core/errors.js";
19
5
  import { warn } from "../../core/warn.js";
6
+ import { isPortableExecutionAgentSelector } from "../../execution/source.js";
20
7
  import { fallbackAnnouncement, NO_ENGINE_MESSAGE_SUFFIX, NO_ENGINE_REMEDY, withEngineFallback, } from "../../integrations/agent/engine-fallback.js";
21
- import { resolveEngine } from "../../integrations/agent/engine-resolution.js";
22
- import { executeRunner } from "../../integrations/agent/runner-dispatch.js";
23
- /**
24
- * Fill `{{0}}`, `{{1}}`, ... placeholders in `template` with the
25
- * corresponding entries in `args`. Any placeholder index that exceeds the
26
- * args array is left as-is.
27
- */
28
- function fillPlaceholders(template, args) {
29
- return template.replace(/\{\{(\d+)\}\}/g, (match, idx) => {
30
- const i = Number.parseInt(idx, 10);
31
- return i < args.length ? args[i] : match;
32
- });
8
+ import { executeInteractiveAgentInvocation } from "../../integrations/agent/execution-lowering.js";
9
+ import { executeCommandInvocation } from "../command/command-execution.js";
10
+ function canonicalCurrent(options) {
11
+ const current = {};
12
+ if (options.agentRef !== undefined)
13
+ current.agent = options.agentRef;
14
+ if (options.engine !== undefined)
15
+ current.engine = options.engine;
16
+ if (options.selection?.model !== undefined)
17
+ current.model = options.selection.model;
18
+ if (Object.hasOwn(options.selection ?? {}, "inference"))
19
+ current.inference = options.selection?.inference;
20
+ if (options.selection?.outputSchema !== undefined)
21
+ current.outputSchema = options.selection.outputSchema;
22
+ if (options.selection?.tools !== undefined)
23
+ current.tools = options.selection.tools;
24
+ if (options.timeoutMs !== undefined)
25
+ current.timeout = options.timeoutMs;
26
+ if (options.cwd !== undefined)
27
+ current.workspace = options.cwd;
28
+ return current;
33
29
  }
34
- /**
35
- * Resolve the body of an asset by ref string. The ref must parse as a
36
- * valid asset ref (e.g. `command:my-cmd`, `workflow:my-flow`). The file
37
- * must exist on disk (the index provides the file path).
38
- *
39
- * Throws `NotFoundError` when the ref cannot be resolved.
40
- */
41
- async function resolveAssetBody(ref) {
42
- let parsed;
43
- try {
44
- parsed = parseRefInput(ref);
45
- }
46
- catch (err) {
47
- throw new UsageError(`Invalid asset ref "${ref}": ${err instanceof Error ? err.message : String(err)}`, "INVALID_FLAG_VALUE");
48
- }
49
- // Lazy import to avoid pulling the full indexer at startup.
50
- const { lookup } = await import("../../indexer/indexer.js");
51
- const entry = await lookup(parsed);
52
- if (!entry) {
53
- throw new NotFoundError(`Asset "${ref}" not found in the index. Run \`akm index\` to rebuild the index.`);
54
- }
55
- try {
56
- return fs.readFileSync(entry.filePath, "utf8");
57
- }
58
- catch (err) {
59
- throw new NotFoundError(`Asset "${ref}" is indexed but the file could not be read (${entry.filePath}): ${err instanceof Error ? err.message : String(err)}`);
60
- }
30
+ function rejectInvalidAgentRef(agentRef) {
31
+ if (agentRef === undefined || isPortableExecutionAgentSelector(agentRef))
32
+ return;
33
+ throw new UsageError(`agent expects an agent asset ref under agents/...; received ${JSON.stringify(agentRef)}.`, "INVALID_FLAG_VALUE");
34
+ }
35
+ async function delegateCanonicalCommand(options, seams, action) {
36
+ const execute = seams.executeCommand ?? executeCommandInvocation;
37
+ const result = await execute({
38
+ action,
39
+ config: options.agentConfig,
40
+ current: canonicalCurrent(options),
41
+ });
42
+ for (const message of result.warnings ?? [])
43
+ warn(message);
44
+ return result;
61
45
  }
62
- export async function akmAgentDispatch(options) {
46
+ export async function akmAgentDispatch(options, seams = {}) {
63
47
  if (!options.agentConfig)
64
48
  throw new UsageError("agent requires a valid config with an agent engine.", "MISSING_REQUIRED_ARGUMENT");
49
+ rejectInvalidAgentRef(options.agentRef);
50
+ const hasResolvedSelection = options.agentRef !== undefined || options.selection !== undefined;
51
+ if (options.prompt !== undefined || hasResolvedSelection) {
52
+ if (options.prompt === undefined) {
53
+ throw new UsageError("Agent persona/model/tool/schema/inference selection requires an explicit task from --prompt or --prompt-stdin; it cannot fabricate an empty command. Omit those selections for a prompt-free interactive launch.", "MISSING_REQUIRED_ARGUMENT");
54
+ }
55
+ return delegateCanonicalCommand(options, seams, { content: options.prompt });
56
+ }
65
57
  // Same implicit opencode-sdk fallback the workflow and task surfaces apply,
66
58
  // so an engine-less install is usable everywhere or nowhere — not a mix.
67
59
  const { config: agentConfig, fallbackEngineName } = withEngineFallback(options.agentConfig);
@@ -73,45 +65,19 @@ export async function akmAgentDispatch(options) {
73
65
  warn(engineAnnouncement);
74
66
  if (!engineName)
75
67
  throw new UsageError(`agent ${NO_ENGINE_MESSAGE_SUFFIX} ${NO_ENGINE_REMEDY}`, "MISSING_REQUIRED_ARGUMENT");
76
- const runner = resolveEngine(engineName, agentConfig);
77
- if (runner.kind === "llm") {
78
- throw new UsageError(`Engine "${engineName}" is an LLM engine; akm agent requires an agent engine.`, "INVALID_FLAG_VALUE");
79
- }
80
- const profile = runner.profile;
81
- // Resolve the prompt text from whichever source was provided.
82
- let prompt;
83
- if (options.commandRef) {
84
- const body = await resolveAssetBody(options.commandRef);
85
- prompt = options.args?.length ? fillPlaceholders(body, options.args) : body;
86
- }
87
- else if (options.workflowRef) {
88
- const body = await resolveAssetBody(options.workflowRef);
89
- prompt = options.args?.length ? fillPlaceholders(body, options.args) : body;
90
- }
91
- else if (options.prompt !== undefined) {
92
- prompt = options.prompt;
93
- }
94
- // When prompt is undefined, the agent is launched interactively.
95
- const stdio = prompt === undefined && runner.kind !== "sdk" ? "interactive" : profile.stdio;
96
- // Build the final dispatch request: merge the caller-supplied dispatch with
97
- // the resolved prompt so the builder has all context in one place.
98
- const dispatchRequest = options.dispatch
99
- ? { ...options.dispatch, prompt: prompt ?? options.dispatch.prompt }
100
- : undefined;
101
- const runOptions = {
102
- stdio,
103
- parseOutput: "text",
104
- ...(options.args?.length && !options.commandRef && !options.workflowRef ? { args: options.args } : {}),
68
+ const executeInteractive = seams.executeInteractive ?? executeInteractiveAgentInvocation;
69
+ const execution = await executeInteractive({
70
+ config: agentConfig,
71
+ engine: engineName,
105
72
  ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),
106
- ...(options.cwd ? { cwd: options.cwd } : {}),
107
- ...(dispatchRequest !== undefined ? { dispatch: dispatchRequest } : {}),
108
- };
109
- const result = await executeRunner(runner, prompt ?? "", runOptions);
73
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
74
+ });
75
+ const result = execution.result;
110
76
  return {
111
77
  schemaVersion: 2,
112
78
  ok: result.ok,
113
79
  shape: "agent-result",
114
- engine: engineName,
80
+ engine: execution.engine,
115
81
  exitCode: result.exitCode,
116
82
  stdout: result.stdout ?? "",
117
83
  stderr: result.stderr ?? "",
@@ -26,7 +26,6 @@ import { getStringArg, parsePositiveIntFlag } from "../../cli/parse-args.js";
26
26
  import { EXIT_CODES, GLOBAL_OUTPUT_ARGS, output, runWithJsonErrors } from "../../cli/shared.js";
27
27
  import { loadConfig } from "../../core/config/config.js";
28
28
  import { UsageError } from "../../core/errors.js";
29
- import { resolveUsageEventSource } from "../../indexer/usage/usage-events.js";
30
29
  import { getHyphenatedBoolean } from "../../output/context.js";
31
30
  import { akmLint } from "../lint/index.js";
32
31
  import { akmAgentDispatch } from "./agent-dispatch.js";
@@ -37,24 +36,22 @@ export function readPromptStdin(read = () => fs.readFileSync(0, "utf8")) {
37
36
  export const agentCommand = defineCommand({
38
37
  meta: {
39
38
  name: "agent",
40
- description: "Dispatch an agent CLI (opencode, claude, …) with an optional agent asset that provides the system prompt, model, and tool policy. Use <agent-ref> to embody a bundle agent, --model to override the model, and --prompt/--command/--workflow to provide the task.",
39
+ description: "Dispatch an agent CLI (opencode, claude, …) with an optional agent persona and model defaults. Use --prompt for work; stored commands run through akm command run. Nonempty tool requests require separate operator authorization and are rejected by the current CLI.",
41
40
  },
42
41
  args: {
43
42
  ...GLOBAL_OUTPUT_ARGS,
44
43
  "agent-ref": {
45
44
  type: "positional",
46
- description: "Optional agent asset ref (e.g. agents/code-reviewer). Loads system prompt, model, and tool policy from the bundle asset.",
45
+ description: "Optional agent asset ref (e.g. agents/code-reviewer). Resolves persona and model defaults; the current CLI rejects a nonempty tool request without separate operator authorization.",
47
46
  required: false,
48
47
  },
49
48
  prompt: { type: "string", description: "Task prompt to pass to the agent" },
50
49
  "prompt-stdin": {
51
50
  type: "boolean",
52
- description: "Read the task prompt from stdin (mutually exclusive with --prompt, --command, and --workflow)",
51
+ description: "Read the task prompt from stdin (mutually exclusive with --prompt)",
53
52
  default: false,
54
53
  },
55
54
  engine: { type: "string", description: "Agent engine to use (default: defaults.engine)" },
56
- command: { type: "string", description: "Load prompt from a command asset" },
57
- workflow: { type: "string", description: "Load prompt from a workflow asset" },
58
55
  model: {
59
56
  type: "string",
60
57
  description: "Model override — accepts aliases (opus, sonnet, haiku) or exact platform model IDs. Overrides the model specified in the agent asset.",
@@ -70,54 +67,24 @@ export const agentCommand = defineCommand({
70
67
  const timeoutMs = parsePositiveIntFlag(args["timeout-ms"], "--timeout-ms");
71
68
  const config = loadConfig();
72
69
  const agentConfig = config;
73
- // Resolve agent asset ref extract system prompt, model, and tool policy.
70
+ // Preserve the selector; the common execution-source adapter resolves it.
74
71
  const agentRef = getStringArg(args, "agent-ref");
75
- let systemPrompt;
76
- let assetModel;
77
- let assetTools;
78
- if (agentRef) {
79
- const { akmShowUnified } = await import("../read/show.js");
80
- const asset = await akmShowUnified({ ref: agentRef, detail: "full", eventSource: resolveUsageEventSource() });
81
- if (asset.type !== "agent") {
82
- throw new UsageError(`Asset ref "${agentRef}" resolves to type "${asset.type}", expected "agent".`, "INVALID_FLAG_VALUE");
83
- }
84
- systemPrompt = typeof asset.prompt === "string" ? asset.prompt : undefined;
85
- assetModel = typeof asset.modelHint === "string" ? asset.modelHint : undefined;
86
- assetTools = asset.toolPolicy;
87
- }
88
- // --model flag wins over the asset's modelHint.
89
- const model = getStringArg(args, "model") ?? assetModel;
90
72
  const promptText = getStringArg(args, "prompt");
91
- const commandRef = getStringArg(args, "command");
92
- const workflowRef = getStringArg(args, "workflow");
93
73
  const promptStdin = args["prompt-stdin"] === true;
94
- if (promptStdin && (promptText !== undefined || commandRef !== undefined || workflowRef !== undefined)) {
95
- throw new UsageError("--prompt-stdin cannot be combined with --prompt, --command, or --workflow.", "INVALID_FLAG_VALUE");
74
+ if (promptStdin && promptText !== undefined) {
75
+ throw new UsageError("--prompt-stdin cannot be combined with --prompt.", "INVALID_FLAG_VALUE");
96
76
  }
97
- const stdinPrompt = promptStdin ? readPromptStdin() : undefined;
98
77
  const cwd = getStringArg(args, "cwd");
99
- // Only build a dispatch request when there is something to dispatch — a
100
- // prompt, an agent asset, or a model override. When none of these are
101
- // present the agent is launched interactively (no injected prompt, no
102
- // platform-specific flags beyond the profile's base args).
103
- const hasDispatchContent = stdinPrompt !== undefined || !!(promptText ?? commandRef ?? workflowRef ?? systemPrompt ?? model ?? assetTools);
78
+ // The common invocation resolver loads a selected agent through its
79
+ // owning bundle adapter. This CLI never re-reads/show-projects the file.
80
+ const model = getStringArg(args, "model");
81
+ const stdinPrompt = promptStdin ? readPromptStdin() : undefined;
104
82
  const result = await akmAgentDispatch({
105
83
  engine: getStringArg(args, "engine"),
106
84
  prompt: stdinPrompt ?? promptText,
107
- commandRef,
108
- workflowRef,
85
+ ...(agentRef === undefined ? {} : { agentRef }),
109
86
  agentConfig,
110
- ...(hasDispatchContent
111
- ? {
112
- dispatch: {
113
- prompt: stdinPrompt ?? promptText ?? "",
114
- systemPrompt,
115
- model,
116
- tools: assetTools,
117
- ...(cwd ? { cwd } : {}),
118
- },
119
- }
120
- : {}),
87
+ ...(model === undefined ? {} : { selection: { model } }),
121
88
  ...(cwd ? { cwd } : {}),
122
89
  ...(timeoutMs !== undefined && Number.isFinite(timeoutMs) ? { timeoutMs } : {}),
123
90
  });
@@ -0,0 +1,32 @@
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 { UsageError } from "../../core/errors.js";
5
+ import { assertSnapshotKeys, snapshotStrictRecord } from "../../execution/record.js";
6
+ /**
7
+ * Parse the `with:` payload of AKM's built-in command action. The executable
8
+ * selector is a strict XOR: exactly one of `ref` or `content`.
9
+ */
10
+ export function parseBuiltinCommandAction(value) {
11
+ const input = snapshotStrictRecord(value, "built-in command action with");
12
+ assertSnapshotKeys(input, ["ref", "content", "arguments"], "built-in command action with");
13
+ const hasRef = Object.hasOwn(input, "ref");
14
+ const hasContent = Object.hasOwn(input, "content");
15
+ if (hasRef === hasContent) {
16
+ throw new UsageError("Built-in command action with requires exactly one of ref or content.", "INVALID_FLAG_VALUE");
17
+ }
18
+ if (Object.hasOwn(input, "arguments") && typeof input.arguments !== "string") {
19
+ throw new UsageError("Built-in command action with.arguments must be a string.", "INVALID_FLAG_VALUE");
20
+ }
21
+ const exactArguments = Object.hasOwn(input, "arguments") ? { arguments: input.arguments } : {};
22
+ if (hasRef) {
23
+ if (typeof input.ref !== "string" || input.ref.length === 0) {
24
+ throw new UsageError("Built-in command action with.ref must be a non-empty string.", "INVALID_FLAG_VALUE");
25
+ }
26
+ return Object.freeze({ kind: "stored", ref: input.ref, ...exactArguments });
27
+ }
28
+ if (typeof input.content !== "string") {
29
+ throw new UsageError("Built-in command action with.content must be a string.", "INVALID_FLAG_VALUE");
30
+ }
31
+ return Object.freeze({ kind: "inline", content: input.content, ...exactArguments });
32
+ }
@@ -0,0 +1,99 @@
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 { getStringArg, parsePositiveIntFlag } from "../../cli/parse-args.js";
5
+ import { defineGroupCommand, defineJsonCommand, EXIT_CODES, output } from "../../cli/shared.js";
6
+ import { loadConfig } from "../../core/config/config.js";
7
+ import { isVerbose, setVerbose, warn, warnVerbose } from "../../core/warn.js";
8
+ import { lookupBundleRefReadonly } from "../../indexer/indexer.js";
9
+ import { dispatchPreparedCommandInvocation, inspectPreparedCommandInvocation, prepareCommandInvocation, } from "./command-execution.js";
10
+ function exactStringArg(args, key) {
11
+ const value = args[key];
12
+ return typeof value === "string" ? value : undefined;
13
+ }
14
+ export const commandRunCommand = defineJsonCommand({
15
+ meta: {
16
+ name: "run",
17
+ description: "Resolve a stored command through its bundle adapter, apply portable arguments, and execute one fresh session",
18
+ },
19
+ args: {
20
+ ref: {
21
+ type: "positional",
22
+ description: "Command asset ref (for example commands/review or team//commands/review)",
23
+ required: true,
24
+ },
25
+ arguments: {
26
+ type: "string",
27
+ description: "Exact string substituted for each literal $ARGUMENTS occurrence (no tokenization or trimming)",
28
+ },
29
+ agent: {
30
+ type: "string",
31
+ description: "Override the command's agent selector with a portable agent ref or native harness selector",
32
+ },
33
+ engine: { type: "string", description: "Override the selected execution engine" },
34
+ model: { type: "string", description: "Override the selected model alias or exact model identifier" },
35
+ "timeout-ms": { type: "string", description: "Override the execution timeout in milliseconds" },
36
+ cwd: { type: "string", description: "Override the execution workspace/current working directory" },
37
+ "dry-run": {
38
+ type: "boolean",
39
+ default: false,
40
+ description: "Authorize and lower the command, then print safe diagnostics without dispatching or writing state",
41
+ },
42
+ },
43
+ async run({ args }) {
44
+ if (args.verbose === true)
45
+ setVerbose(true);
46
+ const timeoutMs = parsePositiveIntFlag(exactStringArg(args, "timeout-ms"), "--timeout-ms");
47
+ const current = {};
48
+ const agent = getStringArg(args, "agent");
49
+ const engine = getStringArg(args, "engine");
50
+ const model = getStringArg(args, "model");
51
+ const workspace = getStringArg(args, "cwd");
52
+ if (agent !== undefined)
53
+ current.agent = agent;
54
+ if (engine !== undefined)
55
+ current.engine = engine;
56
+ if (model !== undefined)
57
+ current.model = model;
58
+ if (timeoutMs !== undefined)
59
+ current.timeout = timeoutMs;
60
+ if (workspace !== undefined)
61
+ current.workspace = workspace;
62
+ const argumentInput = exactStringArg(args, "arguments");
63
+ const dryRun = args["dry-run"] === true;
64
+ const prepared = await prepareCommandInvocation({
65
+ action: {
66
+ ref: args.ref,
67
+ ...(argumentInput === undefined ? {} : { arguments: argumentInput }),
68
+ },
69
+ config: loadConfig(),
70
+ current: current,
71
+ ...(dryRun ? { sourceLookup: lookupBundleRefReadonly } : {}),
72
+ });
73
+ const diagnostics = dryRun || isVerbose() ? inspectPreparedCommandInvocation(prepared) : undefined;
74
+ if (dryRun) {
75
+ output("command-dry-run", diagnostics);
76
+ return;
77
+ }
78
+ if (diagnostics) {
79
+ warnVerbose(`[akm:command] diagnostics ${JSON.stringify({
80
+ engine: diagnostics.engine,
81
+ provenance: diagnostics.provenance,
82
+ notices: diagnostics.notices,
83
+ })}`);
84
+ }
85
+ const result = await dispatchPreparedCommandInvocation(prepared);
86
+ for (const message of result.warnings ?? [])
87
+ warn(message);
88
+ output("agent-result", result);
89
+ if (!result.ok)
90
+ process.exitCode = EXIT_CODES.GENERAL;
91
+ },
92
+ });
93
+ export const commandCommand = defineGroupCommand({
94
+ meta: {
95
+ name: "command",
96
+ description: "Run reusable agent prompt templates through AKM's common execution resolver",
97
+ },
98
+ subCommands: { run: commandRunCommand },
99
+ });