akm-cli 0.9.0-rc.0 → 0.9.0-rc.13

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 (598) hide show
  1. package/CHANGELOG.md +1283 -22
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
  26. package/dist/assets/stash-skeleton/README.md +38 -10
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  38. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  39. package/dist/assets/tasks/core/extract.yml +3 -2
  40. package/dist/assets/tasks/core/improve.yml +2 -1
  41. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  42. package/dist/assets/tasks/core/sync.yml +1 -0
  43. package/dist/assets/tasks/core/version-check.yml +2 -1
  44. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  45. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  46. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  48. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  49. package/dist/assets/templates/html/health.html +5 -4
  50. package/dist/assets/workflows/workflow-template.md +31 -15
  51. package/dist/cli/invocation.js +279 -0
  52. package/dist/cli/parse-args.js +5 -90
  53. package/dist/cli/retired-commands.js +78 -0
  54. package/dist/cli/shared.js +158 -48
  55. package/dist/cli-node.mjs +2 -1
  56. package/dist/cli.js +747 -293
  57. package/dist/commands/agent/agent-dispatch.js +19 -18
  58. package/dist/commands/agent/agent-support.js +0 -24
  59. package/dist/commands/agent/contribute-cli.js +43 -97
  60. package/dist/commands/completions.js +80 -23
  61. package/dist/commands/config-cli.js +44 -281
  62. package/dist/commands/env/env-binding.js +99 -0
  63. package/dist/commands/env/env-cli.js +84 -224
  64. package/dist/commands/env/env.js +12 -163
  65. package/dist/commands/env/marker-path.js +6 -0
  66. package/dist/commands/env/secret-cli.js +45 -61
  67. package/dist/commands/env/secret.js +32 -62
  68. package/dist/commands/feedback-cli.js +179 -85
  69. package/dist/commands/health/accept-rate.js +58 -0
  70. package/dist/commands/health/advisories.js +7 -8
  71. package/dist/commands/health/checks.js +279 -94
  72. package/dist/commands/health/html-report.js +197 -578
  73. package/dist/commands/health/improve-metrics.js +277 -246
  74. package/dist/commands/health/llm-usage.js +19 -19
  75. package/dist/commands/health/md-report.js +16 -7
  76. package/dist/commands/health/metrics.js +67 -32
  77. package/dist/commands/health/renderers.js +47 -0
  78. package/dist/commands/health/report-view-model.js +508 -0
  79. package/dist/commands/health/stash-exposure.js +1 -1
  80. package/dist/commands/health/surfaces.js +16 -56
  81. package/dist/commands/health/task-runs.js +3 -67
  82. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  83. package/dist/commands/health/types-improve.js +29 -0
  84. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  85. package/dist/commands/health/types-result.js +7 -0
  86. package/dist/commands/health/types-runs.js +4 -0
  87. package/dist/commands/health/types-session-log.js +4 -0
  88. package/dist/commands/health/types-windows.js +4 -0
  89. package/dist/commands/health/types.js +26 -21
  90. package/dist/commands/health/windows.js +2 -3
  91. package/dist/commands/health.js +296 -167
  92. package/dist/commands/improve/anti-collapse.js +5 -5
  93. package/dist/commands/improve/autonomy-gate.js +68 -0
  94. package/dist/commands/improve/collapse-detector.js +65 -52
  95. package/dist/commands/improve/consolidate/chunking.js +9 -7
  96. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  97. package/dist/commands/improve/consolidate/merge.js +4 -0
  98. package/dist/commands/improve/consolidate.js +454 -1354
  99. package/dist/commands/improve/content-hash.js +39 -0
  100. package/dist/commands/improve/distill/content-repair.js +4 -10
  101. package/dist/commands/improve/distill/promote-memory.js +89 -64
  102. package/dist/commands/improve/distill/quality-gate.js +118 -42
  103. package/dist/commands/improve/distill-guards.js +1 -1
  104. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  105. package/dist/commands/improve/distill.js +607 -363
  106. package/dist/commands/improve/eligibility.js +165 -79
  107. package/dist/commands/improve/extract-cli.js +35 -126
  108. package/dist/commands/improve/extract-prompt.js +6 -35
  109. package/dist/commands/improve/extract.js +640 -391
  110. package/dist/commands/improve/feedback-valence.js +2 -12
  111. package/dist/commands/improve/improve-cli.js +134 -135
  112. package/dist/commands/improve/improve-result-file.js +30 -50
  113. package/dist/commands/improve/improve-run-types.js +4 -0
  114. package/dist/commands/improve/improve-strategies.js +135 -0
  115. package/dist/commands/improve/improve.js +904 -701
  116. package/dist/commands/improve/locks.js +64 -111
  117. package/dist/commands/improve/loop-stages.js +1110 -923
  118. package/dist/commands/improve/memory/derived-ref.js +124 -0
  119. package/dist/commands/improve/memory/memory-belief.js +79 -7
  120. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  121. package/dist/commands/improve/memory/memory-improve.js +25 -37
  122. package/dist/commands/improve/outcome-loop.js +25 -88
  123. package/dist/commands/improve/preparation.js +1034 -813
  124. package/dist/commands/improve/proactive-maintenance.js +34 -9
  125. package/dist/commands/improve/proposal-envelope.js +31 -0
  126. package/dist/commands/improve/reflect.js +983 -794
  127. package/dist/commands/improve/run-context.js +119 -0
  128. package/dist/commands/improve/salience.js +24 -127
  129. package/dist/commands/improve/session-asset.js +7 -3
  130. package/dist/commands/improve/shared.js +14 -34
  131. package/dist/commands/improve/source-identity.js +28 -0
  132. package/dist/commands/improve/triage.js +20 -17
  133. package/dist/commands/lint/base-linter.js +340 -313
  134. package/dist/commands/lint/env-key-rules.js +31 -47
  135. package/dist/commands/lint/index.js +185 -30
  136. package/dist/commands/{events.js → log.js} +28 -38
  137. package/dist/commands/migrate-cli.js +54 -0
  138. package/dist/commands/migration-tool.js +55 -0
  139. package/dist/commands/observability-cli.js +70 -208
  140. package/dist/commands/proposal/diff-format.js +50 -0
  141. package/dist/commands/proposal/drain-policies.js +0 -6
  142. package/dist/commands/proposal/drain.js +91 -40
  143. package/dist/commands/proposal/proposal-cli.js +134 -132
  144. package/dist/commands/proposal/proposal-types.js +56 -0
  145. package/dist/commands/proposal/proposal.js +83 -65
  146. package/dist/commands/proposal/propose-cli.js +88 -0
  147. package/dist/commands/proposal/propose.js +105 -88
  148. package/dist/commands/proposal/repository.js +1303 -278
  149. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  150. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  151. package/dist/commands/proposal/validators/proposals.js +6 -8
  152. package/dist/commands/read/curate.js +78 -73
  153. package/dist/commands/read/knowledge.js +510 -13
  154. package/dist/commands/read/registry-search.js +2 -2
  155. package/dist/commands/read/remember-cli.js +84 -15
  156. package/dist/commands/read/search-cli.js +203 -96
  157. package/dist/commands/read/search.js +126 -94
  158. package/dist/commands/read/show.js +226 -250
  159. package/dist/commands/registry-cli.js +34 -60
  160. package/dist/commands/remember.js +18 -57
  161. package/dist/commands/sources/add-cli.js +104 -49
  162. package/dist/commands/sources/bundle-cli.js +166 -0
  163. package/dist/commands/sources/bundle-config-ops.js +63 -0
  164. package/dist/commands/sources/info.js +27 -15
  165. package/dist/commands/sources/init.js +30 -40
  166. package/dist/commands/sources/installed-stashes.js +469 -172
  167. package/dist/commands/sources/migration-help.js +7 -4
  168. package/dist/commands/sources/schema-repair.js +10 -9
  169. package/dist/commands/sources/self-update.js +182 -121
  170. package/dist/commands/sources/source-add.js +169 -178
  171. package/dist/commands/sources/source-clone.js +144 -41
  172. package/dist/commands/sources/source-manage.js +94 -59
  173. package/dist/commands/sources/sources-cli.js +64 -205
  174. package/dist/commands/sources/stash-cli.js +91 -54
  175. package/dist/commands/sources/stash-skeleton.js +1 -1
  176. package/dist/commands/tasks/tasks-cli.js +106 -104
  177. package/dist/commands/tasks/tasks.js +445 -262
  178. package/dist/commands/workflow-cli.js +232 -121
  179. package/dist/core/action-contributors.js +1 -1
  180. package/dist/core/activation-policy.js +49 -0
  181. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  182. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  183. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  184. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  185. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  186. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  187. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  188. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  189. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  190. package/dist/core/adapter/adapters/index.js +80 -0
  191. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  192. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  193. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  194. package/dist/core/adapter/adapters/shared.js +286 -0
  195. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  196. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  197. package/dist/core/adapter/bundle-adapter.js +4 -0
  198. package/dist/core/adapter/detect-adapter.js +17 -0
  199. package/dist/core/adapter/recognize-match.js +44 -0
  200. package/dist/core/adapter/registry.js +56 -0
  201. package/dist/core/adapter/types.js +4 -0
  202. package/dist/core/asset/akm-markdown.js +30 -0
  203. package/dist/core/asset/asset-placement.js +243 -0
  204. package/dist/core/asset/asset-ref.js +110 -79
  205. package/dist/core/asset/asset-serialize.js +20 -0
  206. package/dist/core/asset/frontmatter.js +28 -12
  207. package/dist/core/asset/markdown.js +40 -51
  208. package/dist/core/asset/resolve-ref.js +274 -0
  209. package/dist/core/asset/stash-meta.js +2 -2
  210. package/dist/core/bundle-id.js +51 -0
  211. package/dist/core/common.js +281 -86
  212. package/dist/core/config/config-io.js +42 -128
  213. package/dist/core/config/config-schema.js +233 -834
  214. package/dist/core/config/config-sources.js +162 -39
  215. package/dist/core/config/config-types.js +16 -11
  216. package/dist/core/config/config-version.js +29 -0
  217. package/dist/core/config/config-walker.js +126 -37
  218. package/dist/core/config/config.js +154 -331
  219. package/dist/core/config/deep-merge.js +41 -0
  220. package/dist/core/config/engine-semantics.js +28 -0
  221. package/dist/core/config/experimental.js +21 -0
  222. package/dist/core/config/schema/embedding.js +38 -0
  223. package/dist/core/config/schema/engines.js +116 -0
  224. package/dist/core/config/schema/experimental.js +47 -0
  225. package/dist/core/config/schema/feedback.js +31 -0
  226. package/dist/core/config/schema/improve-processes.js +389 -0
  227. package/dist/core/config/schema/improve.js +94 -0
  228. package/dist/core/config/schema/index-config.js +176 -0
  229. package/dist/core/config/schema/output.js +18 -0
  230. package/dist/core/config/schema/primitives.js +94 -0
  231. package/dist/core/config/schema/search.js +30 -0
  232. package/dist/core/config/schema/setup.js +18 -0
  233. package/dist/core/config/schema/sources-bundles.js +169 -0
  234. package/dist/core/config/schema/workflow.js +29 -0
  235. package/dist/core/env-secret-ref.js +155 -20
  236. package/dist/core/errors.js +17 -15
  237. package/dist/core/events-types.js +4 -0
  238. package/dist/core/events.js +46 -128
  239. package/dist/core/extra-params.js +62 -0
  240. package/dist/core/file-change.js +17 -0
  241. package/dist/core/file-lock.js +202 -57
  242. package/dist/core/fs-txn.js +392 -0
  243. package/dist/core/git-message.js +59 -0
  244. package/dist/core/improve-result.js +167 -0
  245. package/dist/core/json-schema.js +142 -0
  246. package/dist/core/lesson-lint.js +1 -17
  247. package/dist/core/logs-db.js +1 -1
  248. package/dist/core/maintenance-barrier.js +135 -0
  249. package/dist/core/migration-operation.js +44 -0
  250. package/dist/core/mutation-target.js +78 -0
  251. package/dist/core/paths.js +22 -25
  252. package/dist/core/platform.js +10 -0
  253. package/dist/core/recognition-util.js +128 -0
  254. package/dist/core/redaction.js +392 -0
  255. package/dist/core/standards/resolve-standards-context.js +36 -65
  256. package/dist/core/standards/resolve-stash-standards.js +2 -2
  257. package/dist/core/standards/resolve-type-conventions.js +5 -5
  258. package/dist/core/state/migrations.js +242 -11
  259. package/dist/core/state-db.js +98 -10
  260. package/dist/core/structured.js +1 -1
  261. package/dist/core/subprocess.js +303 -0
  262. package/dist/core/text-truncation.js +9 -5
  263. package/dist/core/time.js +20 -0
  264. package/dist/core/type-presentation.js +130 -0
  265. package/dist/core/warn.js +0 -3
  266. package/dist/core/write-source.js +834 -118
  267. package/dist/indexer/bundle-identity-guard.js +92 -0
  268. package/dist/indexer/db/graph-db.js +1 -25
  269. package/dist/indexer/db/llm-cache.js +1 -1
  270. package/dist/indexer/ensure-index.js +30 -9
  271. package/dist/indexer/graph/graph-boost.js +9 -30
  272. package/dist/indexer/graph/graph-extraction.js +41 -27
  273. package/dist/indexer/graph/graph-types.js +4 -0
  274. package/dist/indexer/index-writer-lock.js +93 -49
  275. package/dist/indexer/index-written-assets.js +100 -53
  276. package/dist/indexer/indexer.js +746 -329
  277. package/dist/indexer/init.js +18 -25
  278. package/dist/indexer/installations.js +142 -0
  279. package/dist/indexer/passes/dir-staleness.js +18 -10
  280. package/dist/indexer/passes/memory-inference.js +25 -15
  281. package/dist/indexer/passes/metadata.js +412 -243
  282. package/dist/indexer/scan/doc-to-entry.js +160 -0
  283. package/dist/indexer/scan/drain-dir.js +134 -0
  284. package/dist/indexer/search/db-search.js +292 -108
  285. package/dist/indexer/search/fts-query.js +64 -0
  286. package/dist/indexer/search/ranking-contributors.js +145 -25
  287. package/dist/indexer/search/ranking-types.js +4 -0
  288. package/dist/indexer/search/ranking.js +28 -71
  289. package/dist/indexer/search/search-attribution.js +67 -0
  290. package/dist/indexer/search/search-fields.js +18 -3
  291. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  292. package/dist/indexer/search/search-source.js +157 -111
  293. package/dist/indexer/search/semantic-status.js +4 -1
  294. package/dist/indexer/usage/usage-events.js +10 -30
  295. package/dist/indexer/walk/file-context.js +3 -45
  296. package/dist/indexer/walk/matchers.js +42 -34
  297. package/dist/indexer/walk/path-resolver.js +11 -5
  298. package/dist/indexer/walk/walker.js +42 -14
  299. package/dist/integrations/agent/builder-shared.js +7 -0
  300. package/dist/integrations/agent/builders.js +5 -56
  301. package/dist/integrations/agent/config.js +3 -143
  302. package/dist/integrations/agent/detect.js +17 -2
  303. package/dist/integrations/agent/engine-resolution.js +231 -0
  304. package/dist/integrations/agent/index.js +1 -2
  305. package/dist/integrations/agent/model-aliases.js +16 -2
  306. package/dist/integrations/agent/profiles.js +36 -62
  307. package/dist/integrations/agent/prompts.js +46 -18
  308. package/dist/integrations/agent/runner-dispatch.js +93 -4
  309. package/dist/integrations/agent/runner.js +76 -208
  310. package/dist/integrations/agent/spawn.js +88 -196
  311. package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
  312. package/dist/integrations/harnesses/aider/index.js +48 -0
  313. package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
  314. package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
  315. package/dist/integrations/harnesses/amazonq/index.js +45 -0
  316. package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
  317. package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
  318. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  319. package/dist/integrations/harnesses/claude/index.js +24 -35
  320. package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
  321. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  322. package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
  323. package/dist/integrations/harnesses/codex/index.js +52 -0
  324. package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
  325. package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
  326. package/dist/integrations/harnesses/copilot/index.js +48 -0
  327. package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
  328. package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
  329. package/dist/integrations/harnesses/gemini/index.js +48 -0
  330. package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
  331. package/dist/integrations/harnesses/ids.js +24 -0
  332. package/dist/integrations/harnesses/index.js +54 -34
  333. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  334. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  335. package/dist/integrations/harnesses/opencode/index.js +14 -32
  336. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  337. package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
  338. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
  339. package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
  340. package/dist/integrations/harnesses/openhands/index.js +48 -0
  341. package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
  342. package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
  343. package/dist/integrations/harnesses/pi/index.js +45 -0
  344. package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
  345. package/dist/integrations/harnesses/shared.js +17 -0
  346. package/dist/integrations/harnesses/types.js +43 -32
  347. package/dist/integrations/lockfile.js +211 -24
  348. package/dist/integrations/session-logs/index.js +36 -39
  349. package/dist/integrations/session-logs/provider-base.js +113 -0
  350. package/dist/llm/client.js +182 -110
  351. package/dist/llm/embedders/deterministic.js +2 -2
  352. package/dist/llm/embedders/remote.js +21 -9
  353. package/dist/llm/feature-gate.js +17 -57
  354. package/dist/llm/graph-extract.js +12 -13
  355. package/dist/llm/index-passes.js +8 -42
  356. package/dist/llm/memory-infer.js +144 -1
  357. package/dist/llm/metadata-enhance.js +45 -30
  358. package/dist/llm/structured-call.js +16 -8
  359. package/dist/llm/usage-persist.js +30 -5
  360. package/dist/llm/usage-telemetry.js +59 -6
  361. package/dist/output/cli-hints.js +1 -2
  362. package/dist/output/command-registry.js +27 -0
  363. package/dist/output/context.js +22 -7
  364. package/dist/output/format-exempt.js +80 -0
  365. package/dist/output/generic-render.js +251 -0
  366. package/dist/output/html-render.js +11 -16
  367. package/dist/output/render-registry.js +57 -0
  368. package/dist/output/renderers.js +14 -279
  369. package/dist/output/shapes/curate.js +10 -1
  370. package/dist/output/shapes/events.js +12 -7
  371. package/dist/output/shapes/helpers.js +58 -84
  372. package/dist/output/shapes/passthrough.js +11 -39
  373. package/dist/output/shapes/proposal/producer.js +15 -7
  374. package/dist/output/shapes/registry.js +12 -6
  375. package/dist/output/shapes.js +0 -9
  376. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  377. package/dist/output/text/bundle-show.js +7 -0
  378. package/dist/output/text/command-format.js +562 -0
  379. package/dist/output/text/env.js +1 -3
  380. package/dist/output/text/events.js +8 -7
  381. package/dist/output/text/helpers.js +15 -1164
  382. package/dist/output/text/proposal/producer.js +4 -2
  383. package/dist/output/text/proposal-format.js +202 -0
  384. package/dist/output/text/registry-commands.js +1 -2
  385. package/dist/output/text/registry.js +12 -6
  386. package/dist/output/text/show-directives.js +117 -0
  387. package/dist/output/text/show-format.js +103 -0
  388. package/dist/output/text/sync.js +5 -0
  389. package/dist/output/text/workflow-format.js +332 -0
  390. package/dist/output/text/workflow.js +3 -2
  391. package/dist/output/text.js +10 -19
  392. package/dist/registry/factory.js +4 -6
  393. package/dist/registry/origin-resolve.js +16 -27
  394. package/dist/registry/providers/skills-sh.js +3 -3
  395. package/dist/registry/providers/static-index.js +15 -25
  396. package/dist/registry/resolve.js +43 -94
  397. package/dist/registry/semver.js +43 -0
  398. package/dist/runtime.js +81 -12
  399. package/dist/scripts/akm-migrate.js +35529 -0
  400. package/dist/setup/detect.js +5 -7
  401. package/dist/setup/detected-engines.js +136 -0
  402. package/dist/setup/engine-config.js +100 -0
  403. package/dist/setup/registry-stash-loader.js +3 -3
  404. package/dist/setup/semantic-assets.js +12 -9
  405. package/dist/setup/setup.js +444 -208
  406. package/dist/setup/steps/connection-shared.js +120 -0
  407. package/dist/setup/steps/connection.js +108 -305
  408. package/dist/setup/steps/platforms.js +13 -12
  409. package/dist/setup/steps/semantic.js +15 -3
  410. package/dist/setup/steps/sources.js +21 -15
  411. package/dist/setup/steps/stashdir.js +6 -4
  412. package/dist/setup/steps/tasks.js +236 -119
  413. package/dist/setup/steps.js +3 -2
  414. package/dist/sources/freshness.js +39 -0
  415. package/dist/sources/provider-factory.js +11 -17
  416. package/dist/sources/providers/filesystem.js +2 -3
  417. package/dist/sources/providers/git-install.js +278 -34
  418. package/dist/sources/providers/git-provider.js +54 -56
  419. package/dist/sources/providers/git-stash.js +420 -91
  420. package/dist/sources/providers/git.js +2 -2
  421. package/dist/sources/providers/npm.js +16 -19
  422. package/dist/sources/providers/provider-utils.js +47 -22
  423. package/dist/sources/providers/sync-from-ref.js +3 -9
  424. package/dist/sources/providers/website.js +2 -2
  425. package/dist/sources/resolve.js +11 -10
  426. package/dist/sources/snapshot-fetchers/types.js +4 -0
  427. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  428. package/dist/storage/database.js +60 -4
  429. package/dist/storage/engines/sqlite-migrations.js +156 -5
  430. package/dist/storage/locations.js +1 -2
  431. package/dist/storage/repositories/canaries-repository.js +1 -1
  432. package/dist/storage/repositories/events-repository.js +51 -11
  433. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  434. package/dist/storage/repositories/index-connection.js +79 -0
  435. package/dist/storage/repositories/index-db.js +4 -3
  436. package/dist/storage/repositories/index-entries-repository.js +863 -0
  437. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  438. package/dist/storage/repositories/index-entry-types.js +4 -0
  439. package/dist/storage/repositories/index-fts-repository.js +167 -0
  440. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  441. package/dist/storage/repositories/index-meta-repository.js +49 -0
  442. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  443. package/dist/storage/repositories/index-sql.js +12 -0
  444. package/dist/storage/repositories/index-utility-repository.js +356 -0
  445. package/dist/storage/repositories/index-vec-repository.js +250 -0
  446. package/dist/storage/repositories/outcome-repository.js +119 -0
  447. package/dist/storage/repositories/proposals-repository.js +317 -75
  448. package/dist/storage/repositories/registry-cache.js +1 -1
  449. package/dist/storage/repositories/salience-repository.js +172 -0
  450. package/dist/storage/repositories/task-history-repository.js +110 -3
  451. package/dist/storage/repositories/workflow-runs-repository.js +240 -19
  452. package/dist/tasks/backends/cron.js +169 -46
  453. package/dist/tasks/backends/exec-utils.js +76 -3
  454. package/dist/tasks/backends/index.js +6 -9
  455. package/dist/tasks/backends/launchd.js +292 -55
  456. package/dist/tasks/backends/schtasks.js +557 -70
  457. package/dist/tasks/backends/types.js +4 -0
  458. package/dist/tasks/command-executable.js +93 -0
  459. package/dist/tasks/embedded.js +56 -38
  460. package/dist/tasks/parser.js +156 -64
  461. package/dist/tasks/resolve-akm-bin.js +144 -51
  462. package/dist/tasks/runner.js +377 -209
  463. package/dist/tasks/schedule.js +108 -19
  464. package/dist/tasks/scheduler-invocation.js +296 -0
  465. package/dist/tasks/schema.js +1 -1
  466. package/dist/tasks/task-id.js +35 -0
  467. package/dist/tasks/validator.js +30 -16
  468. package/dist/text-import-hook.mjs +1 -1
  469. package/dist/workflows/authoring/authoring.js +104 -43
  470. package/dist/workflows/authoring/scope-key.js +1 -1
  471. package/dist/workflows/cli.js +0 -16
  472. package/dist/workflows/concurrency-policy.js +15 -0
  473. package/dist/workflows/exec/brief.js +450 -0
  474. package/dist/workflows/exec/frozen-judge.js +47 -0
  475. package/dist/workflows/exec/native-executor.js +1038 -0
  476. package/dist/workflows/exec/param-secrets.js +115 -0
  477. package/dist/workflows/exec/report.js +1460 -0
  478. package/dist/workflows/exec/run-workflow.js +602 -0
  479. package/dist/workflows/exec/scheduler.js +71 -0
  480. package/dist/workflows/exec/step-work.js +1190 -0
  481. package/dist/workflows/exec/unit-writer.js +23 -0
  482. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  483. package/dist/workflows/exec/worktree.js +171 -0
  484. package/dist/workflows/ir/compile.js +246 -0
  485. package/dist/workflows/ir/freeze.js +233 -0
  486. package/dist/workflows/ir/params.js +54 -0
  487. package/dist/workflows/ir/plan-hash.js +68 -0
  488. package/dist/workflows/ir/schema.js +540 -0
  489. package/dist/workflows/parser.js +878 -304
  490. package/dist/workflows/program/expressions.js +181 -0
  491. package/dist/workflows/program/schema.js +51 -0
  492. package/dist/workflows/renderer.js +100 -45
  493. package/dist/workflows/resource-limits.js +22 -0
  494. package/dist/workflows/runtime/agent-identity.js +59 -14
  495. package/dist/workflows/runtime/checkin.js +1 -1
  496. package/dist/workflows/runtime/plan-classifier.js +131 -0
  497. package/dist/workflows/runtime/runs.js +376 -119
  498. package/dist/workflows/runtime/unit-checkin.js +45 -0
  499. package/dist/workflows/runtime/unit-phases.js +20 -0
  500. package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
  501. package/dist/workflows/schema.js +1 -11
  502. package/dist/workflows/validate-summary.js +2 -3
  503. package/dist/workflows/validator.js +52 -30
  504. package/docs/README.md +42 -78
  505. package/docs/migration/README.md +8 -0
  506. package/docs/migration/release-notes/0.6.0.md +1 -1
  507. package/docs/migration/release-notes/0.7.0.md +9 -8
  508. package/docs/migration/release-notes/0.9.0.md +158 -14
  509. package/docs/migration/v0.7-to-v0.8.md +46 -47
  510. package/docs/migration/v0.8-to-v0.9.md +844 -0
  511. package/docs/reference/README.md +12 -0
  512. package/docs/reference/data-and-telemetry.md +333 -0
  513. package/package.json +21 -17
  514. package/schemas/akm-asset-envelope.json +93 -0
  515. package/schemas/akm-config.json +4636 -0
  516. package/schemas/akm-task.json +87 -0
  517. package/schemas/akm-workflow.json +373 -0
  518. package/dist/akm-migrate-storage +0 -38
  519. package/dist/assets/help/help-accept.md +0 -12
  520. package/dist/assets/help/help-improve.md +0 -84
  521. package/dist/assets/help/help-proposals.md +0 -17
  522. package/dist/assets/help/help-propose.md +0 -17
  523. package/dist/assets/help/help-reject.md +0 -11
  524. package/dist/assets/profiles/frequent.json +0 -13
  525. package/dist/assets/profiles/recombine-only.json +0 -21
  526. package/dist/assets/profiles/reflect-distill.json +0 -30
  527. package/dist/assets/profiles/synthesize.json +0 -15
  528. package/dist/assets/prompts/procedural-system.md +0 -44
  529. package/dist/assets/prompts/recombine-system.md +0 -40
  530. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  531. package/dist/assets/tasks/core/backup.yml +0 -4
  532. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  533. package/dist/assets/templates/html/default.html +0 -78
  534. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  535. package/dist/assets/wiki/index-template.md +0 -12
  536. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  537. package/dist/assets/wiki/log-template.md +0 -8
  538. package/dist/assets/wiki/schema-template.md +0 -61
  539. package/dist/cli/config-migrate.js +0 -150
  540. package/dist/cli/config-validate.js +0 -39
  541. package/dist/commands/graph/graph-cli.js +0 -124
  542. package/dist/commands/graph/graph.js +0 -487
  543. package/dist/commands/improve/calibration.js +0 -161
  544. package/dist/commands/improve/dedup.js +0 -482
  545. package/dist/commands/improve/extract-watch.js +0 -140
  546. package/dist/commands/improve/hot-probation.js +0 -45
  547. package/dist/commands/improve/improve-auto-accept.js +0 -276
  548. package/dist/commands/improve/improve-profiles.js +0 -168
  549. package/dist/commands/improve/procedural.js +0 -398
  550. package/dist/commands/improve/recombine.js +0 -818
  551. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  552. package/dist/commands/lint/agent-linter.js +0 -44
  553. package/dist/commands/lint/command-linter.js +0 -44
  554. package/dist/commands/lint/default-linter.js +0 -16
  555. package/dist/commands/lint/fact-linter.js +0 -39
  556. package/dist/commands/lint/knowledge-linter.js +0 -16
  557. package/dist/commands/lint/memory-linter.js +0 -61
  558. package/dist/commands/lint/registry.js +0 -41
  559. package/dist/commands/lint/skill-linter.js +0 -45
  560. package/dist/commands/lint/task-linter.js +0 -50
  561. package/dist/commands/lint/workflow-linter.js +0 -81
  562. package/dist/commands/proposal/legacy-import.js +0 -115
  563. package/dist/commands/sources/history.js +0 -196
  564. package/dist/commands/tasks/default-tasks.js +0 -186
  565. package/dist/commands/wiki-cli.js +0 -292
  566. package/dist/core/asset/asset-registry.js +0 -76
  567. package/dist/core/asset/asset-spec.js +0 -259
  568. package/dist/core/config/config-migration.js +0 -602
  569. package/dist/core/deep-merge.js +0 -38
  570. package/dist/core/eval/rank-metrics.js +0 -113
  571. package/dist/core/ripgrep/install.js +0 -163
  572. package/dist/core/ripgrep/resolve.js +0 -81
  573. package/dist/indexer/db/db.js +0 -1413
  574. package/dist/indexer/manifest.js +0 -170
  575. package/dist/indexer/passes/metadata-contributors.js +0 -31
  576. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  577. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
  578. package/dist/llm/call-ai.js +0 -62
  579. package/dist/llm/memory-infer-impl.js +0 -138
  580. package/dist/output/shapes/distill.js +0 -14
  581. package/dist/output/shapes/history.js +0 -11
  582. package/dist/output/text/distill.js +0 -6
  583. package/dist/output/text/enable-disable.js +0 -8
  584. package/dist/output/text/history.js +0 -6
  585. package/dist/output/text/wiki.js +0 -16
  586. package/dist/registry/build-index.js +0 -386
  587. package/dist/scripts/migrate-storage.js +0 -19108
  588. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
  589. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  590. package/dist/setup/legacy-config.js +0 -106
  591. package/dist/storage/repositories/consolidation-repository.js +0 -38
  592. package/dist/storage/repositories/recombine-repository.js +0 -213
  593. package/dist/wiki/wiki-templates.js +0 -15
  594. package/dist/wiki/wiki.js +0 -1012
  595. package/dist/workflows/db.js +0 -215
  596. package/docs/data-and-telemetry.md +0 -226
  597. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  598. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -0,0 +1,128 @@
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
+ * OpenHands CLI agent command builder (P2, plan §"The adapter contract"
6
+ * step 2 / §"Capability matrix").
7
+ *
8
+ * Translates a platform-agnostic {@link AgentDispatchRequest} into the exact
9
+ * headless argv the `openhands` CLI expects. Per the capability matrix the
10
+ * headless invocation is:
11
+ *
12
+ * openhands --headless -t "<p>" --json
13
+ *
14
+ * with `--json` producing the documented JSONL event stream (structured tier
15
+ * "via prompt+validate"), workspace-state resume (no session-id flag), and
16
+ * native MCP support.
17
+ *
18
+ * Platform-specific mapping decisions (all localized here, per the adapter
19
+ * contract):
20
+ *
21
+ * - **prompt** — `--task` is the long form of the matrix's `-t` (used for
22
+ * self-documenting argv, mirroring the aider builder's `--message`). Like
23
+ * aider — and unlike claude/codex/pi — there is NO positional prompt and NO
24
+ * `--` end-of-options separator to hide behind: the task is a *flag value*.
25
+ * The glued `--task=<payload>` form is therefore used so a payload that
26
+ * begins with `-`/`--` binds to the flag lexically and can never be parsed
27
+ * as a separate option by the CLI's argument parser.
28
+ * - **--headless / --json** — always emitted: `--headless` is what makes a
29
+ * captured, unattended run possible, and `--json` switches stdout to the
30
+ * JSONL event stream that `./result-extractor.ts` normalizes (the same
31
+ * "dispatch is the captured path" reasoning as the Claude builder's
32
+ * unconditional `--print`; both flags are the matrix's documented headless
33
+ * shape).
34
+ * - **systemPrompt** — OpenHands headless mode has no documented
35
+ * system-prompt flag (agent behaviour is shaped by its own agent configs
36
+ * and microagents). Folded into the task payload — system text first, blank
37
+ * line, then the task — mirroring the aider/codex treatment.
38
+ * - **model** — OpenHands does not take the model on the headless command
39
+ * line; its documented configuration channel is the `LLM_MODEL` environment
40
+ * variable (config.toml `[llm] model` equivalent). The alias is resolved via
41
+ * `resolveModel` with this platform id and returned on `BuiltCommand.env`
42
+ * (the seam exists precisely for platform-specific extras), NOT as an
43
+ * invented `--model` flag that would produce a silently broken command.
44
+ * - **schema** — the matrix places OpenHands in the "via prompt+validate"
45
+ * tier (plan §"Structured-output normalization", tier "native-json"): no
46
+ * Codex-style `--output-schema` flag exists, so NO temp schema file is
47
+ * written; the JSON Schema is injected into the task payload using the
48
+ * exact directive wording of the engine's prompt assembly
49
+ * (`step-work.ts` `buildUnitPrompt`) and the pi/aider builders, so
50
+ * all dispatch paths speak one dialect. Downstream, the extractor pulls the
51
+ * final message out of the JSONL stream and the engine's shared
52
+ * retry-until-valid loop performs the actual validation.
53
+ * - **tools** — deliberately unconsumed. OpenHands has no per-tool allowlist
54
+ * flag; tool access is governed by its own runtime/sandbox configuration
55
+ * and (natively supported) MCP config. A restrictive policy is therefore
56
+ * dropped rather than approximated — never silently widened.
57
+ * - **resume/session** — NOT expressible: per the matrix OpenHands resumes
58
+ * from *workspace state*, not a session-id flag, so there is no flag-shaped
59
+ * resume to describe. The extractor still captures a
60
+ * conversation/session id opportunistically when the stream reveals one;
61
+ * akm's `workflow_run_units` remains the durable source of truth either way
62
+ * (plan §"Session, MCP, and identity across harnesses").
63
+ * - **effort** — stays unconsumed (reserved; the shared request contract's
64
+ * "no builder consumes it yet" note stays true).
65
+ *
66
+ * Registered: `openhandsBuilder` is `OpenhandsHarness.agentBuilder`
67
+ * (`./index.ts`), one of the ten harnesses `HARNESS_REGISTRY` constructs
68
+ * (`harnesses/index.ts`); `agent/builders.ts` derives `BUILTIN_BUILDERS` from
69
+ * that registry, so this builder is reachable under the `"openhands"`
70
+ * platform name without any further wiring. The registry entry also declares
71
+ * `pattern: "local-runner"`, `structuredOutput: "native-json"` alongside it
72
+ * (`./index.ts`).
73
+ */
74
+ import { assertNotFlag, resolveDispatchModel, } from "../../agent/builder-shared.js";
75
+ /** Canonical harness/platform id used for model-alias resolution. */
76
+ export const OPENHANDS_PLATFORM = "openhands";
77
+ /**
78
+ * Env var OpenHands reads its LLM model from — the platform's documented
79
+ * model-selection channel for headless runs (there is no headless model
80
+ * flag). Exported (re-exported from `./index.ts`) so this harness's tests
81
+ * share the one constant.
82
+ */
83
+ export const OPENHANDS_MODEL_ENV = "LLM_MODEL";
84
+ /**
85
+ * Assemble the `--task` payload: optional system text, the task prompt, and —
86
+ * when a schema is requested — the same schema directive the workflow
87
+ * engine's prompt assembly uses (OpenHands has no native schema flag, so the
88
+ * prompt is the schema's only channel; plan §"Structured-output
89
+ * normalization").
90
+ */
91
+ function buildTaskPayload(req) {
92
+ const sections = [];
93
+ if (req.systemPrompt)
94
+ sections.push(req.systemPrompt);
95
+ sections.push(req.prompt);
96
+ if (req.schema) {
97
+ sections.push(`Respond with ONLY a JSON value matching this JSON Schema (no prose, no code fences):\n${JSON.stringify(req.schema)}`);
98
+ }
99
+ return sections.join("\n\n");
100
+ }
101
+ /**
102
+ * OpenHands builder.
103
+ * Command shape:
104
+ * openhands --headless --json --task=<[system\n\n]prompt[\n\nschema directive]>
105
+ * with the resolved model (if any) carried on env as LLM_MODEL.
106
+ */
107
+ export const openhandsBuilder = {
108
+ platform: OPENHANDS_PLATFORM,
109
+ build(profile, req) {
110
+ assertNotFlag(req.systemPrompt, "systemPrompt");
111
+ assertNotFlag(req.model, "model");
112
+ const args = [...profile.args];
113
+ // Headless essentials (matrix shape): non-interactive run, JSONL stdout
114
+ // for the extractor.
115
+ args.push("--headless");
116
+ args.push("--json");
117
+ // Glued form: the payload is a flag VALUE (no positional prompt exists),
118
+ // so `=` binding keeps a dash-leading payload from parsing as an option.
119
+ args.push(`--task=${buildTaskPayload(req)}`);
120
+ let env;
121
+ if (req.model) {
122
+ const resolved = resolveDispatchModel(req, profile, OPENHANDS_PLATFORM);
123
+ // Model travels via env, not argv — OpenHands' documented channel.
124
+ env = { [OPENHANDS_MODEL_ENV]: resolved };
125
+ }
126
+ return { argv: [profile.bin, ...args], ...(env ? { env } : {}) };
127
+ },
128
+ };
@@ -0,0 +1,48 @@
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
+ * OpenHands CLI harness (P2 integration, plan §"The adapter contract").
6
+ *
7
+ * Per-harness barrel gathering the OpenHands integration surfaces:
8
+ * - agent command builder → ./agent-builder.ts (openhandsBuilder)
9
+ * - result extractor → ./result-extractor.ts (openhandsResultExtractor)
10
+ *
11
+ * It also defines {@link OpenhandsHarness}, the {@link AkmHarness} descriptor
12
+ * that `HARNESS_REGISTRY` registers. Dispatch-only: no native session-log
13
+ * reader or config importer yet.
14
+ */
15
+ import { caps } from "../shared.js";
16
+ import { BaseHarness } from "../types.js";
17
+ import { openhandsBuilder } from "./agent-builder.js";
18
+ import { openhandsResultExtractor } from "./result-extractor.js";
19
+ export { OPENHANDS_MODEL_ENV, OPENHANDS_PLATFORM, openhandsBuilder } from "./agent-builder.js";
20
+ export { openhandsResultExtractor } from "./result-extractor.js";
21
+ /**
22
+ * OpenHands CLI.
23
+ *
24
+ * Canonical id is `'openhands'`; no alias or distinct runtime identity.
25
+ */
26
+ export class OpenhandsHarness extends BaseHarness {
27
+ id = "openhands";
28
+ displayName = "OpenHands";
29
+ aliases = [];
30
+ agentBuilder = openhandsBuilder;
31
+ resultExtractor = openhandsResultExtractor;
32
+ // ── Workflow-engine descriptor (plan §"Capability matrix", P2) ────────────
33
+ // akm spawns `openhands --headless` locally per unit ⇒ local-runner.
34
+ pattern = "local-runner";
35
+ // `--json` emits a documented JSONL event stream akm parses, then validates
36
+ // against the node schema ⇒ native-json tier.
37
+ structuredOutput = "native-json";
38
+ // No flag-shaped resume: per the matrix OpenHands resumes from workspace state, not a
39
+ // session-id flag. The extractor still captures a conversation id
40
+ // opportunistically; akm's `workflow_run_units` remains the durable source
41
+ // of truth.
42
+ // No `identityEnv`: the matrix lists OpenHands' identity markers as
43
+ // uncertain, and it stamps no session var onto child processes.
44
+ capabilities = caps({
45
+ agentDispatch: true,
46
+ detection: true,
47
+ });
48
+ }
@@ -0,0 +1,103 @@
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
+ function isRecord(value) {
5
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6
+ }
7
+ /** Keys that may carry the harness-native session id, in precedence order. */
8
+ const SESSION_KEYS = ["session_id", "sessionId", "sid", "conversation_id"];
9
+ /** Return a non-empty string, else undefined. */
10
+ function nonEmptyString(value) {
11
+ return typeof value === "string" && value.length > 0 ? value : undefined;
12
+ }
13
+ /**
14
+ * Extract the agent's answer text from one parsed OpenHands event, if the
15
+ * event is one of the two message-bearing kinds (see module doc). Everything
16
+ * else — user echoes, observations, tool actions — yields undefined.
17
+ */
18
+ function extractAgentText(event) {
19
+ // Only agent-authored events count; a missing `source` is tolerated for
20
+ // finish/message actions from older serializations, but an explicit
21
+ // non-agent source (user echo, environment) never contributes.
22
+ if (event.source !== undefined && event.source !== "agent")
23
+ return undefined;
24
+ if (typeof event.action !== "string")
25
+ return undefined;
26
+ const args = isRecord(event.args) ? event.args : undefined;
27
+ if (event.action === "message") {
28
+ return nonEmptyString(args?.content) ?? nonEmptyString(event.message);
29
+ }
30
+ if (event.action === "finish") {
31
+ return nonEmptyString(args?.final_thought) ?? nonEmptyString(args?.thought) ?? nonEmptyString(event.message);
32
+ }
33
+ return undefined;
34
+ }
35
+ /** Extract a harness-native session id from one parsed JSON value, if any. */
36
+ function extractSessionId(event) {
37
+ for (const key of SESSION_KEYS) {
38
+ const candidate = nonEmptyString(event[key]);
39
+ if (candidate)
40
+ return candidate;
41
+ }
42
+ return undefined;
43
+ }
44
+ /** JSON.parse that returns undefined instead of throwing. */
45
+ function tryParseJson(raw) {
46
+ try {
47
+ return JSON.parse(raw);
48
+ }
49
+ catch {
50
+ return undefined;
51
+ }
52
+ }
53
+ /**
54
+ * Normalize a raw openhands run result into `{ text, sessionId? }`.
55
+ * See the module doc for the stdout shapes handled.
56
+ */
57
+ export const openhandsResultExtractor = (result) => {
58
+ // The raw result's own sessionId (SDK-style paths) is the fallback; an id
59
+ // found in the output stream wins because it is fresher.
60
+ const fallbackSessionId = result.sessionId;
61
+ const raw = result.stdout.trim();
62
+ // Shape 1 — whole stdout is one JSON document (spawn may have pre-parsed it
63
+ // when the profile requested parseOutput: "json"). A multi-event JSONL
64
+ // stream never parses as a single document, so this cannot shadow shape 2.
65
+ const whole = result.parsed !== undefined ? result.parsed : raw.length > 0 ? tryParseJson(raw) : undefined;
66
+ if (whole !== undefined) {
67
+ if (typeof whole === "string") {
68
+ return { text: whole, ...(fallbackSessionId ? { sessionId: fallbackSessionId } : {}) };
69
+ }
70
+ if (isRecord(whole)) {
71
+ const sessionId = extractSessionId(whole) ?? fallbackSessionId;
72
+ // Unknown envelope (no agent message): fall back to raw stdout so
73
+ // downstream embedded-JSON parsing still has material to work with.
74
+ const text = extractAgentText(whole) ?? raw;
75
+ return { text, ...(sessionId ? { sessionId } : {}) };
76
+ }
77
+ }
78
+ // Shape 2 — JSONL event stream (`--json`): last message-bearing agent event
79
+ // wins; first id-bearing event supplies the session id. Non-JSON banner
80
+ // lines are skipped.
81
+ let lastText;
82
+ let streamSessionId;
83
+ let sawJsonLine = false;
84
+ for (const line of raw.split("\n")) {
85
+ const trimmed = line.trim();
86
+ if (trimmed.length === 0)
87
+ continue;
88
+ const event = tryParseJson(trimmed);
89
+ if (event === undefined || !isRecord(event))
90
+ continue;
91
+ sawJsonLine = true;
92
+ streamSessionId ??= extractSessionId(event);
93
+ const text = extractAgentText(event);
94
+ if (text !== undefined)
95
+ lastText = text;
96
+ }
97
+ if (sawJsonLine) {
98
+ const sessionId = streamSessionId ?? fallbackSessionId;
99
+ return { text: lastText ?? raw, ...(sessionId ? { sessionId } : {}) };
100
+ }
101
+ // Shape 3 — plain text passthrough.
102
+ return { text: raw, ...(fallbackSessionId ? { sessionId: fallbackSessionId } : {}) };
103
+ };
@@ -0,0 +1,97 @@
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
+ * Pi coding-agent CLI command builder (P2, plan §"The adapter contract"
6
+ * step 2 / §"Capability matrix").
7
+ *
8
+ * Translates a platform-agnostic {@link AgentDispatchRequest} into the exact
9
+ * headless argv the `pi` CLI expects. Per the capability matrix the headless
10
+ * invocation is:
11
+ *
12
+ * pi -p "<prompt>"
13
+ *
14
+ * with `--mode json` for structured (JSONL) output, `--model <m>` for model
15
+ * selection, and `-c`/`-r`/`--session <id>` for resume — not built here
16
+ * because `AgentDispatchRequest` carries no session id (akm's
17
+ * `workflow_run_units` is the durable resume source of truth).
18
+ *
19
+ * Platform-specific mapping decisions (all localized here, per the adapter
20
+ * contract):
21
+ *
22
+ * - **prompt** — `-p` is Pi's non-interactive print mode (same convention as
23
+ * Claude Code's `--print`); the prompt is the trailing positional message.
24
+ * The `--` end-of-options separator precedes it, mirroring the claude/codex
25
+ * builders, so a prompt whose text begins with `-`/`--` can never be parsed
26
+ * as flags.
27
+ * - **systemPrompt** — passed via `--system-prompt` (Pi follows the Claude
28
+ * Code flag conventions), guarded by `assertNotFlag`.
29
+ * - **schema** — the matrix places Pi in the "via prompt+validate" tier (no
30
+ * native `--output-schema` equivalent, unlike Codex), so the JSON Schema is
31
+ * passed through the prompt: a directive matching the engine's wording
32
+ * (`step-work.ts` `buildUnitPrompt`) is appended to the prompt
33
+ * payload, and `--mode json` is emitted so stdout is the documented JSONL
34
+ * event stream that `./result-extractor.ts` normalizes. The engine's shared
35
+ * retry-until-valid loop performs the actual validation. Without a schema
36
+ * the argv matches the matrix's bare headless shape (`pi -p "<p>"`) and the
37
+ * extractor's plain-text path applies.
38
+ * - **tools** — deliberately unconsumed. Pi manages tool access through its
39
+ * own config/extension system (the matrix lists MCP as "extensions only");
40
+ * there is no documented per-tool allowlist flag, and inventing one would
41
+ * produce a silently broken command. A restrictive policy is therefore
42
+ * dropped rather than approximated — never silently widened.
43
+ * - **effort** — stays unconsumed (reserved; the shared request contract's
44
+ * "no builder consumes it yet" note stays true).
45
+ *
46
+ * Registered: `piBuilder` is `PiHarness.agentBuilder` (`./index.ts`), one of
47
+ * the ten harnesses `HARNESS_REGISTRY` constructs (`harnesses/index.ts`);
48
+ * `agent/builders.ts` derives `BUILTIN_BUILDERS` from that registry, so this
49
+ * builder is reachable under the `"pi"` platform name without any further
50
+ * wiring. The `PI_SESSION_ID` identity-env marker is declared alongside it
51
+ * (`./index.ts`).
52
+ */
53
+ import { assertNotFlag, resolveDispatchModel, } from "../../agent/builder-shared.js";
54
+ /** Canonical harness/platform id used for model-alias resolution. */
55
+ export const PI_PLATFORM = "pi";
56
+ /**
57
+ * Assemble the positional prompt payload: the task prompt and — when a schema
58
+ * is requested — the same schema directive the workflow engine's prompt
59
+ * assembly uses, so both dispatch paths speak one dialect.
60
+ */
61
+ function buildPromptPayload(req) {
62
+ const sections = [req.prompt];
63
+ if (req.schema) {
64
+ sections.push(`Respond with ONLY a JSON value matching this JSON Schema (no prose, no code fences):\n${JSON.stringify(req.schema)}`);
65
+ }
66
+ return sections.join("\n\n");
67
+ }
68
+ /**
69
+ * Pi builder.
70
+ * Command shape:
71
+ * pi [--system-prompt "..."] [--model <m>] [--mode json] -p -- "<prompt[\n\nschema directive]>"
72
+ */
73
+ export const piBuilder = {
74
+ platform: PI_PLATFORM,
75
+ build(profile, req) {
76
+ assertNotFlag(req.systemPrompt, "systemPrompt");
77
+ assertNotFlag(req.model, "model");
78
+ const args = [...profile.args];
79
+ if (req.systemPrompt) {
80
+ args.push("--system-prompt", req.systemPrompt);
81
+ }
82
+ if (req.model) {
83
+ const resolved = resolveDispatchModel(req, profile, PI_PLATFORM);
84
+ args.push("--model", resolved);
85
+ }
86
+ if (req.schema) {
87
+ // Structured unit: JSONL event stream on stdout — the pi result
88
+ // extractor's documented input (prompt+validate tier).
89
+ args.push("--mode", "json");
90
+ }
91
+ // -p = non-interactive print mode; prompt is the trailing positional.
92
+ args.push("-p");
93
+ args.push("--");
94
+ args.push(buildPromptPayload(req));
95
+ return { argv: [profile.bin, ...args] };
96
+ },
97
+ };
@@ -0,0 +1,45 @@
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
+ * Pi coding-agent CLI harness (P2 integration, plan §"The adapter contract").
6
+ *
7
+ * Per-harness barrel gathering the Pi integration surfaces:
8
+ * - agent command builder → ./agent-builder.ts (piBuilder)
9
+ * - result extractor → ./result-extractor.ts (piResultExtractor)
10
+ *
11
+ * It also defines {@link PiHarness}, the {@link AkmHarness} descriptor that
12
+ * `HARNESS_REGISTRY` registers. Dispatch-only: no native session-log reader or
13
+ * config importer yet.
14
+ */
15
+ import { caps } from "../shared.js";
16
+ import { BaseHarness } from "../types.js";
17
+ import { piBuilder } from "./agent-builder.js";
18
+ import { piResultExtractor } from "./result-extractor.js";
19
+ export { PI_PLATFORM, piBuilder } from "./agent-builder.js";
20
+ export { piResultExtractor } from "./result-extractor.js";
21
+ /**
22
+ * Pi coding-agent CLI.
23
+ *
24
+ * Canonical id is `'pi'`; no alias or distinct runtime identity.
25
+ */
26
+ export class PiHarness extends BaseHarness {
27
+ id = "pi";
28
+ displayName = "Pi";
29
+ aliases = [];
30
+ agentBuilder = piBuilder;
31
+ resultExtractor = piResultExtractor;
32
+ // ── Workflow-engine descriptor (plan §"Capability matrix", P2) ────────────
33
+ // akm spawns the `pi` CLI locally per unit ⇒ local-runner.
34
+ pattern = "local-runner";
35
+ // `--mode json` emits a documented JSONL event stream akm parses, then
36
+ // validates against the node schema ⇒ native-json tier.
37
+ structuredOutput = "native-json";
38
+ // Session-id env marker only — the matrix's bare PI_* presence vars must
39
+ // not stamp identity onto manual runs (see `AkmHarness.identityEnv`).
40
+ identityEnv = ["PI_SESSION_ID"];
41
+ capabilities = caps({
42
+ agentDispatch: true,
43
+ detection: true,
44
+ });
45
+ }
@@ -0,0 +1,135 @@
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
+ function isRecord(value) {
5
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6
+ }
7
+ /** Keys that may carry the harness-native session id, in precedence order. */
8
+ const SESSION_KEYS = ["session_id", "sessionId", "session"];
9
+ /**
10
+ * Coerce a candidate value into text. Handles the shapes Pi nests assistant
11
+ * answers in: bare strings, arrays of content blocks, and `{content|text}`
12
+ * wrappers. Blocks without a `content`/`text` string (thinking, tool-use)
13
+ * contribute nothing. Depth-bounded: JSON.parse output is acyclic, but
14
+ * nesting is capped anyway so a pathological envelope cannot recurse
15
+ * unboundedly.
16
+ */
17
+ function textOf(value, depth = 0) {
18
+ if (depth > 4)
19
+ return undefined;
20
+ if (typeof value === "string")
21
+ return value;
22
+ if (Array.isArray(value)) {
23
+ const parts = [];
24
+ for (const block of value) {
25
+ const t = textOf(block, depth + 1);
26
+ if (t)
27
+ parts.push(t);
28
+ }
29
+ return parts.length > 0 ? parts.join("\n") : undefined;
30
+ }
31
+ if (isRecord(value)) {
32
+ return textOf(value.content ?? value.text, depth + 1);
33
+ }
34
+ return undefined;
35
+ }
36
+ /** Extract the text of one assistant-authored message record, if it is one. */
37
+ function assistantMessageText(message) {
38
+ if (!isRecord(message) || message.role !== "assistant")
39
+ return undefined;
40
+ return textOf(message.content ?? message.text);
41
+ }
42
+ /**
43
+ * Extract assistant text from one parsed JSON event/value:
44
+ * `message` envelopes (`message_start`/`message_end`), `messages` transcripts
45
+ * (`agent_end` — last assistant entry wins), and tolerant flat
46
+ * `role:"assistant"` events.
47
+ */
48
+ function extractAssistantText(event) {
49
+ const fromEnvelope = assistantMessageText(event.message);
50
+ if (fromEnvelope !== undefined)
51
+ return fromEnvelope;
52
+ const transcript = event.messages;
53
+ if (Array.isArray(transcript)) {
54
+ for (let i = transcript.length - 1; i >= 0; i--) {
55
+ const text = assistantMessageText(transcript[i]);
56
+ if (text !== undefined)
57
+ return text;
58
+ }
59
+ return undefined;
60
+ }
61
+ return assistantMessageText(event);
62
+ }
63
+ /** Extract a harness-native session id from one parsed JSON value, if any. */
64
+ function extractSessionId(event) {
65
+ for (const key of SESSION_KEYS) {
66
+ const candidate = event[key];
67
+ if (typeof candidate === "string" && candidate.length > 0)
68
+ return candidate;
69
+ }
70
+ // Session-lifecycle events may carry the id under a bare `id` key.
71
+ if (typeof event.type === "string" && event.type.startsWith("session") && typeof event.id === "string" && event.id) {
72
+ return event.id;
73
+ }
74
+ return undefined;
75
+ }
76
+ /** JSON.parse that returns undefined instead of throwing. */
77
+ function tryParseJson(raw) {
78
+ try {
79
+ return JSON.parse(raw);
80
+ }
81
+ catch {
82
+ return undefined;
83
+ }
84
+ }
85
+ /**
86
+ * Normalize a raw pi run result into `{ text, sessionId? }`.
87
+ * See the module doc for the stdout shapes handled.
88
+ */
89
+ export const piResultExtractor = (result) => {
90
+ // The raw result's own sessionId (SDK-style paths) is the fallback; an id
91
+ // found in the output stream wins because it is fresher.
92
+ const fallbackSessionId = result.sessionId;
93
+ const raw = result.stdout.trim();
94
+ // Shape 1 — whole stdout is one JSON document (spawn may have pre-parsed it
95
+ // when the profile requested parseOutput: "json"). A multi-event JSONL
96
+ // stream never parses as a single document, so this cannot shadow shape 2.
97
+ const whole = result.parsed !== undefined ? result.parsed : raw.length > 0 ? tryParseJson(raw) : undefined;
98
+ if (whole !== undefined) {
99
+ if (typeof whole === "string") {
100
+ return { text: whole, ...(fallbackSessionId ? { sessionId: fallbackSessionId } : {}) };
101
+ }
102
+ if (isRecord(whole)) {
103
+ const sessionId = extractSessionId(whole) ?? fallbackSessionId;
104
+ // Unknown envelope (no assistant text): fall back to raw stdout so
105
+ // downstream embedded-JSON parsing still has material to work with.
106
+ const text = extractAssistantText(whole) ?? textOf(whole) ?? raw;
107
+ return { text, ...(sessionId ? { sessionId } : {}) };
108
+ }
109
+ }
110
+ // Shape 2 — JSONL event stream (`--mode json`): last assistant text-bearing
111
+ // event wins; first session-id-bearing event supplies the id. Non-JSON
112
+ // banner lines are skipped.
113
+ let lastText;
114
+ let streamSessionId;
115
+ let sawJsonLine = false;
116
+ for (const line of raw.split("\n")) {
117
+ const trimmed = line.trim();
118
+ if (trimmed.length === 0)
119
+ continue;
120
+ const event = tryParseJson(trimmed);
121
+ if (event === undefined || !isRecord(event))
122
+ continue;
123
+ sawJsonLine = true;
124
+ streamSessionId ??= extractSessionId(event);
125
+ const text = extractAssistantText(event);
126
+ if (text !== undefined && text.length > 0)
127
+ lastText = text;
128
+ }
129
+ if (sawJsonLine) {
130
+ const sessionId = streamSessionId ?? fallbackSessionId;
131
+ return { text: lastText ?? raw, ...(sessionId ? { sessionId } : {}) };
132
+ }
133
+ // Shape 3 — plain text passthrough.
134
+ return { text: raw, ...(fallbackSessionId ? { sessionId: fallbackSessionId } : {}) };
135
+ };
@@ -0,0 +1,17 @@
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
+ export function caps(c) {
5
+ return {
6
+ sessionLogs: false,
7
+ agentDispatch: false,
8
+ detection: false,
9
+ configImport: false,
10
+ runtimeIdentity: false,
11
+ ...c,
12
+ };
13
+ }
14
+ /** Home directory used for filesystem-only harness config detection. */
15
+ export function homeDir() {
16
+ return process.env.HOME ?? process.env.USERPROFILE ?? "";
17
+ }
@@ -1,44 +1,55 @@
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
+ /**
5
+ * Type-guard narrowing a harness to {@link SessionLogCapableHarness}.
6
+ *
7
+ * `Array.prototype.filter`'s type-predicate overload requires the predicate's
8
+ * inferred type to extend the array's element type — a plain
9
+ * `(h: AkmHarness) => h is SessionLogCapableHarness` predicate fails that
10
+ * constraint against `HARNESS_REGISTRY`'s element type (the union of the ten
11
+ * concrete harness classes, each with literal `id`s narrower than
12
+ * `SessionLogCapableHarness`'s `id: string`), so `.filter` would silently fall
13
+ * back to its non-narrowing overload. Generic over the input `H` and
14
+ * intersecting it into the predicate (`H & SessionLogCapableHarness`) keeps
15
+ * the result always a subtype of `H`, so the constraint holds regardless of
16
+ * what concrete harness type(s) `H` resolves to — this is what lets
17
+ * `HARNESS_REGISTRY.filter(isSessionLogHarness)` (in `./index.ts`) actually
18
+ * narrow to a type where `sessionLogProvider` is known-present, retiring the
19
+ * load-time throw that used to guard this in `session-logs/index.ts`.
20
+ */
21
+ export function isSessionLogHarness(h) {
22
+ return h.capabilities.sessionLogs;
23
+ }
4
24
  /**
5
25
  * Shared base for harness descriptors (#566).
6
26
  *
7
- * Provides the default v1-profile-name matcher so the inference logic lives in
8
- * ONE place instead of being duplicated across the old `guessAgentPlatform()`
9
- * (config-migration) and the `name.includes("claude")` heuristic (setup). A
10
- * concrete harness sets `id`/`aliases`/`capabilities` and, when its v1 profile
11
- * names could be decorated (e.g. `"opencode-sdk-fast"`), `v1ProfilePrefixes`.
27
+ * Provides shared optional descriptor fields for concrete harnesses.
28
+ *
29
+ * Deliberately implements {@link AkmHarnessCommon}, NOT the discriminated
30
+ * `AkmHarness` union (WI-9.7, H1): `AkmHarnessCommon` excludes `capabilities`
31
+ * and `sessionLogProvider`, the two fields whose pairing the union enforces.
32
+ * A base class shared by both branches cannot itself satisfy either specific
33
+ * union member — `capabilities` stays declared `abstract` at the (widened)
34
+ * `HarnessCapabilities` union type here, and each subclass narrows it to a
35
+ * literal `sessionLogs: true`/`false` variant via `caps({...})`.
36
+ * `sessionLogProvider` is intentionally NOT declared here at all (not even
37
+ * optional): the 8 non-session-log subclasses simply never declare it, which
38
+ * satisfies `NonSessionLogHarness`'s `sessionLogProvider?: undefined` (an
39
+ * absent optional property satisfies an `undefined`-typed optional); had this
40
+ * class declared it as `sessionLogProvider?: () => SessionLogHarness`
41
+ * instead, every non-session-log subclass would inherit that (function |
42
+ * undefined) type and fail to satisfy `NonSessionLogHarness` at the
43
+ * `HARNESS_REGISTRY` `satisfies` check. The two session-log subclasses
44
+ * (Claude, OpenCode) declare their own required `sessionLogProvider`.
12
45
  */
