akm-cli 0.8.7 → 0.8.14

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 (324) hide show
  1. package/CHANGELOG.md +428 -0
  2. package/dist/assets/help/help-proposals.md +1 -2
  3. package/dist/assets/hints/cli-hints-full.md +34 -19
  4. package/dist/assets/hints/cli-hints-short.md +1 -1
  5. package/dist/assets/profiles/catchup.json +13 -0
  6. package/dist/assets/profiles/consolidate.json +13 -0
  7. package/dist/assets/profiles/frequent.json +13 -0
  8. package/dist/assets/tasks/core/backup.yml +4 -0
  9. package/dist/assets/tasks/core/extract.yml +4 -0
  10. package/dist/assets/tasks/core/improve.yml +4 -0
  11. package/dist/assets/tasks/core/index-refresh.yml +4 -0
  12. package/dist/assets/tasks/core/sync.yml +4 -0
  13. package/dist/assets/tasks/core/update-stashes.yml +4 -0
  14. package/dist/assets/tasks/core/version-check.yml +4 -0
  15. package/dist/assets/templates/html/default.html +78 -0
  16. package/dist/assets/templates/html/health.html +560 -0
  17. package/dist/assets/templates/html/vendor/echarts.min.js +45 -0
  18. package/dist/cli/config-migrate.js +6 -6
  19. package/dist/cli/config-validate.js +4 -4
  20. package/dist/cli/confirm.js +3 -3
  21. package/dist/cli/parse-args.js +1 -1
  22. package/dist/cli/shared.js +72 -19
  23. package/dist/cli-node.mjs +26 -0
  24. package/dist/cli.js +206 -3866
  25. package/dist/commands/{agent-dispatch.js → agent/agent-dispatch.js} +6 -6
  26. package/dist/commands/{agent-support.js → agent/agent-support.js} +2 -2
  27. package/dist/commands/agent/contribute-cli.js +200 -0
  28. package/dist/commands/completions.js +1 -1
  29. package/dist/commands/config-cli.js +230 -3
  30. package/dist/commands/db-cli.js +2 -2
  31. package/dist/commands/env/env-cli.js +529 -0
  32. package/dist/commands/env/env.js +410 -0
  33. package/dist/commands/env/secret-cli.js +259 -0
  34. package/dist/commands/{secret.js → env/secret.js} +6 -47
  35. package/dist/commands/events.js +4 -4
  36. package/dist/commands/feedback-cli.js +18 -34
  37. package/dist/commands/graph/graph-cli.js +132 -0
  38. package/dist/commands/{graph.js → graph/graph.js} +22 -16
  39. package/dist/commands/health/checks.js +279 -0
  40. package/dist/commands/health/html-report.js +448 -0
  41. package/dist/commands/health.js +189 -266
  42. package/dist/commands/{consolidate.js → improve/consolidate.js} +48 -36
  43. package/dist/commands/{distill-promotion-policy.js → improve/distill-promotion-policy.js} +3 -3
  44. package/dist/commands/{distill.js → improve/distill.js} +39 -18
  45. package/dist/commands/{eval-cases.js → improve/eval-cases.js} +1 -1
  46. package/dist/commands/{extract-cli.js → improve/extract-cli.js} +4 -4
  47. package/dist/commands/{extract-prompt.js → improve/extract-prompt.js} +2 -2
  48. package/dist/commands/{extract.js → improve/extract.js} +221 -26
  49. package/dist/commands/{improve-auto-accept.js → improve/improve-auto-accept.js} +30 -4
  50. package/dist/commands/{improve-cli.js → improve/improve-cli.js} +44 -22
  51. package/dist/commands/{improve-profiles.js → improve/improve-profiles.js} +13 -7
  52. package/dist/commands/{improve-result-file.js → improve/improve-result-file.js} +1 -1
  53. package/dist/commands/{improve.js → improve/improve.js} +672 -292
  54. package/dist/{core → commands/improve/memory}/memory-belief.js +2 -2
  55. package/dist/{core → commands/improve/memory}/memory-contradiction-detect.js +5 -5
  56. package/dist/{core → commands/improve/memory}/memory-improve.js +4 -4
  57. package/dist/commands/improve/reflect-noise.js +0 -0
  58. package/dist/commands/{reflect.js → improve/reflect.js} +58 -28
  59. package/dist/commands/improve/session-asset.js +248 -0
  60. package/dist/commands/lint/agent-linter.js +1 -1
  61. package/dist/commands/lint/base-linter.js +55 -37
  62. package/dist/commands/lint/command-linter.js +1 -1
  63. package/dist/commands/lint/default-linter.js +1 -1
  64. package/dist/commands/lint/env-key-rules.js +1 -1
  65. package/dist/commands/lint/index.js +19 -25
  66. package/dist/commands/lint/knowledge-linter.js +1 -1
  67. package/dist/commands/lint/memory-linter.js +1 -1
  68. package/dist/commands/lint/registry.js +8 -8
  69. package/dist/commands/lint/skill-linter.js +1 -1
  70. package/dist/commands/lint/task-linter.js +1 -1
  71. package/dist/commands/lint/workflow-linter.js +1 -1
  72. package/dist/commands/lint.js +1 -1
  73. package/dist/commands/observability-cli.js +244 -0
  74. package/dist/commands/proposal/drain-policies.js +3 -3
  75. package/dist/commands/proposal/drain.js +87 -15
  76. package/dist/commands/proposal/proposal-cli.js +490 -0
  77. package/dist/commands/{proposal.js → proposal/proposal.js} +17 -6
  78. package/dist/commands/{propose.js → proposal/propose.js} +11 -11
  79. package/dist/{core → commands/proposal/validators}/proposal-quality-validators.js +8 -3
  80. package/dist/{core → commands/proposal/validators}/proposal-validators.js +5 -5
  81. package/dist/{core → commands/proposal/validators}/proposals.js +374 -345
  82. package/dist/commands/{curate.js → read/curate.js} +7 -7
  83. package/dist/commands/{knowledge.js → read/knowledge.js} +22 -9
  84. package/dist/commands/{registry-search.js → read/registry-search.js} +5 -5
  85. package/dist/commands/{remember-cli.js → read/remember-cli.js} +15 -7
  86. package/dist/commands/read/search-cli.js +207 -0
  87. package/dist/commands/{search.js → read/search.js} +22 -27
  88. package/dist/commands/{show.js → read/show.js} +31 -45
  89. package/dist/commands/registry-cli.js +8 -8
  90. package/dist/commands/remember.js +14 -10
  91. package/dist/commands/sources/add-cli.js +293 -0
  92. package/dist/commands/{history.js → sources/history.js} +27 -25
  93. package/dist/commands/{info.js → sources/info.js} +6 -6
  94. package/dist/commands/{init.js → sources/init.js} +6 -6
  95. package/dist/commands/{installed-stashes.js → sources/installed-stashes.js} +12 -12
  96. package/dist/commands/{migration-help.js → sources/migration-help.js} +3 -2
  97. package/dist/commands/{schema-repair.js → sources/schema-repair.js} +8 -8
  98. package/dist/commands/{self-update.js → sources/self-update.js} +10 -9
  99. package/dist/commands/{source-add.js → sources/source-add.js} +10 -10
  100. package/dist/commands/{source-clone.js → sources/source-clone.js} +7 -7
  101. package/dist/commands/{source-manage.js → sources/source-manage.js} +4 -4
  102. package/dist/commands/sources/sources-cli.js +305 -0
  103. package/dist/commands/sources/stash-cli.js +219 -0
  104. package/dist/commands/{stash-skeleton.js → sources/stash-skeleton.js} +2 -1
  105. package/dist/commands/tasks/default-tasks.js +173 -0
  106. package/dist/commands/tasks/tasks-cli.js +210 -0
  107. package/dist/commands/{tasks.js → tasks/tasks.js} +14 -14
  108. package/dist/commands/wiki-cli.js +307 -0
  109. package/dist/commands/workflow-cli.js +329 -0
  110. package/dist/core/action-contributors.js +1 -1
  111. package/dist/core/assert.js +40 -0
  112. package/dist/core/asset/asset-create.js +54 -0
  113. package/dist/core/{asset-ref.js → asset/asset-ref.js} +21 -4
  114. package/dist/core/{asset-registry.js → asset/asset-registry.js} +3 -3
  115. package/dist/core/{asset-spec.js → asset/asset-spec.js} +17 -31
  116. package/dist/core/{markdown.js → asset/markdown.js} +1 -1
  117. package/dist/core/{stash-meta.js → asset/stash-meta.js} +1 -1
  118. package/dist/core/best-effort.js +64 -0
  119. package/dist/core/common.js +32 -18
  120. package/dist/core/{config-io.js → config/config-io.js} +29 -19
  121. package/dist/core/{config-migration.js → config/config-migration.js} +11 -9
  122. package/dist/core/{config-schema.js → config/config-schema.js} +50 -7
  123. package/dist/core/config/config-types.js +16 -0
  124. package/dist/core/{config-walker.js → config/config-walker.js} +2 -2
  125. package/dist/core/{config.js → config/config.js} +10 -8
  126. package/dist/core/env-secret-ref.js +90 -0
  127. package/dist/core/errors.js +13 -3
  128. package/dist/core/events.js +27 -4
  129. package/dist/core/file-lock.js +1 -1
  130. package/dist/core/improve-types.js +48 -0
  131. package/dist/core/lesson-lint.js +2 -2
  132. package/dist/core/logs-db.js +304 -0
  133. package/dist/core/paths.js +2 -2
  134. package/dist/core/ripgrep/install.js +2 -2
  135. package/dist/core/ripgrep/resolve.js +2 -2
  136. package/dist/core/state-db.js +195 -60
  137. package/dist/core/text-truncation.js +148 -0
  138. package/dist/core/time.js +1 -1
  139. package/dist/core/write-source.js +98 -85
  140. package/dist/indexer/{db-backup.js → db/db-backup.js} +9 -24
  141. package/dist/indexer/{db.js → db/db.js} +128 -118
  142. package/dist/indexer/{graph-db.js → db/graph-db.js} +9 -4
  143. package/dist/indexer/{llm-cache.js → db/llm-cache.js} +15 -12
  144. package/dist/indexer/ensure-index.js +4 -4
  145. package/dist/indexer/{graph-boost.js → graph/graph-boost.js} +1 -1
  146. package/dist/indexer/{graph-extraction.js → graph/graph-extraction.js} +55 -13
  147. package/dist/indexer/indexer.js +37 -30
  148. package/dist/indexer/init.js +54 -0
  149. package/dist/indexer/manifest.js +10 -10
  150. package/dist/indexer/{memory-inference.js → passes/memory-inference.js} +141 -33
  151. package/dist/indexer/{metadata-contributors.js → passes/metadata-contributors.js} +10 -8
  152. package/dist/indexer/{metadata.js → passes/metadata.js} +15 -19
  153. package/dist/indexer/{staleness-detect.js → passes/staleness-detect.js} +53 -12
  154. package/dist/indexer/{db-search.js → search/db-search.js} +28 -16
  155. package/dist/indexer/{ranking-contributors.js → search/ranking-contributors.js} +1 -1
  156. package/dist/indexer/{ranking.js → search/ranking.js} +2 -2
  157. package/dist/indexer/{search-hit-enrichers.js → search/search-hit-enrichers.js} +3 -3
  158. package/dist/indexer/{search-source.js → search/search-source.js} +8 -8
  159. package/dist/indexer/{semantic-status.js → search/semantic-status.js} +3 -3
  160. package/dist/indexer/usage/unmigrated-vaults-guard.js +94 -0
  161. package/dist/indexer/{usage-events.js → usage/usage-events.js} +32 -0
  162. package/dist/indexer/{file-context.js → walk/file-context.js} +10 -15
  163. package/dist/indexer/{matchers.js → walk/matchers.js} +13 -9
  164. package/dist/indexer/{path-resolver.js → walk/path-resolver.js} +6 -6
  165. package/dist/indexer/{project-context.js → walk/project-context.js} +1 -1
  166. package/dist/indexer/{walker.js → walk/walker.js} +4 -3
  167. package/dist/integrations/agent/builder-shared.js +39 -0
  168. package/dist/integrations/agent/builders.js +14 -81
  169. package/dist/integrations/agent/config.js +6 -4
  170. package/dist/integrations/agent/detect.js +1 -1
  171. package/dist/integrations/agent/index.js +23 -8
  172. package/dist/integrations/agent/prompts.js +2 -3
  173. package/dist/integrations/agent/runner.js +22 -3
  174. package/dist/integrations/agent/spawn.js +9 -10
  175. package/dist/integrations/harnesses/claude/agent-builder.js +48 -0
  176. package/dist/integrations/harnesses/claude/config-import.js +70 -0
  177. package/dist/integrations/harnesses/claude/index.js +64 -0
  178. package/dist/integrations/{session-logs/providers/claude-code.js → harnesses/claude/session-log.js} +32 -5
  179. package/dist/integrations/harnesses/index.js +144 -0
  180. package/dist/integrations/harnesses/opencode/agent-builder.js +43 -0
  181. package/dist/integrations/harnesses/opencode/config-import.js +82 -0
  182. package/dist/integrations/harnesses/opencode/index.js +59 -0
  183. package/dist/integrations/{session-logs/providers/opencode.js → harnesses/opencode/session-log.js} +1 -1
  184. package/dist/integrations/harnesses/opencode-sdk/index.js +49 -0
  185. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +234 -0
  186. package/dist/integrations/harnesses/types.js +43 -0
  187. package/dist/integrations/lockfile.js +7 -16
  188. package/dist/integrations/session-logs/index.js +82 -9
  189. package/dist/llm/call-ai.js +4 -4
  190. package/dist/llm/client.js +146 -6
  191. package/dist/llm/embedder.js +6 -6
  192. package/dist/llm/embedders/local.js +9 -22
  193. package/dist/llm/embedders/remote.js +2 -2
  194. package/dist/llm/embedders/types.js +1 -1
  195. package/dist/llm/graph-extract.js +31 -12
  196. package/dist/llm/index-passes.js +1 -1
  197. package/dist/llm/memory-infer.js +12 -5
  198. package/dist/llm/metadata-enhance.js +2 -2
  199. package/dist/llm/usage-persist.js +77 -0
  200. package/dist/llm/usage-telemetry.js +103 -0
  201. package/dist/output/context.js +9 -46
  202. package/dist/output/html-render.js +73 -0
  203. package/dist/output/renderers.js +88 -58
  204. package/dist/output/shapes/curate.js +7 -3
  205. package/dist/output/shapes/distill.js +7 -3
  206. package/dist/output/shapes/env-list.js +18 -16
  207. package/dist/output/shapes/events.js +5 -4
  208. package/dist/output/shapes/helpers.js +19 -5
  209. package/dist/output/shapes/history.js +7 -3
  210. package/dist/output/shapes/passthrough.js +8 -11
  211. package/dist/output/shapes/{proposal-accept.js → proposal/accept.js} +7 -3
  212. package/dist/output/shapes/{proposal-diff.js → proposal/diff.js} +7 -3
  213. package/dist/output/shapes/{proposal-list.js → proposal/list.js} +7 -3
  214. package/dist/output/shapes/{proposal-producer.js → proposal/producer.js} +5 -4
  215. package/dist/output/shapes/{proposal-reject.js → proposal/reject.js} +7 -3
  216. package/dist/output/shapes/{proposal-show.js → proposal/show.js} +7 -3
  217. package/dist/output/shapes/registry-search.js +7 -3
  218. package/dist/output/shapes/registry.js +12 -0
  219. package/dist/output/shapes/search.js +7 -3
  220. package/dist/output/shapes/secret-list.js +18 -16
  221. package/dist/output/shapes/show.js +7 -3
  222. package/dist/output/shapes.js +55 -30
  223. package/dist/output/text/add.js +2 -3
  224. package/dist/output/text/clone.js +2 -3
  225. package/dist/output/text/config.js +2 -3
  226. package/dist/output/text/curate.js +4 -3
  227. package/dist/output/text/distill.js +2 -3
  228. package/dist/output/text/enable-disable.js +5 -4
  229. package/dist/output/text/env.js +13 -0
  230. package/dist/output/text/events.js +5 -4
  231. package/dist/output/text/feedback.js +4 -3
  232. package/dist/output/text/helpers.js +123 -40
  233. package/dist/output/text/history.js +2 -3
  234. package/dist/output/text/import.js +2 -3
  235. package/dist/output/text/index.js +2 -3
  236. package/dist/output/text/info.js +2 -3
  237. package/dist/output/text/init.js +2 -3
  238. package/dist/output/text/list.js +2 -3
  239. package/dist/output/text/proposal/producer.js +9 -0
  240. package/dist/output/text/proposal/proposal.js +13 -0
  241. package/dist/output/text/registry-commands.js +8 -7
  242. package/dist/output/text/registry.js +12 -0
  243. package/dist/output/text/remember.js +4 -3
  244. package/dist/output/text/remove.js +2 -3
  245. package/dist/output/text/save.js +2 -3
  246. package/dist/output/text/search.js +4 -3
  247. package/dist/output/text/show.js +4 -3
  248. package/dist/output/text/update.js +2 -3
  249. package/dist/output/text/upgrade.js +2 -3
  250. package/dist/output/text/wiki.js +12 -11
  251. package/dist/output/text/workflow.js +12 -10
  252. package/dist/output/text.js +66 -32
  253. package/dist/registry/build-index.js +11 -10
  254. package/dist/registry/factory.js +1 -1
  255. package/dist/registry/origin-resolve.js +1 -1
  256. package/dist/registry/providers/index.js +2 -2
  257. package/dist/registry/providers/skills-sh.js +91 -72
  258. package/dist/registry/providers/static-index.js +75 -52
  259. package/dist/registry/resolve.js +3 -3
  260. package/dist/runtime.js +242 -0
  261. package/dist/scripts/migrate-storage.js +1654 -683
  262. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +254 -168
  263. package/dist/setup/detect.js +311 -9
  264. package/dist/setup/harness-config-import.js +6 -120
  265. package/dist/setup/setup.js +454 -43
  266. package/dist/sources/include.js +1 -1
  267. package/dist/sources/provider-factory.js +2 -2
  268. package/dist/sources/providers/filesystem.js +3 -3
  269. package/dist/sources/providers/git.js +9 -9
  270. package/dist/sources/providers/index.js +4 -4
  271. package/dist/sources/providers/npm.js +6 -6
  272. package/dist/sources/providers/provider-utils.js +13 -20
  273. package/dist/sources/providers/sync-from-ref.js +5 -5
  274. package/dist/sources/providers/tar-utils.js +2 -2
  275. package/dist/sources/providers/website.js +2 -2
  276. package/dist/sources/resolve.js +5 -5
  277. package/dist/sources/website-ingest.js +5 -5
  278. package/dist/storage/database.js +102 -0
  279. package/dist/storage/engines/sqlite-migrations.js +42 -0
  280. package/dist/storage/locations.js +25 -0
  281. package/dist/storage/repositories/index-db.js +43 -0
  282. package/dist/storage/repositories/workflow-runs-repository.js +141 -0
  283. package/dist/tasks/backends/cron.js +4 -4
  284. package/dist/tasks/backends/exec-utils.js +32 -0
  285. package/dist/tasks/backends/index.js +3 -3
  286. package/dist/tasks/backends/launchd.js +7 -14
  287. package/dist/tasks/backends/schtasks.js +7 -16
  288. package/dist/tasks/embedded.js +71 -0
  289. package/dist/tasks/parser.js +2 -2
  290. package/dist/tasks/resolveAkmBin.js +1 -1
  291. package/dist/tasks/runner.js +127 -31
  292. package/dist/tasks/schedule.js +1 -1
  293. package/dist/tasks/validator.js +7 -7
  294. package/dist/text-import-hook.mjs +51 -0
  295. package/dist/version.js +2 -1
  296. package/dist/wiki/wiki.js +7 -7
  297. package/dist/workflows/{authoring.js → authoring/authoring.js} +6 -6
  298. package/dist/workflows/{scope-key.js → authoring/scope-key.js} +1 -1
  299. package/dist/workflows/cli.js +1 -1
  300. package/dist/workflows/db.js +54 -32
  301. package/dist/workflows/parser.js +4 -4
  302. package/dist/workflows/renderer.js +5 -5
  303. package/dist/workflows/runtime/agent-identity.js +56 -0
  304. package/dist/workflows/runtime/checkin.js +57 -0
  305. package/dist/workflows/{runs.js → runtime/runs.js} +197 -101
  306. package/dist/workflows/validate-summary.js +82 -0
  307. package/docs/README.md +1 -1
  308. package/docs/data-and-telemetry.md +6 -6
  309. package/package.json +17 -8
  310. package/dist/commands/add-cli.js +0 -279
  311. package/dist/commands/env.js +0 -213
  312. package/dist/integrations/agent/sdk-runner.js +0 -126
  313. package/dist/output/shapes/vault-list.js +0 -19
  314. package/dist/output/text/proposal-producer.js +0 -8
  315. package/dist/output/text/proposal.js +0 -12
  316. package/dist/output/text/vault.js +0 -16
  317. /package/dist/core/{asset-serialize.js → asset/asset-serialize.js} +0 -0
  318. /package/dist/core/{frontmatter.js → asset/frontmatter.js} +0 -0
  319. /package/dist/core/{config-sources.js → config/config-sources.js} +0 -0
  320. /package/dist/indexer/{graph-dedup.js → graph/graph-dedup.js} +0 -0
  321. /package/dist/{core/config-types.js → indexer/passes/pass-context.js} +0 -0
  322. /package/dist/indexer/{search-fields.js → search/search-fields.js} +0 -0
  323. /package/dist/indexer/{index-context.js → walk/index-context.js} +0 -0
  324. /package/dist/workflows/{document-cache.js → runtime/document-cache.js} +0 -0
