@deksden-com/dd-flow-cli 0.9.0-beta.16 → 0.9.0-beta.161

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 (670) hide show
  1. package/CHANGELOG.md +965 -0
  2. package/README.md +139 -10
  3. package/dist/build-info.json +8 -8
  4. package/dist/cli/argument-values.js +38 -0
  5. package/dist/cli/command-inputs.js +417 -0
  6. package/dist/cli/command-metadata.js +303 -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/delivery.js +108 -0
  11. package/dist/cli/diagnostic-invocation.js +62 -0
  12. package/dist/cli/diagnostic.js +131 -0
  13. package/dist/cli/error-output.js +62 -0
  14. package/dist/cli/executor-onboarding.js +76 -0
  15. package/dist/cli/flows.js +29 -0
  16. package/dist/cli/harnesses.js +84 -0
  17. package/dist/cli/help.js +521 -19
  18. package/dist/cli/hook-ingress.js +89 -0
  19. package/dist/cli/input-preparation.js +193 -0
  20. package/dist/cli/interactive-invocation.js +33 -0
  21. package/dist/cli/interactive.js +114 -0
  22. package/dist/cli/memory-fix-invocation.js +52 -0
  23. package/dist/cli/memory-fix.js +100 -0
  24. package/dist/cli/memory-flow-admission.js +54 -0
  25. package/dist/cli/memory-init-invocation.js +85 -0
  26. package/dist/cli/memory-init.js +250 -0
  27. package/dist/cli/memory-storage-admission.js +54 -0
  28. package/dist/cli/memory-storage-qualification.js +105 -0
  29. package/dist/cli/memory-storage-transition.js +123 -0
  30. package/dist/cli/memory-upgrade.js +189 -0
  31. package/dist/cli/models.js +39 -0
  32. package/dist/cli/native-hook-ingress.js +94 -0
  33. package/dist/cli/native-hook-preparation.js +82 -0
  34. package/dist/cli/operator-profiles.js +61 -0
  35. package/dist/cli/output-options.js +35 -0
  36. package/dist/cli/response-file.js +72 -0
  37. package/dist/cli/run-cli.js +2020 -555
  38. package/dist/cli/runtime-maintenance-diagnostics.js +46 -0
  39. package/dist/cli/runtime-maintenance-ingress.js +52 -0
  40. package/dist/cli/runtime-process.js +153 -0
  41. package/dist/cli/setup.js +150 -0
  42. package/dist/cli.js +103 -2
  43. package/dist/domain/delivery-flows.js +8 -0
  44. package/dist/domain/diagnostic-aspects.js +103 -0
  45. package/dist/domain/diagnostic-flows.js +8 -0
  46. package/dist/domain/distill-flow.js +20 -0
  47. package/dist/domain/interactive-flow.js +1 -0
  48. package/dist/domain/memory-fix-flow.js +2 -0
  49. package/dist/domain/review-fix-flow.js +2 -0
  50. package/dist/domain/source-snapshot-flows.js +4 -0
  51. package/dist/domain/stage-catalog.js +1 -1
  52. package/dist/domain/stage-handler-identities.js +28 -0
  53. package/dist/harness-runtime/DD-ZCODE.md +112 -0
  54. package/dist/harness-runtime/OPENCODE-LICENSE.txt +24 -0
  55. package/dist/harness-runtime/bin/dd-agy.mjs +71 -0
  56. package/dist/harness-runtime/bin/dd-codex.mjs +27 -0
  57. package/dist/harness-runtime/bin/dd-droid.mjs +34 -0
  58. package/dist/harness-runtime/bin/dd-grok.mjs +50 -0
  59. package/dist/harness-runtime/bin/dd-opencode.mjs +22 -0
  60. package/dist/harness-runtime/bin/dd-zcode.mjs +95 -0
  61. package/dist/harness-runtime/lib/adapter-timeouts.d.mts +5 -0
  62. package/dist/harness-runtime/lib/adapter-timeouts.mjs +34 -0
  63. package/dist/harness-runtime/lib/agy-error-boundary.mjs +87 -0
  64. package/dist/harness-runtime/lib/agy-hooks.d.mts +1 -0
  65. package/dist/harness-runtime/lib/agy-hooks.mjs +9 -0
  66. package/dist/harness-runtime/lib/agy-native-inspection.mjs +225 -0
  67. package/dist/harness-runtime/lib/agy-native-inventory.mjs +19 -0
  68. package/dist/harness-runtime/lib/agy-native_pb.js +117 -0
  69. package/dist/harness-runtime/lib/agy-terminal-envelope.mjs +74 -0
  70. package/dist/harness-runtime/lib/agy-transcript-stream.mjs +54 -0
  71. package/dist/harness-runtime/lib/daemon-observation.d.mts +3 -0
  72. package/dist/harness-runtime/lib/daemon-observation.mjs +171 -0
  73. package/dist/harness-runtime/lib/daemon-operations.d.mts +2 -0
  74. package/dist/harness-runtime/lib/daemon-operations.mjs +512 -0
  75. package/dist/harness-runtime/lib/dd-agy-daemon.d.mts +7 -0
  76. package/dist/harness-runtime/lib/dd-agy-daemon.mjs +1362 -0
  77. package/dist/harness-runtime/lib/dd-agy.mjs +105 -0
  78. package/dist/harness-runtime/lib/dd-codex-daemon.d.mts +1 -0
  79. package/dist/harness-runtime/lib/dd-codex-daemon.mjs +271 -0
  80. package/dist/harness-runtime/lib/dd-codex.d.mts +1 -0
  81. package/dist/harness-runtime/lib/dd-codex.mjs +986 -0
  82. package/dist/harness-runtime/lib/dd-droid-daemon.mjs +155 -0
  83. package/dist/harness-runtime/lib/dd-droid.mjs +739 -0
  84. package/dist/harness-runtime/lib/dd-grok-daemon.d.mts +1 -0
  85. package/dist/harness-runtime/lib/dd-grok-daemon.mjs +667 -0
  86. package/dist/harness-runtime/lib/dd-grok.mjs +182 -0
  87. package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +772 -0
  88. package/dist/harness-runtime/lib/dd-opencode.mjs +411 -0
  89. package/dist/harness-runtime/lib/dd-zcode-daemon.d.mts +1 -0
  90. package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +845 -0
  91. package/dist/harness-runtime/lib/dd-zcode.mjs +1239 -0
  92. package/dist/harness-runtime/lib/delegation-instructions.d.mts +16 -0
  93. package/dist/harness-runtime/lib/delegation-instructions.mjs +179 -0
  94. package/dist/harness-runtime/lib/delivery-command.mjs +84 -0
  95. package/dist/harness-runtime/lib/dispatch-fence.mjs +14 -0
  96. package/dist/harness-runtime/lib/driver-recovery.mjs +121 -0
  97. package/dist/harness-runtime/lib/droid-observation.mjs +70 -0
  98. package/dist/harness-runtime/lib/entity-references.d.mts +2 -0
  99. package/dist/harness-runtime/lib/entity-references.mjs +9 -0
  100. package/dist/harness-runtime/lib/lease-renewal.d.mts +8 -0
  101. package/dist/harness-runtime/lib/lease-renewal.mjs +37 -0
  102. package/dist/harness-runtime/lib/lifecycle-command.d.mts +20 -0
  103. package/dist/harness-runtime/lib/lifecycle-command.mjs +273 -0
  104. package/dist/harness-runtime/lib/lifecycle-contract.d.mts +11 -0
  105. package/dist/harness-runtime/lib/lifecycle-contract.mjs +20 -0
  106. package/dist/harness-runtime/lib/managed-daemon.d.mts +16 -0
  107. package/dist/harness-runtime/lib/managed-daemon.mjs +698 -0
  108. package/dist/harness-runtime/lib/managed-flow-env.mjs +15 -0
  109. package/dist/harness-runtime/lib/model-observations.mjs +113 -0
  110. package/dist/harness-runtime/lib/native-children.d.mts +34 -0
  111. package/dist/harness-runtime/lib/native-children.mjs +265 -0
  112. package/dist/harness-runtime/lib/native-hook-command.d.mts +8 -0
  113. package/dist/harness-runtime/lib/native-hook-command.mjs +306 -0
  114. package/dist/harness-runtime/lib/native-request-proof.d.mts +2 -0
  115. package/dist/harness-runtime/lib/native-request-proof.mjs +65 -0
  116. package/dist/harness-runtime/lib/native-streams.mjs +38 -0
  117. package/dist/harness-runtime/lib/observation-clock.d.mts +18 -0
  118. package/dist/harness-runtime/lib/observation-clock.mjs +95 -0
  119. package/dist/harness-runtime/lib/opencode-plugin.mjs +112 -0
  120. package/dist/harness-runtime/lib/operation-context.mjs +5 -0
  121. package/dist/harness-runtime/lib/operation-errors.d.mts +16 -0
  122. package/dist/harness-runtime/lib/operation-errors.mjs +140 -0
  123. package/dist/harness-runtime/lib/operation-progress.d.mts +7 -0
  124. package/dist/harness-runtime/lib/operation-progress.mjs +118 -0
  125. package/dist/harness-runtime/lib/process-json.d.mts +5 -0
  126. package/dist/harness-runtime/lib/process-json.mjs +200 -0
  127. package/dist/harness-runtime/lib/process-snapshot.mjs +10 -0
  128. package/dist/harness-runtime/lib/provider-overload-policy.d.mts +23 -0
  129. package/dist/harness-runtime/lib/provider-overload-policy.mjs +242 -0
  130. package/dist/harness-runtime/lib/runner-events.mjs +202 -0
  131. package/dist/harness-runtime/lib/runner-lock.mjs +42 -0
  132. package/dist/harness-runtime/lib/session-settlement.mjs +30 -0
  133. package/dist/harness-runtime/lib/setup-progress.d.mts +9 -0
  134. package/dist/harness-runtime/lib/setup-progress.mjs +53 -0
  135. package/dist/harness-runtime/lib/tool-observations.d.mts +21 -0
  136. package/dist/harness-runtime/lib/tool-observations.mjs +238 -0
  137. package/dist/harness-runtime/lib/zcode-native-hook-ownership.mjs +109 -0
  138. package/dist/harness-runtime/lib/zcode-usage.mjs +55 -0
  139. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-1y4a697q.js +81 -0
  140. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-2ny4vxct.js +92 -0
  141. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-6mptkzbc.js +0 -0
  142. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-7x67cf1q.js +52 -0
  143. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9rqn6x4v.js +16 -0
  144. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9vdz0zwn.js +1661 -0
  145. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ecs5ftka.js +1466 -0
  146. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-frbwqjmf.js +145 -0
  147. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gne7h7mq.js +50 -0
  148. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gx9wnkzr.js +105 -0
  149. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-m2eywc8w.js +0 -0
  150. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-nwcpakzx.js +12 -0
  151. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-q4g3afnw.js +623 -0
  152. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-qav6mfdz.js +0 -0
  153. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-sxt88q69.js +12 -0
  154. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-t1xa31vm.js +39 -0
  155. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ve4aws36.js +103 -0
  156. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vmytr4q8.js +4 -0
  157. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vt9jbch8.js +36 -0
  158. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vyas3vgt.js +0 -0
  159. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-wjyeq25y.js +30 -0
  160. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-xgnj2w4v.js +20 -0
  161. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-y2etg5bs.js +9 -0
  162. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ydhz1zrh.js +238 -0
  163. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-z6qdwcsf.js +62 -0
  164. package/dist/harness-runtime/vendor/opencode-client/contract.d.ts +1 -0
  165. package/dist/harness-runtime/vendor/opencode-client/contract.js +12 -0
  166. package/dist/harness-runtime/vendor/opencode-client/effect/api/api.d.ts +2806 -0
  167. package/dist/harness-runtime/vendor/opencode-client/effect/api/api.js +0 -0
  168. package/dist/harness-runtime/vendor/opencode-client/effect/api.d.ts +4 -0
  169. package/dist/harness-runtime/vendor/opencode-client/effect/api.js +0 -0
  170. package/dist/harness-runtime/vendor/opencode-client/effect/client.d.ts +2530 -0
  171. package/dist/harness-runtime/vendor/opencode-client/effect/client.js +15 -0
  172. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.d.ts +7 -0
  173. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.js +6 -0
  174. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.d.ts +2529 -0
  175. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.js +8 -0
  176. package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.d.ts +2 -0
  177. package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.js +12 -0
  178. package/dist/harness-runtime/vendor/opencode-client/effect/index.d.ts +35 -0
  179. package/dist/harness-runtime/vendor/opencode-client/effect/index.js +75 -0
  180. package/dist/harness-runtime/vendor/opencode-client/effect/rpc.d.ts +20 -0
  181. package/dist/harness-runtime/vendor/opencode-client/effect/rpc.js +11 -0
  182. package/dist/harness-runtime/vendor/opencode-client/effect/service.d.ts +90 -0
  183. package/dist/harness-runtime/vendor/opencode-client/effect/service.js +187 -0
  184. package/dist/harness-runtime/vendor/opencode-client/package.json +84 -0
  185. package/dist/harness-runtime/vendor/opencode-client/promise/api.d.ts +21 -0
  186. package/dist/harness-runtime/vendor/opencode-client/promise/api.js +0 -0
  187. package/dist/harness-runtime/vendor/opencode-client/promise/client.d.ts +252 -0
  188. package/dist/harness-runtime/vendor/opencode-client/promise/client.js +14 -0
  189. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.d.ts +8 -0
  190. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.js +6 -0
  191. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.d.ts +259 -0
  192. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.js +7 -0
  193. package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.d.ts +3 -0
  194. package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.js +79 -0
  195. package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.d.ts +8932 -0
  196. package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.js +70 -0
  197. package/dist/harness-runtime/vendor/opencode-client/promise/index.d.ts +6 -0
  198. package/dist/harness-runtime/vendor/opencode-client/promise/index.js +83 -0
  199. package/dist/harness-runtime/vendor/opencode-client/promise/rpc.d.ts +32 -0
  200. package/dist/harness-runtime/vendor/opencode-client/promise/rpc.js +7 -0
  201. package/dist/harness-runtime/vendor/opencode-client/promise/service.d.ts +24 -0
  202. package/dist/harness-runtime/vendor/opencode-client/promise/service.js +187 -0
  203. package/dist/harness-runtime/vendor/opencode-client/pty-handoff.d.ts +12 -0
  204. package/dist/harness-runtime/vendor/opencode-client/pty-handoff.js +14 -0
  205. package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.d.ts +20 -0
  206. package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.js +14 -0
  207. package/dist/harness-runtime/vendor/opencode-client/service-contender.d.ts +37 -0
  208. package/dist/harness-runtime/vendor/opencode-client/service-contender.js +10 -0
  209. package/dist/harness-runtime/vendor/opencode-client/service-probe.d.ts +70 -0
  210. package/dist/harness-runtime/vendor/opencode-client/service-probe.js +16 -0
  211. package/dist/harness-runtime/vendor/opencode-client/service-timing.d.ts +12 -0
  212. package/dist/harness-runtime/vendor/opencode-client/service-timing.js +10 -0
  213. package/dist/harness-runtime/vendor/opencode-client/service-version.d.ts +2 -0
  214. package/dist/harness-runtime/vendor/opencode-client/service-version.js +6 -0
  215. package/dist/harness-runtime/vendor/opencode-client/service.d.ts +52 -0
  216. package/dist/harness-runtime/vendor/opencode-client/service.js +1 -0
  217. package/dist/harness-runtime/vendor/opencode-client/shared-events.d.ts +11 -0
  218. package/dist/harness-runtime/vendor/opencode-client/shared-events.js +8 -0
  219. package/dist/harness-runtime/vendor/opencode-client/solid/connection.d.ts +37 -0
  220. package/dist/harness-runtime/vendor/opencode-client/solid/connection.js +10 -0
  221. package/dist/harness-runtime/vendor/opencode-client/solid/data.d.ts +211 -0
  222. package/dist/harness-runtime/vendor/opencode-client/solid/data.js +18 -0
  223. package/dist/harness-runtime/vendor/opencode-client/solid/index.d.ts +3 -0
  224. package/dist/harness-runtime/vendor/opencode-client/solid/index.js +32 -0
  225. package/dist/harness-runtime/vendor/opencode-client/solid/pty.d.ts +22 -0
  226. package/dist/harness-runtime/vendor/opencode-client/solid/pty.js +8 -0
  227. package/dist/harness-runtime/vendor/opencode-plugin.mjs +3 -0
  228. package/dist/protocol/local-files.js +18 -9
  229. package/dist/runtime/context.js +8 -4
  230. package/dist/schemas/agent-profile.schema.json +1 -1
  231. package/dist/schemas/code-review-decision.schema.json +9 -0
  232. package/dist/schemas/code-review-result.schema.json +1 -1
  233. package/dist/schemas/code-verification.schema.json +7 -5
  234. package/dist/schemas/code-work-batch.schema.json +2 -2
  235. package/dist/schemas/code-work-result.schema.json +2 -1
  236. package/dist/schemas/delivery-stage-result.schema.json +286 -0
  237. package/dist/schemas/diagnostic-stage-result.schema.json +354 -0
  238. package/dist/schemas/diagnostic-work-result.schema.json +296 -0
  239. package/dist/schemas/discovery-result.schema.json +184 -0
  240. package/dist/schemas/distill-stage-result.schema.json +667 -0
  241. package/dist/schemas/distill-work-result.schema.json +428 -0
  242. package/dist/schemas/execution-bundle.schema.json +215 -0
  243. package/dist/schemas/execution-settings.schema.json +162 -0
  244. package/dist/schemas/flow-descriptor.schema.json +54 -0
  245. package/dist/schemas/flow-run.schema.json +29 -0
  246. package/dist/schemas/harness-catalog.schema.json +80 -0
  247. package/dist/schemas/interactive-stage-result.schema.json +47 -0
  248. package/dist/schemas/interactive-work-result.schema.json +63 -0
  249. package/dist/schemas/mb-fix-stage-result.schema.json +93 -0
  250. package/dist/schemas/mb-init-compose-result.schema.json +457 -0
  251. package/dist/schemas/mb-init-discover-result.schema.json +500 -0
  252. package/dist/schemas/mb-init-finish-result.schema.json +422 -0
  253. package/dist/schemas/mb-init-preflight-result.schema.json +367 -0
  254. package/dist/schemas/mb-init-review-result.schema.json +396 -0
  255. package/dist/schemas/mb-init-verify-result.schema.json +391 -0
  256. package/dist/schemas/mb-upgrade-stage-result.schema.json +863 -0
  257. package/dist/schemas/memory-bootstrap-receipt-v2.schema.json +67 -0
  258. package/dist/schemas/memory-bootstrap-receipt.schema.json +354 -0
  259. package/dist/schemas/memory-composition-work-result.schema.json +38 -0
  260. package/dist/schemas/memory-repair-work-result.schema.json +56 -0
  261. package/dist/schemas/memory-review-correction-plan.schema.json +30 -0
  262. package/dist/schemas/memory-review-work-result.schema.json +43 -0
  263. package/dist/schemas/model-catalog.schema.json +153 -0
  264. package/dist/schemas/plan-review-decision.schema.json +12 -3
  265. package/dist/schemas/plan-review-result.schema.json +2 -2
  266. package/dist/schemas/profile-settings.schema.json +122 -0
  267. package/dist/schemas/project-flow-pack-manifest.schema.json +2 -2
  268. package/dist/schemas/release-impact.schema.json +3 -3
  269. package/dist/schemas/release-manifest.schema.json +291 -0
  270. package/dist/schemas/review-fix-stage-result.schema.json +210 -0
  271. package/dist/schemas/run-control-receipt.schema.json +119 -0
  272. package/dist/schemas/run-control-request.schema.json +36 -0
  273. package/dist/schemas/run-engine-binding.schema.json +1 -1
  274. package/dist/schemas/stage-start-response.schema.json +4 -0
  275. package/dist/schemas/vnext-protocol-plan.schema.json +3 -3
  276. package/dist/services/accepted-intent.js +139 -0
  277. package/dist/services/assigned-lifecycle.js +382 -0
  278. package/dist/services/branch-context.js +3 -3
  279. package/dist/services/canon.js +54 -15
  280. package/dist/services/check-environment.js +21 -0
  281. package/dist/services/check-runner-evidence.js +344 -0
  282. package/dist/services/check-runner-proof.js +373 -0
  283. package/dist/services/cleanup.js +133 -40
  284. package/dist/services/cli-operation-classifier.js +32 -64
  285. package/dist/services/cli-upgrade-allowlist.js +27 -0
  286. package/dist/services/code-checks.js +1426 -121
  287. package/dist/services/codex-capacity.js +367 -0
  288. package/dist/services/codex-hook-delivery.js +41 -0
  289. package/dist/services/command-context.js +80 -0
  290. package/dist/services/compatibility-preflight.js +16 -3
  291. package/dist/services/config.js +11 -8
  292. package/dist/services/continuation-outcome.js +25 -0
  293. package/dist/services/controller-child-capacity.js +71 -0
  294. package/dist/services/controller-child-observer.js +121 -0
  295. package/dist/services/controller-child-repair.js +117 -0
  296. package/dist/services/controller-execution.js +97 -0
  297. package/dist/services/controller-fanout.js +277 -0
  298. package/dist/services/controller-memory-task.js +45 -0
  299. package/dist/services/controller-memory-worker.js +51 -0
  300. package/dist/services/controller-result-authority.js +127 -0
  301. package/dist/services/controller-work-failure.js +198 -0
  302. package/dist/services/dashboard.js +145 -58
  303. package/dist/services/delivery-access.js +123 -0
  304. package/dist/services/delivery-approval.js +68 -0
  305. package/dist/services/delivery-artifact.js +86 -0
  306. package/dist/services/delivery-checks.js +178 -0
  307. package/dist/services/delivery-execution.js +181 -0
  308. package/dist/services/delivery-intents.js +212 -0
  309. package/dist/services/delivery-operation.js +81 -0
  310. package/dist/services/delivery-policy.js +91 -0
  311. package/dist/services/delivery-procedures.js +43 -0
  312. package/dist/services/delivery-request.js +99 -0
  313. package/dist/services/delivery-result.js +144 -0
  314. package/dist/services/delivery-stage-commands.js +26 -0
  315. package/dist/services/delivery-stage-entry.js +56 -0
  316. package/dist/services/delivery-stage-handlers.js +135 -0
  317. package/dist/services/delivery-stage-results.js +94 -0
  318. package/dist/services/descriptor-coordinator-session.js +37 -0
  319. package/dist/services/descriptor-root-work.js +53 -0
  320. package/dist/services/descriptor-run-settlement.js +107 -0
  321. package/dist/services/descriptor-run-start.js +495 -0
  322. package/dist/services/descriptor-stage-coordinator.js +318 -0
  323. package/dist/services/descriptor-stage-settlement.js +268 -0
  324. package/dist/services/descriptor-stage-start.js +175 -0
  325. package/dist/services/diagnostic-evidence.js +73 -0
  326. package/dist/services/diagnostic-repair-intake.js +123 -0
  327. package/dist/services/diagnostic-repair-source-intake.js +102 -0
  328. package/dist/services/diagnostic-report-publication.js +72 -0
  329. package/dist/services/diagnostic-report.js +97 -0
  330. package/dist/services/diagnostic-run-bundle.js +113 -0
  331. package/dist/services/diagnostic-snapshot.js +159 -0
  332. package/dist/services/diagnostic-stage-handlers.js +109 -0
  333. package/dist/services/diagnostic-stage-results.js +158 -0
  334. package/dist/services/diagnostic-start.js +134 -0
  335. package/dist/services/diagnostic-work-batch.js +34 -0
  336. package/dist/services/diagnostic-work-collection.js +97 -0
  337. package/dist/services/diagnostic-work-registration.js +101 -0
  338. package/dist/services/diagnostic-work-results.js +93 -0
  339. package/dist/services/discovery/agy-discovery.js +2 -0
  340. package/dist/services/discovery/codex-discovery.js +2 -0
  341. package/dist/services/discovery/droid-discovery.js +2 -0
  342. package/dist/services/discovery/grok-discovery.js +2 -0
  343. package/dist/services/discovery/opencode-discovery.js +2 -0
  344. package/dist/services/discovery/static.js +31 -0
  345. package/dist/services/discovery/zcode-discovery.js +2 -0
  346. package/dist/services/distill-document-publication.js +280 -0
  347. package/dist/services/distill-promotion.js +197 -0
  348. package/dist/services/distill-publication-custody.js +162 -0
  349. package/dist/services/distill-stage-handlers.js +249 -0
  350. package/dist/services/distill-stage-results.js +105 -0
  351. package/dist/services/distill-user-inputs.js +4 -0
  352. package/dist/services/distill-work-batch.js +42 -0
  353. package/dist/services/distill-work-collection.js +74 -0
  354. package/dist/services/distill-work-registration.js +93 -0
  355. package/dist/services/distill-work-results.js +98 -0
  356. package/dist/services/engines.js +354 -163
  357. package/dist/services/eval-snapshots.js +1326 -150
  358. package/dist/services/execution-bundles.js +275 -0
  359. package/dist/services/execution-policy.js +185 -0
  360. package/dist/services/executor-onboarding.js +56 -0
  361. package/dist/services/external-work-launch.js +316 -0
  362. package/dist/services/flow-catalog.js +54 -0
  363. package/dist/services/flow-descriptors.js +82 -0
  364. package/dist/services/frozen-engine.js +404 -0
  365. package/dist/services/generic-execution.js +165 -0
  366. package/dist/services/harness-adapter.js +342 -35
  367. package/dist/services/harness-config.js +2 -0
  368. package/dist/services/harness-discovery.js +29 -0
  369. package/dist/services/harness-doctor.js +75 -0
  370. package/dist/services/harness-probe-effects.js +51 -0
  371. package/dist/services/harness-version-probe.js +100 -0
  372. package/dist/services/hook-memory-routing.js +188 -0
  373. package/dist/services/hook-recovery-guard.js +14 -0
  374. package/dist/services/hook-session-observation.js +24 -0
  375. package/dist/services/hooks.js +813 -327
  376. package/dist/services/hybrid-contracts.js +479 -0
  377. package/dist/services/hybrid-digest.js +14 -0
  378. package/dist/services/ids.js +29 -1
  379. package/dist/services/installation-lock.js +95 -0
  380. package/dist/services/installed-flow-source.js +261 -0
  381. package/dist/services/interactive-attached-session.js +215 -0
  382. package/dist/services/interactive-baseline-custody.js +54 -0
  383. package/dist/services/interactive-before-versions.js +148 -0
  384. package/dist/services/interactive-bundle-data.js +85 -0
  385. package/dist/services/interactive-checks.js +179 -0
  386. package/dist/services/interactive-execution.js +33 -0
  387. package/dist/services/interactive-finish-integration.js +236 -0
  388. package/dist/services/interactive-git-baseline.js +230 -0
  389. package/dist/services/interactive-git-dispatch.js +278 -0
  390. package/dist/services/interactive-input-delivery.js +82 -0
  391. package/dist/services/interactive-mutation-scope.js +231 -0
  392. package/dist/services/interactive-request.js +287 -0
  393. package/dist/services/interactive-run-bundle.js +109 -0
  394. package/dist/services/interactive-stage-entry.js +41 -0
  395. package/dist/services/interactive-stage-handlers.js +289 -0
  396. package/dist/services/interactive-stage-observation.js +136 -0
  397. package/dist/services/interactive-stage-results.js +111 -0
  398. package/dist/services/interactive-user-inputs.js +142 -0
  399. package/dist/services/interactive-work-batch.js +43 -0
  400. package/dist/services/interactive-work-collection.js +119 -0
  401. package/dist/services/interactive-work-completion.js +180 -0
  402. package/dist/services/interactive-work-context.js +249 -0
  403. package/dist/services/interactive-work-history.js +112 -0
  404. package/dist/services/interactive-work-registration.js +124 -0
  405. package/dist/services/interactive-work-results.js +115 -0
  406. package/dist/services/interactive-work-start.js +155 -0
  407. package/dist/services/lanes.js +78 -65
  408. package/dist/services/lifecycle-command.js +1 -288
  409. package/dist/services/lifecycle-contract.js +1 -0
  410. package/dist/services/lifecycle-invocations.js +2549 -0
  411. package/dist/services/managed-daemon-binding.js +129 -0
  412. package/dist/services/managed-lease-monitor.js +133 -0
  413. package/dist/services/managed-processes.js +449 -69
  414. package/dist/services/memory-accepted-composition.js +78 -0
  415. package/dist/services/memory-baseline-preservation.js +65 -0
  416. package/dist/services/memory-completed-correction-wave.js +328 -0
  417. package/dist/services/memory-compose-handler.js +380 -0
  418. package/dist/services/memory-composition-acceptance.js +375 -0
  419. package/dist/services/memory-composition-graph.js +165 -0
  420. package/dist/services/memory-composition-registration.js +161 -0
  421. package/dist/services/memory-composition-work-custody.js +156 -0
  422. package/dist/services/memory-composition-work-results.js +108 -0
  423. package/dist/services/memory-corrected-review-acceptance.js +129 -0
  424. package/dist/services/memory-corrected-review-batch.js +37 -0
  425. package/dist/services/memory-corrected-review-findings.js +108 -0
  426. package/dist/services/memory-corrected-review-inputs.js +215 -0
  427. package/dist/services/memory-corrected-review-projection.js +78 -0
  428. package/dist/services/memory-corrected-review-receipt.js +178 -0
  429. package/dist/services/memory-corrected-review-registration.js +192 -0
  430. package/dist/services/memory-correction-check-receipt.js +235 -0
  431. package/dist/services/memory-correction-input-owner.js +6 -0
  432. package/dist/services/memory-custody-snapshot.js +36 -0
  433. package/dist/services/memory-discover-handler.js +104 -0
  434. package/dist/services/memory-finish-evidence.js +457 -0
  435. package/dist/services/memory-finish-handler.js +229 -0
  436. package/dist/services/memory-finish-integration.js +491 -0
  437. package/dist/services/memory-finish-readiness.js +169 -0
  438. package/dist/services/memory-fix-finish-integration.js +129 -0
  439. package/dist/services/memory-fix-git-dispatch.js +139 -0
  440. package/dist/services/memory-fix-intake-custody.js +11 -0
  441. package/dist/services/memory-fix-intake-settlement.js +127 -0
  442. package/dist/services/memory-fix-publication.js +196 -0
  443. package/dist/services/memory-fix-repair-admission.js +116 -0
  444. package/dist/services/memory-fix-request.js +141 -0
  445. package/dist/services/memory-fix-run-bundle.js +83 -0
  446. package/dist/services/memory-fix-scope.js +78 -0
  447. package/dist/services/memory-fix-sources.js +85 -0
  448. package/dist/services/memory-fix-stage-entry.js +24 -0
  449. package/dist/services/memory-fix-stage-handlers.js +282 -0
  450. package/dist/services/memory-fix-stage-results.js +106 -0
  451. package/dist/services/memory-fix-workspace.js +127 -0
  452. package/dist/services/memory-flow-user-inputs.js +88 -0
  453. package/dist/services/memory-git-integration.js +220 -0
  454. package/dist/services/memory-historical-corrected-review.js +212 -0
  455. package/dist/services/memory-historical-original-review.js +143 -0
  456. package/dist/services/memory-historical-repair-registration.js +105 -0
  457. package/dist/services/memory-historical-second-review.js +147 -0
  458. package/dist/services/memory-init-bootstrap-readiness.js +210 -0
  459. package/dist/services/memory-init-contexts.js +181 -0
  460. package/dist/services/memory-init-controller-start.js +119 -0
  461. package/dist/services/memory-init-engine-release.js +223 -0
  462. package/dist/services/memory-init-git-policy.js +165 -0
  463. package/dist/services/memory-init-lint-capability.js +203 -0
  464. package/dist/services/memory-init-native-capacity.js +309 -0
  465. package/dist/services/memory-init-preflight.js +334 -0
  466. package/dist/services/memory-init-project-bootstrap.js +599 -0
  467. package/dist/services/memory-init-request-candidate.js +213 -0
  468. package/dist/services/memory-init-request-input.js +82 -0
  469. package/dist/services/memory-init-resource-storage.js +125 -0
  470. package/dist/services/memory-init-run-allocation.js +81 -0
  471. package/dist/services/memory-init-run-bundle.js +135 -0
  472. package/dist/services/memory-init-start.js +181 -0
  473. package/dist/services/memory-init-startup-custody.js +80 -0
  474. package/dist/services/memory-init-startup-input.js +240 -0
  475. package/dist/services/memory-init-storage.js +91 -0
  476. package/dist/services/memory-init-stores.js +359 -0
  477. package/dist/services/memory-init-worktrunk-capability.js +174 -0
  478. package/dist/services/memory-layer-publication.js +611 -0
  479. package/dist/services/memory-layer.js +225 -0
  480. package/dist/services/memory-lint-config.js +194 -0
  481. package/dist/services/memory-native-review-copy.js +127 -0
  482. package/dist/services/memory-normal-flow-entry.js +87 -0
  483. package/dist/services/memory-ordinary-defaults.js +129 -0
  484. package/dist/services/memory-preflight-bootstrap-custody.js +115 -0
  485. package/dist/services/memory-preflight-handler.js +274 -0
  486. package/dist/services/memory-repair-current-view.js +299 -0
  487. package/dist/services/memory-repair-document-delta.js +489 -0
  488. package/dist/services/memory-repair-history.js +496 -0
  489. package/dist/services/memory-repair-physical-binding.js +194 -0
  490. package/dist/services/memory-repair-publication-files.js +152 -0
  491. package/dist/services/memory-repair-publication-intent.js +27 -0
  492. package/dist/services/memory-repair-publication-plan.js +162 -0
  493. package/dist/services/memory-repair-publication-source.js +225 -0
  494. package/dist/services/memory-repair-publication.js +795 -0
  495. package/dist/services/memory-repair-registration.js +240 -0
  496. package/dist/services/memory-repair-work-baseline.js +415 -0
  497. package/dist/services/memory-repair-work-completion.js +117 -0
  498. package/dist/services/memory-repair-work-custody.js +73 -0
  499. package/dist/services/memory-repair-work-results.js +108 -0
  500. package/dist/services/memory-repair-workspace.js +261 -0
  501. package/dist/services/memory-repair-writer-copy.js +736 -0
  502. package/dist/services/memory-result-binding.js +239 -0
  503. package/dist/services/memory-retained-review-authority.js +138 -0
  504. package/dist/services/memory-retained-review-results.js +70 -0
  505. package/dist/services/memory-retained-second-baseline.js +102 -0
  506. package/dist/services/memory-retained-second-repairs.js +162 -0
  507. package/dist/services/memory-review-acceptance.js +214 -0
  508. package/dist/services/memory-review-correction-plan.js +206 -0
  509. package/dist/services/memory-review-handler.js +585 -0
  510. package/dist/services/memory-review-inputs.js +246 -0
  511. package/dist/services/memory-review-limits.js +10 -0
  512. package/dist/services/memory-review-receipt.js +180 -0
  513. package/dist/services/memory-review-registration.js +117 -0
  514. package/dist/services/memory-review-work-custody.js +126 -0
  515. package/dist/services/memory-review-work-input.js +91 -0
  516. package/dist/services/memory-review-work-results.js +95 -0
  517. package/dist/services/memory-second-corrected-review-inputs.js +167 -0
  518. package/dist/services/memory-second-correction-plan.js +77 -0
  519. package/dist/services/memory-second-repair-baseline.js +91 -0
  520. package/dist/services/memory-second-repair-launch.js +614 -0
  521. package/dist/services/memory-second-repair-registration.js +88 -0
  522. package/dist/services/memory-second-repair-source.js +187 -0
  523. package/dist/services/memory-second-review-acceptance.js +115 -0
  524. package/dist/services/memory-source-observations.js +117 -0
  525. package/dist/services/memory-stage-dispatch.js +65 -0
  526. package/dist/services/memory-stage-results.js +290 -0
  527. package/dist/services/memory-tool-probe.js +25 -0
  528. package/dist/services/memory-upgrade-analysis-handler.js +243 -0
  529. package/dist/services/memory-upgrade-bootstrap-readiness.js +251 -0
  530. package/dist/services/memory-upgrade-evidence.js +100 -0
  531. package/dist/services/memory-upgrade-inventory.js +442 -0
  532. package/dist/services/memory-upgrade-publication-custody.js +73 -0
  533. package/dist/services/memory-upgrade-publication.js +413 -0
  534. package/dist/services/memory-upgrade-selection.js +430 -0
  535. package/dist/services/memory-upgrade-start.js +60 -0
  536. package/dist/services/memory-upgrade-storage-readiness.js +340 -0
  537. package/dist/services/memory-verification-acceptance.js +156 -0
  538. package/dist/services/memory-verification-checks.js +317 -0
  539. package/dist/services/memory-verification-receipt.js +160 -0
  540. package/dist/services/memory-verify-handler.js +137 -0
  541. package/dist/services/memory-work-result-json.js +12 -0
  542. package/dist/services/memory-work-result-preparation.js +64 -0
  543. package/dist/services/merge-queue.js +228 -149
  544. package/dist/services/merge-server.js +163 -35
  545. package/dist/services/migrations.js +164 -114
  546. package/dist/services/model-catalog.js +109 -0
  547. package/dist/services/model-discovery.js +46 -0
  548. package/dist/services/native-daemon-history.js +50 -0
  549. package/dist/services/native-session-control.js +39 -0
  550. package/dist/services/operator-profiles.js +236 -0
  551. package/dist/services/physical-startup.js +45 -0
  552. package/dist/services/plan-runtime.js +26 -11
  553. package/dist/services/plans.js +28 -25
  554. package/dist/services/project-flow-source.js +195 -0
  555. package/dist/services/project-git-integration.js +92 -0
  556. package/dist/services/project-registry.js +97 -0
  557. package/dist/services/project-summary.js +1 -1
  558. package/dist/services/projects.js +17 -87
  559. package/dist/services/prompt-delivery.js +71 -0
  560. package/dist/services/prompts.js +28 -17
  561. package/dist/services/protocols.js +163 -87
  562. package/dist/services/provider-capacity.js +463 -0
  563. package/dist/services/recovery-observation-budget.js +121 -0
  564. package/dist/services/recovery-snapshot-database.js +588 -0
  565. package/dist/services/release-archive-producer.js +52 -0
  566. package/dist/services/release-archive.js +143 -0
  567. package/dist/services/release-cache.js +150 -0
  568. package/dist/services/release-compatibility.js +18 -0
  569. package/dist/services/release-download.js +67 -0
  570. package/dist/services/release-envelope.js +104 -0
  571. package/dist/services/release-manifest.js +45 -0
  572. package/dist/services/release-payload.js +114 -0
  573. package/dist/services/release-producer.js +63 -0
  574. package/dist/services/release-provenance.js +160 -0
  575. package/dist/services/release-registry.js +66 -0
  576. package/dist/services/release-source.js +194 -0
  577. package/dist/services/repair-intents.js +29 -0
  578. package/dist/services/repair-receipt.js +13 -0
  579. package/dist/services/retained-native-hook.js +274 -0
  580. package/dist/services/review-copy.js +165 -0
  581. package/dist/services/review-deferral.js +23 -0
  582. package/dist/services/review-fix-handoff.js +82 -0
  583. package/dist/services/review-fix-intake-custody.js +17 -0
  584. package/dist/services/review-fix-stage-entry.js +43 -0
  585. package/dist/services/review-fix-stage-handlers.js +176 -0
  586. package/dist/services/review-fix-stage-results.js +86 -0
  587. package/dist/services/run-control-receipt.js +56 -0
  588. package/dist/services/run-control-worker.js +469 -0
  589. package/dist/services/run-control.js +1109 -0
  590. package/dist/services/run-controller-adapter.js +434 -0
  591. package/dist/services/run-controller-capture.js +186 -0
  592. package/dist/services/run-controller-process.js +226 -0
  593. package/dist/services/run-controller-recovery.js +335 -0
  594. package/dist/services/run-controller-state.js +106 -0
  595. package/dist/services/run-controller.js +1717 -0
  596. package/dist/services/run-engine-bindings.js +1 -1
  597. package/dist/services/run-fork.js +147 -0
  598. package/dist/services/run-health.js +149 -0
  599. package/dist/services/run-observations.js +152 -0
  600. package/dist/services/run-projection.js +22 -64
  601. package/dist/services/run-recovery-guard.js +107 -0
  602. package/dist/services/run-recovery-runtime.js +112 -0
  603. package/dist/services/run-recovery.js +485 -0
  604. package/dist/services/run-start-custody.js +189 -0
  605. package/dist/services/run-timeline.js +59 -0
  606. package/dist/services/runs.js +996 -271
  607. package/dist/services/runtime-budget.js +446 -0
  608. package/dist/services/runtime-command.js +43 -0
  609. package/dist/services/runtime-scope-capture.js +52 -0
  610. package/dist/services/runtime-scope-control.js +468 -0
  611. package/dist/services/runtime-scope-resume.js +605 -0
  612. package/dist/services/runtime-scope-stop.js +211 -0
  613. package/dist/services/runtime-scope-worker.js +314 -0
  614. package/dist/services/runtime-service.js +19 -14
  615. package/dist/services/schema-validation.js +10 -8
  616. package/dist/services/scope-writer-cleanup.js +27 -0
  617. package/dist/services/sessions.js +37 -91
  618. package/dist/services/setup.js +427 -0
  619. package/dist/services/stage-blocker.js +17 -7
  620. package/dist/services/stage-context.js +240 -18
  621. package/dist/services/stage-handlers.js +141 -0
  622. package/dist/services/stage-lifecycle.js +156 -119
  623. package/dist/services/stage-pause.js +222 -94
  624. package/dist/services/stage-report-renderer.js +230 -6
  625. package/dist/services/stage-work-graph.js +52 -0
  626. package/dist/services/technical-notes.js +31 -0
  627. package/dist/services/tooling.js +111 -44
  628. package/dist/services/usage.js +49 -101
  629. package/dist/services/verification-matrix.js +393 -0
  630. package/dist/services/version-status.js +1 -1
  631. package/dist/services/vnext-code-review.js +302 -91
  632. package/dist/services/vnext-code.js +325 -251
  633. package/dist/services/vnext-contracts.js +10 -1
  634. package/dist/services/vnext-execution-profile.js +80 -5
  635. package/dist/services/vnext-fanout.js +399 -20
  636. package/dist/services/vnext-merge.js +336 -114
  637. package/dist/services/vnext-plan-review.js +288 -133
  638. package/dist/services/vnext-plan.js +257 -110
  639. package/dist/services/vnext-protocolize.js +534 -96
  640. package/dist/services/vnext-specify.js +131 -84
  641. package/dist/services/vnext-workspace-policy.js +7 -2
  642. package/dist/services/work-registry.js +1950 -215
  643. package/dist/services/work-retry-context.js +55 -0
  644. package/dist/services/workspace-bootstrap.js +53 -15
  645. package/dist/services/workspace-files.js +85 -0
  646. package/dist/services/worktrees.js +108 -48
  647. package/dist/shared/entity-references.js +1 -0
  648. package/dist/shared/errors.js +27 -0
  649. package/dist/storage/agent-output.js +26 -0
  650. package/dist/storage/data-preservation.js +65 -0
  651. package/dist/storage/database.js +931 -40
  652. package/dist/storage/foreign-key-transaction.js +39 -0
  653. package/dist/storage/immutable-input.js +45 -0
  654. package/dist/storage/import-guard.js +159 -0
  655. package/dist/storage/memory-upgrade-schema-bootstrap.js +38 -0
  656. package/dist/storage/native-cleanup.js +52 -0
  657. package/dist/storage/paired-writer-migration.js +424 -0
  658. package/dist/storage/paths.js +17 -4
  659. package/dist/storage/projection-lock.js +73 -0
  660. package/dist/storage/work-references.js +23 -0
  661. package/dist/storage/writer-contract.js +96 -0
  662. package/dist/storage/writer-migration.js +346 -0
  663. package/dist/storage/writer-restore.js +217 -0
  664. package/dist/verification-components.json +384 -0
  665. package/package.json +52 -13
  666. package/tools/create-canon-release.mjs +33 -0
  667. package/tools/probe-codex-history.mjs +37 -0
  668. package/tools/produce-hybrid-release.mjs +41 -0
  669. package/tools/repair-paused-run-status.mjs +84 -0
  670. package/tools/verification-jobs.mjs +342 -0
