akm-cli 0.9.17-alpha.3 → 0.9.17-alpha.5

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 (346) hide show
  1. package/CHANGELOG.md +760 -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/lint/base-linter.js +19 -5
  53. package/dist/commands/proposal/drain.js +251 -644
  54. package/dist/commands/proposal/proposal-cli.js +3 -18
  55. package/dist/commands/proposal/proposal-types.js +20 -41
  56. package/dist/commands/proposal/proposal.js +1 -2
  57. package/dist/commands/proposal/propose.js +134 -160
  58. package/dist/commands/proposal/repository.js +502 -1487
  59. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  60. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  61. package/dist/commands/proposal/validators/proposals.js +13 -89
  62. package/dist/commands/read/curate.js +63 -413
  63. package/dist/commands/read/search-cli.js +16 -33
  64. package/dist/commands/read/search.js +17 -23
  65. package/dist/commands/read/show.js +2 -13
  66. package/dist/commands/sources/bundle-cli.js +25 -2
  67. package/dist/commands/sources/bundle-config-ops.js +4 -0
  68. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  69. package/dist/commands/sources/info.js +2 -11
  70. package/dist/commands/sources/installed-stashes.js +197 -746
  71. package/dist/commands/sources/schema-repair.js +98 -129
  72. package/dist/commands/sources/source-add.js +62 -12
  73. package/dist/commands/sources/source-manage.js +9 -2
  74. package/dist/commands/sources/stash-cli.js +1 -1
  75. package/dist/commands/tasks/explain.js +10 -13
  76. package/dist/commands/tasks/tasks-cli.js +9 -8
  77. package/dist/commands/tasks/tasks.js +326 -930
  78. package/dist/commands/tasks/validate.js +42 -21
  79. package/dist/commands/workflow/plan.js +22 -29
  80. package/dist/commands/workflow-cli.js +4 -4
  81. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  82. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  83. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  84. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  85. package/dist/core/adapter/execution-source.js +17 -29
  86. package/dist/core/asset/asset-placement.js +4 -13
  87. package/dist/core/asset/resolve-ref.js +1 -1
  88. package/dist/core/bundle-id.js +42 -5
  89. package/dist/core/bundle-rename.js +291 -0
  90. package/dist/core/config/config-io.js +1 -2
  91. package/dist/core/config/config-schema.js +1 -33
  92. package/dist/core/config/config-walker.js +1 -1
  93. package/dist/core/config/config.js +163 -68
  94. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  95. package/dist/core/config/schema/embedding.js +20 -5
  96. package/dist/core/config/schema/engines.js +5 -0
  97. package/dist/core/config/schema/execution.js +1 -1
  98. package/dist/core/config/schema/experimental.js +1 -1
  99. package/dist/core/config/schema/improve-processes.js +21 -95
  100. package/dist/core/config/schema/improve.js +4 -42
  101. package/dist/core/config/schema/scheduler.js +12 -12
  102. package/dist/core/config/schema/search.js +6 -22
  103. package/dist/core/env-secret-ref.js +0 -1
  104. package/dist/core/errors.js +8 -9
  105. package/dist/core/file-lock.js +76 -173
  106. package/dist/core/logs-db.js +2 -2
  107. package/dist/core/paths.js +0 -27
  108. package/dist/core/redaction.js +109 -2
  109. package/dist/core/run-lock.js +2 -5
  110. package/dist/core/spawn-env.js +1 -1
  111. package/dist/core/state/migrations.js +108 -61
  112. package/dist/core/state-db-scope.js +2 -4
  113. package/dist/core/state-db.js +126 -692
  114. package/dist/core/type-presentation.js +1 -9
  115. package/dist/core/write-source.js +293 -1012
  116. package/dist/execution/input-contract.js +1 -1
  117. package/dist/execution/resolved-request.js +135 -689
  118. package/dist/execution/source.js +63 -257
  119. package/dist/execution/target-ref.js +1 -1
  120. package/dist/indexer/bundle-identity-guard.js +2 -2
  121. package/dist/indexer/db/graph-db.js +106 -46
  122. package/dist/indexer/ensure-index.js +44 -85
  123. package/dist/indexer/graph/graph-extraction.js +340 -562
  124. package/dist/indexer/graph/graph-related.js +130 -0
  125. package/dist/indexer/index-rebuild-lock.js +3 -11
  126. package/dist/indexer/index-writer-lock.js +8 -17
  127. package/dist/indexer/index-written-assets.js +139 -151
  128. package/dist/indexer/indexer.js +524 -846
  129. package/dist/indexer/materialize-embeddings.js +60 -397
  130. package/dist/indexer/passes/memory-inference.js +81 -90
  131. package/dist/indexer/passes/metadata.js +132 -200
  132. package/dist/indexer/read-preflight.js +0 -7
  133. package/dist/indexer/scan/doc-to-entry.js +1 -3
  134. package/dist/indexer/scan/drain-dir.js +1 -1
  135. package/dist/indexer/search/db-search.js +181 -590
  136. package/dist/indexer/search/fts-query.js +30 -41
  137. package/dist/indexer/search/ranking.js +28 -154
  138. package/dist/indexer/search/search-attribution.js +12 -32
  139. package/dist/indexer/search/search-fields.js +11 -15
  140. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  141. package/dist/indexer/search/search-source.js +1 -4
  142. package/dist/indexer/usage/usage-events.js +2 -7
  143. package/dist/integrations/agent/engine-fallback.js +23 -40
  144. package/dist/integrations/agent/engine-resolution.js +93 -183
  145. package/dist/integrations/agent/execution.js +507 -0
  146. package/dist/integrations/agent/model-map.js +28 -156
  147. package/dist/integrations/agent/request-lowering.js +66 -141
  148. package/dist/integrations/agent/runner-dispatch.js +143 -321
  149. package/dist/integrations/agent/runner.js +54 -14
  150. package/dist/integrations/lockfile.js +53 -101
  151. package/dist/llm/embedders/deterministic.js +2 -3
  152. package/dist/llm/embedders/profile.js +71 -0
  153. package/dist/llm/embedders/remote.js +10 -15
  154. package/dist/llm/graph-extract.js +3 -12
  155. package/dist/llm/index-passes.js +3 -5
  156. package/dist/llm/memory-infer.js +1 -2
  157. package/dist/llm/metadata-enhance.js +1 -2
  158. package/dist/llm/structured-call.js +5 -24
  159. package/dist/output/generic-render.js +23 -11
  160. package/dist/output/html-render.js +13 -10
  161. package/dist/output/render-registry.js +3 -32
  162. package/dist/output/shapes/helpers.js +2 -34
  163. package/dist/output/shapes/passthrough.js +1 -9
  164. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  165. package/dist/output/text/command-format.js +60 -23
  166. package/dist/output/text/helpers.js +1 -1
  167. package/dist/output/text/migrate.js +5 -14
  168. package/dist/output/text/proposal-format.js +1 -2
  169. package/dist/output/text/workflow-format.js +0 -32
  170. package/dist/output/text.js +2 -0
  171. package/dist/registry/factory.js +4 -19
  172. package/dist/registry/network.js +66 -220
  173. package/dist/registry/providers/index.js +0 -2
  174. package/dist/registry/providers/skills-sh.js +3 -14
  175. package/dist/registry/providers/static-index.js +24 -26
  176. package/dist/registry/resolve.js +55 -131
  177. package/dist/scripts/akm-migrate-node.js +43940 -93320
  178. package/dist/scripts/akm-migrate.js +43700 -93078
  179. package/dist/setup/registry-stash-loader.js +4 -13
  180. package/dist/setup/semantic-assets.js +3 -44
  181. package/dist/setup/setup.js +1 -1
  182. package/dist/setup/steps/tasks.js +25 -15
  183. package/dist/sources/provider-factory.js +17 -18
  184. package/dist/sources/providers/filesystem.js +2 -3
  185. package/dist/sources/providers/git-install.js +7 -1
  186. package/dist/sources/providers/git-provider.js +0 -3
  187. package/dist/sources/providers/git-stash.js +0 -17
  188. package/dist/sources/providers/npm.js +2 -4
  189. package/dist/sources/providers/provider-utils.js +5 -10
  190. package/dist/sources/providers/website.js +0 -2
  191. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  192. package/dist/sources/website-url.js +2 -2
  193. package/dist/storage/database.js +9 -35
  194. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  195. package/dist/storage/repositories/index-connection.js +34 -70
  196. package/dist/storage/repositories/index-entries-repository.js +69 -111
  197. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  198. package/dist/storage/repositories/index-entry-schema.js +83 -269
  199. package/dist/storage/repositories/index-fts-repository.js +86 -256
  200. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  201. package/dist/storage/repositories/index-meta-repository.js +6 -4
  202. package/dist/storage/repositories/index-schema.js +192 -220
  203. package/dist/storage/repositories/index-utility-repository.js +8 -29
  204. package/dist/storage/repositories/index-vec-repository.js +133 -414
  205. package/dist/storage/repositories/outcome-repository.js +2 -1
  206. package/dist/storage/repositories/proposals-repository.js +35 -0
  207. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  208. package/dist/storage/repositories/task-history-repository.js +26 -4
  209. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  210. package/dist/storage/sqlite-migrations.js +136 -0
  211. package/dist/storage/sqlite-pragmas.js +11 -9
  212. package/dist/storage/sqlite-transaction.js +170 -0
  213. package/dist/storage/state-db-integrity.js +34 -27
  214. package/dist/tasks/activation-config.js +134 -62
  215. package/dist/tasks/backends/cron.js +129 -277
  216. package/dist/tasks/backends/exec-utils.js +2 -5
  217. package/dist/tasks/backends/launchd.js +125 -745
  218. package/dist/tasks/backends/schtasks.js +101 -620
  219. package/dist/tasks/prepare/prepare-support.js +5 -15
  220. package/dist/tasks/prepare/prepare.js +0 -2
  221. package/dist/tasks/resolve-akm-bin.js +20 -79
  222. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  223. package/dist/tasks/scheduler-binding.js +18 -238
  224. package/dist/tasks/scheduler-invocation.js +52 -52
  225. package/dist/tasks/scheduler-lock.js +53 -0
  226. package/dist/tasks/scheduler-sync.js +361 -751
  227. package/dist/tasks/source/parse-task-source.js +160 -10
  228. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  229. package/dist/tasks/source/task-to-v4.js +2 -2
  230. package/dist/workflows/authoring/authoring.js +3 -12
  231. package/dist/workflows/compile.js +211 -0
  232. package/dist/workflows/concurrency-policy.js +13 -74
  233. package/dist/workflows/exec/child-invocation.js +3 -17
  234. package/dist/workflows/exec/child-workflow.js +32 -141
  235. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  236. package/dist/workflows/exec/environment.js +98 -0
  237. package/dist/workflows/exec/exec-unit.js +33 -140
  238. package/dist/workflows/exec/frozen-judge.js +7 -59
  239. package/dist/workflows/exec/native-executor.js +82 -341
  240. package/dist/workflows/exec/param-secrets.js +29 -47
  241. package/dist/workflows/exec/run-workflow.js +154 -387
  242. package/dist/workflows/exec/scheduler.js +9 -36
  243. package/dist/workflows/exec/step-work.js +127 -430
  244. package/dist/workflows/exec/unit-dispatch.js +11 -63
  245. package/dist/workflows/exec/unit-writer.js +8 -52
  246. package/dist/workflows/exec/worktree.js +39 -273
  247. package/dist/workflows/freeze/child-output-references.js +4 -15
  248. package/dist/workflows/freeze/environment.js +99 -92
  249. package/dist/workflows/freeze/freeze.js +172 -0
  250. package/dist/workflows/freeze/step-values.js +19 -21
  251. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  252. package/dist/workflows/freeze/targets/command.js +10 -33
  253. package/dist/workflows/freeze/targets/script.js +5 -12
  254. package/dist/workflows/freeze/targets/shell.js +3 -6
  255. package/dist/workflows/freeze/targets/task.js +25 -80
  256. package/dist/workflows/freeze/task-bindings.js +20 -67
  257. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  258. package/dist/workflows/ir/params.js +6 -51
  259. package/dist/workflows/ir/plan-hash.js +2 -34
  260. package/dist/workflows/parser.js +140 -43
  261. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  262. package/dist/workflows/renderer.js +36 -69
  263. package/dist/workflows/resource-limits.js +12 -120
  264. package/dist/workflows/runtime/agent-identity.js +8 -40
  265. package/dist/workflows/runtime/run-outputs.js +3 -6
  266. package/dist/workflows/runtime/run-plan.js +316 -0
  267. package/dist/workflows/runtime/runs.js +48 -200
  268. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  269. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  270. package/dist/workflows/validate-summary.js +2 -7
  271. package/docs/integration/bundling-akm.md +49 -42
  272. package/docs/migration/README.md +1 -0
  273. package/docs/migration/release-notes/0.9.17.md +41 -0
  274. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  275. package/docs/reference/cli.md +182 -125
  276. package/docs/reference/configuration.md +49 -56
  277. package/docs/reference/data-and-telemetry.md +19 -20
  278. package/docs/reference/tasks.md +86 -38
  279. package/docs/reference/workflow-schema.md +14 -18
  280. package/docs/reference/workflows.md +6 -9
  281. package/package.json +1 -1
  282. package/schemas/akm-config.json +87 -406
  283. package/dist/commands/health/advisories.js +0 -150
  284. package/dist/commands/health/metrics.js +0 -329
  285. package/dist/commands/health/surfaces.js +0 -102
  286. package/dist/commands/improve/anti-collapse.js +0 -83
  287. package/dist/commands/improve/collapse-detector.js +0 -432
  288. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  289. package/dist/commands/improve/consolidate/merge.js +0 -146
  290. package/dist/commands/improve/distill/promote-memory.js +0 -329
  291. package/dist/commands/improve/distill/quality-gate.js +0 -500
  292. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  293. package/dist/commands/improve/proposal-envelope.js +0 -31
  294. package/dist/commands/improve/run-context.js +0 -123
  295. package/dist/commands/improve/shared.js +0 -21
  296. package/dist/commands/improve/source-identity.js +0 -28
  297. package/dist/commands/improve/triage.js +0 -96
  298. package/dist/commands/proposal/drain-policies.js +0 -151
  299. package/dist/commands/sources/update-transaction.js +0 -220
  300. package/dist/core/action-contributors.js +0 -28
  301. package/dist/core/config/config-version-shim.js +0 -101
  302. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  303. package/dist/core/fs-txn.js +0 -405
  304. package/dist/core/lexical-score.js +0 -25
  305. package/dist/core/maintenance-barrier.js +0 -167
  306. package/dist/execution/executable-identity.js +0 -105
  307. package/dist/execution/guarded-source.js +0 -441
  308. package/dist/indexer/graph/graph-boost.js +0 -427
  309. package/dist/indexer/graph/graph-dedup.js +0 -95
  310. package/dist/indexer/search/name-match.js +0 -35
  311. package/dist/indexer/search/ranking-contributors.js +0 -515
  312. package/dist/indexer/walk/project-context.js +0 -192
  313. package/dist/integrations/agent/execution-cascade.js +0 -566
  314. package/dist/integrations/agent/execution-definitions.js +0 -202
  315. package/dist/integrations/agent/execution-lowering.js +0 -841
  316. package/dist/integrations/agent/execution-preparation.js +0 -98
  317. package/dist/integrations/agent/inline-execution.js +0 -74
  318. package/dist/registry/create-provider-registry.js +0 -29
  319. package/dist/registry/pinned-request-helper.js +0 -247
  320. package/dist/registry/pinned-transport.js +0 -717
  321. package/dist/sources/providers/index.js +0 -14
  322. package/dist/storage/engines/sqlite-migrations.js +0 -271
  323. package/dist/storage/repositories/canaries-repository.js +0 -107
  324. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  325. package/dist/storage/repositories/registry-cache.js +0 -113
  326. package/dist/tasks/scheduler-sync-preview.js +0 -52
  327. package/dist/workflows/freeze/resolve-steps.js +0 -86
  328. package/dist/workflows/freeze/source-freeze.js +0 -64
  329. package/dist/workflows/ir/compile.js +0 -321
  330. package/dist/workflows/ir/environment-v4.js +0 -330
  331. package/dist/workflows/ir/freeze-v4.js +0 -153
  332. package/dist/workflows/ir/schema-v4.js +0 -745
  333. package/dist/workflows/ir/schema.js +0 -354
  334. package/dist/workflows/program/schema.js +0 -78
  335. package/dist/workflows/runtime/checkin.js +0 -57
  336. package/dist/workflows/runtime/plan-classifier.js +0 -196
  337. package/dist/workflows/runtime/unit-checkin.js +0 -45
  338. package/dist/workflows/runtime/unit-phases.js +0 -20
  339. package/dist/workflows/schema.js +0 -4
  340. package/dist/workflows/source-ir/compile.js +0 -200
  341. package/dist/workflows/source-ir/program.js +0 -50
  342. package/dist/workflows/source-ir/result.js +0 -26
  343. package/dist/workflows/source-ir/schema.js +0 -786
  344. package/dist/workflows/source-ir/triggers.js +0 -79
  345. package/dist/workflows/source-ir/uses.js +0 -40
  346. 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;