@@ -1,10 +1,11 @@
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 { Database } from "bun:sqlite";
5
4
  import fs from "node:fs";
6
5
  import path from "node:path";
7
- import { getWorkflowDbPath } from "../core/paths";
6
+ import { getWorkflowDbPath } from "../core/paths.js";
7
+ import { openDatabase } from "../storage/database.js";
8
+ import { runMigrations as runSqliteMigrations } from "../storage/engines/sqlite-migrations.js";
8
9
  /**
9
10
  * workflow.db — Durable SQLite database for workflow run state.
10
11
  *
@@ -44,8 +45,12 @@ export function openWorkflowDatabase(dbPath = getWorkflowDbPath()) {
44
45
  if (!fs.existsSync(dir)) {
45
46
  fs.mkdirSync(dir, { recursive: true });
46
47
  }
47
- const db = new Database(dbPath);
48
+ const db = openDatabase(dbPath);
48
49
  db.exec("PRAGMA journal_mode = WAL");
50
+ // #589: 30 s busy timeout, matching index.db / state.db. Without it the
51
+ // default is 0 ms, so any concurrent writer fails immediately with
52
+ // SQLITE_BUSY.
53
+ db.exec("PRAGMA busy_timeout = 30000");
49
54
  db.exec("PRAGMA foreign_keys = ON");
50
55
  ensureBaseSchema(db);
51
56
  runMigrations(db);
@@ -102,6 +107,13 @@ function ensureBaseSchema(db) {
102
107
  ON workflow_run_steps(run_id, sequence_index);
103
108
  `);
104
109
  }
110
+ // ── Migration engine ─────────────────────────────────────────────────────────
111
+ //
112
+ // The runner itself (ensureMigrationsTable + runMigrations) lives in the shared
113
+ // engine at src/storage/engines/sqlite-migrations.ts. This module owns its own
114
+ // MIGRATIONS array plus the pre-versioning `bootstrap` hook, and delegates
115
+ // application to that shared runner. The {@link Migration} interface is imported
116
+ // from there.
105
117
  /**
106
118
  * All workflow.db migrations in application order. New migrations are
107
119
  * APPENDED — never inserted in the middle or reordered.
@@ -121,29 +133,50 @@ const MIGRATIONS = [
121
133
  ON workflow_runs(scope_key, workflow_ref, status);
122
134
  `,
123
135
  },
136
+ // ── Migration 002 — record agent harness + session identity ──────────────────
137
+ //
138
+ // Persists the agent harness identifier (e.g. "claude-code", "opencode") and
139
+ // the platform-native session id that owns each workflow run. This is the
140
+ // first concrete slice of #501 / #506: capturing *who* is driving a run so a
141
+ // future (separately-approved) monitor can correlate workflow runs with
142
+ // session activity. Both columns are nullable — runs started outside an agent
143
+ // harness, and all pre-existing runs, simply have NULL identity.
144
+ {
145
+ id: "002-add-agent-identity",
146
+ up: `
147
+ ALTER TABLE workflow_runs ADD COLUMN agent_harness TEXT;
148
+ ALTER TABLE workflow_runs ADD COLUMN agent_session_id TEXT;
149
+
150
+ CREATE INDEX IF NOT EXISTS idx_workflow_runs_agent_session
151
+ ON workflow_runs(agent_harness, agent_session_id);
152
+ `,
153
+ },
154
+ // ── Migration 003 — check-in arming + per-step summary (#506) ────────────────
155
+ //
156
+ // Builds on the agent identity recorded by migration 002. Arms a file-signal
157
+ // check-in (a timestamp, NOT a background thread — see
158
+ // docs/technical/workflow-agent-checkin-adr.md) so a stalled run can be
159
+ // re-targeted with a `continue` directive, and adds a per-step `summary`
160
+ // column so step/workflow completion can capture and validate a required
161
+ // summary of work done. Both columns are nullable.
162
+ {
163
+ id: "003-checkin-and-step-summary",
164
+ up: `
165
+ ALTER TABLE workflow_runs ADD COLUMN checkin_armed_at TEXT;
166
+ ALTER TABLE workflow_run_steps ADD COLUMN summary TEXT;
167
+ `,
168
+ },
124
169
  ];
125
170
  /**
126
171
  * Stable id of the scope_key migration. Exported for bootstrap detection and
127
172
  * tests.
128
173
  */
