akm-cli 0.8.0-rc1 → 0.8.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 (295) hide show
  1. package/{.github/CHANGELOG.md → CHANGELOG.md} +191 -3
  2. package/README.md +22 -6
  3. package/SECURITY.md +93 -0
  4. package/dist/cli/config-migrate.js +144 -0
  5. package/dist/cli/config-validate.js +39 -0
  6. package/dist/cli/confirm.js +73 -0
  7. package/dist/cli/parse-args.js +93 -3
  8. package/dist/cli/shared.js +129 -0
  9. package/dist/cli.js +2162 -1258
  10. package/dist/commands/add-cli.js +279 -0
  11. package/dist/commands/agent-dispatch.js +20 -12
  12. package/dist/commands/agent-support.js +11 -5
  13. package/dist/commands/completions.js +3 -0
  14. package/dist/commands/config-cli.js +129 -517
  15. package/dist/commands/consolidate.js +1533 -144
  16. package/dist/commands/curate.js +44 -3
  17. package/dist/commands/db-cli.js +23 -0
  18. package/dist/commands/distill-promotion-policy.js +5 -3
  19. package/dist/commands/distill.js +906 -100
  20. package/dist/commands/env.js +213 -0
  21. package/dist/commands/eval-cases.js +3 -0
  22. package/dist/commands/events.js +3 -0
  23. package/dist/commands/extract-cli.js +127 -0
  24. package/dist/commands/extract-prompt.js +204 -0
  25. package/dist/commands/extract.js +477 -0
  26. package/dist/commands/feedback-cli.js +331 -0
  27. package/dist/commands/graph.js +260 -5
  28. package/dist/commands/health.js +977 -51
  29. package/dist/commands/help/help-accept.md +6 -3
  30. package/dist/commands/help/help-improve.md +36 -8
  31. package/dist/commands/help/help-proposals.md +7 -4
  32. package/dist/commands/help/help-reject.md +5 -2
  33. package/dist/commands/history.js +51 -16
  34. package/dist/commands/improve-auto-accept.js +97 -0
  35. package/dist/commands/improve-cli.js +236 -0
  36. package/dist/commands/improve-profiles.js +184 -0
  37. package/dist/commands/improve-result-file.js +167 -0
  38. package/dist/commands/improve.js +1725 -332
  39. package/dist/commands/info.js +3 -0
  40. package/dist/commands/init.js +49 -1
  41. package/dist/commands/installed-stashes.js +6 -23
  42. package/dist/commands/knowledge.js +3 -0
  43. package/dist/commands/lint/agent-linter.js +3 -0
  44. package/dist/commands/lint/base-linter.js +233 -5
  45. package/dist/commands/lint/command-linter.js +3 -0
  46. package/dist/commands/lint/default-linter.js +3 -0
  47. package/dist/commands/lint/env-key-rules.js +154 -0
  48. package/dist/commands/lint/index.js +92 -3
  49. package/dist/commands/lint/knowledge-linter.js +3 -0
  50. package/dist/commands/lint/markdown-insertion.js +343 -0
  51. package/dist/commands/lint/memory-linter.js +3 -0
  52. package/dist/commands/lint/registry.js +3 -0
  53. package/dist/commands/lint/skill-linter.js +3 -0
  54. package/dist/commands/lint/task-linter.js +15 -12
  55. package/dist/commands/lint/types.js +3 -0
  56. package/dist/commands/lint/workflow-linter.js +3 -0
  57. package/dist/commands/lint.js +3 -0
  58. package/dist/commands/migration-help.js +5 -2
  59. package/dist/commands/proposal-drain-policies.js +128 -0
  60. package/dist/commands/proposal-drain.js +477 -0
  61. package/dist/commands/proposal.js +60 -6
  62. package/dist/commands/propose.js +24 -19
  63. package/dist/commands/reflect.js +1004 -94
  64. package/dist/commands/registry-cli.js +150 -0
  65. package/dist/commands/registry-search.js +3 -0
  66. package/dist/commands/remember-cli.js +257 -0
  67. package/dist/commands/remember.js +15 -6
  68. package/dist/commands/schema-repair.js +88 -15
  69. package/dist/commands/search.js +99 -14
  70. package/dist/commands/secret.js +173 -0
  71. package/dist/commands/self-update.js +3 -0
  72. package/dist/commands/show.js +32 -13
  73. package/dist/commands/source-add.js +7 -35
  74. package/dist/commands/source-clone.js +3 -0
  75. package/dist/commands/source-manage.js +3 -0
  76. package/dist/commands/tasks.js +161 -95
  77. package/dist/commands/url-checker.js +3 -0
  78. package/dist/core/action-contributors.js +3 -0
  79. package/dist/core/asset-ref.js +17 -2
  80. package/dist/core/asset-registry.js +9 -2
  81. package/dist/core/asset-serialize.js +88 -0
  82. package/dist/core/asset-spec.js +61 -5
  83. package/dist/core/common.js +93 -5
  84. package/dist/core/concurrent.js +3 -0
  85. package/dist/core/config-io.js +347 -0
  86. package/dist/core/config-migration.js +622 -0
  87. package/dist/core/config-schema.js +558 -0
  88. package/dist/core/config-sources.js +108 -0
  89. package/dist/core/config-types.js +4 -0
  90. package/dist/core/config-walker.js +337 -0
  91. package/dist/core/config.js +366 -1077
  92. package/dist/core/errors.js +42 -20
  93. package/dist/core/events.js +31 -25
  94. package/dist/core/file-lock.js +104 -0
  95. package/dist/core/frontmatter.js +75 -10
  96. package/dist/core/lesson-lint.js +3 -0
  97. package/dist/core/markdown.js +3 -0
  98. package/dist/core/memory-belief.js +62 -0
  99. package/dist/core/memory-contradiction-detect.js +274 -0
  100. package/dist/core/memory-improve.js +142 -14
  101. package/dist/core/parse.js +3 -0
  102. package/dist/core/paths.js +218 -50
  103. package/dist/core/proposal-quality-validators.js +380 -0
  104. package/dist/core/proposal-validators.js +11 -3
  105. package/dist/core/proposals.js +464 -5
  106. package/dist/core/state-db.js +349 -56
  107. package/dist/core/text-truncation.js +107 -0
  108. package/dist/core/time.js +3 -0
  109. package/dist/core/tty.js +59 -0
  110. package/dist/core/warn.js +7 -2
  111. package/dist/core/write-source.js +12 -0
  112. package/dist/indexer/db-backup.js +391 -0
  113. package/dist/indexer/db-search.js +136 -28
  114. package/dist/indexer/db.js +662 -166
  115. package/dist/indexer/ensure-index.js +3 -0
  116. package/dist/indexer/file-context.js +3 -0
  117. package/dist/indexer/graph-boost.js +162 -40
  118. package/dist/indexer/graph-db.js +241 -51
  119. package/dist/indexer/graph-dedup.js +3 -7
  120. package/dist/indexer/graph-extraction.js +242 -149
  121. package/dist/indexer/index-context.js +3 -9
  122. package/dist/indexer/indexer.js +84 -14
  123. package/dist/indexer/llm-cache.js +24 -19
  124. package/dist/indexer/manifest.js +3 -0
  125. package/dist/indexer/matchers.js +184 -11
  126. package/dist/indexer/memory-inference.js +94 -50
  127. package/dist/indexer/metadata-contributors.js +3 -0
  128. package/dist/indexer/metadata.js +114 -48
  129. package/dist/indexer/path-resolver.js +3 -0
  130. package/dist/indexer/project-context.js +192 -0
  131. package/dist/indexer/ranking-contributors.js +134 -7
  132. package/dist/indexer/ranking.js +8 -1
  133. package/dist/indexer/search-fields.js +5 -9
  134. package/dist/indexer/search-hit-enrichers.js +91 -2
  135. package/dist/indexer/search-source.js +20 -1
  136. package/dist/indexer/semantic-status.js +4 -1
  137. package/dist/indexer/staleness-detect.js +447 -0
  138. package/dist/indexer/usage-events.js +12 -9
  139. package/dist/indexer/walker.js +3 -0
  140. package/dist/integrations/agent/builders.js +135 -0
  141. package/dist/integrations/agent/config.js +121 -401
  142. package/dist/integrations/agent/detect.js +3 -0
  143. package/dist/integrations/agent/index.js +6 -14
  144. package/dist/integrations/agent/model-aliases.js +55 -0
  145. package/dist/integrations/agent/profiles.js +3 -0
  146. package/dist/integrations/agent/prompts.js +137 -8
  147. package/dist/integrations/agent/runner.js +208 -0
  148. package/dist/integrations/agent/sdk-runner.js +8 -2
  149. package/dist/integrations/agent/spawn.js +54 -14
  150. package/dist/integrations/github.js +3 -0
  151. package/dist/integrations/lockfile.js +22 -51
  152. package/dist/integrations/session-logs/index.js +4 -0
  153. package/dist/integrations/session-logs/inline-refs.js +35 -0
  154. package/dist/integrations/session-logs/pre-filter.js +152 -0
  155. package/dist/integrations/session-logs/providers/claude-code.js +226 -0
  156. package/dist/integrations/session-logs/providers/opencode.js +231 -25
  157. package/dist/integrations/session-logs/types.js +3 -0
  158. package/dist/llm/call-ai.js +14 -26
  159. package/dist/llm/client.js +16 -2
  160. package/dist/llm/embedder.js +20 -29
  161. package/dist/llm/embedders/cache.js +3 -7
  162. package/dist/llm/embedders/local.js +42 -1
  163. package/dist/llm/embedders/remote.js +20 -8
  164. package/dist/llm/embedders/types.js +3 -7
  165. package/dist/llm/feature-gate.js +92 -56
  166. package/dist/llm/graph-extract.js +401 -30
  167. package/dist/llm/index-passes.js +44 -29
  168. package/dist/llm/memory-infer.js +30 -2
  169. package/dist/llm/metadata-enhance.js +3 -7
  170. package/dist/llm/prompts/extract-session.md +80 -0
  171. package/dist/llm/prompts/graph-extract-user-prompt.md +24 -1
  172. package/dist/output/cli-hints-full.md +60 -32
  173. package/dist/output/cli-hints-short.md +10 -7
  174. package/dist/output/cli-hints.js +5 -2
  175. package/dist/output/context.js +60 -8
  176. package/dist/output/renderers.js +170 -194
  177. package/dist/output/shapes/curate.js +56 -0
  178. package/dist/output/shapes/distill.js +10 -0
  179. package/dist/output/shapes/env-list.js +19 -0
  180. package/dist/output/shapes/events.js +11 -0
  181. package/dist/output/shapes/helpers.js +424 -0
  182. package/dist/output/shapes/history.js +7 -0
  183. package/dist/output/shapes/passthrough.js +105 -0
  184. package/dist/output/shapes/proposal-accept.js +7 -0
  185. package/dist/output/shapes/proposal-diff.js +7 -0
  186. package/dist/output/shapes/proposal-list.js +7 -0
  187. package/dist/output/shapes/proposal-producer.js +11 -0
  188. package/dist/output/shapes/proposal-reject.js +7 -0
  189. package/dist/output/shapes/proposal-show.js +7 -0
  190. package/dist/output/shapes/registry-search.js +6 -0
  191. package/dist/output/shapes/registry.js +30 -0
  192. package/dist/output/shapes/search.js +6 -0
  193. package/dist/output/shapes/secret-list.js +19 -0
  194. package/dist/output/shapes/show.js +6 -0
  195. package/dist/output/shapes/vault-list.js +19 -0
  196. package/dist/output/shapes.js +51 -549
  197. package/dist/output/text/add.js +6 -0
  198. package/dist/output/text/clone.js +6 -0
  199. package/dist/output/text/config.js +6 -0
  200. package/dist/output/text/curate.js +6 -0
  201. package/dist/output/text/distill.js +7 -0
  202. package/dist/output/text/enable-disable.js +7 -0
  203. package/dist/output/text/events.js +10 -0
  204. package/dist/output/text/feedback.js +6 -0
  205. package/dist/output/text/helpers.js +1059 -0
  206. package/dist/output/text/history.js +7 -0
  207. package/dist/output/text/import.js +6 -0
  208. package/dist/output/text/index.js +6 -0
  209. package/dist/output/text/info.js +6 -0
  210. package/dist/output/text/init.js +6 -0
  211. package/dist/output/text/list.js +6 -0
  212. package/dist/output/text/proposal-producer.js +8 -0
  213. package/dist/output/text/proposal.js +12 -0
  214. package/dist/output/text/registry-commands.js +11 -0
  215. package/dist/output/text/registry.js +30 -0
  216. package/dist/output/text/remember.js +6 -0
  217. package/dist/output/text/remove.js +6 -0
  218. package/dist/output/text/save.js +6 -0
  219. package/dist/output/text/search.js +6 -0
  220. package/dist/output/text/show.js +6 -0
  221. package/dist/output/text/update.js +6 -0
  222. package/dist/output/text/upgrade.js +6 -0
  223. package/dist/output/text/vault.js +16 -0
  224. package/dist/output/text/wiki.js +15 -0
  225. package/dist/output/text/workflow.js +14 -0
  226. package/dist/output/text.js +44 -1329
  227. package/dist/registry/build-index.js +3 -0
  228. package/dist/registry/create-provider-registry.js +3 -0
  229. package/dist/registry/factory.js +4 -1
  230. package/dist/registry/origin-resolve.js +3 -0
  231. package/dist/registry/providers/index.js +3 -0
  232. package/dist/registry/providers/skills-sh.js +11 -2
  233. package/dist/registry/providers/static-index.js +10 -1
  234. package/dist/registry/providers/types.js +3 -24
  235. package/dist/registry/resolve.js +11 -16
  236. package/dist/registry/types.js +3 -0
  237. package/dist/scripts/migrate-storage.js +17767 -0
  238. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +9031 -0
  239. package/dist/scripts/migrations/v16-to-v17.js +141 -0
  240. package/dist/setup/detect.js +3 -0
  241. package/dist/setup/ripgrep-install.js +3 -0
  242. package/dist/setup/ripgrep-resolve.js +3 -0
  243. package/dist/setup/setup.js +306 -67
  244. package/dist/setup/steps.js +3 -15
  245. package/dist/sources/include.js +3 -0
  246. package/dist/sources/provider-factory.js +3 -11
  247. package/dist/sources/provider.js +3 -20
  248. package/dist/sources/providers/filesystem.js +19 -23
  249. package/dist/sources/providers/git.js +171 -21
  250. package/dist/sources/providers/index.js +3 -0
  251. package/dist/sources/providers/install-types.js +3 -13
  252. package/dist/sources/providers/npm.js +3 -4
  253. package/dist/sources/providers/provider-utils.js +3 -0
  254. package/dist/sources/providers/sync-from-ref.js +3 -11
  255. package/dist/sources/providers/tar-utils.js +3 -0
  256. package/dist/sources/providers/website.js +18 -22
  257. package/dist/sources/resolve.js +3 -0
  258. package/dist/sources/types.js +3 -0
  259. package/dist/sources/website-ingest.js +3 -0
  260. package/dist/tasks/backends/cron.js +3 -0
  261. package/dist/tasks/backends/exec-utils.js +3 -0
  262. package/dist/tasks/backends/index.js +3 -11
  263. package/dist/tasks/backends/launchd.js +3 -0
  264. package/dist/tasks/backends/schtasks.js +3 -0
  265. package/dist/tasks/parser.js +51 -38
  266. package/dist/tasks/resolveAkmBin.js +3 -0
  267. package/dist/tasks/runner.js +35 -9
  268. package/dist/tasks/schedule.js +20 -1
  269. package/dist/tasks/schema.js +5 -3
  270. package/dist/tasks/validator.js +6 -3
  271. package/dist/version.js +3 -0
  272. package/dist/wiki/wiki-templates.js +3 -0
  273. package/dist/wiki/wiki.js +3 -0
  274. package/dist/workflows/authoring.js +3 -0
  275. package/dist/workflows/cli.js +3 -0
  276. package/dist/workflows/db.js +140 -10
  277. package/dist/workflows/document-cache.js +3 -10
  278. package/dist/workflows/parser.js +3 -0
  279. package/dist/workflows/renderer.js +3 -0
  280. package/dist/workflows/runs.js +18 -1
  281. package/dist/workflows/schema.js +3 -0
  282. package/dist/workflows/scope-key.js +3 -0
  283. package/dist/workflows/validator.js +5 -9
  284. package/docs/README.md +7 -2
  285. package/docs/data-and-telemetry.md +225 -0
  286. package/docs/migration/release-notes/0.7.5.md +2 -2
  287. package/docs/migration/release-notes/0.8.0.md +57 -5
  288. package/docs/migration/v0.7-to-v0.8.md +1378 -0
  289. package/package.json +28 -11
  290. package/.github/LICENSE +0 -374
  291. package/dist/commands/install-audit.js +0 -385
  292. package/dist/commands/vault.js +0 -307
  293. package/dist/indexer/match-contributors.js +0 -141
  294. package/dist/integrations/agent/pipeline.js +0 -39
  295. package/dist/integrations/agent/runners.js +0 -31