@@ -0,0 +1,87 @@
1
+ import { parseLifecycleCommand, commandOption, commandPosition } from "./lifecycle-command.mjs";
2
+ import { entityReferenceVariants } from "./entity-references.mjs";
3
+ import { agyTerminalEnvelope, ownedAgyOutput } from "./agy-terminal-envelope.mjs";
4
+
5
+ /** Ordered native transcript evidence, never assistant text as a success signal. */
6
+ export function recoveredAgyErrorBoundary(text, error, floor = -1, source = null, sessionId = null) {
7
+ let rows;
8
+ try { rows = text.trim().split("\n").filter(Boolean).map(JSON.parse); } catch { return null; }
9
+ const reducer = createAgyErrorBoundary(error, floor, source, sessionId);
10
+ for (const row of rows) reducer.add(row);
11
+ return reducer.finish();
12
+ }
13
+
14
+ /** Stateful equivalent for an owned, validated JSONL snapshot. */
15
+ export function createAgyErrorBoundary(error, floor = -1, source = null, sessionId = null) {
16
+ let previous = -1, lastError = null, boundary = null, invocation = null, call = null;
17
+ const launches = new Map(); let invalid = false;
18
+ function add(row) {
19
+ if (invalid) return;
20
+ if (!Number.isInteger(row.step_index) || row.step_index <= previous) { invalid = true; return; }
21
+ previous = row.step_index;
22
+ if (row.step_index <= (floor ?? -1)) return;
23
+ if (row.type === "USER_INPUT") { lastError = null; boundary = null; invocation = null; call = null; launches.clear(); return; }
24
+ if (row.type === "ERROR_MESSAGE") { lastError = row; boundary = null; invocation = null; return; }
25
+ if (Array.isArray(row.tool_calls)) {
26
+ invocation = null;
27
+ call = row.tool_calls.length === 1 ? row.tool_calls[0] : null;
28
+ if (row.tool_calls.length === 1 && row.tool_calls[0]?.name === "run_command") {
29
+ let command = row.tool_calls[0]?.args?.CommandLine;
30
+ if (typeof command === "string") {
31
+ try { const unquoted = JSON.parse(command); if (typeof unquoted === "string") command = unquoted; } catch { /* ordinary shell bytes */ }
32
+ const parsed = parseLifecycleCommand(command);
33
+ if ((parsed.kind === "standalone" || parsed.kind === "compound" && parsed.supported === true && parsed.invocations?.length === 1) && ["stage_finish", "work_finish", "stage_pause", "recovery_accept"].includes(parsed.invocation.operation)) invocation = parsed.invocation;
34
+ }
35
+ }
36
+ }
37
+ if (row.type === 'GENERIC' && row.status === 'RUNNING') {
38
+ const task = row.content?.match(/^Created At: [^\n]+\nTool is running as a background task with task id: ([\w-]+\/task-\d+)\n/);
39
+ if (task && invocation && (!sessionId || task[1].startsWith(`${sessionId}/`))) launches.set(task[1], launches.has(task[1]) ? null : { invocation, step: row.step_index });
40
+ call = null; invocation = null; return;
41
+ }
42
+ const envelope = agyTerminalEnvelope(row, call);
43
+ let launchStep = null;
44
+ if (envelope?.task_id) {
45
+ const launch = launches.get(envelope.task_id);
46
+ invocation = launch && launch.step < row.step_index ? launch.invocation : null;
47
+ launchStep = launch?.step ?? null;
48
+ }
49
+ if (!lastError || envelope?.exit_code !== 0) return;
50
+ const retained = envelope.output_reference && source && sessionId ? ownedAgyOutput(envelope.output_reference, source, sessionId, envelope.task_id) : null;
51
+ const full = retained ? agyTerminalEnvelope({ type: 'GENERIC', status: 'DONE', content: retained.text }) : null;
52
+ const output = (retained ? full?.exit_code === 0 ? full.output : null : envelope.output)?.replaceAll("\r", "");
53
+ if (!output) return;
54
+ for (const match of output.matchAll(/^\s*\{/gm)) {
55
+ let receipt;
56
+ const candidate = output.slice(match.index).trim();
57
+ try { receipt = JSON.parse(candidate); } catch {
58
+ // AGY's transcript renderer can unescape control characters inside
59
+ // pause.user_message. Parse only the intact machine header, never the
60
+ // rendered question; the controller must still verify the DB receipt.
61
+ const end = candidate.indexOf(',\n "user_message":');
62
+ if (end < 0) continue;
63
+ try { receipt = JSON.parse(`${candidate.slice(0, end)}}}`); } catch { continue; }
64
+ }
65
+ if (receipt.ok === true && invocation && invocation.operation !== "stage_pause") {
66
+ if (invocation.operation === "recovery_accept" && receipt.accepted === true && typeof receipt.recovery_id === "string") boundary = { receipt: { ok: true, outcome: "completed", lifecycle_operation: "recovery_accept", recovery_id: receipt.recovery_id }, error_step: lastError.step_index, boundary_step: row.step_index };
67
+ const stage = receipt.stage ?? commandOption(invocation, "stage");
68
+ const runId = receipt.run_id;
69
+ const workId = receipt.work_id ?? receipt.work?.work_id ?? commandOption(invocation, "work") ?? (invocation.operation === "work_finish" ? commandPosition(invocation, 0) : null);
70
+ if (invocation.operation === "work_finish" && receipt.status === "completed" && typeof workId === "string") boundary = { receipt: { ok: true, outcome: "completed", work_id: workId, lifecycle_operation: "work_finish" }, error_step: lastError.step_index, boundary_step: row.step_index };
71
+ if (typeof stage === "string" && typeof runId === "string" && (invocation.operation === "work_finish" || entityReferenceVariants(runId).includes(commandPosition(invocation, 0)))) {
72
+ boundary = { receipt: { ok: true, outcome: "completed", run_id: runId, stage, ...(workId ? { work_id: workId } : {}), lifecycle_operation: invocation.operation }, error_step: lastError.step_index, boundary_step: row.step_index };
73
+ }
74
+ }
75
+ if (invocation?.operation === "stage_pause" && commandOption(invocation, "stage") === receipt.stage && receipt.ok === true && receipt.outcome === "paused"
76
+ && [receipt.run_id, receipt.stage, receipt.work_id].every(value => typeof value === "string" && value)
77
+ && (receipt.outcome !== "paused" || typeof receipt.pause?.id === "string")) boundary = { receipt: { ok: true, outcome: receipt.outcome, run_id: receipt.run_id, stage: receipt.stage, work_id: receipt.work_id,
78
+ lifecycle_operation: "stage_pause", pause: { id: receipt.pause.id } }, error_step: lastError.step_index, boundary_step: row.step_index };
79
+ if (boundary?.boundary_step === row.step_index) {
80
+ if (launchStep !== null) boundary.invocation_step = launchStep;
81
+ if (retained) boundary.output_source = { locator: retained.locator, sha256: retained.sha256 };
82
+ }
83
+ }
84
+ }
85
+ return { add, finish: () => !invalid && boundary && lastError?.error === error ? boundary : null };
86
+ }
87
+
@@ -0,0 +1 @@
1
+ export function agyWorkspaceHooks(): Record<string, unknown>;
@@ -0,0 +1,9 @@
1
+ // Qualified hooks are stable; only the launching process selects its pinned
2
+ // entrypoint and daemon. Keep this document shared with product-file policy.
3
+ export function agyWorkspaceHooks() {
4
+ const command = '"${DD_AGY_HOOK_NODE:?missing AGY hook binding}" "${DD_AGY_HOOK_ENTRY:?missing AGY hook binding}" hook handle --event __EVENT__ --state-dir "${DD_AGY_STATE_DIR:?missing AGY hook binding}" --daemon-id "${DD_AGY_DAEMON_ID:?missing AGY hook binding}" --json';
5
+ return { "dd-flow": {
6
+ PreToolUse: [{ matcher: "^run_command$", hooks: [{ type: "command", command: command.replace("__EVENT__", "PreToolUse"), timeout: 30 }] }],
7
+ Stop: [{ type: "command", command: command.replace("__EVENT__", "Stop"), timeout: 30 }]
8
+ } };
9
+ }
@@ -0,0 +1,225 @@
1
+ import * as grpc from '@grpc/grpc-js';
2
+ import { create, toBinary, fromBinary } from '@bufbuild/protobuf';
3
+ import { WaitForConversationFullyIdleRequestSchema, WaitForConversationFullyIdleResponseSchema, GetConversationMetadataRequestSchema, GetConversationMetadataResponseSchema, ForceStopCascadeTreeRequestSchema, ForceStopCascadeTreeResponseSchema, StreamAgentStateUpdatesRequestSchema, StreamAgentStateUpdatesResponseSchema } from './agy-native_pb.js';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { readFile, lstat, realpath, open } from 'node:fs/promises';
6
+ import { createReadStream, constants } from 'node:fs';
7
+ import { createHash } from 'node:crypto';
8
+ import { execFile } from 'node:child_process';
9
+ import { promisify } from 'node:util';
10
+ import { fileURLToPath } from 'node:url';
11
+ import path from 'node:path';
12
+ import { processSnapshot } from './process-snapshot.mjs';
13
+
14
+ export const AGY_NATIVE_INSPECTION_CONTRACT = 'agy-native-inspection@2';
15
+ export const AGY_NATIVE_LIVE_CASES = ['root_child_running', 'child_background_running', 'grandchild_running', 'completion_delivery', 'fully_idle', 'timer_delivery', 'daemon_excluded_from_required_execution', 'owned_daemon_retirement'];
16
+ export const AGY_NATIVE_SAFETY_CASES = ['executor_error', 'timeout', 'late_activity_cancel_restart'];
17
+ export const AGY_NATIVE_QUALIFICATION_CASES = [...AGY_NATIVE_LIVE_CASES, ...AGY_NATIVE_SAFETY_CASES];
18
+ export const AGY_NATIVE_EVIDENCE_CONTRACT = 'agy-native-inspection-evidence@2';
19
+ /** Operator-retained native observations, not a bag of manually asserted PASSes.
20
+ * This validates evidence structure/meaning, not its authenticity: the operator
21
+ * still owns capture and review, as with every local qualification receipt. */
22
+ export function validateAgyNativeEvidence(evidence, identity) {
23
+ const checks = Object.fromEntries(AGY_NATIVE_QUALIFICATION_CASES.map(name => [name, false]));
24
+ const failed = new Set();
25
+ const fencedChanges = new Set();
26
+ const liveServices = new Map(), retiredServices = [];
27
+ if (evidence?.schema_id !== AGY_NATIVE_EVIDENCE_CONTRACT || evidence.binary_sha256 !== identity.sha256 || evidence.client_contract_sha256 !== identity.client_contract_sha256 || !['self', 'empty_self'].includes(evidence.root_relation) || !Array.isArray(evidence.observations)) return { qualified: false, checks };
28
+ for (const item of evidence.observations) {
29
+ if (!item || !AGY_NATIVE_QUALIFICATION_CASES.includes(item.case)) continue;
30
+ if (AGY_NATIVE_LIVE_CASES.includes(item.case) && item.evidence_kind !== 'live' || AGY_NATIVE_SAFETY_CASES.includes(item.case) && !['live', 'deterministic'].includes(item.evidence_kind)) { failed.add(item.case); continue; }
31
+ if (item.source !== 'agy.native' || typeof item.session_id !== 'string' || !item.session_id || typeof item.locator !== 'string' || !item.locator || !Number.isFinite(Date.parse(item.observed_at))) { failed.add(item.case); continue; }
32
+ const before = item.before, after = item.after, wait = item.wait;
33
+ // Observation itself must not create a user/model turn; background model
34
+ // work may continue, hence the explicit inspection-attributed counters.
35
+ if (!before || !after || !['user_turns', 'model_requests'].every(key => Number.isSafeInteger(before[key]) && before[key] >= 0 && after[key] === before[key]) || !wait || !Number.isInteger(wait.grpc_code) || wait.grpc_code < 0 || wait.grpc_code > 16 || typeof item.idle_granted !== 'boolean') { failed.add(item.case); continue; }
36
+ const idle = wait.grpc_code === 0 && wait.timed_out === false;
37
+ const busy = wait.grpc_code === 4 || wait.grpc_code === 0 && wait.timed_out === true;
38
+ const noGrant = item.idle_granted === false;
39
+ const work = Array.isArray(item.work) ? item.work : [];
40
+ const has = (kind, status) => work.some(record => record?.kind === kind && record.status === status && typeof record.id === 'string' && record.id && record.root_session_id === item.session_id);
41
+ const prior = checks[item.case]; checks[item.case] = false;
42
+ if (item.case === 'root_child_running' && item.root_status === 'terminal' && has('child', 'running') && busy && noGrant) checks[item.case] = true;
43
+ if (item.case === 'child_background_running' && has('child', 'terminal') && has('background', 'running') && busy && noGrant) checks[item.case] = true;
44
+ if (item.case === 'grandchild_running' && item.root_status === 'terminal' && item.inventory_complete === true && has('child', 'terminal') && has('grandchild', 'running') && work.every(record => record?.kind === 'grandchild' || record?.status === 'terminal') && busy && noGrant) checks[item.case] = true;
45
+ if (item.case === 'completion_delivery' && has('completion', 'pending') && busy && noGrant) checks[item.case] = true;
46
+ if (item.case === 'timer_delivery' && has('timer', 'terminal') && has('completion', 'terminal') && item.inventory_complete === true && work.every(record => record?.status === 'terminal' && record.root_session_id === item.session_id) && item.root_status === 'terminal' && idle && item.idle_granted === true) checks[item.case] = true;
47
+ if (item.case === 'fully_idle' && item.root_status === 'terminal' && item.inventory_complete === true && work.every(record => record?.status === 'terminal' && typeof record.id === 'string' && record.id && record.root_session_id === item.session_id) && idle && item.idle_granted === true) checks[item.case] = true;
48
+ if (item.case === 'executor_error' && typeof item.executor_error === 'string' && item.executor_error && noGrant && (busy || wait.grpc_code !== 0)) checks[item.case] = true;
49
+ if (item.case === 'timeout' && busy && noGrant) checks[item.case] = true;
50
+ if (item.case === 'late_activity_cancel_restart' && ['activity', 'cancel', 'restart'].includes(item.fence?.change) && typeof item.fence.before === 'string' && item.fence.before && typeof item.fence.after === 'string' && item.fence.after && item.fence.after !== item.fence.before && idle && noGrant) { checks[item.case] = true; fencedChanges.add(item.fence.change); }
51
+ const service = work.find(record => record?.kind === 'persistent' && record.native_tool === 'run_command' && record.native_is_daemon === true && record.root_session_id === item.session_id && typeof record.id === 'string' && record.id && Number.isSafeInteger(record.process?.pid) && record.process.pid > 0 && typeof record.process.birth === 'string' && record.process.birth && record.process.owned === true);
52
+ const serviceKey = service && JSON.stringify([item.session_id, service.id, service.process.pid, service.process.birth]);
53
+ if (item.case === 'daemon_excluded_from_required_execution' && service?.status === 'running' && service.process.live === true && item.root_status === 'terminal' && item.native_result_status === 'SUCCESS' && item.inventory_complete === true && work.every(record => record === service || record?.status === 'terminal' && typeof record.id === 'string' && record.id && record.root_session_id === item.session_id) && idle && item.idle_granted === true) { checks[item.case] = true; liveServices.set(serviceKey, Date.parse(item.observed_at)); }
54
+ if (item.case === 'owned_daemon_retirement' && service?.status === 'terminal' && service.process.live === false && item.cleanup?.coverage === 'complete' && item.cleanup.provider_stopped === true && typeof item.cleanup.snapshot_locator === 'string' && item.cleanup.snapshot_locator && noGrant) { checks[item.case] = true; retiredServices.push([serviceKey, Date.parse(item.observed_at)]); }
55
+ if (!checks[item.case]) failed.add(item.case);
56
+ checks[item.case] ||= prior;
57
+ }
58
+ checks.late_activity_cancel_restart &&= fencedChanges.size === 3;
59
+ checks.owned_daemon_retirement &&= liveServices.size > 0 && [...liveServices].every(([key, started]) => retiredServices.some(([retiredKey, at]) => retiredKey === key && at >= started));
60
+ for (const name of failed) checks[name] = false;
61
+ return { qualified: Object.values(checks).every(Boolean), checks };
62
+ }
63
+ const run = promisify(execFile);
64
+ const invalid = reason => Object.assign(new Error(`AGY native inspection unavailable: ${reason}`), { code: 'agy_native_inspection_unavailable', details: { reason, capability: AGY_NATIVE_INSPECTION_CONTRACT } });
65
+ const codec = schema => ({ serialize: value => Buffer.from(toBinary(schema, create(schema, value))), deserialize: bytes => fromBinary(schema, bytes) });
66
+ const method = (name, request, response) => ({ path: `/exa.language_server_pb.LanguageServerService/${name}`, requestStream: false, responseStream: false, requestSerialize: codec(request).serialize, requestDeserialize: codec(request).deserialize, responseSerialize: codec(response).serialize, responseDeserialize: codec(response).deserialize });
67
+ export const agyNativeService = {
68
+ wait: method('WaitForConversationFullyIdle', WaitForConversationFullyIdleRequestSchema, WaitForConversationFullyIdleResponseSchema),
69
+ metadata: method('GetConversationMetadata', GetConversationMetadataRequestSchema, GetConversationMetadataResponseSchema),
70
+ stop: method('ForceStopCascadeTree', ForceStopCascadeTreeRequestSchema, ForceStopCascadeTreeResponseSchema),
71
+ state: { ...method('StreamAgentStateUpdates', StreamAgentStateUpdatesRequestSchema, StreamAgentStateUpdatesResponseSchema), responseStream: true }
72
+ };
73
+ const Client = grpc.makeGenericClientConstructor(agyNativeService, 'AgyReadOnlyInspection');
74
+
75
+ async function readRegular(file, maximum, prefix = false) {
76
+ if (!path.isAbsolute(file)) throw invalid('native_file_path_invalid');
77
+ const before = await lstat(file);
78
+ if (!before.isFile() || before.isSymbolicLink() || !prefix && before.size > maximum) throw invalid('native_file_rejected');
79
+ const handle = await open(file, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
80
+ try {
81
+ const stat = await handle.stat();
82
+ if (!stat.isFile() || stat.dev !== before.dev || stat.ino !== before.ino || !prefix && stat.size > maximum) throw invalid('native_file_changed');
83
+ const bytes = Buffer.alloc(prefix ? Math.min(stat.size, maximum) : maximum + 1);
84
+ const { bytesRead } = await handle.read(bytes, 0, bytes.length, 0);
85
+ const after = await lstat(file);
86
+ if (!after.isFile() || after.dev !== stat.dev || after.ino !== stat.ino || !prefix && bytesRead > maximum) throw invalid('native_file_changed');
87
+ return { bytes: bytes.subarray(0, bytesRead), stat };
88
+ } finally { await handle.close(); }
89
+ }
90
+
91
+ export async function agyBinaryIdentity(bin) {
92
+ if (typeof bin !== 'string' || !bin) throw invalid('native_binary_missing');
93
+ const candidate = path.isAbsolute(bin) ? bin : (await Promise.all((process.env.PATH ?? '').split(path.delimiter).map(async dir => {
94
+ const file = path.join(dir, bin); try { return (await lstat(file)).isFile() || (await lstat(file)).isSymbolicLink() ? file : null; } catch { return null; }
95
+ }))).find(Boolean);
96
+ if (!candidate) throw invalid('native_binary_missing');
97
+ const file = await realpath(candidate), hash = createHash('sha256');
98
+ for await (const chunk of createReadStream(file)) hash.update(chunk);
99
+ return { file, sha256: hash.digest('hex') };
100
+ }
101
+ export async function agyInspectionPolicyIdentity() {
102
+ const manifest = JSON.parse(await readFile(new URL('../../../package.json', import.meta.url), 'utf8'));
103
+ const versions = [manifest.dependencies?.['@grpc/grpc-js'], manifest.dependencies?.['@bufbuild/protobuf']];
104
+ if (versions[0] !== '1.14.6' || versions[1] !== '2.16.0') throw invalid('native_protocol_dependency_unqualified');
105
+ return createHash('sha256').update(AGY_NATIVE_INSPECTION_CONTRACT).update(JSON.stringify(versions)).update(await readFile(new URL('./agy-native_pb.js', import.meta.url))).update(await readFile(new URL('./agy-native-inspection.mjs', import.meta.url))).digest('hex');
106
+ }
107
+ export async function readAgyNativeQualification(stateDir, bin, receiptFile = null) {
108
+ const binary = await agyBinaryIdentity(bin);
109
+ const clientContract = await agyInspectionPolicyIdentity();
110
+ let receipt;
111
+ const file = receiptFile ?? path.join(stateDir, 'native-inspection-qualification.json');
112
+ if (!path.isAbsolute(file)) throw invalid('qualification_path_invalid');
113
+ try {
114
+ receipt = JSON.parse((await readRegular(file, 64 * 1024)).bytes.toString('utf8'));
115
+ }
116
+ catch (error) { if (error.code !== 'ENOENT') throw invalid('qualification_receipt_invalid'); }
117
+ let evidenceValid = false;
118
+ if (typeof receipt?.evidence_path === 'string' && path.isAbsolute(receipt.evidence_path)) {
119
+ try {
120
+ const evidence = (await readRegular(receipt.evidence_path, 1024 * 1024)).bytes;
121
+ const parsed = JSON.parse(evidence.toString('utf8'));
122
+ evidenceValid = createHash('sha256').update(evidence).digest('hex') === receipt.evidence_sha256
123
+ && parsed.root_relation === receipt.root_relation
124
+ && validateAgyNativeEvidence(parsed, { ...binary, client_contract_sha256: clientContract }).qualified;
125
+ } catch { /* No retained evidence means no qualification grant. */ }
126
+ }
127
+ const qualified = evidenceValid && receipt?.schema_id === AGY_NATIVE_INSPECTION_CONTRACT && receipt.scope === 'required_execution' && receipt.binary_sha256 === binary.sha256
128
+ && receipt.client_contract_sha256 === clientContract
129
+ && ['self', 'empty_self'].includes(receipt.root_relation)
130
+ && AGY_NATIVE_QUALIFICATION_CASES.every(name => receipt.checks?.[name] === true)
131
+ && typeof receipt.evidence_sha256 === 'string' && /^[a-f0-9]{64}$/.test(receipt.evidence_sha256);
132
+ return { ...binary, client_contract_sha256: clientContract, qualified, rootRelation: qualified ? receipt.root_relation : null };
133
+ }
134
+
135
+ /** Only the log for this physical launch may nominate an endpoint. Its live
136
+ * listener must be this provider or an OS descendant, with retained PID birth. */
137
+ export async function ownedAgyEndpoint({ logFile, providerPid, providerBirth, snapshot = processSnapshot, listeners = async port => {
138
+ const { stdout } = await run('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-Fpn'], { timeout: 5_000, maxBuffer: 64 * 1024 });
139
+ let pid; return stdout.trim().split('\n').flatMap(line => line.startsWith('p') ? (pid = Number(line.slice(1)), []) : line.startsWith('n') ? [{ pid, address: line.slice(1) }] : []);
140
+ } }) {
141
+ if (!path.isAbsolute(logFile ?? '') || !Number.isSafeInteger(providerPid) || !providerBirth) throw invalid('provider_binding_missing');
142
+ // Startup prefix only: later log growth is not an expiry or model progress.
143
+ const { bytes, stat } = await readRegular(logFile, 1024 * 1024, true), text = bytes.toString('utf8');
144
+ const ports = [...new Set([...text.matchAll(/Language server listening on random port at (\d+) for HTTP(?:\r?$)/gm)].map(match => Number(match[1])))];
145
+ if (ports.length !== 1 || ports[0] < 1 || ports[0] > 65535) throw invalid('native_endpoint_missing_or_ambiguous');
146
+ const records = await snapshot(), provider = records.find(record => record.pid === providerPid);
147
+ if (!provider || provider.started !== providerBirth || provider.zombie) throw invalid('provider_birth_changed');
148
+ const allowed = new Set([providerPid]); let changed;
149
+ do { changed = false; for (const record of records) if (allowed.has(record.ppid) && !allowed.has(record.pid) && !record.zombie) { allowed.add(record.pid); changed = true; } } while (changed);
150
+ const owners = await listeners(ports[0]);
151
+ if (!owners.length || owners.some(owner => !allowed.has(owner.pid) || !/^(?:127\.0\.0\.1|\[::1\]|localhost):\d+$/.test(owner.address))) throw invalid('native_endpoint_foreign_or_nonloopback');
152
+ const births = owners.map(owner => ({ pid: owner.pid, started: records.find(record => record.pid === owner.pid)?.started }));
153
+ if (births.some(owner => !owner.started)) throw invalid('listener_birth_missing');
154
+ return { target: `127.0.0.1:${ports[0]}`, provider_pid: providerPid, provider_birth: providerBirth, listeners: births, log_identity: `${stat.dev}:${stat.ino}` };
155
+ }
156
+
157
+ /** No model request: metadata read followed by the native idle barrier. The
158
+ * caller owns freshness fencing and qualification; a raw reply is not a grant. */
159
+ async function agyNativeRequest({ endpoint, sessionId, cwd, remainingMs, signal, rootRelation = null, onMetadata = null, csrfToken, rootSessionId = sessionId, parentSessionId = '' }, action = 'wait', ownedSessions = []) {
160
+ if (!/^127\.0\.0\.1:\d+$/.test(endpoint?.target ?? '') || Number(endpoint.target.split(':')[1]) < 1 || Number(endpoint.target.split(':')[1]) > 65535) throw invalid('native_endpoint_nonloopback');
161
+ if (!Number.isFinite(remainingMs) || remainingMs < 1) throw invalid('observation_budget_exhausted');
162
+ const deadline = Date.now() + remainingMs;
163
+ const client = new Client(endpoint.target, grpc.credentials.createInsecure(), { 'grpc.max_receive_message_length': -1, 'grpc.max_send_message_length': 64 * 1024, 'grpc.enable_retries': 0 });
164
+ let active;
165
+ const headers = new grpc.Metadata();
166
+ if (typeof csrfToken === 'string' && csrfToken) headers.set('x-codeium-csrf-token', csrfToken);
167
+ const abort = () => active?.cancel();
168
+ // Native error details may contain request or authentication material. Keep
169
+ // the method and numeric status for diagnosis without copying those bytes.
170
+ const grpcError = (name, error) => {
171
+ const code = Number.isInteger(error?.code) ? error.code : null;
172
+ const failure = invalid(`grpc_${code ?? 'unknown'}`);
173
+ failure.details.grpc_method = agyNativeService[name].path;
174
+ failure.details.grpc_code = code;
175
+ return failure;
176
+ };
177
+ const unary = (name, request) => new Promise((resolve, reject) => {
178
+ if (signal?.aborted) return reject(invalid('inspection_cancelled'));
179
+ active = client[name](request, headers, { deadline }, (error, value) => error ? reject(grpcError(name, error)) : value ? resolve(value) : reject(invalid('grpc_message_missing')));
180
+ });
181
+ signal?.addEventListener('abort', abort, { once: true });
182
+ try {
183
+ const metadata = await unary('metadata', { conversationId: sessionId });
184
+ onMetadata?.(metadata);
185
+ const relation = metadata.metadata;
186
+ const rootMatches = relation?.rootConversationId === rootSessionId || rootRelation === 'empty_self' && rootSessionId === sessionId && relation?.rootConversationId === '';
187
+ const workspaces = await Promise.all((relation?.workspaceUris ?? []).map(async uri => { try { return await realpath(fileURLToPath(uri)); } catch { return null; } }));
188
+ if (!relation || relation.parentConversationId !== (action === 'state' ? parentSessionId : '') || action !== 'state' && rootSessionId !== sessionId || !rootMatches || !metadata.trajectoryId || !workspaces.includes(await realpath(cwd))) throw invalid('native_metadata_binding_unproven');
189
+ if (action === 'state') {
190
+ return await new Promise((resolve, reject) => {
191
+ if (signal?.aborted) return reject(invalid('inspection_cancelled'));
192
+ active = client.state({ conversationId: sessionId, subscriberId: randomUUID() }, headers, { deadline });
193
+ let done = false;
194
+ active.on('data', value => {
195
+ if (done) return;
196
+ const update = value.update;
197
+ // Every subscription begins with a native full snapshot. Never fold
198
+ // deltas from a previous subscription into a new incarnation.
199
+ if (!update || update.conversationId !== sessionId || update.trajectoryId !== metadata.trajectoryId) return;
200
+ const snapshot = JSON.parse(JSON.stringify(update, (key, value) => key.startsWith('$') ? undefined : value));
201
+ done = true; resolve({ ...snapshot, observed_at: new Date().toISOString(), method: agyNativeService.state.path }); active.cancel();
202
+ });
203
+ active.on('error', error => { if (!done) { done = true; reject(grpcError('state', error)); } });
204
+ active.on('end', () => { if (!done) { done = true; reject(invalid('native_state_snapshot_missing')); } });
205
+ });
206
+ }
207
+ if (action === 'stop') {
208
+ const reply = await unary('stop', { conversationId: sessionId });
209
+ const stopped = reply.stoppedConversationIds, owned = new Set([sessionId, ...ownedSessions]);
210
+ if (!Array.isArray(stopped) || !stopped.length || new Set(stopped).size !== stopped.length
211
+ || ![...owned].every(id => stopped.includes(id)) || stopped.some(id => !owned.has(id))) {
212
+ const error = invalid('native_stopped_tree_binding_unproven'); error.details.stopped_session_ids = stopped ?? null; throw error;
213
+ }
214
+ return { stopped_session_ids: stopped, trajectory_id: metadata.trajectoryId, method: agyNativeService.stop.path };
215
+ }
216
+ const reply = await unary('wait', { conversationId: sessionId, inactivityTimeoutSeconds: Math.max(1, Math.min(2147483647, Math.ceil((deadline - Date.now()) / 1000))), returnOnExecutorError: false });
217
+ return { idle: reply.timedOut === false, reason: reply.timedOut ? 'native_wait_timed_out' : 'native_wait_fully_idle', method: agyNativeService.wait.path, trajectory_id: metadata.trajectoryId };
218
+ } finally { signal?.removeEventListener('abort', abort); client.close(); }
219
+ }
220
+
221
+ export const inspectAgyNative = input => agyNativeRequest(input);
222
+ /** Read-only per-node native state; no execution/readiness grant. */
223
+ export const inspectAgyNativeState = input => agyNativeRequest(input, 'state');
224
+ /** Scoped control, not an idle/physical grant. Caller must verify retirement. */
225
+ export const stopAgyNativeTree = (input, ownedSessions = []) => agyNativeRequest(input, 'stop', ownedSessions);
@@ -0,0 +1,19 @@
1
+ // A new StreamAgentStateUpdates subscription starts with a full snapshot.
2
+ // An omitted protobuf update is an empty list; a partial indexed list is not.
3
+ export const agyNativeFullList = (update, key) => !update ||
4
+ Array.isArray(update[key]) && update.totalLength === update[key].length &&
5
+ update.indices?.length === update.totalLength && update.indices.every((value, offset) => value === offset);
6
+
7
+ export function agyNativeInventory(snapshot, sessionId) {
8
+ if (snapshot?.conversationId !== sessionId || !snapshot.trajectoryId || snapshot.error ||
9
+ snapshot.method !== '/exa.language_server_pb.LanguageServerService/StreamAgentStateUpdates' ||
10
+ !agyNativeFullList(snapshot.backgroundTasksUpdate, 'backgroundTasks') ||
11
+ !agyNativeFullList(snapshot.pendingAgentMessagesUpdate, 'pendingAgentMessages'))
12
+ throw Object.assign(new Error('AGY native task inventory is incomplete or unbound'), { code: 'native_resources_unproven' });
13
+ const tasks = snapshot.backgroundTasksUpdate?.backgroundTasks?.map(item => item.taskSnapshot) ?? [];
14
+ if (tasks.some(task => !task || typeof task.taskId !== 'string' || !task.taskId.startsWith(`${sessionId}/task-`) || !/\/task-\d+$/.test(task.taskId) || !task.toolName) ||
15
+ new Set(tasks.map(task => task.taskId)).size !== tasks.length)
16
+ throw Object.assign(new Error('AGY native task identity is unproven'), { code: 'native_resources_unproven' });
17
+ return { tasks, messages: snapshot.pendingAgentMessagesUpdate?.pendingAgentMessages ?? [],
18
+ idle: snapshot.fullyIdle === true && snapshot.status === 1 && snapshot.executorLoopStatus === 1 && snapshot.hasActiveChildren !== true };
19
+ }
@@ -0,0 +1,117 @@
1
+ // @generated by protoc-gen-es v2.16.0 with parameter "target=js"
2
+ // @generated from file agy-native.proto (package exa.language_server_pb, syntax proto3)
3
+ /* eslint-disable */
4
+
5
+ import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
6
+
7
+ /**
8
+ * Describes the file agy-native.proto.
9
+ */
10
+ export const file_agy_native = /*@__PURE__*/
11
+ fileDesc("ChBhZ3ktbmF0aXZlLnByb3RvEhZleGEubGFuZ3VhZ2Vfc2VydmVyX3BiIoQBCiNXYWl0Rm9yQ29udmVyc2F0aW9uRnVsbHlJZGxlUmVxdWVzdBIXCg9jb252ZXJzYXRpb25faWQYASABKAkSIgoaaW5hY3Rpdml0eV90aW1lb3V0X3NlY29uZHMYAiABKAUSIAoYcmV0dXJuX29uX2V4ZWN1dG9yX2Vycm9yGAQgASgIIjkKJFdhaXRGb3JDb252ZXJzYXRpb25GdWxseUlkbGVSZXNwb25zZRIRCgl0aW1lZF9vdXQYASABKAgiOQoeR2V0Q29udmVyc2F0aW9uTWV0YWRhdGFSZXF1ZXN0EhcKD2NvbnZlcnNhdGlvbl9pZBgBIAEoCSJsChRDb252ZXJzYXRpb25NZXRhZGF0YRIeChZwYXJlbnRfY29udmVyc2F0aW9uX2lkGAUgASgJEhwKFHJvb3RfY29udmVyc2F0aW9uX2lkGAYgASgJEhYKDndvcmtzcGFjZV91cmlzGAcgAygJIosBCh9HZXRDb252ZXJzYXRpb25NZXRhZGF0YVJlc3BvbnNlEj4KCG1ldGFkYXRhGAEgASgLMiwuZXhhLmxhbmd1YWdlX3NlcnZlcl9wYi5Db252ZXJzYXRpb25NZXRhZGF0YRIRCgludW1fc3RlcHMYAiABKA0SFQoNdHJhamVjdG9yeV9pZBgDIAEoCSI2ChtGb3JjZVN0b3BDYXNjYWRlVHJlZVJlcXVlc3QSFwoPY29udmVyc2F0aW9uX2lkGAEgASgJIkAKHEZvcmNlU3RvcENhc2NhZGVUcmVlUmVzcG9uc2USIAoYc3RvcHBlZF9jb252ZXJzYXRpb25faWRzGAEgAygJIlAKHlN0cmVhbUFnZW50U3RhdGVVcGRhdGVzUmVxdWVzdBIXCg9jb252ZXJzYXRpb25faWQYASABKAkSFQoNc3Vic2NyaWJlcl9pZBgCIAEoCSJOCgxBZ2VudE1lc3NhZ2USCgoCaWQYASABKAkSEQoJcmVjaXBpZW50GAIgASgJEg4KBnNlbmRlchgDIAEoCRIPCgdjb250ZW50GAQgASgJIokBChpQZW5kaW5nQWdlbnRNZXNzYWdlc1VwZGF0ZRIPCgdpbmRpY2VzGAEgAygNEkQKFnBlbmRpbmdfYWdlbnRfbWVzc2FnZXMYAiADKAsyJC5leGEubGFuZ3VhZ2Vfc2VydmVyX3BiLkFnZW50TWVzc2FnZRIUCgx0b3RhbF9sZW5ndGgYAyABKA0iagoMVGFza1NuYXBzaG90Eg8KB3Rhc2tfaWQYASABKAkSEQoJdG9vbF9uYW1lGAIgASgJEhIKCnN0ZXBfaW5kZXgYBiABKA0SDwoHbG9nX3VyaRgHIAEoCRIRCglpc19kYWVtb24YCCABKAgiTQoOQmFja2dyb3VuZFRhc2sSOwoNdGFza19zbmFwc2hvdBgBIAEoCzIkLmV4YS5sYW5ndWFnZV9zZXJ2ZXJfcGIuVGFza1NuYXBzaG90IoABChVCYWNrZ3JvdW5kVGFza3NVcGRhdGUSDwoHaW5kaWNlcxgBIAMoDRJAChBiYWNrZ3JvdW5kX3Rhc2tzGAIgAygLMiYuZXhhLmxhbmd1YWdlX3NlcnZlcl9wYi5CYWNrZ3JvdW5kVGFzaxIUCgx0b3RhbF9sZW5ndGgYAyABKA0i5wIKEEFnZW50U3RhdGVVcGRhdGUSFwoPY29udmVyc2F0aW9uX2lkGAEgASgJEhUKDXRyYWplY3RvcnlfaWQYAiABKAkSDgoGc3RhdHVzGAMgASgFEhkKEWV4ZWN1dGFibGVfc3RhdHVzGAQgASgFEhwKFGV4ZWN1dG9yX2xvb3Bfc3RhdHVzGAUgASgFEhsKE2hhc19hY3RpdmVfY2hpbGRyZW4YDiABKAgSTgoXYmFja2dyb3VuZF90YXNrc191cGRhdGUYESABKAsyLS5leGEubGFuZ3VhZ2Vfc2VydmVyX3BiLkJhY2tncm91bmRUYXNrc1VwZGF0ZRISCgpmdWxseV9pZGxlGBIgASgIElkKHXBlbmRpbmdfYWdlbnRfbWVzc2FnZXNfdXBkYXRlGBQgASgLMjIuZXhhLmxhbmd1YWdlX3NlcnZlcl9wYi5QZW5kaW5nQWdlbnRNZXNzYWdlc1VwZGF0ZSJbCh9TdHJlYW1BZ2VudFN0YXRlVXBkYXRlc1Jlc3BvbnNlEjgKBnVwZGF0ZRgBIAEoCzIoLmV4YS5sYW5ndWFnZV9zZXJ2ZXJfcGIuQWdlbnRTdGF0ZVVwZGF0ZWIGcHJvdG8z");
12
+
13
+ /**
14
+ * Describes the message exa.language_server_pb.WaitForConversationFullyIdleRequest.
15
+ * Use `create(WaitForConversationFullyIdleRequestSchema)` to create a new message.
16
+ */
17
+ export const WaitForConversationFullyIdleRequestSchema = /*@__PURE__*/
18
+ messageDesc(file_agy_native, 0);
19
+
20
+ /**
21
+ * Describes the message exa.language_server_pb.WaitForConversationFullyIdleResponse.
22
+ * Use `create(WaitForConversationFullyIdleResponseSchema)` to create a new message.
23
+ */
24
+ export const WaitForConversationFullyIdleResponseSchema = /*@__PURE__*/
25
+ messageDesc(file_agy_native, 1);
26
+
27
+ /**
28
+ * Describes the message exa.language_server_pb.GetConversationMetadataRequest.
29
+ * Use `create(GetConversationMetadataRequestSchema)` to create a new message.
30
+ */
31
+ export const GetConversationMetadataRequestSchema = /*@__PURE__*/
32
+ messageDesc(file_agy_native, 2);
33
+
34
+ /**
35
+ * Describes the message exa.language_server_pb.ConversationMetadata.
36
+ * Use `create(ConversationMetadataSchema)` to create a new message.
37
+ */
38
+ export const ConversationMetadataSchema = /*@__PURE__*/
39
+ messageDesc(file_agy_native, 3);
40
+
41
+ /**
42
+ * Describes the message exa.language_server_pb.GetConversationMetadataResponse.
43
+ * Use `create(GetConversationMetadataResponseSchema)` to create a new message.
44
+ */
45
+ export const GetConversationMetadataResponseSchema = /*@__PURE__*/
46
+ messageDesc(file_agy_native, 4);
47
+
48
+ /**
49
+ * Describes the message exa.language_server_pb.ForceStopCascadeTreeRequest.
50
+ * Use `create(ForceStopCascadeTreeRequestSchema)` to create a new message.
51
+ */
52
+ export const ForceStopCascadeTreeRequestSchema = /*@__PURE__*/
53
+ messageDesc(file_agy_native, 5);
54
+
55
+ /**
56
+ * Describes the message exa.language_server_pb.ForceStopCascadeTreeResponse.
57
+ * Use `create(ForceStopCascadeTreeResponseSchema)` to create a new message.
58
+ */
59
+ export const ForceStopCascadeTreeResponseSchema = /*@__PURE__*/
60
+ messageDesc(file_agy_native, 6);
61
+
62
+ /**
63
+ * Describes the message exa.language_server_pb.StreamAgentStateUpdatesRequest.
64
+ * Use `create(StreamAgentStateUpdatesRequestSchema)` to create a new message.
65
+ */
66
+ export const StreamAgentStateUpdatesRequestSchema = /*@__PURE__*/
67
+ messageDesc(file_agy_native, 7);
68
+
69
+ /**
70
+ * Describes the message exa.language_server_pb.AgentMessage.
71
+ * Use `create(AgentMessageSchema)` to create a new message.
72
+ */
73
+ export const AgentMessageSchema = /*@__PURE__*/
74
+ messageDesc(file_agy_native, 8);
75
+
76
+ /**
77
+ * Describes the message exa.language_server_pb.PendingAgentMessagesUpdate.
78
+ * Use `create(PendingAgentMessagesUpdateSchema)` to create a new message.
79
+ */
80
+ export const PendingAgentMessagesUpdateSchema = /*@__PURE__*/
81
+ messageDesc(file_agy_native, 9);
82
+
83
+ /**
84
+ * Describes the message exa.language_server_pb.TaskSnapshot.
85
+ * Use `create(TaskSnapshotSchema)` to create a new message.
86
+ */
87
+ export const TaskSnapshotSchema = /*@__PURE__*/
88
+ messageDesc(file_agy_native, 10);
89
+
90
+ /**
91
+ * Describes the message exa.language_server_pb.BackgroundTask.
92
+ * Use `create(BackgroundTaskSchema)` to create a new message.
93
+ */
94
+ export const BackgroundTaskSchema = /*@__PURE__*/
95
+ messageDesc(file_agy_native, 11);
96
+
97
+ /**
98
+ * Describes the message exa.language_server_pb.BackgroundTasksUpdate.
99
+ * Use `create(BackgroundTasksUpdateSchema)` to create a new message.
100
+ */
101
+ export const BackgroundTasksUpdateSchema = /*@__PURE__*/
102
+ messageDesc(file_agy_native, 12);
103
+
104
+ /**
105
+ * Describes the message exa.language_server_pb.AgentStateUpdate.
106
+ * Use `create(AgentStateUpdateSchema)` to create a new message.
107
+ */
108
+ export const AgentStateUpdateSchema = /*@__PURE__*/
109
+ messageDesc(file_agy_native, 13);
110
+
111
+ /**
112
+ * Describes the message exa.language_server_pb.StreamAgentStateUpdatesResponse.
113
+ * Use `create(StreamAgentStateUpdatesResponseSchema)` to create a new message.
114
+ */
115
+ export const StreamAgentStateUpdatesResponseSchema = /*@__PURE__*/
116
+ messageDesc(file_agy_native, 14);
117
+
@@ -0,0 +1,74 @@
1
+ import { constants, openSync, closeSync, fstatSync, lstatSync, readSync, realpathSync } from 'node:fs';
2
+ import { fileURLToPath } from 'node:url';
3
+ import path from 'node:path';
4
+ import { createHash } from 'node:crypto';
5
+ import { StringDecoder } from 'node:string_decoder';
6
+
7
+ const taskId = '[\\w-]+/task-\\d+';
8
+
9
+ export function ownedAgyOutput(reference, source, sessionId, ownerTask = null) {
10
+ let fd;
11
+ try {
12
+ const transcript = fileURLToPath(source.locator), file = fileURLToPath(reference);
13
+ const system = path.dirname(path.dirname(transcript));
14
+ if (path.basename(path.dirname(system)) !== sessionId || path.basename(system) !== '.system_generated') return null;
15
+ const relative = path.relative(system, file);
16
+ if (!/^(?:steps\/\d+\/output\.txt|tasks\/task-\d+\.log)$/.test(relative) || realpathSync(file) !== file || realpathSync(system) !== system) return null;
17
+ if (ownerTask) {
18
+ const number = ownerTask.match(new RegExp(`^${sessionId}/task-(\\d+)$`))?.[1];
19
+ if (!number || ![`steps/${number}/output.txt`, `tasks/task-${number}.log`].includes(relative)) return null;
20
+ }
21
+ const before = lstatSync(file);
22
+ if (!before.isFile()) return null;
23
+ fd = openSync(file, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
24
+ const stat = fstatSync(fd);
25
+ if (!stat.isFile() || stat.ino !== before.ino || stat.dev !== before.dev) return null;
26
+ const bytes = Buffer.allocUnsafe(64 * 1024), decoder = new StringDecoder('utf8'), hash = createHash('sha256');
27
+ let offset = 0, text = '';
28
+ while (offset < stat.size) {
29
+ const count = readSync(fd, bytes, 0, Math.min(bytes.length, stat.size - offset), offset); if (!count) return null;
30
+ const chunk = bytes.subarray(0, count); hash.update(chunk); text += decoder.write(chunk); offset += count;
31
+ }
32
+ text += decoder.end();
33
+ const after = fstatSync(fd);
34
+ const finalPath = lstatSync(file);
35
+ if (!finalPath.isFile() || finalPath.dev !== stat.dev || finalPath.ino !== stat.ino || realpathSync(file) !== file
36
+ || stat.size !== after.size || stat.mtimeMs !== after.mtimeMs || stat.ctimeMs !== after.ctimeMs) return null;
37
+ return { text, sha256: hash.digest('hex'), locator: reference };
38
+ } catch { return null; }
39
+ finally { if (fd !== undefined) closeSync(fd); }
40
+ }
41
+
42
+ /** Only a native envelope is decoded here; stdout cannot introduce terminal authority. */
43
+ export function agyTerminalEnvelope(row, call = null) {
44
+ if (row?.status !== 'DONE' || typeof row.content !== 'string') return null;
45
+ let body = row.content.replaceAll('\r\n', '\n'), id = null, cancelled = false;
46
+ if (row.source === 'SYSTEM' && row.type === 'SYSTEM_MESSAGE') {
47
+ const match = body.match(new RegExp(`(?:^|\\n)\\[Message\\] timestamp=[^\\n]+ sender=(${taskId}) priority=MESSAGE_PRIORITY_(?:HIGH|LOW) content=Task id "(${taskId})" (finished with result:|was canceled with result:)\\n`));
48
+ if (!match || match[1] !== match[2]) return null;
49
+ id = match[1]; cancelled = match[3].startsWith('was canceled');
50
+ body = body.slice(match.index + match[0].length).replace(/\n<\/SYSTEM_MESSAGE>\s*$/, '');
51
+ } else if (row.type !== 'GENERIC' || row.source && row.source !== 'MODEL') return null;
52
+ else {
53
+ body = body.replace(/^Created At: [^\n]+\nCompleted At: [^\n]+\n/, '');
54
+ if (call?.name === 'manage_task') {
55
+ const decode = value => { try { return JSON.parse(value); } catch { return value; } };
56
+ id = decode(call.args?.TaskId);
57
+ const action = decode(call.args?.Action);
58
+ const status = body.match(new RegExp(`^Task: (${taskId})\\nStatus: (DONE|COMPLETED|FAILED|CANCELLED)(?:\\n|$)`));
59
+ if (action === 'status' && status?.[1] === id) return { task_id: id, task_terminal: true, exit_code: null, command_outcome: status[2] === 'DONE' ? null : status[2].toLowerCase(), output: null };
60
+ if (action === 'kill' && body.match(new RegExp(`^Task "(${taskId})" cancelled\\.(?:\\n|$)`))?.[1] === id) return { task_id: id, task_terminal: true, exit_code: null, command_outcome: 'cancelled', output: null };
61
+ return null;
62
+ }
63
+ }
64
+ // This exact wrapper preserves the beginning of the native result, including its exit header.
65
+ const wrapper = body.match(/^The tool's output was truncated due to being too long\. You can find the full output in a file at (file:\/\/[^\n]+)\.\n\nHere is a preview with the middle of the output truncated:\n/);
66
+ if (wrapper) body = body.slice(wrapper[0].length);
67
+ if (cancelled && /^Tool execution was canceled(?:\n|$)/.test(body)) return { task_id: id, task_terminal: true, exit_code: null, command_outcome: 'cancelled', output: null };
68
+ const header = body.match(/^Command exited with code (-?\d+)\.(?:\n|$)/);
69
+ if (!header) return null;
70
+ const exit = Number(header[1]);
71
+ if (!Number.isSafeInteger(exit)) return null;
72
+ return { task_id: id, task_terminal: true, exit_code: exit, command_outcome: exit === 0 ? 'completed' : 'failed', output: wrapper ? null : body.split('Command output:\n')[1] ?? null,
73
+ ...(wrapper ? { output_reference: wrapper[1] } : {}) };
74
+ }
@@ -0,0 +1,54 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { StringDecoder } from 'node:string_decoder';
3
+
4
+ // The caller opens and validates the owned no-symlink handle and must discard
5
+ // tentative callback results if this function rejects. One complete JSONL
6
+ // record, rather than the whole transcript, is the largest retained value.
7
+ export async function readAgyTranscriptSnapshot(handle, { locator, assertIdentity, onRecord, onProgress }) {
8
+ if (typeof assertIdentity !== 'function' || typeof onRecord !== 'function') throw new TypeError('snapshot requires owner validation and a record consumer');
9
+ const original = await handle.stat();
10
+ const unchanged = async () => {
11
+ const current = await handle.stat();
12
+ if (!current.isFile() || current.dev !== original.dev || current.ino !== original.ino || current.size !== original.size
13
+ || current.mtimeMs !== original.mtimeMs || current.ctimeMs !== original.ctimeMs) throw new Error('agy_transcript_snapshot_changed');
14
+ await assertIdentity(current);
15
+ };
16
+ if (!original.isFile()) throw new Error('agy_transcript_snapshot_changed');
17
+ await unchanged();
18
+ const buffer = Buffer.allocUnsafe(64 * 1024), digest = createHash('sha256');
19
+ let offset = 0, complete = 0, completeHash = digest.copy();
20
+ while (offset < original.size) {
21
+ const { bytesRead } = await handle.read(buffer, 0, Math.min(buffer.length, original.size - offset), offset);
22
+ if (!bytesRead) throw new Error('agy_transcript_snapshot_changed');
23
+ const chunk = buffer.subarray(0, bytesRead), lastNewline = chunk.lastIndexOf(10);
24
+ if (lastNewline >= 0) {
25
+ digest.update(chunk.subarray(0, lastNewline + 1));
26
+ complete = offset + lastNewline + 1; completeHash = digest.copy();
27
+ digest.update(chunk.subarray(lastNewline + 1));
28
+ } else digest.update(chunk);
29
+ offset += bytesRead;
30
+ await onProgress?.(`digest:${original.dev}:${original.ino}:${original.size}:${original.mtimeMs}:${offset}`);
31
+ }
32
+ const source = { locator, byte_start: 0, byte_end: complete, sha256: completeHash.digest('hex') };
33
+ await unchanged();
34
+ const decoder = new StringDecoder('utf8'); let pending = '', line = 0;
35
+ offset = 0;
36
+ while (offset < complete) {
37
+ const { bytesRead } = await handle.read(buffer, 0, Math.min(buffer.length, complete - offset), offset);
38
+ if (!bytesRead) throw new Error('agy_transcript_snapshot_changed');
39
+ pending += decoder.write(buffer.subarray(0, bytesRead)); offset += bytesRead;
40
+ await onProgress?.(`records:${source.sha256}:${offset}`);
41
+ let newline;
42
+ while ((newline = pending.indexOf('\n')) >= 0) {
43
+ const text = pending.slice(0, newline); pending = pending.slice(newline + 1); line += 1;
44
+ if (!text.trim()) continue;
45
+ let record;
46
+ try { record = JSON.parse(text); } catch { throw new Error('agy_transcript_invalid_record'); }
47
+ await onRecord(record, { ...source, line });
48
+ }
49
+ }
50
+ pending += decoder.end();
51
+ if (pending) throw new Error('agy_transcript_snapshot_changed');
52
+ await unchanged();
53
+ return { source, partial_tail: complete !== original.size };
54
+ }
@@ -0,0 +1,3 @@
1
+ export function recoverDaemonReply(root: string, id: string, options?: { timeoutMs?: number | null; signal?: AbortSignal; binding?: Record<string, unknown>; onProgress?: (value: Record<string, unknown>) => void; onOutcome?: (value: Record<string, unknown>) => void; onPendingSettlement?: (value: Record<string, unknown>) => Promise<void>; observationClock?: import("./observation-clock.mjs").ObservationClock }): Promise<Record<string, unknown>>;
2
+ export function retainedDaemonReply(root: string, id: string, binding?: Record<string, unknown>): Promise<{ ready: boolean; outcome: unknown; value?: unknown; settlement?: Record<string, unknown> | null; reason?: string } | null>;
3
+ export function withDaemonProgressObserver<T>(observer: (value: Record<string, unknown>) => void, action: () => Promise<T>): Promise<T>;