@deksden-com/dd-flow-cli 0.9.0-beta.15 → 0.9.0-beta.150

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 (557) hide show
  1. package/CHANGELOG.md +895 -0
  2. package/README.md +140 -6
  3. package/dist/build-info.json +8 -8
  4. package/dist/cli/argument-values.js +38 -0
  5. package/dist/cli/command-inputs.js +386 -0
  6. package/dist/cli/command-metadata.js +232 -0
  7. package/dist/cli/command-option-descriptions.js +192 -0
  8. package/dist/cli/completion-cli.js +70 -0
  9. package/dist/cli/completion.js +57 -0
  10. package/dist/cli/diagnostic-invocation.js +46 -0
  11. package/dist/cli/diagnostic.js +120 -0
  12. package/dist/cli/error-output.js +52 -0
  13. package/dist/cli/executor-onboarding.js +76 -0
  14. package/dist/cli/flows.js +29 -0
  15. package/dist/cli/harnesses.js +84 -0
  16. package/dist/cli/help.js +396 -19
  17. package/dist/cli/hook-ingress.js +102 -0
  18. package/dist/cli/input-preparation.js +165 -0
  19. package/dist/cli/memory-flow-admission.js +50 -0
  20. package/dist/cli/memory-init-invocation.js +85 -0
  21. package/dist/cli/memory-init.js +249 -0
  22. package/dist/cli/memory-storage-admission.js +54 -0
  23. package/dist/cli/memory-storage-qualification.js +105 -0
  24. package/dist/cli/memory-storage-transition.js +123 -0
  25. package/dist/cli/memory-upgrade.js +189 -0
  26. package/dist/cli/models.js +39 -0
  27. package/dist/cli/native-hook-ingress.js +90 -0
  28. package/dist/cli/native-hook-preparation.js +55 -0
  29. package/dist/cli/operator-profiles.js +61 -0
  30. package/dist/cli/output-options.js +35 -0
  31. package/dist/cli/response-file.js +72 -0
  32. package/dist/cli/run-cli.js +1734 -550
  33. package/dist/cli/runtime-maintenance-diagnostics.js +46 -0
  34. package/dist/cli/runtime-maintenance-ingress.js +52 -0
  35. package/dist/cli/runtime-process.js +153 -0
  36. package/dist/cli/setup.js +150 -0
  37. package/dist/cli.js +89 -2
  38. package/dist/domain/diagnostic-aspects.js +103 -0
  39. package/dist/domain/diagnostic-flows.js +8 -0
  40. package/dist/domain/stage-catalog.js +1 -1
  41. package/dist/domain/stage-handler-identities.js +28 -0
  42. package/dist/harness-runtime/DD-ZCODE.md +112 -0
  43. package/dist/harness-runtime/OPENCODE-LICENSE.txt +24 -0
  44. package/dist/harness-runtime/bin/dd-agy.mjs +56 -0
  45. package/dist/harness-runtime/bin/dd-codex.mjs +27 -0
  46. package/dist/harness-runtime/bin/dd-droid.mjs +34 -0
  47. package/dist/harness-runtime/bin/dd-grok.mjs +40 -0
  48. package/dist/harness-runtime/bin/dd-opencode.mjs +22 -0
  49. package/dist/harness-runtime/bin/dd-zcode.mjs +87 -0
  50. package/dist/harness-runtime/lib/adapter-timeouts.d.mts +5 -0
  51. package/dist/harness-runtime/lib/adapter-timeouts.mjs +34 -0
  52. package/dist/harness-runtime/lib/agy-error-boundary.mjs +58 -0
  53. package/dist/harness-runtime/lib/agy-hooks.d.mts +1 -0
  54. package/dist/harness-runtime/lib/agy-hooks.mjs +9 -0
  55. package/dist/harness-runtime/lib/agy-native-inspection.mjs +216 -0
  56. package/dist/harness-runtime/lib/agy-native_pb.js +117 -0
  57. package/dist/harness-runtime/lib/daemon-observation.d.mts +2 -0
  58. package/dist/harness-runtime/lib/daemon-observation.mjs +163 -0
  59. package/dist/harness-runtime/lib/daemon-operations.d.mts +2 -0
  60. package/dist/harness-runtime/lib/daemon-operations.mjs +462 -0
  61. package/dist/harness-runtime/lib/dd-agy-daemon.d.mts +6 -0
  62. package/dist/harness-runtime/lib/dd-agy-daemon.mjs +1096 -0
  63. package/dist/harness-runtime/lib/dd-agy.mjs +86 -0
  64. package/dist/harness-runtime/lib/dd-codex-daemon.d.mts +1 -0
  65. package/dist/harness-runtime/lib/dd-codex-daemon.mjs +231 -0
  66. package/dist/harness-runtime/lib/dd-codex.d.mts +1 -0
  67. package/dist/harness-runtime/lib/dd-codex.mjs +954 -0
  68. package/dist/harness-runtime/lib/dd-droid-daemon.mjs +141 -0
  69. package/dist/harness-runtime/lib/dd-droid.mjs +626 -0
  70. package/dist/harness-runtime/lib/dd-grok-daemon.mjs +555 -0
  71. package/dist/harness-runtime/lib/dd-grok.mjs +180 -0
  72. package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +622 -0
  73. package/dist/harness-runtime/lib/dd-opencode.mjs +390 -0
  74. package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +752 -0
  75. package/dist/harness-runtime/lib/dd-zcode.mjs +1175 -0
  76. package/dist/harness-runtime/lib/delegation-instructions.d.mts +14 -0
  77. package/dist/harness-runtime/lib/delegation-instructions.mjs +157 -0
  78. package/dist/harness-runtime/lib/dispatch-fence.mjs +14 -0
  79. package/dist/harness-runtime/lib/driver-recovery.mjs +140 -0
  80. package/dist/harness-runtime/lib/droid-observation.mjs +66 -0
  81. package/dist/harness-runtime/lib/entity-references.d.mts +2 -0
  82. package/dist/harness-runtime/lib/entity-references.mjs +9 -0
  83. package/dist/harness-runtime/lib/lease-renewal.d.mts +8 -0
  84. package/dist/harness-runtime/lib/lease-renewal.mjs +37 -0
  85. package/dist/harness-runtime/lib/lifecycle-command.d.mts +20 -0
  86. package/dist/harness-runtime/lib/lifecycle-command.mjs +273 -0
  87. package/dist/harness-runtime/lib/lifecycle-contract.d.mts +10 -0
  88. package/dist/harness-runtime/lib/lifecycle-contract.mjs +19 -0
  89. package/dist/harness-runtime/lib/managed-daemon.d.mts +16 -0
  90. package/dist/harness-runtime/lib/managed-daemon.mjs +698 -0
  91. package/dist/harness-runtime/lib/managed-flow-env.mjs +15 -0
  92. package/dist/harness-runtime/lib/model-observations.mjs +101 -0
  93. package/dist/harness-runtime/lib/native-children.d.mts +23 -0
  94. package/dist/harness-runtime/lib/native-children.mjs +219 -0
  95. package/dist/harness-runtime/lib/native-hook-command.d.mts +7 -0
  96. package/dist/harness-runtime/lib/native-hook-command.mjs +251 -0
  97. package/dist/harness-runtime/lib/native-request-proof.d.mts +2 -0
  98. package/dist/harness-runtime/lib/native-request-proof.mjs +65 -0
  99. package/dist/harness-runtime/lib/native-streams.mjs +45 -0
  100. package/dist/harness-runtime/lib/observation-clock.d.mts +18 -0
  101. package/dist/harness-runtime/lib/observation-clock.mjs +95 -0
  102. package/dist/harness-runtime/lib/opencode-plugin.mjs +85 -0
  103. package/dist/harness-runtime/lib/operation-context.mjs +5 -0
  104. package/dist/harness-runtime/lib/operation-errors.d.mts +16 -0
  105. package/dist/harness-runtime/lib/operation-errors.mjs +127 -0
  106. package/dist/harness-runtime/lib/operation-progress.d.mts +7 -0
  107. package/dist/harness-runtime/lib/operation-progress.mjs +114 -0
  108. package/dist/harness-runtime/lib/process-json.d.mts +5 -0
  109. package/dist/harness-runtime/lib/process-json.mjs +201 -0
  110. package/dist/harness-runtime/lib/process-snapshot.mjs +10 -0
  111. package/dist/harness-runtime/lib/provider-overload-policy.d.mts +15 -0
  112. package/dist/harness-runtime/lib/provider-overload-policy.mjs +151 -0
  113. package/dist/harness-runtime/lib/runner-events.mjs +202 -0
  114. package/dist/harness-runtime/lib/runner-lock.mjs +42 -0
  115. package/dist/harness-runtime/lib/session-settlement.mjs +30 -0
  116. package/dist/harness-runtime/lib/setup-progress.d.mts +9 -0
  117. package/dist/harness-runtime/lib/setup-progress.mjs +53 -0
  118. package/dist/harness-runtime/lib/tool-observations.d.mts +21 -0
  119. package/dist/harness-runtime/lib/tool-observations.mjs +228 -0
  120. package/dist/harness-runtime/lib/zcode-usage.mjs +55 -0
  121. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-1y4a697q.js +81 -0
  122. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-2ny4vxct.js +92 -0
  123. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-6mptkzbc.js +0 -0
  124. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-7x67cf1q.js +52 -0
  125. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9rqn6x4v.js +16 -0
  126. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9vdz0zwn.js +1661 -0
  127. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ecs5ftka.js +1466 -0
  128. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-frbwqjmf.js +145 -0
  129. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gne7h7mq.js +50 -0
  130. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gx9wnkzr.js +105 -0
  131. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-m2eywc8w.js +0 -0
  132. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-nwcpakzx.js +12 -0
  133. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-q4g3afnw.js +623 -0
  134. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-qav6mfdz.js +0 -0
  135. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-sxt88q69.js +12 -0
  136. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-t1xa31vm.js +39 -0
  137. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ve4aws36.js +103 -0
  138. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vmytr4q8.js +4 -0
  139. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vt9jbch8.js +36 -0
  140. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vyas3vgt.js +0 -0
  141. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-wjyeq25y.js +30 -0
  142. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-xgnj2w4v.js +20 -0
  143. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-y2etg5bs.js +9 -0
  144. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ydhz1zrh.js +238 -0
  145. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-z6qdwcsf.js +62 -0
  146. package/dist/harness-runtime/vendor/opencode-client/contract.d.ts +1 -0
  147. package/dist/harness-runtime/vendor/opencode-client/contract.js +12 -0
  148. package/dist/harness-runtime/vendor/opencode-client/effect/api/api.d.ts +2806 -0
  149. package/dist/harness-runtime/vendor/opencode-client/effect/api/api.js +0 -0
  150. package/dist/harness-runtime/vendor/opencode-client/effect/api.d.ts +4 -0
  151. package/dist/harness-runtime/vendor/opencode-client/effect/api.js +0 -0
  152. package/dist/harness-runtime/vendor/opencode-client/effect/client.d.ts +2530 -0
  153. package/dist/harness-runtime/vendor/opencode-client/effect/client.js +15 -0
  154. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.d.ts +7 -0
  155. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.js +6 -0
  156. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.d.ts +2529 -0
  157. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.js +8 -0
  158. package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.d.ts +2 -0
  159. package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.js +12 -0
  160. package/dist/harness-runtime/vendor/opencode-client/effect/index.d.ts +35 -0
  161. package/dist/harness-runtime/vendor/opencode-client/effect/index.js +75 -0
  162. package/dist/harness-runtime/vendor/opencode-client/effect/rpc.d.ts +20 -0
  163. package/dist/harness-runtime/vendor/opencode-client/effect/rpc.js +11 -0
  164. package/dist/harness-runtime/vendor/opencode-client/effect/service.d.ts +90 -0
  165. package/dist/harness-runtime/vendor/opencode-client/effect/service.js +187 -0
  166. package/dist/harness-runtime/vendor/opencode-client/package.json +84 -0
  167. package/dist/harness-runtime/vendor/opencode-client/promise/api.d.ts +21 -0
  168. package/dist/harness-runtime/vendor/opencode-client/promise/api.js +0 -0
  169. package/dist/harness-runtime/vendor/opencode-client/promise/client.d.ts +252 -0
  170. package/dist/harness-runtime/vendor/opencode-client/promise/client.js +14 -0
  171. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.d.ts +8 -0
  172. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.js +6 -0
  173. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.d.ts +259 -0
  174. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.js +7 -0
  175. package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.d.ts +3 -0
  176. package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.js +79 -0
  177. package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.d.ts +8932 -0
  178. package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.js +70 -0
  179. package/dist/harness-runtime/vendor/opencode-client/promise/index.d.ts +6 -0
  180. package/dist/harness-runtime/vendor/opencode-client/promise/index.js +83 -0
  181. package/dist/harness-runtime/vendor/opencode-client/promise/rpc.d.ts +32 -0
  182. package/dist/harness-runtime/vendor/opencode-client/promise/rpc.js +7 -0
  183. package/dist/harness-runtime/vendor/opencode-client/promise/service.d.ts +24 -0
  184. package/dist/harness-runtime/vendor/opencode-client/promise/service.js +187 -0
  185. package/dist/harness-runtime/vendor/opencode-client/pty-handoff.d.ts +12 -0
  186. package/dist/harness-runtime/vendor/opencode-client/pty-handoff.js +14 -0
  187. package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.d.ts +20 -0
  188. package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.js +14 -0
  189. package/dist/harness-runtime/vendor/opencode-client/service-contender.d.ts +37 -0
  190. package/dist/harness-runtime/vendor/opencode-client/service-contender.js +10 -0
  191. package/dist/harness-runtime/vendor/opencode-client/service-probe.d.ts +70 -0
  192. package/dist/harness-runtime/vendor/opencode-client/service-probe.js +16 -0
  193. package/dist/harness-runtime/vendor/opencode-client/service-timing.d.ts +12 -0
  194. package/dist/harness-runtime/vendor/opencode-client/service-timing.js +10 -0
  195. package/dist/harness-runtime/vendor/opencode-client/service-version.d.ts +2 -0
  196. package/dist/harness-runtime/vendor/opencode-client/service-version.js +6 -0
  197. package/dist/harness-runtime/vendor/opencode-client/service.d.ts +52 -0
  198. package/dist/harness-runtime/vendor/opencode-client/service.js +1 -0
  199. package/dist/harness-runtime/vendor/opencode-client/shared-events.d.ts +11 -0
  200. package/dist/harness-runtime/vendor/opencode-client/shared-events.js +8 -0
  201. package/dist/harness-runtime/vendor/opencode-client/solid/connection.d.ts +37 -0
  202. package/dist/harness-runtime/vendor/opencode-client/solid/connection.js +10 -0
  203. package/dist/harness-runtime/vendor/opencode-client/solid/data.d.ts +211 -0
  204. package/dist/harness-runtime/vendor/opencode-client/solid/data.js +18 -0
  205. package/dist/harness-runtime/vendor/opencode-client/solid/index.d.ts +3 -0
  206. package/dist/harness-runtime/vendor/opencode-client/solid/index.js +32 -0
  207. package/dist/harness-runtime/vendor/opencode-client/solid/pty.d.ts +22 -0
  208. package/dist/harness-runtime/vendor/opencode-client/solid/pty.js +8 -0
  209. package/dist/harness-runtime/vendor/opencode-plugin.mjs +3 -0
  210. package/dist/protocol/local-files.js +18 -9
  211. package/dist/runtime/context.js +8 -4
  212. package/dist/schemas/agent-profile.schema.json +1 -1
  213. package/dist/schemas/code-review-decision.schema.json +9 -0
  214. package/dist/schemas/code-review-result.schema.json +1 -1
  215. package/dist/schemas/code-verification.schema.json +7 -5
  216. package/dist/schemas/code-work-batch.schema.json +2 -2
  217. package/dist/schemas/diagnostic-stage-result.schema.json +354 -0
  218. package/dist/schemas/diagnostic-work-result.schema.json +296 -0
  219. package/dist/schemas/discovery-result.schema.json +184 -0
  220. package/dist/schemas/execution-bundle.schema.json +211 -0
  221. package/dist/schemas/execution-settings.schema.json +162 -0
  222. package/dist/schemas/flow-descriptor.schema.json +54 -0
  223. package/dist/schemas/flow-run.schema.json +29 -0
  224. package/dist/schemas/harness-catalog.schema.json +80 -0
  225. package/dist/schemas/mb-init-compose-result.schema.json +457 -0
  226. package/dist/schemas/mb-init-discover-result.schema.json +500 -0
  227. package/dist/schemas/mb-init-finish-result.schema.json +422 -0
  228. package/dist/schemas/mb-init-preflight-result.schema.json +367 -0
  229. package/dist/schemas/mb-init-review-result.schema.json +396 -0
  230. package/dist/schemas/mb-init-verify-result.schema.json +391 -0
  231. package/dist/schemas/mb-upgrade-stage-result.schema.json +863 -0
  232. package/dist/schemas/memory-bootstrap-receipt-v2.schema.json +67 -0
  233. package/dist/schemas/memory-bootstrap-receipt.schema.json +354 -0
  234. package/dist/schemas/memory-composition-work-result.schema.json +38 -0
  235. package/dist/schemas/memory-repair-work-result.schema.json +56 -0
  236. package/dist/schemas/memory-review-correction-plan.schema.json +30 -0
  237. package/dist/schemas/memory-review-work-result.schema.json +43 -0
  238. package/dist/schemas/model-catalog.schema.json +153 -0
  239. package/dist/schemas/plan-review-decision.schema.json +12 -3
  240. package/dist/schemas/plan-review-result.schema.json +2 -2
  241. package/dist/schemas/profile-settings.schema.json +122 -0
  242. package/dist/schemas/project-flow-pack-manifest.schema.json +1 -1
  243. package/dist/schemas/release-impact.schema.json +3 -3
  244. package/dist/schemas/release-manifest.schema.json +291 -0
  245. package/dist/schemas/run-control-receipt.schema.json +118 -0
  246. package/dist/schemas/run-control-request.schema.json +36 -0
  247. package/dist/schemas/run-engine-binding.schema.json +1 -1
  248. package/dist/schemas/stage-start-response.schema.json +4 -0
  249. package/dist/schemas/vnext-protocol-plan.schema.json +2 -2
  250. package/dist/services/accepted-intent.js +139 -0
  251. package/dist/services/branch-context.js +3 -3
  252. package/dist/services/canon.js +54 -15
  253. package/dist/services/check-environment.js +21 -0
  254. package/dist/services/check-runner-evidence.js +562 -0
  255. package/dist/services/cleanup.js +133 -40
  256. package/dist/services/cli-operation-classifier.js +26 -63
  257. package/dist/services/cli-upgrade-allowlist.js +27 -0
  258. package/dist/services/code-checks.js +1398 -119
  259. package/dist/services/codex-hook-delivery.js +32 -0
  260. package/dist/services/command-context.js +80 -0
  261. package/dist/services/compatibility-preflight.js +16 -3
  262. package/dist/services/config.js +11 -8
  263. package/dist/services/continuation-outcome.js +20 -0
  264. package/dist/services/controller-child-capacity.js +13 -0
  265. package/dist/services/controller-child-observer.js +115 -0
  266. package/dist/services/controller-execution.js +94 -0
  267. package/dist/services/controller-fanout.js +226 -0
  268. package/dist/services/controller-memory-task.js +45 -0
  269. package/dist/services/controller-memory-worker.js +49 -0
  270. package/dist/services/dashboard.js +143 -58
  271. package/dist/services/descriptor-coordinator-session.js +35 -0
  272. package/dist/services/descriptor-root-work.js +53 -0
  273. package/dist/services/descriptor-run-settlement.js +107 -0
  274. package/dist/services/descriptor-run-start.js +475 -0
  275. package/dist/services/descriptor-stage-coordinator.js +250 -0
  276. package/dist/services/descriptor-stage-settlement.js +223 -0
  277. package/dist/services/descriptor-stage-start.js +175 -0
  278. package/dist/services/diagnostic-evidence.js +73 -0
  279. package/dist/services/diagnostic-report-publication.js +72 -0
  280. package/dist/services/diagnostic-report.js +67 -0
  281. package/dist/services/diagnostic-run-bundle.js +74 -0
  282. package/dist/services/diagnostic-snapshot.js +159 -0
  283. package/dist/services/diagnostic-stage-handlers.js +108 -0
  284. package/dist/services/diagnostic-stage-results.js +132 -0
  285. package/dist/services/diagnostic-start.js +84 -0
  286. package/dist/services/diagnostic-work-batch.js +34 -0
  287. package/dist/services/diagnostic-work-collection.js +97 -0
  288. package/dist/services/diagnostic-work-registration.js +101 -0
  289. package/dist/services/diagnostic-work-results.js +93 -0
  290. package/dist/services/discovery/agy-discovery.js +2 -0
  291. package/dist/services/discovery/codex-discovery.js +2 -0
  292. package/dist/services/discovery/droid-discovery.js +2 -0
  293. package/dist/services/discovery/grok-discovery.js +2 -0
  294. package/dist/services/discovery/opencode-discovery.js +2 -0
  295. package/dist/services/discovery/static.js +31 -0
  296. package/dist/services/discovery/zcode-discovery.js +2 -0
  297. package/dist/services/engines.js +354 -163
  298. package/dist/services/eval-snapshots.js +1316 -150
  299. package/dist/services/execution-bundles.js +275 -0
  300. package/dist/services/execution-policy.js +185 -0
  301. package/dist/services/executor-onboarding.js +56 -0
  302. package/dist/services/external-work-launch.js +310 -0
  303. package/dist/services/flow-catalog.js +30 -0
  304. package/dist/services/flow-descriptors.js +82 -0
  305. package/dist/services/frozen-engine.js +387 -0
  306. package/dist/services/generic-execution.js +164 -0
  307. package/dist/services/harness-adapter.js +355 -36
  308. package/dist/services/harness-config.js +2 -0
  309. package/dist/services/harness-discovery.js +29 -0
  310. package/dist/services/harness-doctor.js +75 -0
  311. package/dist/services/harness-probe-effects.js +51 -0
  312. package/dist/services/harness-version-probe.js +100 -0
  313. package/dist/services/hook-memory-routing.js +188 -0
  314. package/dist/services/hook-recovery-guard.js +14 -0
  315. package/dist/services/hook-session-observation.js +24 -0
  316. package/dist/services/hooks.js +791 -326
  317. package/dist/services/hybrid-contracts.js +474 -0
  318. package/dist/services/hybrid-digest.js +14 -0
  319. package/dist/services/ids.js +29 -1
  320. package/dist/services/installation-lock.js +95 -0
  321. package/dist/services/installed-flow-source.js +226 -0
  322. package/dist/services/lanes.js +78 -65
  323. package/dist/services/lifecycle-command.js +1 -288
  324. package/dist/services/lifecycle-contract.js +1 -0
  325. package/dist/services/lifecycle-invocations.js +2148 -0
  326. package/dist/services/managed-daemon-binding.js +38 -0
  327. package/dist/services/managed-lease-monitor.js +133 -0
  328. package/dist/services/managed-processes.js +449 -69
  329. package/dist/services/memory-accepted-composition.js +78 -0
  330. package/dist/services/memory-baseline-preservation.js +65 -0
  331. package/dist/services/memory-completed-correction-wave.js +328 -0
  332. package/dist/services/memory-compose-handler.js +400 -0
  333. package/dist/services/memory-composition-acceptance.js +375 -0
  334. package/dist/services/memory-composition-graph.js +165 -0
  335. package/dist/services/memory-composition-registration.js +161 -0
  336. package/dist/services/memory-composition-work-custody.js +156 -0
  337. package/dist/services/memory-composition-work-results.js +108 -0
  338. package/dist/services/memory-corrected-review-acceptance.js +129 -0
  339. package/dist/services/memory-corrected-review-batch.js +37 -0
  340. package/dist/services/memory-corrected-review-findings.js +108 -0
  341. package/dist/services/memory-corrected-review-inputs.js +215 -0
  342. package/dist/services/memory-corrected-review-projection.js +78 -0
  343. package/dist/services/memory-corrected-review-receipt.js +178 -0
  344. package/dist/services/memory-corrected-review-registration.js +192 -0
  345. package/dist/services/memory-correction-check-receipt.js +235 -0
  346. package/dist/services/memory-correction-input-owner.js +6 -0
  347. package/dist/services/memory-custody-snapshot.js +36 -0
  348. package/dist/services/memory-discover-handler.js +104 -0
  349. package/dist/services/memory-finish-evidence.js +457 -0
  350. package/dist/services/memory-finish-handler.js +229 -0
  351. package/dist/services/memory-finish-integration.js +450 -0
  352. package/dist/services/memory-finish-readiness.js +169 -0
  353. package/dist/services/memory-git-integration.js +220 -0
  354. package/dist/services/memory-historical-corrected-review.js +212 -0
  355. package/dist/services/memory-historical-original-review.js +143 -0
  356. package/dist/services/memory-historical-repair-registration.js +105 -0
  357. package/dist/services/memory-historical-second-review.js +147 -0
  358. package/dist/services/memory-init-bootstrap-readiness.js +210 -0
  359. package/dist/services/memory-init-contexts.js +131 -0
  360. package/dist/services/memory-init-controller-start.js +103 -0
  361. package/dist/services/memory-init-engine-release.js +223 -0
  362. package/dist/services/memory-init-git-policy.js +165 -0
  363. package/dist/services/memory-init-lint-capability.js +203 -0
  364. package/dist/services/memory-init-native-capacity.js +309 -0
  365. package/dist/services/memory-init-preflight.js +334 -0
  366. package/dist/services/memory-init-project-bootstrap.js +599 -0
  367. package/dist/services/memory-init-request-candidate.js +213 -0
  368. package/dist/services/memory-init-request-input.js +82 -0
  369. package/dist/services/memory-init-resource-storage.js +125 -0
  370. package/dist/services/memory-init-run-allocation.js +81 -0
  371. package/dist/services/memory-init-run-bundle.js +135 -0
  372. package/dist/services/memory-init-start.js +181 -0
  373. package/dist/services/memory-init-startup-custody.js +80 -0
  374. package/dist/services/memory-init-startup-input.js +240 -0
  375. package/dist/services/memory-init-storage.js +91 -0
  376. package/dist/services/memory-init-stores.js +359 -0
  377. package/dist/services/memory-init-worktrunk-capability.js +174 -0
  378. package/dist/services/memory-layer-publication.js +611 -0
  379. package/dist/services/memory-layer.js +221 -0
  380. package/dist/services/memory-lint-config.js +194 -0
  381. package/dist/services/memory-native-review-copy.js +103 -0
  382. package/dist/services/memory-normal-flow-entry.js +87 -0
  383. package/dist/services/memory-ordinary-defaults.js +129 -0
  384. package/dist/services/memory-preflight-bootstrap-custody.js +115 -0
  385. package/dist/services/memory-preflight-handler.js +274 -0
  386. package/dist/services/memory-repair-current-view.js +299 -0
  387. package/dist/services/memory-repair-document-delta.js +488 -0
  388. package/dist/services/memory-repair-history.js +496 -0
  389. package/dist/services/memory-repair-physical-binding.js +194 -0
  390. package/dist/services/memory-repair-publication-files.js +152 -0
  391. package/dist/services/memory-repair-publication-intent.js +27 -0
  392. package/dist/services/memory-repair-publication-plan.js +162 -0
  393. package/dist/services/memory-repair-publication-source.js +225 -0
  394. package/dist/services/memory-repair-publication.js +795 -0
  395. package/dist/services/memory-repair-registration.js +240 -0
  396. package/dist/services/memory-repair-work-baseline.js +415 -0
  397. package/dist/services/memory-repair-work-completion.js +117 -0
  398. package/dist/services/memory-repair-work-custody.js +73 -0
  399. package/dist/services/memory-repair-work-results.js +108 -0
  400. package/dist/services/memory-repair-workspace.js +261 -0
  401. package/dist/services/memory-repair-writer-copy.js +736 -0
  402. package/dist/services/memory-result-binding.js +239 -0
  403. package/dist/services/memory-retained-review-authority.js +138 -0
  404. package/dist/services/memory-retained-review-results.js +70 -0
  405. package/dist/services/memory-retained-second-baseline.js +102 -0
  406. package/dist/services/memory-retained-second-repairs.js +162 -0
  407. package/dist/services/memory-review-acceptance.js +214 -0
  408. package/dist/services/memory-review-correction-plan.js +206 -0
  409. package/dist/services/memory-review-handler.js +585 -0
  410. package/dist/services/memory-review-inputs.js +246 -0
  411. package/dist/services/memory-review-limits.js +10 -0
  412. package/dist/services/memory-review-receipt.js +180 -0
  413. package/dist/services/memory-review-registration.js +117 -0
  414. package/dist/services/memory-review-work-custody.js +126 -0
  415. package/dist/services/memory-review-work-input.js +91 -0
  416. package/dist/services/memory-review-work-results.js +95 -0
  417. package/dist/services/memory-second-corrected-review-inputs.js +167 -0
  418. package/dist/services/memory-second-correction-plan.js +77 -0
  419. package/dist/services/memory-second-repair-baseline.js +91 -0
  420. package/dist/services/memory-second-repair-launch.js +614 -0
  421. package/dist/services/memory-second-repair-registration.js +88 -0
  422. package/dist/services/memory-second-repair-source.js +187 -0
  423. package/dist/services/memory-second-review-acceptance.js +115 -0
  424. package/dist/services/memory-source-observations.js +117 -0
  425. package/dist/services/memory-stage-dispatch.js +65 -0
  426. package/dist/services/memory-stage-results.js +290 -0
  427. package/dist/services/memory-tool-probe.js +25 -0
  428. package/dist/services/memory-upgrade-analysis-handler.js +243 -0
  429. package/dist/services/memory-upgrade-bootstrap-readiness.js +251 -0
  430. package/dist/services/memory-upgrade-evidence.js +100 -0
  431. package/dist/services/memory-upgrade-inventory.js +442 -0
  432. package/dist/services/memory-upgrade-publication-custody.js +73 -0
  433. package/dist/services/memory-upgrade-publication.js +413 -0
  434. package/dist/services/memory-upgrade-selection.js +430 -0
  435. package/dist/services/memory-upgrade-start.js +60 -0
  436. package/dist/services/memory-upgrade-storage-readiness.js +340 -0
  437. package/dist/services/memory-verification-acceptance.js +156 -0
  438. package/dist/services/memory-verification-checks.js +317 -0
  439. package/dist/services/memory-verification-receipt.js +160 -0
  440. package/dist/services/memory-verify-handler.js +137 -0
  441. package/dist/services/memory-work-result-json.js +12 -0
  442. package/dist/services/memory-work-result-preparation.js +64 -0
  443. package/dist/services/merge-queue.js +228 -149
  444. package/dist/services/merge-server.js +163 -35
  445. package/dist/services/migrations.js +164 -114
  446. package/dist/services/model-catalog.js +109 -0
  447. package/dist/services/model-discovery.js +46 -0
  448. package/dist/services/native-daemon-history.js +50 -0
  449. package/dist/services/native-session-control.js +39 -0
  450. package/dist/services/operator-profiles.js +236 -0
  451. package/dist/services/physical-startup.js +45 -0
  452. package/dist/services/plan-runtime.js +26 -11
  453. package/dist/services/plans.js +28 -25
  454. package/dist/services/project-registry.js +97 -0
  455. package/dist/services/project-summary.js +1 -1
  456. package/dist/services/projects.js +17 -87
  457. package/dist/services/prompt-delivery.js +71 -0
  458. package/dist/services/prompts.js +28 -17
  459. package/dist/services/protocols.js +163 -87
  460. package/dist/services/provider-capacity.js +455 -0
  461. package/dist/services/recovery-observation-budget.js +121 -0
  462. package/dist/services/recovery-snapshot-database.js +588 -0
  463. package/dist/services/release-archive-producer.js +52 -0
  464. package/dist/services/release-archive.js +143 -0
  465. package/dist/services/release-cache.js +150 -0
  466. package/dist/services/release-compatibility.js +18 -0
  467. package/dist/services/release-download.js +67 -0
  468. package/dist/services/release-envelope.js +104 -0
  469. package/dist/services/release-manifest.js +45 -0
  470. package/dist/services/release-payload.js +114 -0
  471. package/dist/services/release-producer.js +63 -0
  472. package/dist/services/release-provenance.js +160 -0
  473. package/dist/services/release-registry.js +66 -0
  474. package/dist/services/release-source.js +194 -0
  475. package/dist/services/repair-intents.js +31 -0
  476. package/dist/services/repair-receipt.js +13 -0
  477. package/dist/services/review-copy.js +165 -0
  478. package/dist/services/review-deferral.js +23 -0
  479. package/dist/services/run-control-receipt.js +56 -0
  480. package/dist/services/run-control-worker.js +428 -0
  481. package/dist/services/run-control.js +1092 -0
  482. package/dist/services/run-controller-adapter.js +400 -0
  483. package/dist/services/run-controller-capture.js +186 -0
  484. package/dist/services/run-controller-process.js +205 -0
  485. package/dist/services/run-controller-recovery.js +295 -0
  486. package/dist/services/run-controller-state.js +97 -0
  487. package/dist/services/run-controller.js +1326 -0
  488. package/dist/services/run-engine-bindings.js +1 -1
  489. package/dist/services/run-fork.js +147 -0
  490. package/dist/services/run-health.js +149 -0
  491. package/dist/services/run-observations.js +152 -0
  492. package/dist/services/run-projection.js +22 -64
  493. package/dist/services/run-recovery-guard.js +107 -0
  494. package/dist/services/run-recovery-runtime.js +112 -0
  495. package/dist/services/run-recovery.js +456 -0
  496. package/dist/services/run-start-custody.js +189 -0
  497. package/dist/services/runs.js +1023 -246
  498. package/dist/services/runtime-budget.js +446 -0
  499. package/dist/services/runtime-command.js +43 -0
  500. package/dist/services/runtime-scope-capture.js +52 -0
  501. package/dist/services/runtime-scope-control.js +468 -0
  502. package/dist/services/runtime-scope-resume.js +605 -0
  503. package/dist/services/runtime-scope-stop.js +211 -0
  504. package/dist/services/runtime-scope-worker.js +314 -0
  505. package/dist/services/runtime-service.js +19 -14
  506. package/dist/services/schema-validation.js +10 -8
  507. package/dist/services/scope-writer-cleanup.js +27 -0
  508. package/dist/services/sessions.js +36 -91
  509. package/dist/services/setup.js +427 -0
  510. package/dist/services/stage-blocker.js +17 -7
  511. package/dist/services/stage-context.js +193 -19
  512. package/dist/services/stage-handlers.js +89 -0
  513. package/dist/services/stage-lifecycle.js +152 -116
  514. package/dist/services/stage-pause.js +202 -91
  515. package/dist/services/stage-report-renderer.js +234 -6
  516. package/dist/services/stage-work-graph.js +52 -0
  517. package/dist/services/tooling.js +41 -30
  518. package/dist/services/usage.js +49 -101
  519. package/dist/services/verification-matrix.js +393 -0
  520. package/dist/services/version-status.js +1 -1
  521. package/dist/services/vnext-code-review.js +235 -88
  522. package/dist/services/vnext-code.js +327 -226
  523. package/dist/services/vnext-contracts.js +10 -1
  524. package/dist/services/vnext-execution-profile.js +80 -5
  525. package/dist/services/vnext-fanout.js +355 -21
  526. package/dist/services/vnext-merge.js +332 -111
  527. package/dist/services/vnext-plan-review.js +287 -132
  528. package/dist/services/vnext-plan.js +228 -104
  529. package/dist/services/vnext-protocolize.js +533 -95
  530. package/dist/services/vnext-specify.js +123 -81
  531. package/dist/services/vnext-workspace-policy.js +7 -2
  532. package/dist/services/work-registry.js +1706 -200
  533. package/dist/services/workspace-bootstrap.js +53 -15
  534. package/dist/services/workspace-files.js +85 -0
  535. package/dist/services/worktrees.js +105 -48
  536. package/dist/shared/entity-references.js +1 -0
  537. package/dist/shared/errors.js +27 -0
  538. package/dist/storage/agent-output.js +26 -0
  539. package/dist/storage/data-preservation.js +65 -0
  540. package/dist/storage/database.js +930 -40
  541. package/dist/storage/foreign-key-transaction.js +39 -0
  542. package/dist/storage/immutable-input.js +45 -0
  543. package/dist/storage/import-guard.js +159 -0
  544. package/dist/storage/memory-upgrade-schema-bootstrap.js +38 -0
  545. package/dist/storage/native-cleanup.js +52 -0
  546. package/dist/storage/paired-writer-migration.js +424 -0
  547. package/dist/storage/paths.js +17 -4
  548. package/dist/storage/projection-lock.js +73 -0
  549. package/dist/storage/work-references.js +23 -0
  550. package/dist/storage/writer-contract.js +96 -0
  551. package/dist/storage/writer-migration.js +346 -0
  552. package/dist/storage/writer-restore.js +217 -0
  553. package/package.json +50 -13
  554. package/tools/create-canon-release.mjs +33 -0
  555. package/tools/probe-codex-history.mjs +37 -0
  556. package/tools/produce-hybrid-release.mjs +41 -0
  557. package/tools/repair-paused-run-status.mjs +84 -0