129
174
  const SCOPE_KEY_MIGRATION_ID = "001-add-scope-key";
130
- /**
131
- * Create the migrations table if it does not exist. Called unconditionally on
132
- * every open so a fresh database bootstraps correctly.
133
- */
134
- function ensureMigrationsTable(db) {
135
- db.exec(`
136
- CREATE TABLE IF NOT EXISTS schema_migrations (
137
- id TEXT PRIMARY KEY,
138
- applied_at TEXT NOT NULL DEFAULT (datetime('now'))
139
- );
140
- `);
141
- }
142
175
  /**
143
176
  * Detect whether a column exists on a given table.
144
177
  */
145
178
  function hasColumn(db, table, column) {
146
- const rows = db.query(`PRAGMA table_info(${table})`).all();
179
+ const rows = db.prepare(`PRAGMA table_info(${table})`).all();
147
180
  return rows.some((r) => r.name === column);
148
181
  }
149
182
  /**
@@ -171,24 +204,13 @@ function bootstrapPreVersioningDb(db) {
171
204
  /**
172
205
  * Apply every pending migration in a single transaction per migration.
173
206
  *
174
- * Each migration is applied in its own transaction so a failure in migration N
175
- * does not roll back already-applied migrations 1..N-1. The migration row is
176
- * inserted AFTER the DDL succeeds a crash mid-migration leaves no row and
177
- * the migration is retried on next open.
207
+ * Delegates to the shared SQLite migration engine, passing the
208
+ * `bootstrapPreVersioningDb` hook so databases created before this file gained
209
+ * migration tracking back-fill their scope_key row instead of re-running the
210
+ * ALTER.
178
211
  *
179
212
  * Called automatically by {@link openWorkflowDatabase}.
180
213
  */