@@ -1,3 +1,6 @@
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/.
1
4
  /**
2
5
  * `akm proposal {list,show,accept,reject,diff}` — review surface for the
3
6
  * proposal substrate (#225).
@@ -12,7 +15,7 @@ import { resolveStashDir } from "../core/common";
12
15
  import { loadConfig } from "../core/config";
13
16
  import { UsageError } from "../core/errors";
14
17
  import { appendEvent } from "../core/events";
15
- import { archiveProposal, createProposal, diffProposal, getProposal, listProposals, promoteProposal, resolveProposalId, validateProposal, } from "../core/proposals";
18
+ import { archiveProposal, createProposal, diffProposal, getProposal, isProposalSkipped, listProposals, promoteProposal, resolveProposalId, revertProposal, validateProposal, } from "../core/proposals";
16
19
  // ── Shared helpers ──────────────────────────────────────────────────────────
17
20
  function resolveStash(stashDir) {
18
21
  if (stashDir)
@@ -21,13 +24,17 @@ function resolveStash(stashDir) {
21
24
  }
22
25
  export function akmProposalList(options = {}) {
23
26
  const stash = resolveStash(options.stashDir);
24
- // `--status accepted|rejected` implies archive-inclusion since the live
25
- // queue only ever contains pending entries.
26
- const includeArchive = options.includeArchive === true || options.status === "accepted" || options.status === "rejected";
27
+ // `--status accepted|rejected|reverted` implies archive-inclusion since the
28
+ // live queue only ever contains pending entries.
29
+ const includeArchive = options.includeArchive === true ||
30
+ options.status === "accepted" ||
31
+ options.status === "rejected" ||
32
+ options.status === "reverted";
27
33
  const proposals = listProposals(stash, {
28
34
  includeArchive,
29
35
  status: options.status,
30
36
  ref: options.ref,
37
+ type: options.type,
31
38
  });
32
39
  return { schemaVersion: 1, totalCount: proposals.length, proposals };
33
40
  }
@@ -110,11 +117,58 @@ export function akmProposalDiff(options) {
110
117
  }
111
118
  export function akmProposalCreate(options) {
112
119
  const stash = resolveStash(options.stashDir);
113
- const proposal = createProposal(stash, {
120
+ // Manual proposal creation (via `akm proposal create`) always bypasses
121
+ // dedup/cooldown guards — the operator is explicitly requesting a proposal.
122
+ const result = createProposal(stash, {
114
123
  ref: options.ref,
115
124
  source: options.source,
116
125
  ...(options.sourceRun !== undefined ? { sourceRun: options.sourceRun } : {}),
117
126
  payload: options.payload,
127
+ force: true,
118
128
  }, options.ctx);
119
- return { schemaVersion: 1, ok: true, proposal };
129
+ if (isProposalSkipped(result)) {
130
+ // Should never happen with force:true — defensive only.
131
+ throw new Error(`Unexpected proposal skip: ${result.message}`);
132
+ }
133
+ return { schemaVersion: 1, ok: true, proposal: result };
134
+ }
135
+ /**
136
+ * Restore an accepted proposal's prior content from the backup captured at
137
+ * promotion time (Advantage D6c / Phase 6C).
138
+ *
139
+ * Failure modes (all surface as typed errors so the CLI can map exit codes):
140
+ * - Proposal id does not resolve → `NotFoundError("FILE_NOT_FOUND")`
141
+ * (raised by `resolveProposalId` / `getProposal`).
142
+ * - Proposal is not `status === "accepted"` → `UsageError("INVALID_FLAG_VALUE")`
143
+ * with message `"only accepted proposals can be reverted ..."`.
144
+ * - No `backup` field, or the backup file is missing on disk →
145
+ * `UsageError` with message `"no backup available for this proposal ..."`.
146
+ *
147
+ * On success, emits a `proposal_reverted` event for observability, mirroring
148
+ * how `akmProposalAccept` emits `promoted` and `akmProposalReject` emits
149
+ * `rejected`.
150
+ */
151
+ export async function akmProposalRevert(options) {
152
+ const stash = resolveStash(options.stashDir);
153
+ const config = options.config ?? loadConfig();
154
+ const resolvedId = resolveProposalId(stash, options.id).id;
155
+ const result = await revertProposal(stash, config, resolvedId, { target: options.target }, options.ctx);
156
+ appendEvent({
157
+ eventType: "proposal_reverted",
158
+ ref: result.ref,
159
+ metadata: {
160
+ proposalId: result.proposal.id,
161
+ source: result.proposal.source,
162
+ ...(result.proposal.sourceRun !== undefined ? { sourceRun: result.proposal.sourceRun } : {}),
163
+ assetPath: result.assetPath,
164
+ },
165
+ });
166
+ return {
167
+ schemaVersion: 1,
168
+ ok: true,
169
+ id: result.proposal.id,
170
+ ref: result.ref,
171
+ assetPath: result.assetPath,
172
+ proposal: result.proposal,
173
+ };
120
174
  }
