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
@@ -0,0 +1,220 @@
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 { randomBytes } from "node:crypto";
5
+ import fs from "node:fs";
6
+ import path from "node:path";
7
+ import { ConfigError } from "../../core/errors.js";
8
+ import { warn } from "../../core/warn.js";
9
+ import { runGit } from "../../sources/providers/git.js";
10
+ import { assertNoIgnoredPathOverwrite } from "../../sources/providers/git-install.js";
11
+ export function prepareDirectoryPublication(stagedRoot, liveRoot) {
12
+ const backupRoot = `${liveRoot}.akm-update-backup-${randomBytes(6).toString("hex")}`;
13
+ let published = false;
14
+ let hadLiveRoot = false;
15
+ return {
16
+ publish() {
17
+ if (published)
18
+ throw new ConfigError(`Update content at ${liveRoot} was already published.`);
19
+ hadLiveRoot = fs.existsSync(liveRoot);
20
+ fs.mkdirSync(path.dirname(liveRoot), { recursive: true });
21
+ if (hadLiveRoot)
22
+ fs.renameSync(liveRoot, backupRoot);
23
+ try {
24
+ fs.renameSync(stagedRoot, liveRoot);
25
+ published = true;
26
+ }
27
+ catch (error) {
28
+ if (hadLiveRoot && fs.existsSync(backupRoot))
29
+ fs.renameSync(backupRoot, liveRoot);
30
+ throw error;
31
+ }
32
+ },
33
+ rollback() {
34
+ if (!published)
35
+ return;
36
+ const failedRoot = `${liveRoot}.akm-update-failed-${randomBytes(6).toString("hex")}`;
37
+ if (fs.existsSync(liveRoot))
38
+ fs.renameSync(liveRoot, failedRoot);
39
+ try {
40
+ if (hadLiveRoot && fs.existsSync(backupRoot))
41
+ fs.renameSync(backupRoot, liveRoot);
42
+ }
43
+ catch (error) {
44
+ // The prior generation could not be restored. Put the published
45
+ // candidate back at the live path so resolution never sees a missing
46
+ // root, then surface the rollback failure loudly.
47
+ try {
48
+ if (!fs.existsSync(liveRoot) && fs.existsSync(failedRoot))
49
+ fs.renameSync(failedRoot, liveRoot);
50
+ }
51
+ catch {
52
+ // Preserve the original restoration failure; both paths remain for
53
+ // manual recovery when even the defensive rename cannot complete.
54
+ }
55
+ published = false;
56
+ throw error;
57
+ }
58
+ try {
59
+ fs.rmSync(failedRoot, { recursive: true, force: true });
60
+ }
61
+ catch (error) {
62
+ warn(`[akm bundle update] restored ${liveRoot}, but could not remove failed candidate ${failedRoot}: ${error instanceof Error ? error.message : String(error)}`);
63
+ }
64
+ published = false;
65
+ },
66
+ commit() {
67
+ if (hadLiveRoot) {
68
+ try {
69
+ fs.rmSync(backupRoot, { recursive: true, force: true });
70
+ }
71
+ catch (error) {
72
+ warn(`[akm bundle update] update committed, but could not remove backup ${backupRoot}: ${error instanceof Error ? error.message : String(error)}`);
73
+ }
74
+ }
75
+ published = false;
76
+ },
77
+ };
78
+ }
79
+ function gitOutput(repoDir, args, description) {
80
+ const result = runGit(["-C", repoDir, ...args], { timeout: 120_000 });
81
+ if (result.status !== 0) {
82
+ throw new ConfigError(`${description}: ${result.stderr.trim() || result.stdout.trim() || "git failed"}`);
83
+ }
84
+ return result.stdout.trim();
85
+ }
86
+ function assertGitCheckoutGeneration(repoDir, expectedHead, phase) {
87
+ const actualHead = gitOutput(repoDir, ["rev-parse", "HEAD"], `Cannot read writable Git HEAD at ${repoDir}`);
88
+ if (actualHead !== expectedHead) {
89
+ throw new ConfigError(`Writable Git checkout at ${repoDir} changed after the update was audited (${phase}: expected ${expectedHead}, found ${actualHead}); refusing to overwrite the live commit.`);
90
+ }
91
+ const status = gitOutput(repoDir, ["status", "--porcelain=v1", "--untracked-files=all", "--ignore-submodules=none"], `Cannot inspect writable Git checkout at ${repoDir}`);
92
+ if (status) {
93
+ throw new ConfigError(`Writable Git checkout at ${repoDir} changed after the update was audited (${phase}: working tree is no longer clean); refusing to overwrite live files.`);
94
+ }
95
+ }
96
+ function assertNoGitlinks(repoDir, targetHead) {
97
+ const tree = gitOutput(repoDir, ["ls-tree", "-r", "-z", targetHead], `Cannot inspect audited Git tree ${targetHead} at ${repoDir}`);
98
+ const gitlink = tree.split("\0").find((entry) => entry.startsWith("160000 "));
99
+ if (gitlink) {
100
+ const targetPath = gitlink.slice(gitlink.indexOf("\t") + 1);
101
+ throw new ConfigError(`Writable Git target contains unaudited submodule/gitlink ${targetPath}; refusing to materialize it.`);
102
+ }
103
+ }
104
+ function copyWorktree(source, destination) {
105
+ fs.mkdirSync(destination, { recursive: true, mode: 0o700 });
106
+ for (const entry of fs.readdirSync(source, { withFileTypes: true })) {
107
+ if (entry.name === ".git")
108
+ continue;
109
+ fs.cpSync(path.join(source, entry.name), path.join(destination, entry.name), {
110
+ recursive: true,
111
+ preserveTimestamps: true,
112
+ });
113
+ }
114
+ }
115
+ function clearWorktree(repoDir) {
116
+ for (const entry of fs.readdirSync(repoDir, { withFileTypes: true })) {
117
+ if (entry.name === ".git")
118
+ continue;
119
+ fs.rmSync(path.join(repoDir, entry.name), { recursive: true, force: true });
120
+ }
121
+ }
122
+ /**
123
+ * Publish the exact audited commit into a writable checkout without replacing
124
+ * the checkout directory. The expected-old-HEAD and clean-tree fence runs
125
+ * under the caller's asset mutation lease immediately before the fast-forward.
126
+ */
127
+ export function prepareWritableGitPublication(opts) {
128
+ let published = false;
129
+ let rollbackParent;
130
+ let rollbackWorktree;
131
+ const discardRollback = () => {
132
+ if (!rollbackParent)
133
+ return;
134
+ cleanupStagingParent(rollbackParent);
135
+ rollbackParent = undefined;
136
+ rollbackWorktree = undefined;
137
+ };
138
+ const restore = () => {
139
+ if (!rollbackWorktree)
140
+ return;
141
+ const actualHead = gitOutput(opts.liveRepo, ["rev-parse", "HEAD"], `Cannot read writable Git rollback HEAD`);
142
+ if (actualHead !== opts.expectedOldHead && actualHead !== opts.auditedTargetHead) {
143
+ throw new ConfigError(`Writable Git checkout ${opts.liveRepo} advanced concurrently to ${actualHead}; refusing to overwrite that commit during rollback.`);
144
+ }
145
+ gitOutput(opts.liveRepo, ["reset", "--hard", opts.expectedOldHead], `Cannot restore writable Git checkout ${opts.liveRepo} to ${opts.expectedOldHead}`);
146
+ clearWorktree(opts.liveRepo);
147
+ copyWorktree(rollbackWorktree, opts.liveRepo);
148
+ assertGitCheckoutGeneration(opts.liveRepo, opts.expectedOldHead, "rollback verification");
149
+ published = false;
150
+ discardRollback();
151
+ };
152
+ return {
153
+ publish() {
154
+ if (published)
155
+ throw new ConfigError(`Writable Git update at ${opts.liveRepo} was already published.`);
156
+ assertGitCheckoutGeneration(opts.liveRepo, opts.expectedOldHead, "pre-publish fence");
157
+ assertGitCheckoutGeneration(opts.stagedRepo, opts.auditedTargetHead, "staged audit fence");
158
+ const ancestor = runGit([
159
+ "-C",
160
+ opts.stagedRepo,
161
+ "merge-base",
162
+ "--is-ancestor",
163
+ opts.expectedOldHead,
164
+ opts.auditedTargetHead,
165
+ ]);
166
+ if (ancestor.status !== 0) {
167
+ throw new ConfigError(`Audited Git target ${opts.auditedTargetHead} is not a fast-forward of live HEAD ${opts.expectedOldHead}; refusing writable update.`);
168
+ }
169
+ assertNoGitlinks(opts.stagedRepo, opts.auditedTargetHead);
170
+ gitOutput(opts.liveRepo, ["fetch", "--no-tags", opts.stagedRepo, opts.auditedTargetHead], `Cannot import audited Git target ${opts.auditedTargetHead} into ${opts.liveRepo}`);
171
+ // A non-cooperating local Git command may have committed while fetch ran.
172
+ assertGitCheckoutGeneration(opts.liveRepo, opts.expectedOldHead, "post-fetch fence");
173
+ assertNoIgnoredPathOverwrite(opts.liveRepo, opts.auditedTargetHead);
174
+ rollbackParent = createStagingParent(path.dirname(opts.liveRepo));
175
+ rollbackWorktree = path.join(rollbackParent, "worktree");
176
+ try {
177
+ copyWorktree(opts.liveRepo, rollbackWorktree);
178
+ }
179
+ catch (error) {
180
+ discardRollback();
181
+ throw error;
182
+ }
183
+ try {
184
+ gitOutput(opts.liveRepo, ["merge", "--ff-only", "--no-overwrite-ignore", opts.auditedTargetHead], `Cannot fast-forward writable Git checkout ${opts.liveRepo}`);
185
+ published = true;
186
+ assertGitCheckoutGeneration(opts.liveRepo, opts.auditedTargetHead, "post-materialization fence");
187
+ }
188
+ catch (error) {
189
+ try {
190
+ restore();
191
+ }
192
+ catch (restoreError) {
193
+ throw new ConfigError(`Writable Git publication failed and its worktree could not be restored: ${restoreError instanceof Error ? restoreError.message : String(restoreError)}`);
194
+ }
195
+ throw error;
196
+ }
197
+ },
198
+ rollback() {
199
+ if (!published)
200
+ return;
201
+ restore();
202
+ },
203
+ commit() {
204
+ published = false;
205
+ discardRollback();
206
+ },
207
+ };
208
+ }
209
+ export function createStagingParent(parent) {
210
+ fs.mkdirSync(parent, { recursive: true, mode: 0o700 });
211
+ return fs.mkdtempSync(path.join(parent, ".akm-update-stage-"));
212
+ }
213
+ export function cleanupStagingParent(stagingParent) {
214
+ try {
215
+ fs.rmSync(stagingParent, { recursive: true, force: true });
216
+ }
217
+ catch (error) {
218
+ warn(`[akm bundle update] could not remove staging directory ${stagingParent}: ${error instanceof Error ? error.message : String(error)}`);
219
+ }
220
+ }
@@ -57,11 +57,11 @@ const tasksAddCommand = defineJsonCommand({
57
57
  workflow: { type: "string", description: "Workflow ref to invoke (e.g. workflows/my-flow)" },
58
58
  prompt: {
59
59
  type: "string",
60
- description: "Prompt for the configured agent harness inline text, an asset ref like agents/foo, or ./path.md",
60
+ description: "Inline text prompt for the configured agent harness (asset refs and file paths are rejected)",
61
61
  },
62
62
  command: {
63
63
  type: "string",
64
- description: 'Shell command to run on the schedule (no AI agent), e.g. "akm improve --strategy frequent". Split on whitespace; quote the whole flag value.',
64
+ description: 'Exact shell string to run on the schedule (no AI agent), e.g. "akm improve --strategy frequent".',
65
65
  },
66
66
  engine: { type: "string", description: "Engine to use for prompt targets (default: defaults.engine)" },
67
67
  model: { type: "string", description: "Model override for prompt targets" },
@@ -156,7 +156,7 @@ const tasksHistoryCommand = defineJsonCommand({
156
156
  const tasksSyncCommand = defineJsonCommand({
157
157
  meta: {
158
158
  name: "sync",
159
- description: "Reconcile the on-disk task files of a bundle with the OS scheduler",
159
+ description: "Atomically preflight and reconcile a bundle's task/workflow schedules with the OS scheduler",
160
160
  },
161
161
  args: {
162
162
  ...bundleArg,