13
46
  export class BaseHarness {
14
47
  runtimeId;
15
48
  setupDetectionDir;
16
49
  agentBuilder;
17
- /**
18
- * Lowercase prefixes that a decorated v1 profile name may start with and
19
- * still belong to this harness (e.g. `["opencode-sdk"]`). The canonical id
20
- * and aliases are always matched in addition to these; an empty list means
21
- * only exact id/alias matches.
22
- */
23
- v1ProfilePrefixes = [];
24
- matchesV1ProfileName(name) {
25
- // Only harnesses with a v1→v2 mapping participate; others never claim a
26
- // legacy profile name (so unknown names are dropped, not misclassified).
27
- if (!this.capabilities.v1Migration)
28
- return false;
29
- const lower = name.trim().toLowerCase();
30
- if (!lower)
31
- return false;
32
- if (lower === this.id.toLowerCase())
33
- return true;
34
- for (const alias of this.aliases) {
35
- if (lower === alias.toLowerCase())
36
- return true;
37
- }
38
- for (const prefix of this.v1ProfilePrefixes) {
39
- if (lower.startsWith(prefix.toLowerCase()))
40
- return true;
41
- }
42
- return false;
43
- }
50
+ pattern;
51
+ structuredOutput;
52
+ identityEnv;
53
+ presenceEnv;
54
+ resultExtractor;
44
55
  }