181
214
  export function runMigrations(db) {
182
- ensureMigrationsTable(db);
183
- bootstrapPreVersioningDb(db);
184
- const appliedRows = db.prepare("SELECT id FROM schema_migrations").all();
185
- const applied = new Set(appliedRows.map((r) => r.id));
186
- for (const migration of MIGRATIONS) {
187
- if (applied.has(migration.id))
188
- continue;
189
- db.transaction(() => {
190
- db.exec(migration.up);
191
- db.prepare("INSERT INTO schema_migrations (id) VALUES (?)").run(migration.id);
192
- })();
193
- }
215
+ runSqliteMigrations(db, MIGRATIONS, { bootstrap: bootstrapPreVersioningDb });
194
216
  }
@@ -11,10 +11,10 @@
11
11
  * line spans, accumulating `WorkflowError`s rather than throwing.
12
12
  */
13
13
  import { parse as yamlParse } from "yaml";
14
- import { parseFrontmatterBlock } from "../core/frontmatter";
15
- import { parseMarkdownToc } from "../core/markdown";
16
- import { WORKFLOW_SCHEMA_VERSION, } from "./schema";
17
- import { runSemanticChecks } from "./validator";
14
+ import { parseFrontmatterBlock } from "../core/asset/frontmatter.js";
15
+ import { parseMarkdownToc } from "../core/asset/markdown.js";
16
+ import { WORKFLOW_SCHEMA_VERSION, } from "./schema.js";
17
+ import { runSemanticChecks } from "./validator.js";
18
18
  const WORKFLOW_TITLE_PREFIX = "Workflow:";