@@ -1,3 +1,6 @@
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/.
1
4
  /**
2
5
  * `akm propose <type> <name> --task ...` — proposal-producing agent
3
6
  * command (#226).
@@ -9,16 +12,17 @@
9
12
  * Failures use the same {@link AgentFailureReason} discriminants as
10
13
  * `akm reflect`. `propose_invoked` is emitted at command entry.
11
14
  */
15
+ import fs from "node:fs";
12
16
  import { parseAssetRef } from "../core/asset-ref";
13
17
  import { TYPE_DIRS } from "../core/asset-spec";
14
18
  import { resolveStashDir } from "../core/common";
15
19
  import { ConfigError, UsageError } from "../core/errors";
16
20
  import { appendEvent } from "../core/events";
17
- import { createProposal } from "../core/proposals";
21
+ import { createProposal, isProposalSkipped, } from "../core/proposals";
18
22
  import { runAgent, } from "../integrations/agent";
19
23
  import { resolveProcessAgentProfile } from "../integrations/agent/config";
20
- import { runProposalAgentPipeline } from "../integrations/agent/pipeline";
21
24
  import { buildProposePrompt, parseAgentProposalPayload } from "../integrations/agent/prompts";
25
+ import { runAgentSdk } from "../integrations/agent/sdk-runner";
22
26
  import { baseFailureFields, enoentHintMessage, isEnoentFailure, loadAgentConfigFromDisk, resolveAgentProfile, } from "./agent-support";
