akm-cli 0.9.17-alpha.2 → 0.9.17-alpha.4

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 (343) hide show
  1. package/CHANGELOG.md +756 -0
  2. package/dist/akm +94 -196
  3. package/dist/cli/shared.js +6 -2
  4. package/dist/cli.js +22 -9
  5. package/dist/commands/agent/agent-dispatch.js +1 -1
  6. package/dist/commands/command/command-execution.js +24 -62
  7. package/dist/commands/feedback-cli.js +0 -1
  8. package/dist/commands/health/accept-rate.js +2 -2
  9. package/dist/commands/health/checks.js +30 -75
  10. package/dist/commands/health/config-skew.js +38 -0
  11. package/dist/commands/health/egress.js +54 -0
  12. package/dist/commands/health/html-report.js +0 -38
  13. package/dist/commands/health/improve-metrics.js +123 -562
  14. package/dist/commands/health/plugin-staleness.js +53 -3
  15. package/dist/commands/health/renderers.js +12 -4
  16. package/dist/commands/health/report-view-model.js +11 -106
  17. package/dist/commands/health/types-improve.js +4 -19
  18. package/dist/commands/health/windows.js +64 -73
  19. package/dist/commands/health.js +122 -143
  20. package/dist/commands/improve/consolidate/chunking.js +25 -100
  21. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  22. package/dist/commands/improve/consolidate.js +538 -1075
  23. package/dist/commands/improve/content-hash.js +16 -24
  24. package/dist/commands/improve/distill/content-repair.js +18 -100
  25. package/dist/commands/improve/distill-guards.js +20 -81
  26. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  27. package/dist/commands/improve/distill.js +608 -1075
  28. package/dist/commands/improve/eligibility.js +126 -400
  29. package/dist/commands/improve/execution.js +3 -5
  30. package/dist/commands/improve/extract.js +487 -1046
  31. package/dist/commands/improve/feedback-valence.js +0 -25
  32. package/dist/commands/improve/improve-cli.js +29 -166
  33. package/dist/commands/improve/improve-result-file.js +10 -66
  34. package/dist/commands/improve/improve-strategies.js +12 -7
  35. package/dist/commands/improve/improve-usage-report.js +18 -64
  36. package/dist/commands/improve/improve.js +443 -1063
  37. package/dist/commands/improve/ledger.js +114 -0
  38. package/dist/commands/improve/locks.js +2 -8
  39. package/dist/commands/improve/loop-stages.js +459 -1172
  40. package/dist/commands/improve/memory/derived-ref.js +12 -77
  41. package/dist/commands/improve/memory/memory-belief.js +14 -118
  42. package/dist/commands/improve/memory/memory-improve.js +4 -3
  43. package/dist/commands/improve/outcome-loop.js +28 -156
  44. package/dist/commands/improve/planner.js +5 -10
  45. package/dist/commands/improve/preparation.js +851 -2339
  46. package/dist/commands/improve/proactive-maintenance.js +34 -101
  47. package/dist/commands/improve/reflect-noise.js +104 -280
  48. package/dist/commands/improve/reflect.js +621 -1367
  49. package/dist/commands/improve/salience.js +46 -232
  50. package/dist/commands/improve/session-asset.js +19 -100
  51. package/dist/commands/improve/stage.js +323 -0
  52. package/dist/commands/proposal/drain.js +251 -644
  53. package/dist/commands/proposal/proposal-cli.js +3 -18
  54. package/dist/commands/proposal/proposal-types.js +20 -41
  55. package/dist/commands/proposal/proposal.js +1 -2
  56. package/dist/commands/proposal/propose.js +134 -160
  57. package/dist/commands/proposal/repository.js +502 -1487
  58. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  59. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  60. package/dist/commands/proposal/validators/proposals.js +13 -89
  61. package/dist/commands/read/curate.js +63 -413
  62. package/dist/commands/read/search-cli.js +16 -33
  63. package/dist/commands/read/search.js +17 -23
  64. package/dist/commands/read/show.js +2 -13
  65. package/dist/commands/sources/bundle-cli.js +25 -2
  66. package/dist/commands/sources/bundle-config-ops.js +7 -0
  67. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  68. package/dist/commands/sources/info.js +2 -11
  69. package/dist/commands/sources/installed-stashes.js +197 -746
  70. package/dist/commands/sources/schema-repair.js +98 -129
  71. package/dist/commands/sources/source-add.js +62 -12
  72. package/dist/commands/sources/stash-cli.js +1 -1
  73. package/dist/commands/tasks/explain.js +10 -13
  74. package/dist/commands/tasks/tasks-cli.js +9 -8
  75. package/dist/commands/tasks/tasks.js +326 -930
  76. package/dist/commands/tasks/validate.js +42 -21
  77. package/dist/commands/workflow/plan.js +22 -29
  78. package/dist/commands/workflow-cli.js +4 -4
  79. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  80. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  81. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  82. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  83. package/dist/core/adapter/execution-source.js +17 -29
  84. package/dist/core/asset/resolve-ref.js +1 -1
  85. package/dist/core/bundle-id.js +42 -5
  86. package/dist/core/bundle-rename.js +291 -0
  87. package/dist/core/config/config-io.js +1 -2
  88. package/dist/core/config/config-schema.js +1 -33
  89. package/dist/core/config/config-walker.js +1 -1
  90. package/dist/core/config/config.js +163 -68
  91. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  92. package/dist/core/config/schema/embedding.js +20 -5
  93. package/dist/core/config/schema/engines.js +5 -0
  94. package/dist/core/config/schema/execution.js +1 -1
  95. package/dist/core/config/schema/experimental.js +1 -1
  96. package/dist/core/config/schema/improve-processes.js +21 -95
  97. package/dist/core/config/schema/improve.js +4 -42
  98. package/dist/core/config/schema/scheduler.js +12 -12
  99. package/dist/core/config/schema/search.js +6 -22
  100. package/dist/core/env-secret-ref.js +0 -1
  101. package/dist/core/errors.js +8 -9
  102. package/dist/core/file-lock.js +76 -173
  103. package/dist/core/logs-db.js +2 -2
  104. package/dist/core/paths.js +0 -27
  105. package/dist/core/redaction.js +109 -2
  106. package/dist/core/run-lock.js +2 -5
  107. package/dist/core/spawn-env.js +1 -1
  108. package/dist/core/state/migrations.js +108 -61
  109. package/dist/core/state-db-scope.js +2 -4
  110. package/dist/core/state-db.js +126 -692
  111. package/dist/core/type-presentation.js +1 -9
  112. package/dist/core/write-source.js +293 -1012
  113. package/dist/execution/input-contract.js +1 -1
  114. package/dist/execution/resolved-request.js +135 -689
  115. package/dist/execution/source.js +63 -257
  116. package/dist/execution/target-ref.js +1 -1
  117. package/dist/indexer/bundle-identity-guard.js +2 -2
  118. package/dist/indexer/db/graph-db.js +106 -46
  119. package/dist/indexer/ensure-index.js +44 -85
  120. package/dist/indexer/graph/graph-extraction.js +340 -562
  121. package/dist/indexer/graph/graph-related.js +130 -0
  122. package/dist/indexer/index-rebuild-lock.js +3 -11
  123. package/dist/indexer/index-writer-lock.js +8 -17
  124. package/dist/indexer/index-written-assets.js +139 -151
  125. package/dist/indexer/indexer.js +524 -846
  126. package/dist/indexer/materialize-embeddings.js +60 -397
  127. package/dist/indexer/passes/memory-inference.js +81 -90
  128. package/dist/indexer/passes/metadata.js +132 -200
  129. package/dist/indexer/read-preflight.js +0 -7
  130. package/dist/indexer/scan/doc-to-entry.js +1 -3
  131. package/dist/indexer/scan/drain-dir.js +1 -1
  132. package/dist/indexer/search/db-search.js +181 -590
  133. package/dist/indexer/search/fts-query.js +30 -41
  134. package/dist/indexer/search/ranking.js +28 -154
  135. package/dist/indexer/search/search-attribution.js +12 -32
  136. package/dist/indexer/search/search-fields.js +11 -15
  137. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  138. package/dist/indexer/search/search-source.js +1 -4
  139. package/dist/indexer/usage/usage-events.js +2 -7
  140. package/dist/integrations/agent/engine-fallback.js +23 -40
  141. package/dist/integrations/agent/engine-resolution.js +93 -183
  142. package/dist/integrations/agent/execution.js +507 -0
  143. package/dist/integrations/agent/model-map.js +28 -156
  144. package/dist/integrations/agent/request-lowering.js +66 -141
  145. package/dist/integrations/agent/runner-dispatch.js +143 -321
  146. package/dist/integrations/agent/runner.js +54 -14
  147. package/dist/integrations/lockfile.js +53 -101
  148. package/dist/llm/embedders/deterministic.js +2 -3
  149. package/dist/llm/embedders/profile.js +71 -0
  150. package/dist/llm/embedders/remote.js +10 -15
  151. package/dist/llm/graph-extract.js +3 -12
  152. package/dist/llm/index-passes.js +3 -5
  153. package/dist/llm/memory-infer.js +1 -2
  154. package/dist/llm/metadata-enhance.js +1 -2
  155. package/dist/llm/structured-call.js +5 -24
  156. package/dist/output/generic-render.js +23 -11
  157. package/dist/output/html-render.js +13 -10
  158. package/dist/output/render-registry.js +3 -32
  159. package/dist/output/shapes/helpers.js +2 -34
  160. package/dist/output/shapes/passthrough.js +1 -9
  161. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  162. package/dist/output/text/command-format.js +60 -23
  163. package/dist/output/text/helpers.js +1 -1
  164. package/dist/output/text/migrate.js +5 -14
  165. package/dist/output/text/proposal-format.js +1 -2
  166. package/dist/output/text/workflow-format.js +0 -32
  167. package/dist/output/text.js +2 -0
  168. package/dist/registry/factory.js +4 -19
  169. package/dist/registry/network.js +66 -220
  170. package/dist/registry/providers/index.js +0 -2
  171. package/dist/registry/providers/skills-sh.js +3 -14
  172. package/dist/registry/providers/static-index.js +24 -26
  173. package/dist/registry/resolve.js +55 -131
  174. package/dist/scripts/akm-migrate-node.js +43937 -93313
  175. package/dist/scripts/akm-migrate.js +43697 -93071
  176. package/dist/setup/registry-stash-loader.js +4 -13
  177. package/dist/setup/semantic-assets.js +3 -44
  178. package/dist/setup/setup.js +1 -1
  179. package/dist/setup/steps/tasks.js +25 -15
  180. package/dist/sources/provider-factory.js +17 -18
  181. package/dist/sources/providers/filesystem.js +2 -3
  182. package/dist/sources/providers/git-install.js +7 -1
  183. package/dist/sources/providers/git-provider.js +0 -3
  184. package/dist/sources/providers/git-stash.js +0 -17
  185. package/dist/sources/providers/npm.js +2 -4
  186. package/dist/sources/providers/provider-utils.js +5 -10
  187. package/dist/sources/providers/website.js +0 -2
  188. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  189. package/dist/sources/website-url.js +2 -2
  190. package/dist/storage/database.js +9 -35
  191. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  192. package/dist/storage/repositories/index-connection.js +34 -70
  193. package/dist/storage/repositories/index-entries-repository.js +69 -111
  194. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  195. package/dist/storage/repositories/index-entry-schema.js +83 -269
  196. package/dist/storage/repositories/index-fts-repository.js +86 -256
  197. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  198. package/dist/storage/repositories/index-meta-repository.js +6 -4
  199. package/dist/storage/repositories/index-schema.js +192 -220
  200. package/dist/storage/repositories/index-utility-repository.js +8 -29
  201. package/dist/storage/repositories/index-vec-repository.js +133 -414
  202. package/dist/storage/repositories/outcome-repository.js +2 -1
  203. package/dist/storage/repositories/proposals-repository.js +35 -0
  204. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  205. package/dist/storage/repositories/task-history-repository.js +26 -4
  206. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  207. package/dist/storage/sqlite-migrations.js +136 -0
  208. package/dist/storage/sqlite-pragmas.js +11 -9
  209. package/dist/storage/sqlite-transaction.js +170 -0
  210. package/dist/storage/state-db-integrity.js +34 -27
  211. package/dist/tasks/activation-config.js +134 -62
  212. package/dist/tasks/backends/cron.js +129 -277
  213. package/dist/tasks/backends/exec-utils.js +2 -5
  214. package/dist/tasks/backends/launchd.js +125 -745
  215. package/dist/tasks/backends/schtasks.js +101 -620
  216. package/dist/tasks/prepare/prepare-support.js +5 -15
  217. package/dist/tasks/prepare/prepare.js +0 -2
  218. package/dist/tasks/resolve-akm-bin.js +20 -79
  219. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  220. package/dist/tasks/scheduler-binding.js +18 -238
  221. package/dist/tasks/scheduler-invocation.js +52 -52
  222. package/dist/tasks/scheduler-lock.js +53 -0
  223. package/dist/tasks/scheduler-sync.js +363 -679
  224. package/dist/tasks/source/parse-task-source.js +160 -10
  225. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  226. package/dist/tasks/source/task-to-v4.js +2 -2
  227. package/dist/workflows/authoring/authoring.js +3 -12
  228. package/dist/workflows/compile.js +211 -0
  229. package/dist/workflows/concurrency-policy.js +13 -74
  230. package/dist/workflows/exec/child-invocation.js +3 -17
  231. package/dist/workflows/exec/child-workflow.js +32 -141
  232. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  233. package/dist/workflows/exec/environment.js +98 -0
  234. package/dist/workflows/exec/exec-unit.js +33 -140
  235. package/dist/workflows/exec/frozen-judge.js +7 -59
  236. package/dist/workflows/exec/native-executor.js +82 -341
  237. package/dist/workflows/exec/param-secrets.js +29 -47
  238. package/dist/workflows/exec/run-workflow.js +154 -387
  239. package/dist/workflows/exec/scheduler.js +9 -36
  240. package/dist/workflows/exec/step-work.js +127 -430
  241. package/dist/workflows/exec/unit-dispatch.js +11 -63
  242. package/dist/workflows/exec/unit-writer.js +8 -52
  243. package/dist/workflows/exec/worktree.js +39 -273
  244. package/dist/workflows/freeze/child-output-references.js +4 -15
  245. package/dist/workflows/freeze/environment.js +99 -92
  246. package/dist/workflows/freeze/freeze.js +172 -0
  247. package/dist/workflows/freeze/step-values.js +19 -21
  248. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  249. package/dist/workflows/freeze/targets/command.js +10 -33
  250. package/dist/workflows/freeze/targets/script.js +5 -12
  251. package/dist/workflows/freeze/targets/shell.js +3 -6
  252. package/dist/workflows/freeze/targets/task.js +25 -80
  253. package/dist/workflows/freeze/task-bindings.js +20 -67
  254. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  255. package/dist/workflows/ir/params.js +6 -51
  256. package/dist/workflows/ir/plan-hash.js +2 -34
  257. package/dist/workflows/parser.js +140 -43
  258. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  259. package/dist/workflows/renderer.js +36 -69
  260. package/dist/workflows/resource-limits.js +12 -120
  261. package/dist/workflows/runtime/agent-identity.js +8 -40
  262. package/dist/workflows/runtime/run-outputs.js +3 -6
  263. package/dist/workflows/runtime/run-plan.js +316 -0
  264. package/dist/workflows/runtime/runs.js +48 -200
  265. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  266. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  267. package/dist/workflows/validate-summary.js +2 -7
  268. package/docs/integration/bundling-akm.md +49 -42
  269. package/docs/migration/README.md +1 -0
  270. package/docs/migration/release-notes/0.9.17.md +41 -0
  271. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  272. package/docs/reference/cli.md +182 -125
  273. package/docs/reference/configuration.md +49 -56
  274. package/docs/reference/data-and-telemetry.md +19 -20
  275. package/docs/reference/tasks.md +86 -38
  276. package/docs/reference/workflow-schema.md +14 -18
  277. package/docs/reference/workflows.md +6 -9
  278. package/package.json +1 -1
  279. package/schemas/akm-config.json +87 -406
  280. package/dist/commands/health/advisories.js +0 -150
  281. package/dist/commands/health/metrics.js +0 -329
  282. package/dist/commands/health/surfaces.js +0 -102
  283. package/dist/commands/improve/anti-collapse.js +0 -83
  284. package/dist/commands/improve/collapse-detector.js +0 -432
  285. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  286. package/dist/commands/improve/consolidate/merge.js +0 -146
  287. package/dist/commands/improve/distill/promote-memory.js +0 -329
  288. package/dist/commands/improve/distill/quality-gate.js +0 -500
  289. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  290. package/dist/commands/improve/proposal-envelope.js +0 -31
  291. package/dist/commands/improve/run-context.js +0 -123
  292. package/dist/commands/improve/shared.js +0 -21
  293. package/dist/commands/improve/source-identity.js +0 -28
  294. package/dist/commands/improve/triage.js +0 -96
  295. package/dist/commands/proposal/drain-policies.js +0 -151
  296. package/dist/commands/sources/update-transaction.js +0 -220
  297. package/dist/core/action-contributors.js +0 -28
  298. package/dist/core/config/config-version-shim.js +0 -101
  299. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  300. package/dist/core/fs-txn.js +0 -405
  301. package/dist/core/lexical-score.js +0 -25
  302. package/dist/core/maintenance-barrier.js +0 -167
  303. package/dist/execution/executable-identity.js +0 -105
  304. package/dist/execution/guarded-source.js +0 -427
  305. package/dist/indexer/graph/graph-boost.js +0 -427
  306. package/dist/indexer/graph/graph-dedup.js +0 -95
  307. package/dist/indexer/search/name-match.js +0 -35
  308. package/dist/indexer/search/ranking-contributors.js +0 -515
  309. package/dist/indexer/walk/project-context.js +0 -192
  310. package/dist/integrations/agent/execution-cascade.js +0 -566
  311. package/dist/integrations/agent/execution-definitions.js +0 -202
  312. package/dist/integrations/agent/execution-lowering.js +0 -841
  313. package/dist/integrations/agent/execution-preparation.js +0 -98
  314. package/dist/integrations/agent/inline-execution.js +0 -74
  315. package/dist/registry/create-provider-registry.js +0 -29
  316. package/dist/registry/pinned-request-helper.js +0 -247
  317. package/dist/registry/pinned-transport.js +0 -717
  318. package/dist/sources/providers/index.js +0 -14
  319. package/dist/storage/engines/sqlite-migrations.js +0 -271
  320. package/dist/storage/repositories/canaries-repository.js +0 -107
  321. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  322. package/dist/storage/repositories/registry-cache.js +0 -113
  323. package/dist/tasks/scheduler-sync-preview.js +0 -52
  324. package/dist/workflows/freeze/resolve-steps.js +0 -86
  325. package/dist/workflows/freeze/source-freeze.js +0 -64
  326. package/dist/workflows/ir/compile.js +0 -321
  327. package/dist/workflows/ir/environment-v4.js +0 -330
  328. package/dist/workflows/ir/freeze-v4.js +0 -153
  329. package/dist/workflows/ir/schema-v4.js +0 -745
  330. package/dist/workflows/ir/schema.js +0 -354
  331. package/dist/workflows/program/schema.js +0 -78
  332. package/dist/workflows/runtime/checkin.js +0 -57
  333. package/dist/workflows/runtime/plan-classifier.js +0 -196
  334. package/dist/workflows/runtime/unit-checkin.js +0 -45
  335. package/dist/workflows/runtime/unit-phases.js +0 -20
  336. package/dist/workflows/schema.js +0 -4
  337. package/dist/workflows/source-ir/compile.js +0 -200
  338. package/dist/workflows/source-ir/program.js +0 -50
  339. package/dist/workflows/source-ir/result.js +0 -26
  340. package/dist/workflows/source-ir/schema.js +0 -786
  341. package/dist/workflows/source-ir/triggers.js +0 -79
  342. package/dist/workflows/source-ir/uses.js +0 -40
  343. package/dist/workflows/validator.js +0 -60