19
19
  const STEP_PREFIX = "Step:";
20
20
  const STEP_ID_LINE = /^Step ID:\s+(.+?)\s*$/;
@@ -9,11 +9,11 @@
9
9
  * uses the flat `WorkflowStepDefinition` type for backwards compatibility)
10
10
  * and into search hints for the indexer.
11
11
  */
12
- import { makeAssetRef } from "../core/asset-ref";
13
- import { UsageError } from "../core/errors";
14
- import { registerMetadataContributor } from "../indexer/metadata-contributors";
15
- import { cacheWorkflowDocument } from "./document-cache";
16
- import { parseWorkflow } from "./parser";
12
+ import { makeAssetRef } from "../core/asset/asset-ref.js";
13
+ import { UsageError } from "../core/errors.js";
14
+ import { registerMetadataContributor } from "../indexer/passes/metadata-contributors.js";
15
+ import { parseWorkflow } from "./parser.js";
16
+ import { cacheWorkflowDocument } from "./runtime/document-cache.js";
17
17
  function shellQuote(value) {
18
18
  return `'${value.replace(/'/g, `'\\''`)}'`;
19
19
  }
@@ -0,0 +1,56 @@
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
+ /**
5
+ * Resolve the agent harness + session identity for the current process.
6
+ *
7
+ * This is the first concrete slice of #501 / #506: capturing *who* is driving a
8
+ * workflow run so a future (separately-approved) monitor can correlate runs
9
+ * with session activity. It deliberately does NOT start any background thread,
10
+ * timer, or daemon — it only reads identity that the surrounding agent harness
11
+ * already exposes via the environment.
12
+ *
13
+ * Resolution is best-effort and environment-driven:
14
+ * - harness: AKM_AGENT_HARNESS, else inferred from a known harness env var.
15
+ * - sessionId: AKM_SESSION_ID, else the harness-native session env var.
16
+ *
17
+ * Explicit values passed to `startWorkflowRun` always win over the environment.
18
+ *
19
+ * @module workflows/agent-identity
20
+ */
21
+ import { denormalizeRuntimeIdentity } from "../../integrations/harnesses/index.js";
22
+ function firstNonEmpty(env, keys) {
23
+ for (const key of keys) {
24
+ const value = env[key];
25
+ if (typeof value === "string" && value.trim().length > 0) {
26
+ return value.trim();
27
+ }
28
+ }
29
+ return null;
30
+ }
31
+ /**
32
+ * Best-effort resolution of the agent harness + session id from the process
33
+ * environment. Returns `{ harness: null, sessionId: null }` when nothing is
34
+ * detectable (e.g. a human running the CLI directly).
35
+ */
36
+ export function resolveAgentIdentity(env = process.env) {
37
+ // Explicit override always wins.
38
+ let harness = firstNonEmpty(env, ["AKM_AGENT_HARNESS"]);
39
+ if (!harness) {
40
+ // Infer the harness from a harness-specific *session* env var. We only
41
+ // infer when a concrete session id is present: the bare "this process is
42
+ // Claude Code" flag does not mean a given run is owned by an agent session,
43
+ // so it must not silently stamp identity onto manual CLI invocations.
44
+ if (firstNonEmpty(env, ["CLAUDE_SESSION_ID"])) {
45
+ // Runtime identity for Claude Code is "claude-code" (vs the canonical
46
+ // config id "claude"). Derived from the unified registry's bridge (#562)
47
+ // so the persisted runtime string can't drift — still emits "claude-code".
48
+ harness = denormalizeRuntimeIdentity("claude");
49
+ }
50
+ else if (firstNonEmpty(env, ["OPENCODE_SESSION_ID"])) {
51
+ harness = denormalizeRuntimeIdentity("opencode");
52
+ }
53
+ }
54
+ const sessionId = firstNonEmpty(env, ["AKM_SESSION_ID", "CLAUDE_SESSION_ID", "OPENCODE_SESSION_ID"]);
55
+ return { harness, sessionId };
56
+ }
@@ -0,0 +1,57 @@
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
+ /**
5
+ * Agent check-in: a no-background-thread "continue" nudge for stalled workflow
6
+ * runs (#506).
7
+ *
8
+ * The design decision (see docs/technical/workflow-agent-checkin-adr.md)
9
+ * reconciles #506 (file/command-loop signal) with #501 (background thread) in
10
+ * favour of the former. There is intentionally NO timer or resident process
11
+ * here. Arming a check-in writes a timestamp (`checkin_armed_at`) on the run
12
+ * row; the next time the agent polls the engine via `workflow next`/`status`,
13
+ * {@link evaluateCheckin} is called to decide — purely from timestamps — whether
14
+ * the run looks stalled and a strong `continue` directive should be surfaced
15
+ * through the normal command output.
16
+ *
17
+ * @module workflows/checkin
18
+ */
19
+ /**
20
+ * Default stall window. If a run has been active and untouched for at least
21
+ * this long since the later of its last update and its armed timestamp, the
22
+ * next poll surfaces a check-in directive.
23
+ */
24
+ export const CHECKIN_STALL_MS = 90_000;
25
+ function parseIso(value) {
26
+ if (!value)
27
+ return null;
28
+ const ms = Date.parse(value);
29
+ return Number.isNaN(ms) ? null : ms;
30
+ }
31
+ /**
32
+ * Pure check-in evaluator. Returns a `continue` directive when an *active* run
33
+ * has been idle past the stall window, otherwise `null`. Deterministic in
34
+ * `now`, so it is trivially unit-testable and free of timer flakiness.
35
+ */
36
+ export function evaluateCheckin(run, now = Date.now(), stallMs = CHECKIN_STALL_MS) {
37
+ if (run.status !== "active")
38
+ return null;
39
+ const updated = parseIso(run.updatedAt);
40
+ const armed = parseIso(run.checkinArmedAt);
41
+ // Never armed → no check-in (opt-in per run via startWorkflowRun).
42
+ if (armed === null)
43
+ return null;
44
+ const last = Math.max(updated ?? armed, armed);
45
+ const idleMs = now - last;
46
+ if (idleMs < stallMs)
47
+ return null;
48
+ return {
49
+ signal: "continue",
50
+ directive: "CONTINUE: this workflow run has stalled with no progress. Resume immediately — " +
51
+ "re-read the current step's instructions, finish the outstanding work, then call " +
52
+ "`akm workflow complete` with a summary. Do not stop until the step is complete.",
53
+ idleMs,
54
+ agentHarness: run.agentHarness ?? null,
55
+ agentSessionId: run.agentSessionId ?? null,
56
+ };
57
+ }