@@ -0,0 +1,390 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { setTimeout as delay } from "node:timers/promises";
3
+ import { ToolObservations, openCodeToolObservation } from "./tool-observations.mjs";
4
+ import { ObservationClock, observedTimeout, validateObservationDuration } from "./observation-clock.mjs";
5
+ import { assertNativeLine } from "./native-streams.mjs";
6
+ import { operationProgressReporter } from "./operation-progress.mjs";
7
+ import { classifyProviderError, safeProviderError } from "./provider-overload-policy.mjs";
8
+
9
+ export const OPENCODE_PROTOCOL = 2;
10
+ export class OpenCodeError extends Error {
11
+ constructor(code, message, retryable = false, details) { super(message); Object.assign(this, { code, retryable, details }); }
12
+ }
13
+ const lost = (message, details) => new OpenCodeError("operation_observation_lost", message, false, { native_outcome: "unknown", ...details });
14
+ export const requestDigest = value => createHash("sha256").update(JSON.stringify(value)).digest("hex");
15
+ export const nativeModel = ({ provider, model, variant }) => ({ providerID: provider, id: model, ...(variant && variant !== "default" ? { variant } : {}) });
16
+
17
+ /** Native finite session.log includes a control watermark, not a domain event. */
18
+ export function decodeFiniteLog(items, sessionId, after = 0) {
19
+ const fail = (reason, field, unproven = false) => { throw new OpenCodeError(unproven ? "opencode_observation_unproven" : "opencode_observation_corrupt", "OpenCode finite log has no trustworthy revision", false,
20
+ { native_outcome: "unknown", session_id: sessionId, cursor: after, reason, field }); };
21
+ if (!Number.isSafeInteger(after) || after < 0) fail("invalid_cursor", "after");
22
+ if (!Array.isArray(items)) fail("invalid_batch", "items");
23
+ const events = []; let watermark, cursor = after;
24
+ for (const item of items) {
25
+ if (watermark !== undefined) fail("frame_after_sync", "type");
26
+ const sync = item?.type === "log.synced", metadata = sync ? item : item?.durable;
27
+ if (!metadata) fail("missing_metadata", "durable");
28
+ if (metadata.aggregateID !== sessionId) fail("foreign_aggregate", sync ? "aggregateID" : "durable.aggregateID");
29
+ if (!Number.isSafeInteger(metadata.seq) || metadata.seq < 0) fail("invalid_sequence", sync ? "seq" : "durable.seq", sync && metadata.seq === undefined);
30
+ if (sync) {
31
+ if (metadata.seq < cursor) fail("watermark_behind_cursor", "seq");
32
+ watermark = metadata.seq;
33
+ } else {
34
+ if (typeof item.type !== "string" || !item.type.startsWith("session.") || !item.data || typeof item.data !== "object") fail("invalid_domain_event", "type/data");
35
+ if (item.data.sessionID !== undefined && item.data.sessionID !== sessionId) fail("foreign_session", "data.sessionID");
36
+ if (metadata.seq <= cursor) fail("non_increasing_sequence", "durable.seq");
37
+ cursor = metadata.seq; events.push(item);
38
+ }
39
+ }
40
+ if (watermark === undefined) fail("missing_sync", "log.synced", true);
41
+ return { events, watermark };
42
+ }
43
+
44
+ /** info/parts is our normalized projection, not a second v1 native protocol. */
45
+ export function normalizeMessage(message, sessionID) {
46
+ if (!message?.id || !message.type) throw lost("OpenCode message has no native identity");
47
+ const { model, time = {} } = message;
48
+ const parts = (message.content ?? []).map(part => part.type === "tool"
49
+ ? { ...part, tool: part.name, callID: part.id, state: { ...part.state, output: part.state?.result ?? part.state?.output } }
50
+ : { ...part });
51
+ if (message.type !== "assistant" && typeof message.text === "string") parts.push({ type: "text", text: message.text });
52
+ return { info: { id: message.id, sessionID, role: message.type, providerID: model?.providerID, modelID: model?.id,
53
+ variant: model?.variant ?? "default", mode: message.agent, finish: message.finish, error: message.error,
54
+ cost: message.cost, tokens: message.tokens, created: time.created, completed: time.completed, metadata: message.metadata, outcome: message.outcome }, parts };
55
+ }
56
+
57
+ export function providerFailure(native, sessionId, turnId) {
58
+ const status = native?.status, type = String(native?.type ?? "unknown");
59
+ const category = classifyProviderError(native), code = category === "provider_failed" ? "opencode_provider_failed" : category;
60
+ // Never forward response.body or provider credentials into controller/Judge.
61
+ return new OpenCodeError(code, `OpenCode native execution failed (${type}${status ? `, HTTP ${status}` : ""})`,
62
+ ["provider_capacity_transient", "provider_rate_limited"].includes(code), {
63
+ provider_session_id: sessionId, session_id: sessionId, turn_id: turnId, native_error_type: type,
64
+ native_turn_id: turnId, terminal_status: "failed",
65
+ provider_error: safeProviderError(native),
66
+ will_retry: native?.willRetry === true, native_retry_active: native?.willRetry === true,
67
+ native_turn_items: { observed: true, possible_effects: true, pending: false },
68
+ ...(Number.isInteger(status) ? { http_status: status } : {}), observed_at: new Date().toISOString(), native_source: "opencode.v2.session.execution" });
69
+ }
70
+
71
+ export class OpenCodeClient {
72
+ constructor({ baseUrl, password, directory, timeoutMs = 1_800_000, api }) {
73
+ Object.assign(this, { baseUrl: new URL(baseUrl), password, directory, timeoutMs });
74
+ this.ready = api ? Promise.resolve(api) : import("../vendor/opencode-client/promise/index.js").then(({ OpenCode }) => OpenCode.make({
75
+ baseUrl: this.baseUrl.href, headers: { authorization: `Basic ${Buffer.from(`opencode:${password}`).toString("base64")}` }
76
+ }));
77
+ }
78
+ async call(method, input, { timeoutMs, progress, onDispatched, productive = false, signal } = {}) {
79
+ const observation = this.readObservation?.();
80
+ timeoutMs ??= observation?.timeoutMs ?? this.timeoutMs; progress ??= observation?.progress;
81
+ const controller = new AbortController();
82
+ let timer;
83
+ const abort = () => { controller.abort(); clearInterval(timer); };
84
+ signal?.addEventListener("abort", abort, { once: true });
85
+ if (signal?.aborted) abort();
86
+ timer = observedTimeout(() => controller.abort(), timeoutMs, { progress });
87
+ if (signal?.aborted) clearInterval(timer);
88
+ try {
89
+ // Cover initialization as well as RPC. Abort still reaches the owned
90
+ // request; an unresolved module import cannot start a late RPC.
91
+ let rejectAbort;
92
+ const aborted = new Promise((_, reject) => { rejectAbort = () => reject(Object.assign(new Error("OpenCode probe aborted"), { name: "AbortError" })); controller.signal.addEventListener("abort", rejectAbort, { once: true }); });
93
+ let api;
94
+ try { if (controller.signal.aborted) rejectAbort(); api = await Promise.race([this.ready, aborted]); }
95
+ finally { controller.signal.removeEventListener("abort", rejectAbort); }
96
+ const keys = method.split("."), name = keys.pop(), domain = keys.reduce((value, key) => value?.[key], api);
97
+ if (typeof domain?.[name] !== "function") throw new OpenCodeError("opencode_capability_missing", `OpenCode v2 does not expose ${method}`);
98
+ const options = { signal: controller.signal };
99
+ const pending = input === undefined ? domain[name](options) : domain[name](input, options);
100
+ void pending.catch(() => {}); await onDispatched?.(); const result = await pending;
101
+ assertNativeLine(JSON.stringify(result ?? null)); return result;
102
+ } catch (cause) {
103
+ if (cause instanceof OpenCodeError || cause.code === "operation_observation_lost") throw cause;
104
+ if (cause._tag === "SessionNotFoundError" || cause._tag === "NotFoundError") throw new OpenCodeError("session_not_found", "OpenCode native Session is unavailable");
105
+ if (productive && ["InvalidRequestError", "ConflictError", "UnauthorizedError", "ForbiddenError"].includes(cause._tag))
106
+ throw new OpenCodeError("opencode_admission_rejected", "OpenCode rejected native admission", false, { effect: "no_effect", native_type: cause._tag });
107
+ if (!productive && ["UnauthorizedError", "ForbiddenError"].includes(cause._tag)) throw new OpenCodeError("opencode_auth_rejected", "OpenCode rejected authentication", false, { method, native_type: cause._tag });
108
+ if (!productive && ["InvalidRequestError", "ConflictError"].includes(cause._tag)) throw new OpenCodeError("opencode_configuration_invalid", "OpenCode rejected the diagnostic request", false, { method, native_type: cause._tag });
109
+ if (productive || controller.signal.aborted) throw Object.assign(lost(`OpenCode observer lost during ${method}`, { method }), { cause });
110
+ throw Object.assign(new OpenCodeError("opencode_unavailable", `OpenCode ${method} observation failed`, true,
111
+ { method, native_type: cause._tag ?? cause.name ?? null, native_reason: cause.reason ?? null }), { cause });
112
+ } finally { clearInterval(timer); signal?.removeEventListener("abort", abort); }
113
+ }
114
+ async health(options = {}) {
115
+ const info = await this.call("server.info", undefined, { timeoutMs: 5_000, ...options });
116
+ if (!/^2\./.test(info?.version) || !Number.isInteger(info.pid)) throw new OpenCodeError("unsupported_version", "OpenCode v2 server identity is unavailable");
117
+ return info;
118
+ }
119
+ async pages(method, input) {
120
+ const items = new Map(), seen = new Set(); let cursor;
121
+ do {
122
+ const page = await this.call(method, { ...input, limit: 100, ...(cursor ? { cursor } : { order: "asc" }) });
123
+ if (!Array.isArray(page?.data)) throw lost(`OpenCode ${method} returned an invalid page`);
124
+ for (const item of page.data) { if (!item?.id) throw lost("OpenCode page item has no identity"); items.set(item.id, item); }
125
+ cursor = page.cursor?.next;
126
+ if (cursor && seen.has(cursor)) throw lost("OpenCode pagination cursor repeated");
127
+ if (cursor) seen.add(cursor);
128
+ } while (cursor);
129
+ return [...items.values()];
130
+ }
131
+ create(title, profile = {}, id) { return this.call("session.create", { ...(title ? { title } : {}), ...(id ? { id } : {}),
132
+ location: { directory: this.directory }, agent: profile.agent ?? "build", model: nativeModel(profile) }, { productive: true }); }
133
+ async inspect(id) { const info = await this.call("session.get", { sessionID: id }); return { ...info, directory: info.location?.directory }; }
134
+ list() { return this.pages("session.list", { directory: this.directory }); }
135
+ async statuses() { const active = await this.call("session.active"); return Object.fromEntries(Object.keys(active).map(id => [id, { type: "busy" }])); }
136
+ async children(id) { return (await this.pages("session.list", { parentID: id })).map(info => ({ ...info, directory: info.location?.directory })); }
137
+ async messages(id) { return (await this.pages("message.list", { sessionID: id })).map(message => normalizeMessage(message, id)); }
138
+ inbox(id) { return this.call("session.inbox.list", { sessionID: id }); }
139
+ async shellDirectory(id) { const api = await this.ready; return typeof api.session?.get === "function" ? (await this.inspect(id)).directory : this.directory; }
140
+ async shells(id) { const directory = await this.shellDirectory(id); const result = await this.call("shell.list", { location: { directory } }); return result.data.filter(item => item.metadata?.sessionID === id).map(item => ({ ...item, location: item.location ?? { directory } })); }
141
+ async pending(id) {
142
+ const [inbox, forms, permissions] = await Promise.all([this.inbox(id), this.call("session.form.list", { sessionID: id }), this.call("permission.list", { sessionID: id })]);
143
+ const value = { inbox, forms: forms.data ?? forms, permissions: permissions.data ?? permissions };
144
+ if (Object.values(value).some(items => !Array.isArray(items))) throw lost("OpenCode returned invalid pending-input evidence", { session_id: id });
145
+ return value;
146
+ }
147
+ async logs(id, after = 0) {
148
+ const api = await this.ready, controller = new AbortController(), events = [];
149
+ const observation = this.readObservation?.();
150
+ const timer = observedTimeout(() => controller.abort(), observation?.timeoutMs ?? this.timeoutMs, { progress: observation?.progress });
151
+ try { for await (const event of api.session.log({ sessionID: id, after, follow: false }, { signal: controller.signal })) events.push(event); }
152
+ catch (cause) { throw Object.assign(lost("OpenCode durable log observation failed", { session_id: id }), { cause }); }
153
+ finally { clearInterval(timer); }
154
+ return decodeFiniteLog(events, id, after);
155
+ }
156
+ async abort(id) {
157
+ // Queued input must not become fresh work during interruption cleanup.
158
+ for (const item of await this.inbox(id)) await this.call("session.inbox.cancel", { sessionID: id, inboxID: item.id }, { productive: true });
159
+ const result = await this.call("session.interrupt", { sessionID: id, resume: false }, { productive: true });
160
+ const api = await this.ready;
161
+ if (typeof api.shell?.list === "function") for (const shell of await this.shells(id)) {
162
+ if (shell.status === "running") await this.call("shell.remove", { id: shell.id, location: shell.location }, { productive: true });
163
+ }
164
+ return result;
165
+ }
166
+ fork(id, messageID) { return this.call("session.fork", { sessionID: id, ...(messageID ? { before: messageID } : {}) }, { productive: true }); }
167
+ delete(id) { return this.call("session.remove", { sessionID: id }, { productive: true }); }
168
+ export(id) { return this.call("session.export", { sessionID: id }); }
169
+ import(data) { return this.call("session.import", data, { productive: true }); }
170
+
171
+ async prompt(id, { prompt, messageId = `msg_${randomUUID().replaceAll("-", "")}`, retained,
172
+ save, onModelMessages, onObservationError, assertDispatch, onDispatched, checkHookFailures, livenessTimeoutMs = this.timeoutMs }) {
173
+ validateObservationDuration(livenessTimeoutMs);
174
+ const request = { sessionID: id, id: messageId, text: prompt, delivery: "queue", resume: true }, digest = requestDigest(request);
175
+ if (retained && (retained.request_sha256 !== digest || retained.message_id !== messageId)) throw new OpenCodeError("operation_request_mismatch", "OpenCode operation already binds another prompt", false, { effect: "no_effect" });
176
+ let state = retained ?? { message_id: messageId, request_sha256: digest, phase: "prepared", cursor: 0 };
177
+ const previous = await this.messages(id), baseline = new Map([[id, new Set(previous.map(item => item.info.id))]]), parents = new Map();
178
+ const capture = async session => { for (const child of await this.children(session)) { parents.set(child.id, child.parentID); baseline.set(child.id, new Set((await this.messages(child.id)).map(item => item.info.id))); await capture(child.id); } };
179
+ await capture(id);
180
+ if (retained) {
181
+ const index = previous.findIndex(item => item.info.id === messageId);
182
+ if (index >= 0) baseline.set(id, new Set(previous.slice(0, index + 1).map(item => item.info.id)));
183
+ }
184
+ assertDispatch?.(); // Cancellation/ownership wins before observer setup.
185
+ const api = await this.ready, streamAbort = new AbortController(), clock = new ObservationClock({ timeoutMs: livenessTimeoutMs });
186
+ const publish = operationProgressReporter(), known = new Set([id, ...baseline.keys()]), signatures = new Map(), shellCursors = new Map(), liveSeen = new Set();
187
+ let progress = 0, marker, stream;
188
+ const liveParts = new Map(), liveShells = new Map(), backgroundShells = new Set();
189
+ const completedTools = new Set(), outputReads = new Map(), shellLocations = new Map();
190
+ const observationErrors = { count: 0 };
191
+ const observeOutput = (shellID, location) => {
192
+ if (outputReads.has(shellID) || !location?.directory) return;
193
+ const cursor = shellCursors.get(shellID) ?? 0;
194
+ const pending = this.call("shell.output", { id: shellID, location, cursor, limit: 65536 }, { signal: streamAbort.signal })
195
+ .then(async output => { const data = output.data ?? output; if (!streamAbort.signal.aborted && data.cursor > cursor) { shellCursors.set(shellID, data.cursor); await advance(); } })
196
+ .catch(async error => {
197
+ if (streamAbort.signal.aborted) return;
198
+ const diagnostic = { method: "shell.output", shell_id: shellID, native_type: error.details?.native_type ?? error.cause?._tag ?? null, http_status: error.cause?.status ?? null };
199
+ observationErrors.count++; observationErrors.first ??= diagnostic; observationErrors.last = diagnostic;
200
+ if (observationErrors.count === 1) await onObservationError?.(error);
201
+ }).finally(() => outputReads.delete(shellID));
202
+ outputReads.set(shellID, pending); void pending.catch(() => {});
203
+ };
204
+ const advance = async (observedAt = Date.now()) => { marker = { cursor: ++progress, observed_at: observedAt }; await publish("native_progress", { session_id: id, observed_at: new Date(marker.observed_at).toISOString() }); };
205
+ let connected;
206
+ const connection = new Promise(resolve => { connected = resolve; });
207
+ const connectionTimer = api.event?.subscribe ? observedTimeout(() => { connected(false); streamAbort.abort(); }, livenessTimeoutMs) : null;
208
+ if (api.event?.subscribe) stream = (async () => {
209
+ try { for await (const event of api.event.subscribe({ signal: streamAbort.signal, onActivity: () => connected(true) })) {
210
+ connected(true); // Stream establishment is not model progress.
211
+ const data = event.data, floor = baseline.get(data?.sessionID);
212
+ if (known.has(data?.sessionID) && data?.assistantMessageID && !floor?.has(data.assistantMessageID)
213
+ && event.created >= clock.startedWall && event.created <= Date.now() && event.id && !liveSeen.has(event.id)
214
+ && ["session.text.delta", "session.reasoning.delta", "session.tool.input.delta", "session.tool.progress"].includes(event.type)) {
215
+ liveSeen.add(event.id); if (liveSeen.size > 1024) liveSeen.delete(liveSeen.values().next().value);
216
+ const key = `${data.sessionID}:${data.assistantMessageID}:${data.id ?? ""}`, signature = requestDigest(data.metadata ?? null);
217
+ if (event.type === "session.tool.progress" && completedTools.has(key)) continue;
218
+ if (event.type === "session.tool.progress" && typeof data.metadata?.shellID === "string" && !completedTools.has(key)) liveShells.set(key, data.metadata.shellID);
219
+ if (typeof data.delta === "string" && data.delta.length || event.type === "session.tool.progress" && liveParts.get(key) !== signature) {
220
+ liveParts.set(key, signature); await advance(event.created);
221
+ }
222
+ }
223
+ } } catch (error) { if (!streamAbort.signal.aborted) await onObservationError?.(error); }
224
+ finally { connected(false); }
225
+ })();
226
+ const priorObservation = this.readObservation;
227
+ this.readObservation = () => {
228
+ if (clock.sample(marker)) throw lost("OpenCode operation observation expired", { session_id: id, message_id: messageId, observation: clock.state() });
229
+ return { timeoutMs: Math.max(1, Math.ceil(livenessTimeoutMs - clock.elapsed)), progress: () => marker };
230
+ };
231
+ try {
232
+ if (api.event?.subscribe && !await connection) throw new OpenCodeError("opencode_unavailable", "Native observer stream could not be established before dispatch", true, { effect: "no_effect" });
233
+ clearInterval(connectionTimer);
234
+ if (!retained) {
235
+ await save?.(state); assertDispatch?.();
236
+ // Subscribe before dispatch; persisted intent precedes HTTP. Unknown
237
+ // ack permits reconciliation only, never another same-ID wake.
238
+ state = { ...state, phase: "dispatched" }; await save?.(state);
239
+ try {
240
+ const admission = await this.call("session.prompt", request, { productive: true, onDispatched });
241
+ if (admission?.id !== messageId || admission.sessionID !== id) throw lost("OpenCode prompt acknowledgement has another identity");
242
+ state = { ...state, phase: "admitted" }; await save?.(state);
243
+ } catch (error) {
244
+ if (error.details?.effect === "no_effect") throw error;
245
+ await onObservationError?.(error);
246
+ }
247
+ }
248
+ for (;;) {
249
+ try {
250
+ await checkHookFailures?.();
251
+ const { events, watermark } = await this.logs(id, state.cursor);
252
+ let delivered = state.delivered === true, terminal = state.terminal;
253
+ for (const event of events) {
254
+ if (event.type === "session.inbox.delivered" && event.data.inboxID === messageId) { delivered = true; terminal = null; }
255
+ if (delivered && event.type === "session.execution.started") terminal = null;
256
+ if (delivered && ["session.execution.succeeded", "session.execution.failed", "session.execution.interrupted"].includes(event.type)) terminal = { type: event.type, error: event.data.error };
257
+ state = { ...state, cursor: event.durable.seq, delivered, terminal }; await save?.(state);
258
+ }
259
+ if (state.cursor !== watermark) { state = { ...state, cursor: watermark }; await save?.(state); }
260
+ let runningTools = false;
261
+ const observe = async (session, visited = new Set()) => {
262
+ if (visited.has(session)) throw lost("OpenCode topology contains a cycle"); visited.add(session); known.add(session);
263
+ const messages = await this.messages(session);
264
+ await onModelMessages?.(session, messages, parents.get(session) ?? null);
265
+ const floor = baseline.get(session) ?? new Set(), current = messages.filter(item => item.info.role === "assistant" && !floor.has(item.info.id));
266
+ for (const item of current) {
267
+ const key = `${session}:${item.info.id}`, encoded = JSON.stringify(item.parts.map(stablePart)), next = requestDigest(encoded), before = signatures.get(key);
268
+ if (before?.signature !== next && !before?.seen.has(next) && (!before || before.seen.size < 128 || encoded.length > before.highWater)) {
269
+ if (item.parts.length) await advance();
270
+ const seen = before?.seen ?? new Set(); if (seen.size < 128) seen.add(next);
271
+ signatures.set(key, { signature: next, seen, highWater: Math.max(before?.highWater ?? 0, encoded.length) });
272
+ }
273
+ for (const part of item.parts) {
274
+ const toolKey = `${session}:${item.info.id}:${part.id}`;
275
+ if (part.type === "tool" && ["running", "streaming", "pending"].includes(part.state?.status)) runningTools = true;
276
+ if (part.type === "tool" && !["running", "streaming", "pending"].includes(part.state?.status)) { completedTools.add(toolKey); liveShells.delete(toolKey); }
277
+ let shellID = part.type === "tool" ? part.state?.metadata?.shellID ?? liveShells.get(toolKey) : null;
278
+ if (!shellID && part.tool === "shell" && part.state?.status === "running") {
279
+ // Tool progress metadata is volatile in the CLI. Reconcile
280
+ // only an unambiguous native shell in this current message.
281
+ const candidates = (await this.shells(session)).filter(shell => shell.time.started >= item.info.created);
282
+ if (candidates.length === 1) { shellID = candidates[0].id; shellLocations.set(shellID, candidates[0].location); }
283
+ }
284
+ if (!shellID) continue;
285
+ const cursor = shellCursors.get(shellID) ?? 0;
286
+ shellCursors.set(shellID, cursor); // Zero-output shells still own their native notification.
287
+ if (part.tool === "shell" && part.state?.metadata?.status === "running") backgroundShells.add(shellID);
288
+ if (!completedTools.has(toolKey)) {
289
+ if (!shellLocations.has(shellID)) shellLocations.set(shellID, (await this.shells(session)).find(shell => shell.id === shellID)?.location);
290
+ observeOutput(shellID, shellLocations.get(shellID));
291
+ }
292
+ }
293
+ }
294
+ for (const child of await this.children(session)) {
295
+ if (child.parentID !== session) throw lost("OpenCode child has a foreign parent");
296
+ parents.set(child.id, session); await observe(child.id, visited);
297
+ }
298
+ return current;
299
+ };
300
+ const current = await observe(id), rootMessages = await this.messages(id);
301
+ // CLI v2 defaults to non-persistent event payloads. The native
302
+ // projected user + idle records remain durable and carry the
303
+ // exact terminal error; do not invent a 'latest assistant' outcome.
304
+ const deliveredIndex = rootMessages.findIndex(item => item.info.id === messageId && item.info.role === "user");
305
+ if (deliveredIndex >= 0) {
306
+ for (const item of rootMessages.slice(deliveredIndex + 1)) {
307
+ if (item.info.role === "synthetic" && item.info.metadata?.source === "subagent"
308
+ && typeof item.info.metadata.childID === "string" && parents.get(item.info.metadata.childID) !== id) {
309
+ // Native messages and topology are separate reads: a child can
310
+ // finish between them. Reconcile its ancestry before rejecting
311
+ // the notification, never trust the notification alone.
312
+ const child = (await this.children(id)).find(child => child.id === item.info.metadata.childID && child.parentID === id);
313
+ if (child) { parents.set(child.id, id); await observe(child.id); }
314
+ }
315
+ if (item.info.role === "user" || item.info.role === "synthetic" && !(
316
+ item.info.metadata?.source === "subagent" && parents.get(item.info.metadata.childID) === id
317
+ || item.info.metadata?.source === "shell" && shellCursors.has(item.info.metadata.shellID)))
318
+ throw new OpenCodeError("opencode_foreign_input", "OpenCode received input outside the owned operation", false, { session_id: id, message_id: item.info.id, role: item.info.role, source: item.info.metadata?.source });
319
+ }
320
+ const terminal = rootMessages.slice(deliveredIndex + 1).findLast(item => item.info.role === "idle");
321
+ if (terminal) {
322
+ if (!["succeeded", "failed", "interrupted"].includes(terminal.info.outcome)) throw lost("OpenCode idle record has no proven native outcome");
323
+ state = { ...state, delivered: true, terminal: { type: `session.execution.${terminal.info.outcome}`, error: terminal.info.error } }; await save?.(state);
324
+ }
325
+ }
326
+ const statuses = await this.statuses(); let unsettled = runningTools;
327
+ // A background child's native completion notification is delivered
328
+ // asynchronously. An idle parent before that delivery is not the
329
+ // completion of the coordinating operation.
330
+ const deliveredNotifications = new Set(rootMessages.filter(item => item.info.role === "synthetic" && item.info.metadata?.source === "subagent").map(item => item.info.metadata.childID));
331
+ const shellNotifications = new Set(rootMessages.filter(item => item.info.role === "synthetic" && item.info.metadata?.source === "shell").map(item => item.info.metadata.shellID));
332
+ unsettled ||= [...backgroundShells].some(shell => !shellNotifications.has(shell));
333
+ for (const item of current) for (const part of item.parts) {
334
+ if (part.tool === "subagent" && part.state?.input?.background === true) {
335
+ const child = part.state?.metadata?.sessionID;
336
+ if (!child || !deliveredNotifications.has(child)) unsettled = true;
337
+ }
338
+ }
339
+ for (const session of known) {
340
+ const pending = await this.pending(session);
341
+ if (pending.forms.length || pending.permissions.length) throw new OpenCodeError("opencode_native_hitl", "OpenCode requires native operator input", false, { provider_session_id: session, form_ids: pending.forms.map(item => item.id), permission_ids: pending.permissions.map(item => item.id) });
342
+ unsettled ||= Boolean(statuses[session]) || pending.inbox.length > 0;
343
+ if (typeof api.shell?.list === "function") unsettled ||= (await this.shells(session)).some(shell => shell.status === "running");
344
+ }
345
+ if (state.delivered && state.terminal && !unsettled) {
346
+ await checkHookFailures?.();
347
+ if (state.terminal.type === "session.execution.failed") throw providerFailure(state.terminal.error, id, messageId);
348
+ if (state.terminal.type === "session.execution.interrupted") throw new OpenCodeError("opencode_execution_interrupted", "OpenCode execution was interrupted", false, { provider_session_id: id, turn_id: messageId });
349
+ const final = current.findLast(item => item.info.completed !== undefined && item.info.finish && item.info.finish !== "tool-calls");
350
+ if (!final) throw lost("OpenCode terminal has no current assistant response", { session_id: id, message_id: messageId });
351
+ if (final.info.error) throw providerFailure(final.info.error, id, messageId);
352
+ return { ...final, admission_message_id: messageId, log_cursor: state.cursor, ...(observationErrors.count ? { observation_errors: observationErrors } : {}) };
353
+ }
354
+ } catch (error) {
355
+ await checkHookFailures?.();
356
+ if (error instanceof OpenCodeError && !["opencode_unavailable", "operation_observation_lost"].includes(error.code)) throw error;
357
+ await onObservationError?.(error);
358
+ }
359
+ if (clock.sample(marker)) throw lost("OpenCode native progress stopped or observation could not recover", { session_id: id, message_id: messageId, observation: clock.state(), ...(observationErrors.count ? { observation_errors: observationErrors } : {}) });
360
+ await delay(Math.max(5, Math.min(500, livenessTimeoutMs / 4)));
361
+ }
362
+ } finally { clearInterval(connectionTimer); this.readObservation = priorObservation; streamAbort.abort(); await stream; }
363
+ }
364
+ }
365
+
366
+ function stablePart(part) {
367
+ if (part.type === "text" || part.type === "reasoning") return { type: part.type, text: part.text };
368
+ if (part.type === "tool") return { type: "tool", tool: part.tool, state: part.state };
369
+ return { type: part.type };
370
+ }
371
+ export function canonicalHistory(messages) {
372
+ return messages.map(({ info, parts }) => ({ role: info.role, ...(info.role === "assistant" ? { provider: info.providerID, model: info.modelID, mode: info.mode, finish: info.finish ?? null, error: info.error?.type ?? null } : {}), parts: parts.map(stablePart) }));
373
+ }
374
+ export function historyDigest(messages) { return requestDigest(canonicalHistory(messages)); }
375
+ export function usageSnapshot(messages, sessionId) {
376
+ const assistants = messages.filter(item => item.info?.role === "assistant"), tokens = { input: 0, output: 0, reasoning: 0, cache_read: 0, cache_write: 0 };
377
+ let complete = true, cost = 0, costComplete = true;
378
+ for (const item of assistants) {
379
+ const value = item.info.tokens; complete &&= Boolean(value && [value.input, value.output, value.reasoning, value.cache?.read, value.cache?.write].every(Number.isFinite));
380
+ for (const name of ["input", "output", "reasoning"]) tokens[name] += value?.[name] ?? 0;
381
+ tokens.cache_read += value?.cache?.read ?? 0; tokens.cache_write += value?.cache?.write ?? 0;
382
+ costComplete &&= Number.isFinite(item.info.cost); cost += item.info.cost ?? 0;
383
+ }
384
+ const tools = new ToolObservations();
385
+ for (const item of messages) for (const part of item.parts ?? []) tools.add(openCodeToolObservation(part, item.info?.sessionID ?? sessionId, item.info?.id));
386
+ return { input_tokens: tokens.input, output_tokens: tokens.output, reasoning_tokens: tokens.reasoning,
387
+ cached_input_tokens: tokens.cache_read, cache_write_tokens: tokens.cache_write,
388
+ total_tokens: tokens.input + tokens.output + tokens.reasoning + tokens.cache_read + tokens.cache_write,
389
+ tool_calls: tools.summary(), cost_usd: costComplete ? cost : null, completeness: complete ? "complete" : "partial" };
390
+ }