@@ -1,88 +1,160 @@
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
- import { bundleRefToString, parseBundleRef } from "../core/asset/asset-ref.js";
5
- import { deriveBundleId } from "../core/bundle-id.js";
6
- import { resolveStashDir } from "../core/common.js";
7
- import { mutateConfig } from "../core/config/config.js";
8
- import { bundleSourceId, filesystemBundleSourceId, isBundleEnabled } from "../core/config/config-sources.js";
4
+ /**
5
+ * The host's scheduling choice.
6
+ *
7
+ * `scheduler.enabled` in config.json is the list of fully-qualified refs
8
+ * (`bundle//tasks/x`, `bundle//workflows/y`) this host installs in its native
9
+ * scheduler. Installing a bundle never schedules anything: a task only gets a
10
+ * native row once its ref is on this list (`akm task enable`, `akm setup`),
11
+ * and only bundles that are active on this host are eligible.
12
+ *
13
+ * A config that predates the list (`scheduler.enabled` absent) is read as
14
+ * "keep what is installed": `akm task sync` takes the akm-written rows already
15
+ * in the native scheduler as the host's choice and writes the list once. A
16
+ * 0.9.17-alpha `{kind, ref, sourceId}` entry is read as its `ref`.
17
+ */
18
+ import fs from "node:fs";
19
+ import path from "node:path";
20
+ import { assetPathForName, stashDirFor } from "../core/asset/asset-placement.js";
21
+ import { bundleRefToString, makeBundleRef, parseBundleRef } from "../core/asset/asset-ref.js";
22
+ import { typeNameFromConceptId } from "../core/asset/resolve-ref.js";
23
+ import { mutateConfig, schedulerSourceIdFor } from "../core/config/config.js";
24
+ import { bundleComponentConfig, bundleContentRoots, isBundleEnabled } from "../core/config/config-sources.js";
9
25
  import { UsageError } from "../core/errors.js";