23
27
  function failureEnvelope(result, type, name, fallbackReason = "non_zero_exit") {
24
28
  return {
@@ -112,22 +116,15 @@ export async function akmPropose(options) {
112
116
  result = await runAgent(profile, prompt, runOptions);
113
117
  }
114
118
  else {
115
- // Production path: route through runProposalAgentPipeline (shared logic).
116
- const pipelineResult = await runProposalAgentPipeline({
117
- profile,
118
- prompt,
119
- draftFilePath: resolvedDraftPath,
120
- timeoutMs: resolvedTimeoutMs,
121
- });
122
- result = {
123
- ok: pipelineResult.ok,
124
- exitCode: pipelineResult.exitCode,
125
- stdout: pipelineResult.stdout,
126
- stderr: pipelineResult.stderr,
127
- durationMs: pipelineResult.durationMs,
128
- error: pipelineResult.error,
129
- reason: pipelineResult.reason,
119
+ // Production path: dispatch directly to the appropriate runner.
120
+ const runOptions = {
121
+ stdio: resolvedDraftPath ? "interactive" : "captured",
122
+ parseOutput: "text",
123
+ ...(resolvedTimeoutMs !== undefined ? { timeoutMs: resolvedTimeoutMs } : {}),
130
124
  };
125
+ result = profile.sdkMode
126
+ ? await runAgentSdk(profile, prompt ?? "", runOptions)
127
+ : await runAgent(profile, prompt, runOptions);
131
128
  }
132
129
  if (!result.ok) {
133
130
  // B3: ENOENT / not-found gives an actionable hint.
@@ -139,7 +136,6 @@ export async function akmPropose(options) {
139
136
  // 5. Resolve the proposal content.
140
137
  // Path A: opencode wrote the draft file — read it directly (no stdout parse).
141
138
  // Path B: fallback to stdout JSON parse for non-file-writing agents.
142
- const fs = await import("node:fs");
143
139
  let payload;
144
140
  if (fs.existsSync(resolvedDraftPath)) {
145
141
  const draftContent = fs.readFileSync(resolvedDraftPath, "utf8");
@@ -224,12 +220,21 @@ export async function akmPropose(options) {
224
220
  ref,
225
221
  source: "propose",
226
222
  sourceRun: `propose-${Date.now()}`,
223
+ // User-initiated proposals always bypass dedup/cooldown guards — the
224
+ // operator is explicitly asking for a new proposal.
225
+ force: true,
227
226
  payload: {
228
227
  content: payload.content,
229
228
  ...(payload.frontmatter ? { frontmatter: payload.frontmatter } : {}),
230
229
  },
231
230
  };
232
- const proposal = createProposal(stash, createInput, options.ctx);
231
+ const proposalResult = createProposal(stash, createInput, options.ctx);
232
+ // With force:true, the result is always a Proposal (never skipped).
233
+ if (isProposalSkipped(proposalResult)) {
234
+ // Should never happen when force:true, but be defensive.
235
+ throw new Error(`Unexpected skip in propose command: ${proposalResult.message}`);
236
+ }
237
+ const proposal = proposalResult;
233
238
  return {
234
239
  schemaVersion: 1,
235
240
  ok: true,