10
- export function canonicalSchedulerActivationRef(ref) {
26
+ import { warnOnce } from "../core/warn.js";
27
+ export function canonicalSchedulerRef(ref) {
11
28
  const parsed = parseBundleRef(ref);
12
29
  if (!parsed.bundle || parsed.fragment !== undefined || bundleRefToString(parsed) !== ref) {
13
- throw new UsageError(`Scheduler activation requires a canonical fully-qualified ref, got ${JSON.stringify(ref)}.`, "INVALID_FLAG_VALUE");
30
+ throw new UsageError(`Scheduling requires a canonical fully-qualified ref, got ${JSON.stringify(ref)}.`, "INVALID_FLAG_VALUE");
14
31
  }
15
32
  return ref;
16
33
  }
17
- export function schedulerActivations(config) {
18
- return Object.freeze((config.scheduler?.enabled ?? []).map((activation) => Object.freeze({
19
- kind: activation.kind,
20
- ref: canonicalSchedulerActivationRef(activation.ref),
21
- sourceId: activation.sourceId,
22
- })));
23
- }
24
- export function isSchedulerRefEnabled(config, kind, ref) {
25
- const canonicalRef = canonicalSchedulerActivationRef(ref);
26
- const bundle = parseBundleRef(canonicalRef).bundle;
27
- const currentSourceId = schedulerActivationSourceId(config, bundle);
28
- if (!currentSourceId)
29
- return false;
30
- return schedulerActivations(config).some((activation) => activation.kind === kind && activation.ref === canonicalRef && activation.sourceId === currentSourceId);
34
+ /**
35
+ * Refs this host schedules, or `undefined` when the host has never chosen
36
+ * (the config predates the list). An entry that is not a canonical ref is
37
+ * skipped with a warning, never fatal.
38
+ */
39
+ export function schedulerEnabledRefs(config) {
40
+ const enabled = config.scheduler?.enabled;
41
+ if (enabled === undefined)
42
+ return undefined;
43
+ const refs = new Set();
44
+ for (const ref of enabled) {
45
+ try {
46
+ refs.add(canonicalSchedulerRef(ref));
47
+ }
48
+ catch {
49
+ warnOnce(`scheduler:enabled:${ref}`, `Ignoring scheduler.enabled entry ${JSON.stringify(ref)}: not a canonical ref.`);
50
+ }
51
+ }
52
+ return Object.freeze([...refs]);
31
53
  }
32
- /** Grants that still name the same active source installation they approved. */
33
- export function activeSchedulerActivations(config) {
34
- return schedulerActivations(config).filter((activation) => {
35
- const bundle = parseBundleRef(activation.ref).bundle;
36
- return activation.sourceId === schedulerActivationSourceId(config, bundle);
37
- });
54
+ export function isSchedulerRefEnabled(config, ref) {
55
+ return (schedulerEnabledRefs(config) ?? []).includes(canonicalSchedulerRef(ref));
38
56
  }
39
- /** Pure lifecycle helper used when a bundle is removed or replaced. */
40
57
  export function revokeSchedulerActivationsForBundle(config, bundleId) {
41
- const enabled = schedulerActivations(config).filter((activation) => parseBundleRef(activation.ref).bundle !== bundleId);
42
- if (enabled.length === (config.scheduler?.enabled ?? []).length)
58
+ const current = config.scheduler?.enabled;
59
+ if (current === undefined)
60
+ return config;
61
+ const enabled = current.filter((ref) => bundleOf(ref) !== bundleId);
62
+ if (enabled.length === current.length)
43
63
  return config;
44
64
  return { ...config, scheduler: { ...config.scheduler, enabled } };
45
65
  }
46
- export function setSchedulerRefEnabled(kind, ref, enabled) {
47
- let canonicalRef = ref;
66
+ /** Whether refs from this bundle may be scheduled here: configured and enabled, or the implicit `AKM_BUNDLE_DIR` stash. */
67
+ export function isSchedulerBundleActive(config, bundleId) {
68
+ return schedulerSourceIdFor(config, bundleId) !== undefined;
69
+ }
70
+ /**
71
+ * Add or remove one ref on this host's list. Callers must have made the host's
72
+ * choice explicit first (see `initializeSchedulerChoice` in
73
+ * `commands/tasks/tasks.ts`): on a config without the list this writes just
74
+ * the one ref, which is the whole choice from then on.
75
+ */
76
+ export function setSchedulerRefEnabled(ref, enabled) {
77
+ const canonicalRef = canonicalSchedulerRef(ref);
48
78
  const result = mutateConfig((current) => {
49
- canonicalRef = canonicalSchedulerActivationRef(ref);
50
- const existing = schedulerActivations(current);
51
- const bundle = parseBundleRef(canonicalRef).bundle;
52
- const sourceId = enabled ? schedulerActivationSourceId(current, bundle) : undefined;
53
- if (enabled && !sourceId) {
54
- throw new UsageError(`Cannot enable scheduled execution from inactive or unconfigured bundle ${JSON.stringify(bundle)}.`, "INVALID_FLAG_VALUE");
79
+ const existing = current.scheduler?.enabled ?? [];
80
+ if (enabled && !isSchedulerBundleActive(current, bundleOf(canonicalRef) ?? "")) {
81
+ throw new UsageError(`Cannot enable scheduled execution from inactive or unconfigured bundle ${JSON.stringify(bundleOf(canonicalRef))}.`, "INVALID_FLAG_VALUE");
55
82
  }
56
- const present = existing.some((activation) => activation.kind === kind && activation.ref === canonicalRef && (!enabled || activation.sourceId === sourceId));
57
- if (present === enabled)
83
+ if (current.scheduler?.enabled !== undefined && existing.includes(canonicalRef) === enabled)
58
84
  return current;
59
- const next = enabled
60
- ? [
61
- ...existing.filter((activation) => activation.kind !== kind || activation.ref !== canonicalRef),
62
- { kind, ref: canonicalRef, sourceId: sourceId },
63
- ]
64
- : existing.filter((activation) => activation.kind !== kind || activation.ref !== canonicalRef);
65
- next.sort((left, right) => left.ref.localeCompare(right.ref) || left.kind.localeCompare(right.kind));
66
- return {
67
- ...current,
68
- scheduler: {
69
- ...current.scheduler,
70
- enabled: next,
71
- },
72
- };
85
+ const next = existing.filter((entry) => entry !== canonicalRef);
86
+ if (enabled)
87
+ next.push(canonicalRef);
88
+ next.sort((left, right) => left.localeCompare(right));
89
+ return { ...current, scheduler: { ...current.scheduler, enabled: next } };
73
90
  });
74
91
  return { config: result.config, changed: result.written, ref: canonicalRef };
75
92
  }
76
- /** Current active source identity for a configured or environment-only bundle. */
77
- export function schedulerActivationSourceId(config, bundleId) {
78
- if (isBundleEnabled(config, bundleId))
79
- return bundleSourceId(config, bundleId);
80
- if (config.bundles?.[bundleId] !== undefined || !process.env.AKM_BUNDLE_DIR?.trim())
93
+ /**
94
+ * The refs behind the akm-written rows currently installed in the native
95
+ * scheduler: what this host was running before it had a `scheduler.enabled`
96
+ * list. Rows the backend proves disabled, rows for bundles that are not
97
+ * active here, and rows whose task file is gone are left out.
98
+ */
99
+ export function enabledRefsFromInstalled(installed, config) {
100
+ const refs = new Set();
101
+ for (const entry of installed) {
102
+ const ref = installedEntryRef(entry, config);
103
+ if (ref !== undefined)
104
+ refs.add(ref);
105
+ }
106
+ return Object.freeze([...refs].sort((left, right) => left.localeCompare(right)));
107
+ }
108
+ function installedEntryRef(entry, config) {
109
+ if (entry.enabled === false || !entry.invocation)
110
+ return undefined;
111
+ const invocation = entry.invocation;
112
+ try {
113
+ if (invocation[0] === "workflow" && invocation[1] === "run" && invocation.length === 3 && invocation[2]) {
114
+ const ref = canonicalSchedulerRef(invocation[2]);
115
+ const parsed = parseBundleRef(ref);
116
+ if (!parsed.bundle || !isBundleEnabled(config, parsed.bundle))
117
+ return undefined;
118
+ return hasBackingFile(config, parsed.bundle, parsed.conceptId) ? ref : undefined;
119
+ }
120
+ if (invocation[0] !== "task" || invocation[1] !== "run" || !invocation[2])
121
+ return undefined;
122
+ const bundleIndex = invocation.indexOf("--bundle", 3);
123
+ const bundle = bundleIndex === -1 ? config.defaultBundle : invocation[bundleIndex + 1];
124
+ if (!bundle || !isBundleEnabled(config, bundle))
125
+ return undefined;
126
+ const bundleConfig = config.bundles?.[bundle];
127
+ const adapter = bundleConfig ? (bundleComponentConfig(bundleConfig)?.adapter ?? "akm") : "akm";
128
+ const conceptId = adapter === "akm-task" ? invocation[2] : `tasks/${invocation[2]}`;
129
+ if (!hasBackingFile(config, bundle, conceptId))
130
+ return undefined;
131
+ return canonicalSchedulerRef(makeBundleRef(bundle, conceptId));
132
+ }
133
+ catch {
81
134
  return undefined;
135
+ }
136
+ }
137
+ function hasBackingFile(config, bundle, conceptId) {
138
+ const parts = typeNameFromConceptId(conceptId);
139
+ if (!parts)
140
+ return true;
141
+ const typeDir = stashDirFor(parts.type);
142
+ if (!typeDir)
143
+ return true;
144
+ const contentRoot = bundleContentRoots(config).find((entry) => entry.id === bundle)?.contentRoot;
145
+ if (!contentRoot)
146
+ return true;
147
+ try {
148
+ const target = assetPathForName(parts.type, path.join(contentRoot, typeDir), parts.name);
149
+ return fs.existsSync(target) && fs.statSync(target).isFile();
150
+ }
151
+ catch {
152
+ return false;
153
+ }
154
+ }
155
+ function bundleOf(ref) {
82
156
  try {
83
- const root = resolveStashDir();
84
- const implicitId = deriveBundleId(undefined, root, new Set(Object.keys(config.bundles ?? {})));
85
- return implicitId === bundleId ? filesystemBundleSourceId(root) : undefined;
157
+ return parseBundleRef(ref).bundle;
86
158
  }
87
159
  catch {
88
160
  return undefined;