@caupulican/pi-adaptative 0.81.39 → 0.81.41

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 (884) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/README.md +2 -0
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +2 -0
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -1
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +3 -0
  6. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -1
  7. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +4 -0
  8. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +9 -0
  9. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
  10. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +290 -107
  11. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
  12. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +357 -122
  13. package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +2 -2
  14. package/dist/cli/args.d.ts +4 -0
  15. package/dist/cli/args.d.ts.map +1 -1
  16. package/dist/cli/args.js +31 -1
  17. package/dist/cli/args.js.map +1 -1
  18. package/dist/core/agent-directory-layout.d.ts +15 -0
  19. package/dist/core/agent-directory-layout.d.ts.map +1 -0
  20. package/dist/core/agent-directory-layout.js +72 -0
  21. package/dist/core/agent-directory-layout.js.map +1 -0
  22. package/dist/core/agent-paths.d.ts +25 -2
  23. package/dist/core/agent-paths.d.ts.map +1 -1
  24. package/dist/core/agent-paths.js +79 -4
  25. package/dist/core/agent-paths.js.map +1 -1
  26. package/dist/core/agent-session-contracts.d.ts +293 -0
  27. package/dist/core/agent-session-contracts.d.ts.map +1 -0
  28. package/dist/core/agent-session-contracts.js +26 -0
  29. package/dist/core/agent-session-contracts.js.map +1 -0
  30. package/dist/core/agent-session-runtime.d.ts +52 -8
  31. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  32. package/dist/core/agent-session-runtime.js +400 -79
  33. package/dist/core/agent-session-runtime.js.map +1 -1
  34. package/dist/core/agent-session-services.d.ts +1 -0
  35. package/dist/core/agent-session-services.d.ts.map +1 -1
  36. package/dist/core/agent-session-services.js +1 -0
  37. package/dist/core/agent-session-services.js.map +1 -1
  38. package/dist/core/agent-session.d.ts +74 -518
  39. package/dist/core/agent-session.d.ts.map +1 -1
  40. package/dist/core/agent-session.js +370 -1432
  41. package/dist/core/agent-session.js.map +1 -1
  42. package/dist/core/auth-storage.d.ts.map +1 -1
  43. package/dist/core/auth-storage.js +3 -1
  44. package/dist/core/auth-storage.js.map +1 -1
  45. package/dist/core/autonomy/approval-gate.d.ts +3 -2
  46. package/dist/core/autonomy/approval-gate.d.ts.map +1 -1
  47. package/dist/core/autonomy/approval-gate.js +6 -28
  48. package/dist/core/autonomy/approval-gate.js.map +1 -1
  49. package/dist/core/autonomy/bounded-completion.d.ts +1 -1
  50. package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
  51. package/dist/core/autonomy/bounded-completion.js +1 -1
  52. package/dist/core/autonomy/bounded-completion.js.map +1 -1
  53. package/dist/core/autonomy/contracts.d.ts +20 -12
  54. package/dist/core/autonomy/contracts.d.ts.map +1 -1
  55. package/dist/core/autonomy/contracts.js.map +1 -1
  56. package/dist/core/autonomy/foreground-envelope.d.ts +8 -2
  57. package/dist/core/autonomy/foreground-envelope.d.ts.map +1 -1
  58. package/dist/core/autonomy/foreground-envelope.js +8 -25
  59. package/dist/core/autonomy/foreground-envelope.js.map +1 -1
  60. package/dist/core/autonomy/gates.d.ts.map +1 -1
  61. package/dist/core/autonomy/gates.js +8 -10
  62. package/dist/core/autonomy/gates.js.map +1 -1
  63. package/dist/core/autonomy/lane-private-paths.d.ts +2 -0
  64. package/dist/core/autonomy/lane-private-paths.d.ts.map +1 -0
  65. package/dist/core/autonomy/lane-private-paths.js +16 -0
  66. package/dist/core/autonomy/lane-private-paths.js.map +1 -0
  67. package/dist/core/autonomy/lane-tool-surface.d.ts +10 -0
  68. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  69. package/dist/core/autonomy/lane-tool-surface.js +48 -9
  70. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  71. package/dist/core/autonomy/lane-tracker.d.ts +14 -0
  72. package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
  73. package/dist/core/autonomy/lane-tracker.js +38 -0
  74. package/dist/core/autonomy/lane-tracker.js.map +1 -1
  75. package/dist/core/autonomy/risk-assessment.d.ts +1 -2
  76. package/dist/core/autonomy/risk-assessment.d.ts.map +1 -1
  77. package/dist/core/autonomy/risk-assessment.js +1 -123
  78. package/dist/core/autonomy/risk-assessment.js.map +1 -1
  79. package/dist/core/autonomy/session-lane-record.d.ts +4 -4
  80. package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
  81. package/dist/core/autonomy/session-lane-record.js +16 -29
  82. package/dist/core/autonomy/session-lane-record.js.map +1 -1
  83. package/dist/core/autonomy/telemetry-events.d.ts +1 -1
  84. package/dist/core/autonomy/telemetry-events.d.ts.map +1 -1
  85. package/dist/core/autonomy/telemetry-events.js +1 -1
  86. package/dist/core/autonomy/telemetry-events.js.map +1 -1
  87. package/dist/core/autonomy-telemetry.d.ts +7 -7
  88. package/dist/core/autonomy-telemetry.d.ts.map +1 -1
  89. package/dist/core/autonomy-telemetry.js +9 -9
  90. package/dist/core/autonomy-telemetry.js.map +1 -1
  91. package/dist/core/background-lane-controller.d.ts +56 -236
  92. package/dist/core/background-lane-controller.d.ts.map +1 -1
  93. package/dist/core/background-lane-controller.js +141 -1273
  94. package/dist/core/background-lane-controller.js.map +1 -1
  95. package/dist/core/bedrock-sso-login.d.ts +16 -0
  96. package/dist/core/bedrock-sso-login.d.ts.map +1 -0
  97. package/dist/core/bedrock-sso-login.js +98 -0
  98. package/dist/core/bedrock-sso-login.js.map +1 -0
  99. package/dist/core/capability-contract.d.ts +4 -0
  100. package/dist/core/capability-contract.d.ts.map +1 -0
  101. package/dist/core/capability-contract.js +28 -0
  102. package/dist/core/capability-contract.js.map +1 -0
  103. package/dist/core/compaction-controller.d.ts +90 -0
  104. package/dist/core/compaction-controller.d.ts.map +1 -0
  105. package/dist/core/compaction-controller.js +452 -0
  106. package/dist/core/compaction-controller.js.map +1 -0
  107. package/dist/core/compaction-support.d.ts +13 -17
  108. package/dist/core/compaction-support.d.ts.map +1 -1
  109. package/dist/core/compaction-support.js +3 -3
  110. package/dist/core/compaction-support.js.map +1 -1
  111. package/dist/core/context/context-artifacts.d.ts +6 -2
  112. package/dist/core/context/context-artifacts.d.ts.map +1 -1
  113. package/dist/core/context/context-artifacts.js +34 -2
  114. package/dist/core/context/context-artifacts.js.map +1 -1
  115. package/dist/core/context/context-store-retention.d.ts +8 -2
  116. package/dist/core/context/context-store-retention.d.ts.map +1 -1
  117. package/dist/core/context/context-store-retention.js +158 -35
  118. package/dist/core/context/context-store-retention.js.map +1 -1
  119. package/dist/core/context/okf-memory.d.ts.map +1 -1
  120. package/dist/core/context/okf-memory.js +9 -11
  121. package/dist/core/context/okf-memory.js.map +1 -1
  122. package/dist/core/context/sqlite-runtime-index.d.ts.map +1 -1
  123. package/dist/core/context/sqlite-runtime-index.js +6 -8
  124. package/dist/core/context/sqlite-runtime-index.js.map +1 -1
  125. package/dist/core/context-gc.d.ts +3 -0
  126. package/dist/core/context-gc.d.ts.map +1 -1
  127. package/dist/core/context-gc.js +10 -5
  128. package/dist/core/context-gc.js.map +1 -1
  129. package/dist/core/context-pipeline.d.ts +1 -1
  130. package/dist/core/context-pipeline.d.ts.map +1 -1
  131. package/dist/core/context-pipeline.js +16 -37
  132. package/dist/core/context-pipeline.js.map +1 -1
  133. package/dist/core/cost/cost-summary.d.ts.map +1 -1
  134. package/dist/core/cost/cost-summary.js +5 -3
  135. package/dist/core/cost/cost-summary.js.map +1 -1
  136. package/dist/core/cost/daily-usage.d.ts.map +1 -1
  137. package/dist/core/cost/daily-usage.js +4 -5
  138. package/dist/core/cost/daily-usage.js.map +1 -1
  139. package/dist/core/default-tool-surface.d.ts.map +1 -1
  140. package/dist/core/default-tool-surface.js +2 -0
  141. package/dist/core/default-tool-surface.js.map +1 -1
  142. package/dist/core/delegation/managed-lane-controller.d.ts +34 -0
  143. package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -0
  144. package/dist/core/delegation/managed-lane-controller.js +217 -0
  145. package/dist/core/delegation/managed-lane-controller.js.map +1 -0
  146. package/dist/core/delegation/session-worker-claim.d.ts +44 -0
  147. package/dist/core/delegation/session-worker-claim.d.ts.map +1 -0
  148. package/dist/core/delegation/session-worker-claim.js +98 -0
  149. package/dist/core/delegation/session-worker-claim.js.map +1 -0
  150. package/dist/core/delegation/worker-actions.d.ts +7 -5
  151. package/dist/core/delegation/worker-actions.d.ts.map +1 -1
  152. package/dist/core/delegation/worker-actions.js +20 -4
  153. package/dist/core/delegation/worker-actions.js.map +1 -1
  154. package/dist/core/delegation/{worker-result.d.ts → worker-claim.d.ts} +13 -13
  155. package/dist/core/delegation/worker-claim.d.ts.map +1 -0
  156. package/dist/core/delegation/{worker-result.js → worker-claim.js} +61 -51
  157. package/dist/core/delegation/worker-claim.js.map +1 -0
  158. package/dist/core/delegation/worker-delegation-controller.d.ts +110 -0
  159. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -0
  160. package/dist/core/delegation/worker-delegation-controller.js +861 -0
  161. package/dist/core/delegation/worker-delegation-controller.js.map +1 -0
  162. package/dist/core/delegation/worker-delegation-request.d.ts +11 -0
  163. package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -0
  164. package/dist/core/delegation/worker-delegation-request.js +2 -0
  165. package/dist/core/delegation/worker-delegation-request.js.map +1 -0
  166. package/dist/core/delegation/worker-dispatch-scheduler.d.ts +40 -0
  167. package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -0
  168. package/dist/core/delegation/worker-dispatch-scheduler.js +93 -0
  169. package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -0
  170. package/dist/core/delegation/worker-execution-policy.d.ts +62 -0
  171. package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -0
  172. package/dist/core/delegation/worker-execution-policy.js +160 -0
  173. package/dist/core/delegation/worker-execution-policy.js.map +1 -0
  174. package/dist/core/delegation/worker-lane-projection.d.ts +14 -0
  175. package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -0
  176. package/dist/core/delegation/worker-lane-projection.js +100 -0
  177. package/dist/core/delegation/worker-lane-projection.js.map +1 -0
  178. package/dist/core/delegation/worker-lifecycle.d.ts +97 -0
  179. package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -0
  180. package/dist/core/delegation/worker-lifecycle.js +339 -0
  181. package/dist/core/delegation/worker-lifecycle.js.map +1 -0
  182. package/dist/core/delegation/worker-notification-coordinator.d.ts +36 -0
  183. package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -0
  184. package/dist/core/delegation/worker-notification-coordinator.js +90 -0
  185. package/dist/core/delegation/worker-notification-coordinator.js.map +1 -0
  186. package/dist/core/delegation/worker-profile-resolver.d.ts +55 -0
  187. package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -0
  188. package/dist/core/delegation/worker-profile-resolver.js +113 -0
  189. package/dist/core/delegation/worker-profile-resolver.js.map +1 -0
  190. package/dist/core/delegation/worker-runner.d.ts +25 -14
  191. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  192. package/dist/core/delegation/worker-runner.js +122 -53
  193. package/dist/core/delegation/worker-runner.js.map +1 -1
  194. package/dist/core/delegation/worker-task-label.d.ts +3 -0
  195. package/dist/core/delegation/worker-task-label.d.ts.map +1 -0
  196. package/dist/core/delegation/worker-task-label.js +11 -0
  197. package/dist/core/delegation/worker-task-label.js.map +1 -0
  198. package/dist/core/doctor.d.ts +8 -0
  199. package/dist/core/doctor.d.ts.map +1 -1
  200. package/dist/core/doctor.js +32 -1
  201. package/dist/core/doctor.js.map +1 -1
  202. package/dist/core/extension-import-authority.d.ts +6 -0
  203. package/dist/core/extension-import-authority.d.ts.map +1 -0
  204. package/dist/core/extension-import-authority.js +10 -0
  205. package/dist/core/extension-import-authority.js.map +1 -0
  206. package/dist/core/extensions/index.d.ts +1 -1
  207. package/dist/core/extensions/index.d.ts.map +1 -1
  208. package/dist/core/extensions/index.js.map +1 -1
  209. package/dist/core/extensions/loader.d.ts +5 -1
  210. package/dist/core/extensions/loader.d.ts.map +1 -1
  211. package/dist/core/extensions/loader.js +52 -18
  212. package/dist/core/extensions/loader.js.map +1 -1
  213. package/dist/core/extensions/runner.d.ts +3 -0
  214. package/dist/core/extensions/runner.d.ts.map +1 -1
  215. package/dist/core/extensions/runner.js +20 -5
  216. package/dist/core/extensions/runner.js.map +1 -1
  217. package/dist/core/extensions/stale-context.d.ts +2 -0
  218. package/dist/core/extensions/stale-context.d.ts.map +1 -0
  219. package/dist/core/extensions/stale-context.js +2 -0
  220. package/dist/core/extensions/stale-context.js.map +1 -0
  221. package/dist/core/extensions/storage.d.ts +8 -0
  222. package/dist/core/extensions/storage.d.ts.map +1 -0
  223. package/dist/core/extensions/storage.js +28 -0
  224. package/dist/core/extensions/storage.js.map +1 -0
  225. package/dist/core/extensions/types.d.ts +78 -21
  226. package/dist/core/extensions/types.d.ts.map +1 -1
  227. package/dist/core/extensions/types.js.map +1 -1
  228. package/dist/core/failure-corpus.d.ts +1 -15
  229. package/dist/core/failure-corpus.d.ts.map +1 -1
  230. package/dist/core/failure-corpus.js +9 -37
  231. package/dist/core/failure-corpus.js.map +1 -1
  232. package/dist/core/foreground-recovery-controller.d.ts +53 -0
  233. package/dist/core/foreground-recovery-controller.d.ts.map +1 -0
  234. package/dist/core/foreground-recovery-controller.js +111 -0
  235. package/dist/core/foreground-recovery-controller.js.map +1 -0
  236. package/dist/core/gateways/channel-provider.d.ts +3 -0
  237. package/dist/core/gateways/channel-provider.d.ts.map +1 -1
  238. package/dist/core/gateways/channel-provider.js +31 -6
  239. package/dist/core/gateways/channel-provider.js.map +1 -1
  240. package/dist/core/goal-loop-controller.d.ts +14 -9
  241. package/dist/core/goal-loop-controller.d.ts.map +1 -1
  242. package/dist/core/goal-loop-controller.js +47 -75
  243. package/dist/core/goal-loop-controller.js.map +1 -1
  244. package/dist/core/goals/compact-goal-context.d.ts +11 -0
  245. package/dist/core/goals/compact-goal-context.d.ts.map +1 -0
  246. package/dist/core/goals/compact-goal-context.js +59 -0
  247. package/dist/core/goals/compact-goal-context.js.map +1 -0
  248. package/dist/core/goals/goal-acceptance.d.ts +11 -0
  249. package/dist/core/goals/goal-acceptance.d.ts.map +1 -0
  250. package/dist/core/goals/goal-acceptance.js +27 -0
  251. package/dist/core/goals/goal-acceptance.js.map +1 -0
  252. package/dist/core/goals/goal-auto-continue-controller.d.ts +28 -0
  253. package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -0
  254. package/dist/core/goals/goal-auto-continue-controller.js +90 -0
  255. package/dist/core/goals/goal-auto-continue-controller.js.map +1 -0
  256. package/dist/core/goals/goal-continuation-controller.d.ts +2 -2
  257. package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
  258. package/dist/core/goals/goal-continuation-controller.js +52 -11
  259. package/dist/core/goals/goal-continuation-controller.js.map +1 -1
  260. package/dist/core/goals/goal-continuation-defaults.d.ts +4 -29
  261. package/dist/core/goals/goal-continuation-defaults.d.ts.map +1 -1
  262. package/dist/core/goals/goal-continuation-defaults.js +4 -32
  263. package/dist/core/goals/goal-continuation-defaults.js.map +1 -1
  264. package/dist/core/goals/goal-continuation-prompt.d.ts +8 -18
  265. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  266. package/dist/core/goals/goal-continuation-prompt.js +9 -179
  267. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  268. package/dist/core/goals/goal-lifecycle.d.ts +43 -0
  269. package/dist/core/goals/goal-lifecycle.d.ts.map +1 -0
  270. package/dist/core/goals/goal-lifecycle.js +102 -0
  271. package/dist/core/goals/goal-lifecycle.js.map +1 -0
  272. package/dist/core/goals/goal-record.d.ts +17 -0
  273. package/dist/core/goals/goal-record.d.ts.map +1 -0
  274. package/dist/core/goals/goal-record.js +31 -0
  275. package/dist/core/goals/goal-record.js.map +1 -0
  276. package/dist/core/goals/goal-runtime-snapshot.d.ts +11 -9
  277. package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
  278. package/dist/core/goals/goal-runtime-snapshot.js +10 -8
  279. package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
  280. package/dist/core/goals/goal-session-controller.d.ts +42 -0
  281. package/dist/core/goals/goal-session-controller.d.ts.map +1 -0
  282. package/dist/core/goals/goal-session-controller.js +128 -0
  283. package/dist/core/goals/goal-session-controller.js.map +1 -0
  284. package/dist/core/goals/goal-state.d.ts +46 -25
  285. package/dist/core/goals/goal-state.d.ts.map +1 -1
  286. package/dist/core/goals/goal-state.js +91 -24
  287. package/dist/core/goals/goal-state.js.map +1 -1
  288. package/dist/core/goals/goal-tool-core.d.ts +9 -10
  289. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  290. package/dist/core/goals/goal-tool-core.js +60 -75
  291. package/dist/core/goals/goal-tool-core.js.map +1 -1
  292. package/dist/core/goals/session-goal-state.d.ts +20 -12
  293. package/dist/core/goals/session-goal-state.d.ts.map +1 -1
  294. package/dist/core/goals/session-goal-state.js +133 -33
  295. package/dist/core/goals/session-goal-state.js.map +1 -1
  296. package/dist/core/human-input-controller.d.ts +47 -0
  297. package/dist/core/human-input-controller.d.ts.map +1 -0
  298. package/dist/core/human-input-controller.js +181 -0
  299. package/dist/core/human-input-controller.js.map +1 -0
  300. package/dist/core/human-input.d.ts +100 -0
  301. package/dist/core/human-input.d.ts.map +1 -0
  302. package/dist/core/human-input.js +362 -0
  303. package/dist/core/human-input.js.map +1 -0
  304. package/dist/core/index.d.ts +9 -1
  305. package/dist/core/index.d.ts.map +1 -1
  306. package/dist/core/index.js +9 -1
  307. package/dist/core/index.js.map +1 -1
  308. package/dist/core/{telemetry.d.ts → install-telemetry.d.ts} +1 -1
  309. package/dist/core/install-telemetry.d.ts.map +1 -0
  310. package/dist/core/{telemetry.js → install-telemetry.js} +1 -1
  311. package/dist/core/install-telemetry.js.map +1 -0
  312. package/dist/core/keybindings.d.ts +17 -1
  313. package/dist/core/keybindings.d.ts.map +1 -1
  314. package/dist/core/keybindings.js +24 -6
  315. package/dist/core/keybindings.js.map +1 -1
  316. package/dist/core/learning/learning-audit.d.ts +2 -4
  317. package/dist/core/learning/learning-audit.d.ts.map +1 -1
  318. package/dist/core/learning/learning-audit.js +9 -29
  319. package/dist/core/learning/learning-audit.js.map +1 -1
  320. package/dist/core/learning/learning-gate.d.ts.map +1 -1
  321. package/dist/core/learning/learning-gate.js +1 -6
  322. package/dist/core/learning/learning-gate.js.map +1 -1
  323. package/dist/core/learning/session-learning-decision.d.ts +2 -4
  324. package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
  325. package/dist/core/learning/session-learning-decision.js +9 -29
  326. package/dist/core/learning/session-learning-decision.js.map +1 -1
  327. package/dist/core/local-runtime-controller.d.ts +1 -1
  328. package/dist/core/local-runtime-controller.d.ts.map +1 -1
  329. package/dist/core/local-runtime-controller.js.map +1 -1
  330. package/dist/core/memory-controller.d.ts.map +1 -1
  331. package/dist/core/memory-controller.js +4 -4
  332. package/dist/core/memory-controller.js.map +1 -1
  333. package/dist/core/model-capability.d.ts +0 -19
  334. package/dist/core/model-capability.d.ts.map +1 -1
  335. package/dist/core/model-capability.js +1 -19
  336. package/dist/core/model-capability.js.map +1 -1
  337. package/dist/core/model-registry.d.ts +6 -1
  338. package/dist/core/model-registry.d.ts.map +1 -1
  339. package/dist/core/model-registry.js +13 -5
  340. package/dist/core/model-registry.js.map +1 -1
  341. package/dist/core/model-resolver.d.ts +17 -2
  342. package/dist/core/model-resolver.d.ts.map +1 -1
  343. package/dist/core/model-resolver.js +38 -25
  344. package/dist/core/model-resolver.js.map +1 -1
  345. package/dist/core/model-router/intent-classifier.d.ts +1 -4
  346. package/dist/core/model-router/intent-classifier.d.ts.map +1 -1
  347. package/dist/core/model-router/intent-classifier.js +1 -156
  348. package/dist/core/model-router/intent-classifier.js.map +1 -1
  349. package/dist/core/model-router-controller.d.ts +1 -1
  350. package/dist/core/model-router-controller.d.ts.map +1 -1
  351. package/dist/core/model-router-controller.js +2 -2
  352. package/dist/core/model-router-controller.js.map +1 -1
  353. package/dist/core/model-selection-controller.d.ts +5 -5
  354. package/dist/core/model-selection-controller.d.ts.map +1 -1
  355. package/dist/core/model-selection-controller.js.map +1 -1
  356. package/dist/core/model-tool-protocol.d.ts +23 -0
  357. package/dist/core/model-tool-protocol.d.ts.map +1 -0
  358. package/dist/core/model-tool-protocol.js +43 -0
  359. package/dist/core/model-tool-protocol.js.map +1 -0
  360. package/dist/core/models/adaptation-store.d.ts +4 -6
  361. package/dist/core/models/adaptation-store.d.ts.map +1 -1
  362. package/dist/core/models/adaptation-store.js +95 -83
  363. package/dist/core/models/adaptation-store.js.map +1 -1
  364. package/dist/core/models/fitness-store.d.ts +2 -12
  365. package/dist/core/models/fitness-store.d.ts.map +1 -1
  366. package/dist/core/models/fitness-store.js +84 -57
  367. package/dist/core/models/fitness-store.js.map +1 -1
  368. package/dist/core/models/host-state-store.d.ts +34 -0
  369. package/dist/core/models/host-state-store.d.ts.map +1 -0
  370. package/dist/core/models/host-state-store.js +86 -0
  371. package/dist/core/models/host-state-store.js.map +1 -0
  372. package/dist/core/orchestration/agent-resume.d.ts +24 -0
  373. package/dist/core/orchestration/agent-resume.d.ts.map +1 -0
  374. package/dist/core/orchestration/agent-resume.js +90 -0
  375. package/dist/core/orchestration/agent-resume.js.map +1 -0
  376. package/dist/core/orchestration/capability-gateway.d.ts +61 -0
  377. package/dist/core/orchestration/capability-gateway.d.ts.map +1 -0
  378. package/dist/core/orchestration/capability-gateway.js +152 -0
  379. package/dist/core/orchestration/capability-gateway.js.map +1 -0
  380. package/dist/core/orchestration/contracts.d.ts +343 -0
  381. package/dist/core/orchestration/contracts.d.ts.map +1 -0
  382. package/dist/core/orchestration/contracts.js +135 -0
  383. package/dist/core/orchestration/contracts.js.map +1 -0
  384. package/dist/core/orchestration/delegation-ledger.d.ts +56 -0
  385. package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -0
  386. package/dist/core/orchestration/delegation-ledger.js +200 -0
  387. package/dist/core/orchestration/delegation-ledger.js.map +1 -0
  388. package/dist/core/orchestration/event-store.d.ts +83 -0
  389. package/dist/core/orchestration/event-store.d.ts.map +1 -0
  390. package/dist/core/orchestration/event-store.js +560 -0
  391. package/dist/core/orchestration/event-store.js.map +1 -0
  392. package/dist/core/orchestration/lane-tool-manifests.d.ts +9 -0
  393. package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -0
  394. package/dist/core/orchestration/lane-tool-manifests.js +37 -0
  395. package/dist/core/orchestration/lane-tool-manifests.js.map +1 -0
  396. package/dist/core/orchestration/model-binding.d.ts +15 -0
  397. package/dist/core/orchestration/model-binding.d.ts.map +1 -0
  398. package/dist/core/orchestration/model-binding.js +29 -0
  399. package/dist/core/orchestration/model-binding.js.map +1 -0
  400. package/dist/core/orchestration/policy-compiler.d.ts +49 -0
  401. package/dist/core/orchestration/policy-compiler.d.ts.map +1 -0
  402. package/dist/core/orchestration/policy-compiler.js +191 -0
  403. package/dist/core/orchestration/policy-compiler.js.map +1 -0
  404. package/dist/core/orchestration/policy-gate.d.ts +18 -0
  405. package/dist/core/orchestration/policy-gate.d.ts.map +1 -0
  406. package/dist/core/orchestration/policy-gate.js +24 -0
  407. package/dist/core/orchestration/policy-gate.js.map +1 -0
  408. package/dist/core/orchestration/profile-registry.d.ts +51 -0
  409. package/dist/core/orchestration/profile-registry.d.ts.map +1 -0
  410. package/dist/core/orchestration/profile-registry.js +393 -0
  411. package/dist/core/orchestration/profile-registry.js.map +1 -0
  412. package/dist/core/orchestration/profile-store.d.ts +31 -0
  413. package/dist/core/orchestration/profile-store.d.ts.map +1 -0
  414. package/dist/core/orchestration/profile-store.js +136 -0
  415. package/dist/core/orchestration/profile-store.js.map +1 -0
  416. package/dist/core/orchestration/risk-budget.d.ts +9 -0
  417. package/dist/core/orchestration/risk-budget.d.ts.map +1 -0
  418. package/dist/core/orchestration/risk-budget.js +48 -0
  419. package/dist/core/orchestration/risk-budget.js.map +1 -0
  420. package/dist/core/orchestration/task-runtime.d.ts +168 -0
  421. package/dist/core/orchestration/task-runtime.d.ts.map +1 -0
  422. package/dist/core/orchestration/task-runtime.js +1600 -0
  423. package/dist/core/orchestration/task-runtime.js.map +1 -0
  424. package/dist/core/orchestration/work-state-projection.d.ts +32 -0
  425. package/dist/core/orchestration/work-state-projection.d.ts.map +1 -0
  426. package/dist/core/orchestration/work-state-projection.js +116 -0
  427. package/dist/core/orchestration/work-state-projection.js.map +1 -0
  428. package/dist/core/orchestration/worker-execution-contract.d.ts +21 -0
  429. package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -0
  430. package/dist/core/orchestration/worker-execution-contract.js +179 -0
  431. package/dist/core/orchestration/worker-execution-contract.js.map +1 -0
  432. package/dist/core/orchestration/worker-result-adapter.d.ts +21 -0
  433. package/dist/core/orchestration/worker-result-adapter.d.ts.map +1 -0
  434. package/dist/core/orchestration/worker-result-adapter.js +109 -0
  435. package/dist/core/orchestration/worker-result-adapter.js.map +1 -0
  436. package/dist/core/package-manager.d.ts.map +1 -1
  437. package/dist/core/package-manager.js +20 -3
  438. package/dist/core/package-manager.js.map +1 -1
  439. package/dist/core/process-identity.d.ts +11 -0
  440. package/dist/core/process-identity.d.ts.map +1 -0
  441. package/dist/core/process-identity.js +26 -0
  442. package/dist/core/process-identity.js.map +1 -0
  443. package/dist/core/process-matrix/codes.d.ts +14 -3
  444. package/dist/core/process-matrix/codes.d.ts.map +1 -1
  445. package/dist/core/process-matrix/codes.js.map +1 -1
  446. package/dist/core/process-matrix/resume-launcher.d.ts +26 -0
  447. package/dist/core/process-matrix/resume-launcher.d.ts.map +1 -0
  448. package/dist/core/process-matrix/resume-launcher.js +62 -0
  449. package/dist/core/process-matrix/resume-launcher.js.map +1 -0
  450. package/dist/core/process-matrix/runtime.d.ts +37 -22
  451. package/dist/core/process-matrix/runtime.d.ts.map +1 -1
  452. package/dist/core/process-matrix/runtime.js +399 -76
  453. package/dist/core/process-matrix/runtime.js.map +1 -1
  454. package/dist/core/process-matrix/store.d.ts +5 -2
  455. package/dist/core/process-matrix/store.d.ts.map +1 -1
  456. package/dist/core/process-matrix/store.js +123 -14
  457. package/dist/core/process-matrix/store.js.map +1 -1
  458. package/dist/core/process-matrix/supervisor.d.ts +10 -7
  459. package/dist/core/process-matrix/supervisor.d.ts.map +1 -1
  460. package/dist/core/process-matrix/supervisor.js +45 -14
  461. package/dist/core/process-matrix/supervisor.js.map +1 -1
  462. package/dist/core/profile-filter-controller.d.ts +8 -1
  463. package/dist/core/profile-filter-controller.d.ts.map +1 -1
  464. package/dist/core/profile-filter-controller.js +23 -5
  465. package/dist/core/profile-filter-controller.js.map +1 -1
  466. package/dist/core/profile-registry.d.ts.map +1 -1
  467. package/dist/core/profile-registry.js +6 -8
  468. package/dist/core/profile-registry.js.map +1 -1
  469. package/dist/core/prompt-templates.d.ts +1 -0
  470. package/dist/core/prompt-templates.d.ts.map +1 -1
  471. package/dist/core/prompt-templates.js +18 -29
  472. package/dist/core/prompt-templates.js.map +1 -1
  473. package/dist/core/reflection-controller.d.ts +5 -5
  474. package/dist/core/reflection-controller.d.ts.map +1 -1
  475. package/dist/core/reflection-controller.js +5 -2
  476. package/dist/core/reflection-controller.js.map +1 -1
  477. package/dist/core/reload-blockers.d.ts.map +1 -1
  478. package/dist/core/reload-blockers.js +6 -8
  479. package/dist/core/reload-blockers.js.map +1 -1
  480. package/dist/core/request-auth.d.ts +7 -0
  481. package/dist/core/request-auth.d.ts.map +1 -0
  482. package/dist/core/request-auth.js +8 -0
  483. package/dist/core/request-auth.js.map +1 -0
  484. package/dist/core/research/evidence-bundle.d.ts.map +1 -1
  485. package/dist/core/research/evidence-bundle.js +1 -6
  486. package/dist/core/research/evidence-bundle.js.map +1 -1
  487. package/dist/core/research/lane-model-resolver.d.ts +33 -0
  488. package/dist/core/research/lane-model-resolver.d.ts.map +1 -0
  489. package/dist/core/research/lane-model-resolver.js +65 -0
  490. package/dist/core/research/lane-model-resolver.js.map +1 -0
  491. package/dist/core/research/model-fitness-controller.d.ts +38 -0
  492. package/dist/core/research/model-fitness-controller.d.ts.map +1 -0
  493. package/dist/core/research/model-fitness-controller.js +106 -0
  494. package/dist/core/research/model-fitness-controller.js.map +1 -0
  495. package/dist/core/research/model-fitness.d.ts +1 -1
  496. package/dist/core/research/model-fitness.d.ts.map +1 -1
  497. package/dist/core/research/model-fitness.js +4 -4
  498. package/dist/core/research/model-fitness.js.map +1 -1
  499. package/dist/core/research/research-gate.d.ts.map +1 -1
  500. package/dist/core/research/research-gate.js +7 -7
  501. package/dist/core/research/research-gate.js.map +1 -1
  502. package/dist/core/research/research-lane-controller.d.ts +62 -0
  503. package/dist/core/research/research-lane-controller.d.ts.map +1 -0
  504. package/dist/core/research/research-lane-controller.js +292 -0
  505. package/dist/core/research/research-lane-controller.js.map +1 -0
  506. package/dist/core/research/session-evidence-bundle.d.ts +2 -4
  507. package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
  508. package/dist/core/research/session-evidence-bundle.js +10 -46
  509. package/dist/core/research/session-evidence-bundle.js.map +1 -1
  510. package/dist/core/resource-loader.d.ts.map +1 -1
  511. package/dist/core/resource-loader.js +23 -8
  512. package/dist/core/resource-loader.js.map +1 -1
  513. package/dist/core/risk-classifier.d.ts +6 -0
  514. package/dist/core/risk-classifier.d.ts.map +1 -0
  515. package/dist/core/risk-classifier.js +233 -0
  516. package/dist/core/risk-classifier.js.map +1 -0
  517. package/dist/core/runtime-builder.d.ts +41 -23
  518. package/dist/core/runtime-builder.d.ts.map +1 -1
  519. package/dist/core/runtime-builder.js +365 -253
  520. package/dist/core/runtime-builder.js.map +1 -1
  521. package/dist/core/sdk.d.ts +6 -3
  522. package/dist/core/sdk.d.ts.map +1 -1
  523. package/dist/core/sdk.js +68 -25
  524. package/dist/core/sdk.js.map +1 -1
  525. package/dist/core/secrets/credential-exposure-guard.d.ts +9 -0
  526. package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -0
  527. package/dist/core/secrets/credential-exposure-guard.js +241 -0
  528. package/dist/core/secrets/credential-exposure-guard.js.map +1 -0
  529. package/dist/core/secrets/secret-dotenv.d.ts +27 -0
  530. package/dist/core/secrets/secret-dotenv.d.ts.map +1 -0
  531. package/dist/core/secrets/secret-dotenv.js +183 -0
  532. package/dist/core/secrets/secret-dotenv.js.map +1 -0
  533. package/dist/core/secrets/secret-vault-format.d.ts +112 -0
  534. package/dist/core/secrets/secret-vault-format.d.ts.map +1 -0
  535. package/dist/core/secrets/secret-vault-format.js +397 -0
  536. package/dist/core/secrets/secret-vault-format.js.map +1 -0
  537. package/dist/core/secrets/secret-vault.d.ts +72 -0
  538. package/dist/core/secrets/secret-vault.d.ts.map +1 -0
  539. package/dist/core/secrets/secret-vault.js +671 -0
  540. package/dist/core/secrets/secret-vault.js.map +1 -0
  541. package/dist/core/session-analytics.d.ts +4 -23
  542. package/dist/core/session-analytics.d.ts.map +1 -1
  543. package/dist/core/session-analytics.js +67 -70
  544. package/dist/core/session-analytics.js.map +1 -1
  545. package/dist/core/session-image-store.d.ts +33 -0
  546. package/dist/core/session-image-store.d.ts.map +1 -0
  547. package/dist/core/session-image-store.js +283 -0
  548. package/dist/core/session-image-store.js.map +1 -0
  549. package/dist/core/session-role.d.ts +11 -4
  550. package/dist/core/session-role.d.ts.map +1 -1
  551. package/dist/core/session-role.js +24 -5
  552. package/dist/core/session-role.js.map +1 -1
  553. package/dist/core/session-snapshot.d.ts +34 -0
  554. package/dist/core/session-snapshot.d.ts.map +1 -0
  555. package/dist/core/session-snapshot.js +68 -0
  556. package/dist/core/session-snapshot.js.map +1 -0
  557. package/dist/core/session-supervision-runtime.d.ts +31 -0
  558. package/dist/core/session-supervision-runtime.d.ts.map +1 -0
  559. package/dist/core/session-supervision-runtime.js +97 -0
  560. package/dist/core/session-supervision-runtime.js.map +1 -0
  561. package/dist/core/session-tree-navigator.d.ts +4 -6
  562. package/dist/core/session-tree-navigator.d.ts.map +1 -1
  563. package/dist/core/session-tree-navigator.js +4 -1
  564. package/dist/core/session-tree-navigator.js.map +1 -1
  565. package/dist/core/settings-manager.d.ts +10 -5
  566. package/dist/core/settings-manager.d.ts.map +1 -1
  567. package/dist/core/settings-manager.js +81 -29
  568. package/dist/core/settings-manager.js.map +1 -1
  569. package/dist/core/slash-commands.d.ts.map +1 -1
  570. package/dist/core/slash-commands.js +2 -2
  571. package/dist/core/slash-commands.js.map +1 -1
  572. package/dist/core/tasks/session-task-state.d.ts +2 -4
  573. package/dist/core/tasks/session-task-state.d.ts.map +1 -1
  574. package/dist/core/tasks/session-task-state.js +10 -28
  575. package/dist/core/tasks/session-task-state.js.map +1 -1
  576. package/dist/core/tasks/task-projection.d.ts +20 -0
  577. package/dist/core/tasks/task-projection.d.ts.map +1 -0
  578. package/dist/core/tasks/task-projection.js +47 -0
  579. package/dist/core/tasks/task-projection.js.map +1 -0
  580. package/dist/core/tasks/task-state.d.ts +4 -0
  581. package/dist/core/tasks/task-state.d.ts.map +1 -1
  582. package/dist/core/tasks/task-state.js +28 -11
  583. package/dist/core/tasks/task-state.js.map +1 -1
  584. package/dist/core/tool-capability-policy.d.ts +13 -0
  585. package/dist/core/tool-capability-policy.d.ts.map +1 -0
  586. package/dist/core/tool-capability-policy.js +86 -0
  587. package/dist/core/tool-capability-policy.js.map +1 -0
  588. package/dist/core/tool-gate-controller.d.ts.map +1 -1
  589. package/dist/core/tool-gate-controller.js +8 -2
  590. package/dist/core/tool-gate-controller.js.map +1 -1
  591. package/dist/core/tool-protocol-controller.d.ts +89 -0
  592. package/dist/core/tool-protocol-controller.d.ts.map +1 -0
  593. package/dist/core/tool-protocol-controller.js +512 -0
  594. package/dist/core/tool-protocol-controller.js.map +1 -0
  595. package/dist/core/tool-recovery-log-records.d.ts +2 -3
  596. package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
  597. package/dist/core/tool-recovery-log-records.js +9 -35
  598. package/dist/core/tool-recovery-log-records.js.map +1 -1
  599. package/dist/core/tool-recovery-stats.d.ts +21 -1
  600. package/dist/core/tool-recovery-stats.d.ts.map +1 -1
  601. package/dist/core/tool-recovery-stats.js.map +1 -1
  602. package/dist/core/tool-selection/tool-performance-store.d.ts +3 -7
  603. package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -1
  604. package/dist/core/tool-selection/tool-performance-store.js +97 -138
  605. package/dist/core/tool-selection/tool-performance-store.js.map +1 -1
  606. package/dist/core/tools/ask-question.d.ts +124 -0
  607. package/dist/core/tools/ask-question.d.ts.map +1 -0
  608. package/dist/core/tools/ask-question.js +693 -0
  609. package/dist/core/tools/ask-question.js.map +1 -0
  610. package/dist/core/tools/bash.d.ts +5 -0
  611. package/dist/core/tools/bash.d.ts.map +1 -1
  612. package/dist/core/tools/bash.js +59 -5
  613. package/dist/core/tools/bash.js.map +1 -1
  614. package/dist/core/tools/delegate-status.d.ts +31 -3
  615. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  616. package/dist/core/tools/delegate-status.js +148 -29
  617. package/dist/core/tools/delegate-status.js.map +1 -1
  618. package/dist/core/tools/delegate.d.ts +15 -13
  619. package/dist/core/tools/delegate.d.ts.map +1 -1
  620. package/dist/core/tools/delegate.js +106 -23
  621. package/dist/core/tools/delegate.js.map +1 -1
  622. package/dist/core/tools/extensionify.d.ts.map +1 -1
  623. package/dist/core/tools/extensionify.js +1 -0
  624. package/dist/core/tools/extensionify.js.map +1 -1
  625. package/dist/core/tools/git-filter.d.ts +1 -8
  626. package/dist/core/tools/git-filter.d.ts.map +1 -1
  627. package/dist/core/tools/git-filter.js +2 -63
  628. package/dist/core/tools/git-filter.js.map +1 -1
  629. package/dist/core/tools/goal.d.ts +10 -8
  630. package/dist/core/tools/goal.d.ts.map +1 -1
  631. package/dist/core/tools/goal.js +106 -28
  632. package/dist/core/tools/goal.js.map +1 -1
  633. package/dist/core/tools/index.d.ts +1 -0
  634. package/dist/core/tools/index.d.ts.map +1 -1
  635. package/dist/core/tools/index.js +1 -0
  636. package/dist/core/tools/index.js.map +1 -1
  637. package/dist/core/tools/model-fitness.d.ts.map +1 -1
  638. package/dist/core/tools/model-fitness.js +2 -2
  639. package/dist/core/tools/model-fitness.js.map +1 -1
  640. package/dist/core/tools/orchestration-panel.d.ts +40 -0
  641. package/dist/core/tools/orchestration-panel.d.ts.map +1 -0
  642. package/dist/core/tools/orchestration-panel.js +124 -0
  643. package/dist/core/tools/orchestration-panel.js.map +1 -0
  644. package/dist/core/tools/output-accumulator.d.ts +11 -0
  645. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  646. package/dist/core/tools/output-accumulator.js +36 -3
  647. package/dist/core/tools/output-accumulator.js.map +1 -1
  648. package/dist/core/tools/python.d.ts +2 -0
  649. package/dist/core/tools/python.d.ts.map +1 -1
  650. package/dist/core/tools/python.js +3 -1
  651. package/dist/core/tools/python.js.map +1 -1
  652. package/dist/core/tools/read.d.ts.map +1 -1
  653. package/dist/core/tools/read.js +1 -1
  654. package/dist/core/tools/read.js.map +1 -1
  655. package/dist/core/tools/run-process.d.ts +26 -0
  656. package/dist/core/tools/run-process.d.ts.map +1 -0
  657. package/dist/core/tools/run-process.js +138 -0
  658. package/dist/core/tools/run-process.js.map +1 -0
  659. package/dist/core/tools/search-command-guard.d.ts +14 -0
  660. package/dist/core/tools/search-command-guard.d.ts.map +1 -0
  661. package/dist/core/tools/search-command-guard.js +333 -0
  662. package/dist/core/tools/search-command-guard.js.map +1 -0
  663. package/dist/core/tools/secret-store.d.ts +38 -0
  664. package/dist/core/tools/secret-store.d.ts.map +1 -0
  665. package/dist/core/tools/secret-store.js +412 -0
  666. package/dist/core/tools/secret-store.js.map +1 -0
  667. package/dist/core/tools/shell-command-parser.d.ts +16 -0
  668. package/dist/core/tools/shell-command-parser.d.ts.map +1 -0
  669. package/dist/core/tools/shell-command-parser.js +113 -0
  670. package/dist/core/tools/shell-command-parser.js.map +1 -0
  671. package/dist/core/tools/task-steps.d.ts +2 -0
  672. package/dist/core/tools/task-steps.d.ts.map +1 -1
  673. package/dist/core/tools/task-steps.js +99 -0
  674. package/dist/core/tools/task-steps.js.map +1 -1
  675. package/dist/core/tools/tmux-dispatch.d.ts +3 -5
  676. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
  677. package/dist/core/tools/tmux-dispatch.js +4 -4
  678. package/dist/core/tools/tmux-dispatch.js.map +1 -1
  679. package/dist/core/tools/windows-shell-engine.d.ts.map +1 -1
  680. package/dist/core/tools/windows-shell-engine.js +4 -6
  681. package/dist/core/tools/windows-shell-engine.js.map +1 -1
  682. package/dist/core/util/atomic-file.d.ts +6 -2
  683. package/dist/core/util/atomic-file.d.ts.map +1 -1
  684. package/dist/core/util/atomic-file.js +4 -4
  685. package/dist/core/util/atomic-file.js.map +1 -1
  686. package/dist/core/util/bounded-jsonl.d.ts +10 -0
  687. package/dist/core/util/bounded-jsonl.d.ts.map +1 -0
  688. package/dist/core/util/bounded-jsonl.js +75 -0
  689. package/dist/core/util/bounded-jsonl.js.map +1 -0
  690. package/dist/core/util/value-guards.d.ts +5 -0
  691. package/dist/core/util/value-guards.d.ts.map +1 -0
  692. package/dist/core/util/value-guards.js +12 -0
  693. package/dist/core/util/value-guards.js.map +1 -0
  694. package/dist/core/worktree-sync/store.d.ts +3 -3
  695. package/dist/core/worktree-sync/store.d.ts.map +1 -1
  696. package/dist/core/worktree-sync/store.js +10 -5
  697. package/dist/core/worktree-sync/store.js.map +1 -1
  698. package/dist/index.d.ts +15 -4
  699. package/dist/index.d.ts.map +1 -1
  700. package/dist/index.js +14 -3
  701. package/dist/index.js.map +1 -1
  702. package/dist/main.d.ts.map +1 -1
  703. package/dist/main.js +149 -51
  704. package/dist/main.js.map +1 -1
  705. package/dist/migrations.d.ts +4 -6
  706. package/dist/migrations.d.ts.map +1 -1
  707. package/dist/migrations.js +186 -28
  708. package/dist/migrations.js.map +1 -1
  709. package/dist/modes/interactive/auth-dialogs-controller.d.ts +4 -0
  710. package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -1
  711. package/dist/modes/interactive/auth-dialogs-controller.js +60 -1
  712. package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -1
  713. package/dist/modes/interactive/clipboard-input.d.ts +7 -1
  714. package/dist/modes/interactive/clipboard-input.d.ts.map +1 -1
  715. package/dist/modes/interactive/clipboard-input.js +44 -6
  716. package/dist/modes/interactive/clipboard-input.js.map +1 -1
  717. package/dist/modes/interactive/components/activity-lane.d.ts +55 -0
  718. package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -0
  719. package/dist/modes/interactive/components/activity-lane.js +304 -0
  720. package/dist/modes/interactive/components/activity-lane.js.map +1 -0
  721. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  722. package/dist/modes/interactive/components/assistant-message.js +19 -10
  723. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  724. package/dist/modes/interactive/components/expandable-text.d.ts +12 -0
  725. package/dist/modes/interactive/components/expandable-text.d.ts.map +1 -0
  726. package/dist/modes/interactive/components/expandable-text.js +17 -0
  727. package/dist/modes/interactive/components/expandable-text.js.map +1 -0
  728. package/dist/modes/interactive/components/extension-editor.d.ts +15 -1
  729. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  730. package/dist/modes/interactive/components/extension-editor.js +30 -21
  731. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  732. package/dist/modes/interactive/components/extension-input.d.ts +1 -0
  733. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  734. package/dist/modes/interactive/components/extension-input.js +6 -1
  735. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  736. package/dist/modes/interactive/components/scoped-models-selector.d.ts +2 -2
  737. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  738. package/dist/modes/interactive/components/scoped-models-selector.js +23 -14
  739. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  740. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  741. package/dist/modes/interactive/components/settings-selector.js +6 -6
  742. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  743. package/dist/modes/interactive/components/tool-execution.d.ts +19 -11
  744. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  745. package/dist/modes/interactive/components/tool-execution.js +53 -20
  746. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  747. package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
  748. package/dist/modes/interactive/components/tool-group.js +3 -0
  749. package/dist/modes/interactive/components/tool-group.js.map +1 -1
  750. package/dist/modes/interactive/components/usage-action-selector.d.ts +16 -0
  751. package/dist/modes/interactive/components/usage-action-selector.d.ts.map +1 -0
  752. package/dist/modes/interactive/components/usage-action-selector.js +46 -0
  753. package/dist/modes/interactive/components/usage-action-selector.js.map +1 -0
  754. package/dist/modes/interactive/config-backup.d.ts.map +1 -1
  755. package/dist/modes/interactive/config-backup.js +5 -4
  756. package/dist/modes/interactive/config-backup.js.map +1 -1
  757. package/dist/modes/interactive/extension-ui-host.d.ts +14 -0
  758. package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -1
  759. package/dist/modes/interactive/extension-ui-host.js +77 -15
  760. package/dist/modes/interactive/extension-ui-host.js.map +1 -1
  761. package/dist/modes/interactive/external-editor.d.ts +15 -0
  762. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  763. package/dist/modes/interactive/external-editor.js +27 -19
  764. package/dist/modes/interactive/external-editor.js.map +1 -1
  765. package/dist/modes/interactive/history-reload-math.d.ts +6 -2
  766. package/dist/modes/interactive/history-reload-math.d.ts.map +1 -1
  767. package/dist/modes/interactive/history-reload-math.js +10 -5
  768. package/dist/modes/interactive/history-reload-math.js.map +1 -1
  769. package/dist/modes/interactive/interactive-event-controller.d.ts +74 -0
  770. package/dist/modes/interactive/interactive-event-controller.d.ts.map +1 -0
  771. package/dist/modes/interactive/interactive-event-controller.js +328 -0
  772. package/dist/modes/interactive/interactive-event-controller.js.map +1 -0
  773. package/dist/modes/interactive/interactive-mode.d.ts +22 -24
  774. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  775. package/dist/modes/interactive/interactive-mode.js +245 -595
  776. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  777. package/dist/modes/interactive/key-handlers.d.ts.map +1 -1
  778. package/dist/modes/interactive/key-handlers.js +1 -1
  779. package/dist/modes/interactive/key-handlers.js.map +1 -1
  780. package/dist/modes/interactive/loaded-resources-view.d.ts +20 -0
  781. package/dist/modes/interactive/loaded-resources-view.d.ts.map +1 -0
  782. package/dist/modes/interactive/loaded-resources-view.js +147 -0
  783. package/dist/modes/interactive/loaded-resources-view.js.map +1 -0
  784. package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
  785. package/dist/modes/interactive/profile-menu-controller.js +7 -7
  786. package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
  787. package/dist/modes/interactive/report-commands.d.ts.map +1 -1
  788. package/dist/modes/interactive/report-commands.js +21 -0
  789. package/dist/modes/interactive/report-commands.js.map +1 -1
  790. package/dist/modes/interactive/resource-display.d.ts.map +1 -1
  791. package/dist/modes/interactive/resource-display.js +8 -2
  792. package/dist/modes/interactive/resource-display.js.map +1 -1
  793. package/dist/modes/interactive/resource-shell-commands.d.ts +1 -5
  794. package/dist/modes/interactive/resource-shell-commands.d.ts.map +1 -1
  795. package/dist/modes/interactive/resource-shell-commands.js +0 -5
  796. package/dist/modes/interactive/resource-shell-commands.js.map +1 -1
  797. package/dist/modes/interactive/session-flow-commands.d.ts +27 -8
  798. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
  799. package/dist/modes/interactive/session-flow-commands.js +150 -64
  800. package/dist/modes/interactive/session-flow-commands.js.map +1 -1
  801. package/dist/modes/interactive/session-io-commands.d.ts.map +1 -1
  802. package/dist/modes/interactive/session-io-commands.js +16 -6
  803. package/dist/modes/interactive/session-io-commands.js.map +1 -1
  804. package/dist/modes/interactive/session-replacement-errors.d.ts +7 -0
  805. package/dist/modes/interactive/session-replacement-errors.d.ts.map +1 -0
  806. package/dist/modes/interactive/session-replacement-errors.js +15 -0
  807. package/dist/modes/interactive/session-replacement-errors.js.map +1 -0
  808. package/dist/modes/interactive/startup-checks.d.ts.map +1 -1
  809. package/dist/modes/interactive/startup-checks.js +1 -1
  810. package/dist/modes/interactive/startup-checks.js.map +1 -1
  811. package/dist/modes/interactive/usage-commands.d.ts +34 -0
  812. package/dist/modes/interactive/usage-commands.d.ts.map +1 -0
  813. package/dist/modes/interactive/usage-commands.js +225 -0
  814. package/dist/modes/interactive/usage-commands.js.map +1 -0
  815. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  816. package/dist/modes/rpc/rpc-mode.js +82 -23
  817. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  818. package/dist/modes/rpc/rpc-types.d.ts +15 -0
  819. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  820. package/dist/modes/rpc/rpc-types.js +138 -1
  821. package/dist/modes/rpc/rpc-types.js.map +1 -1
  822. package/dist/utils/clipboard-image.d.ts.map +1 -1
  823. package/dist/utils/clipboard-image.js +2 -13
  824. package/dist/utils/clipboard-image.js.map +1 -1
  825. package/dist/utils/clipboard-native.d.ts +1 -0
  826. package/dist/utils/clipboard-native.d.ts.map +1 -1
  827. package/dist/utils/clipboard-native.js.map +1 -1
  828. package/dist/utils/clipboard.d.ts +1 -0
  829. package/dist/utils/clipboard.d.ts.map +1 -1
  830. package/dist/utils/clipboard.js +52 -1
  831. package/dist/utils/clipboard.js.map +1 -1
  832. package/dist/utils/platform.d.ts +3 -0
  833. package/dist/utils/platform.d.ts.map +1 -0
  834. package/dist/utils/platform.js +8 -0
  835. package/dist/utils/platform.js.map +1 -0
  836. package/dist/utils/shell.d.ts.map +1 -1
  837. package/dist/utils/shell.js +5 -3
  838. package/dist/utils/shell.js.map +1 -1
  839. package/dist/utils/version-check.d.ts.map +1 -1
  840. package/dist/utils/version-check.js +3 -1
  841. package/dist/utils/version-check.js.map +1 -1
  842. package/dist/utils/work-directory.d.ts +11 -0
  843. package/dist/utils/work-directory.d.ts.map +1 -1
  844. package/dist/utils/work-directory.js +30 -9
  845. package/dist/utils/work-directory.js.map +1 -1
  846. package/docs/UI_POLISH_ORCHESTRATION.md +38 -0
  847. package/docs/UI_QUALITY_ORCHESTRATION.md +28 -0
  848. package/docs/docs.json +4 -0
  849. package/docs/extensions.md +62 -2
  850. package/docs/harness-architecture.md +156 -0
  851. package/docs/keybindings.md +11 -1
  852. package/docs/process-matrix.md +59 -26
  853. package/docs/providers.md +9 -1
  854. package/docs/rpc.md +45 -2
  855. package/docs/sessions.md +15 -0
  856. package/docs/settings.md +125 -11
  857. package/docs/task-steps.md +8 -0
  858. package/docs/telemetry.md +19 -0
  859. package/docs/tmux-agent-manager.md +10 -3
  860. package/docs/ui-reference/README.md +9 -0
  861. package/docs/ui-reference/orchestration-after.txt +14 -0
  862. package/docs/ui-reference/orchestration-before.txt +13 -0
  863. package/docs/ui-reference/orchestration-reference.txt +16 -0
  864. package/docs/usage.md +22 -2
  865. package/docs/work-directory.md +19 -8
  866. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  867. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  868. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  869. package/examples/extensions/question.ts +34 -245
  870. package/examples/extensions/questionnaire.ts +41 -407
  871. package/examples/extensions/sandbox/package-lock.json +2 -2
  872. package/examples/extensions/sandbox/package.json +1 -1
  873. package/examples/extensions/with-deps/package-lock.json +2 -2
  874. package/examples/extensions/with-deps/package.json +1 -1
  875. package/npm-shrinkwrap.json +13 -13
  876. package/package.json +4 -4
  877. package/dist/core/delegation/session-worker-result.d.ts +0 -46
  878. package/dist/core/delegation/session-worker-result.d.ts.map +0 -1
  879. package/dist/core/delegation/session-worker-result.js +0 -113
  880. package/dist/core/delegation/session-worker-result.js.map +0 -1
  881. package/dist/core/delegation/worker-result.d.ts.map +0 -1
  882. package/dist/core/delegation/worker-result.js.map +0 -1
  883. package/dist/core/telemetry.d.ts.map +0 -1
  884. package/dist/core/telemetry.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/core/process-matrix/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Process-matrix runtime composition: the pieces main.ts wires together for durable,\n * restart-surviving master/worker process supervision.\n *\n * Contract:\n * - A WORKER is any process launched with a known parent (`PI_PARENT_PID` -- set by the\n * `--parent-pid` CLI flag, or directly by a launcher such as tmux dispatch). It self-registers\n * its OWN entry (the single writer of that entry during normal operation) and watches its\n * parent's liveness. On parent death it winds down GRACEFULLY -- never silently -- leaving a\n * `resumable` payload, then exits on its own after a bounded grace window (during which it may\n * instead be adopted by a new parent). \"No new turns\" after that point is automatic: a dead\n * parent injects no further follow-ups, so the worker simply runs out of work to do.\n * - A MASTER is everything else (no known parent). On startup it scans the matrix for orphaned\n * workers (workers whose recorded parent is dead) and, when interactive, ASKS the owner before\n * touching anything -- adopt, cooperative cleanup, or leave untouched. Non-interactive: report\n * only, zero writes, zero kills.\n *\n * One sanctioned exception to \"a worker's entry is written only by that worker\": the master\n * orphan-scan writes an adoption or a cooperative-cleanup request directly into an ORPHANED\n * worker's own entry, but ONLY after explicit owner confirmation (`promptConfirm`) -- mirroring\n * the worktree-sync integration lock's dead-owner takeover (a new owner may claim a PROVABLY DEAD\n * owner's resource). The worker itself later confirms/applies that grant locally via\n * `pollWorkerDirective` and re-writes its own entry -- see `docs/process-matrix.md`. Outside this\n * one ask-gated handshake, a master NEVER writes another session's entry, and nothing here ever\n * kills a process directly: every termination is either owner-confirmed or the worker's own\n * cooperative self-exit.\n */\n\nimport { hostname as osHostname } from \"node:os\";\nimport type { ResolvedProcessMatrixSettings } from \"../settings-manager.ts\";\nimport { getBoundWorktreeLaneKey } from \"../worktree-sync/runtime.ts\";\nimport type { ProcessMatrixEntry, ResumablePayload } from \"./codes.ts\";\nimport { buildEntryId, listEntries, readEntry, writeEntry, writeEntrySync } from \"./store.ts\";\nimport {\n\tapplyAdoption,\n\tapplyHeartbeat,\n\tbeginWindDown,\n\tbuildMasterEntry,\n\tbuildWorkerEntry,\n\tdetectOrphanedWorkers,\n\tmarkClosed,\n\tmarkResumable,\n\tpollWorkerDirective,\n} from \"./supervisor.ts\";\n\nexport const PI_PARENT_PID_ENV = \"PI_PARENT_PID\";\nexport const PI_PARENT_SESSION_ENV = \"PI_PARENT_SESSION\";\n\n/** This process's declared parent pid, from the cross-process env contract. A malformed or\n * non-positive value is ignored (never a crash on bad env). */\nexport function getParentPid(env: NodeJS.ProcessEnv = process.env): number | undefined {\n\tconst raw = env[PI_PARENT_PID_ENV];\n\tif (raw === undefined) return undefined;\n\tconst value = Number.parseInt(raw, 10);\n\treturn Number.isFinite(value) && value > 0 ? value : undefined;\n}\n\n/** This process's declared parent sessionId, from the cross-process env contract. */\nexport function getParentSessionId(env: NodeJS.ProcessEnv = process.env): string | undefined {\n\tconst value = env[PI_PARENT_SESSION_ENV]?.trim();\n\treturn value && value.length > 0 ? value : undefined;\n}\n\nexport interface ProcessMatrixRuntimeConfig {\n\tagentDir: string;\n\tsessionId: string;\n\t/** Whether an interactive UI is available to ask the owner (see `promptConfirm`). */\n\thasUI: boolean;\n\tsettings: ResolvedProcessMatrixSettings;\n\tisProcessAlive: (pid: number) => boolean;\n\tnow?: () => number;\n\t/** Structural notice injection into the running session (host `sendCustomMessage` seam). */\n\tnotify: (text: string) => void;\n\t/** Diagnostics sink (never throws into the session). */\n\tonDiagnostic?: (message: string) => void;\n\t/** The ask seam: resolves false on decline AND on any non-interactive/non-TTY caller. */\n\tpromptConfirm: (message: string) => Promise<boolean>;\n\t/** Cooperative self-exit -- called by a worker once wound down (grace expiry or a\n\t * master-granted cleanup directive). Never called for the master's own lifecycle. */\n\trequestExit: () => void;\n}\n\nexport interface ProcessMatrixRuntimeHandle {\n\tstop(): void;\n}\n\nconst NOOP_HANDLE: ProcessMatrixRuntimeHandle = { stop: () => {} };\n\nfunction describeError(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction nowIso(now: () => number): string {\n\treturn new Date(now()).toISOString();\n}\n\n/**\n * Start the per-session process-matrix runtime. No-op when disabled (byte-identical to not\n * calling this at all). Never throws: a broken store must surface as a diagnostic, not a startup\n * crash.\n */\nexport async function startProcessMatrixRuntime(\n\tconfig: ProcessMatrixRuntimeConfig,\n): Promise<ProcessMatrixRuntimeHandle> {\n\tif (!config.settings.enabled) return NOOP_HANDLE;\n\tconst now = config.now ?? Date.now;\n\tconst parentPid = getParentPid();\n\n\ttry {\n\t\tif (parentPid !== undefined) {\n\t\t\treturn await startWorkerBranch(config, parentPid, now);\n\t\t}\n\t\treturn await startMasterBranch(config, now);\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(`process-matrix: runtime failed to start: ${describeError(error)}`);\n\t\treturn NOOP_HANDLE;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Master branch\n// ---------------------------------------------------------------------------\n\nasync function startMasterBranch(\n\tconfig: ProcessMatrixRuntimeConfig,\n\tnow: () => number,\n): Promise<ProcessMatrixRuntimeHandle> {\n\tlet entry = buildMasterEntry({\n\t\tsessionId: config.sessionId,\n\t\tpid: process.pid,\n\t\thostname: osHostname(),\n\t\tnow: nowIso(now),\n\t});\n\ttry {\n\t\tawait writeEntry(config.agentDir, entry);\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(`process-matrix: failed to register master entry: ${describeError(error)}`);\n\t}\n\n\tlet stopped = false;\n\tconst heartbeatTimer = setInterval(() => {\n\t\tif (stopped) return;\n\t\tentry = applyHeartbeat(entry, nowIso(now));\n\t\tvoid writeEntry(config.agentDir, entry).catch((error) => {\n\t\t\tconfig.onDiagnostic?.(`process-matrix: failed to write master heartbeat: ${describeError(error)}`);\n\t\t});\n\t}, config.settings.heartbeatMs);\n\theartbeatTimer.unref?.();\n\n\t// Best-effort close on process exit. A SIGKILLed master leaving \"running\" is fine -- reconcile's\n\t// own dead-pid detection covers it; this only makes the common clean-exit case tidy.\n\tprocess.on(\"exit\", () => {\n\t\ttry {\n\t\t\twriteEntrySync(config.agentDir, markClosed(entry, nowIso(now)));\n\t\t} catch {\n\t\t\t// Best-effort only -- see module doc.\n\t\t}\n\t});\n\n\tvoid runOrphanScan(config, now);\n\n\treturn {\n\t\tstop() {\n\t\t\tstopped = true;\n\t\t\tclearInterval(heartbeatTimer);\n\t\t},\n\t};\n}\n\nasync function runOrphanScan(config: ProcessMatrixRuntimeConfig, now: () => number): Promise<void> {\n\tlet entries: ProcessMatrixEntry[];\n\ttry {\n\t\tentries = await listEntries(config.agentDir);\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(`process-matrix: orphan scan failed to list entries: ${describeError(error)}`);\n\t\treturn;\n\t}\n\tconst orphans = detectOrphanedWorkers(entries, {\n\t\tisPidAlive: config.isProcessAlive,\n\t\townSessionId: config.sessionId,\n\t});\n\tif (orphans.length === 0) return;\n\n\tif (!config.hasUI) {\n\t\tconfig.onDiagnostic?.(\n\t\t\t`process-matrix: found ${orphans.length} orphaned worker(s) with no reachable parent (report-only, non-interactive; nothing written, nothing killed): ${orphans\n\t\t\t\t.map((orphan) => orphan.entryId)\n\t\t\t\t.join(\", \")}`,\n\t\t);\n\t\treturn;\n\t}\n\n\tfor (const orphan of orphans) {\n\t\tconst adopt = await config.promptConfirm(`adopt worker ${orphan.entryId} (lane ${orphan.laneKey ?? \"none\"})?`);\n\t\tif (adopt) {\n\t\t\tconst adopted = applyAdoption(orphan, { parentPid: process.pid, parentSessionId: config.sessionId });\n\t\t\ttry {\n\t\t\t\tawait writeEntry(config.agentDir, adopted);\n\t\t\t} catch (error) {\n\t\t\t\tconfig.onDiagnostic?.(\n\t\t\t\t\t`process-matrix: failed to write adoption for ${orphan.entryId}: ${describeError(error)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tconst cleanup = await config.promptConfirm(`clean up worker ${orphan.entryId} gracefully?`);\n\t\tif (!cleanup) continue;\n\t\tconst windingDown = beginWindDown(orphan, \"user_cleanup\", nowIso(now));\n\t\ttry {\n\t\t\tawait writeEntry(config.agentDir, windingDown);\n\t\t} catch (error) {\n\t\t\tconfig.onDiagnostic?.(\n\t\t\t\t`process-matrix: failed to write cleanup for ${orphan.entryId}: ${describeError(error)}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Worker branch\n// ---------------------------------------------------------------------------\n\nasync function startWorkerBranch(\n\tconfig: ProcessMatrixRuntimeConfig,\n\tinitialParentPid: number,\n\tnow: () => number,\n): Promise<ProcessMatrixRuntimeHandle> {\n\tconst parentSessionId = getParentSessionId();\n\tconst laneKey = getBoundWorktreeLaneKey();\n\n\tlet entry = buildWorkerEntry({\n\t\tsessionId: config.sessionId,\n\t\tpid: process.pid,\n\t\thostname: osHostname(),\n\t\tnow: nowIso(now),\n\t\tparentPid: initialParentPid,\n\t\t...(parentSessionId !== undefined ? { parentSessionId } : {}),\n\t\t...(laneKey !== undefined ? { laneKey } : {}),\n\t});\n\ttry {\n\t\tawait writeEntry(config.agentDir, entry);\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(`process-matrix: failed to register worker entry: ${describeError(error)}`);\n\t}\n\n\tlet currentParentPid = initialParentPid;\n\tlet currentParentSessionId = parentSessionId;\n\tlet stopped = false;\n\tlet timer: NodeJS.Timeout | undefined;\n\tlet ticking = false;\n\n\tconst stop = (): void => {\n\t\tstopped = true;\n\t\tif (timer) clearInterval(timer);\n\t\ttimer = undefined;\n\t};\n\n\tconst persist = async (next: ProcessMatrixEntry, failureContext: string): Promise<void> => {\n\t\tentry = next;\n\t\ttry {\n\t\t\tawait writeEntry(config.agentDir, entry);\n\t\t} catch (error) {\n\t\t\tconfig.onDiagnostic?.(`process-matrix: ${failureContext}: ${describeError(error)}`);\n\t\t}\n\t};\n\n\tconst startHealthyWatch = (): void => {\n\t\ttimer = setInterval(() => {\n\t\t\tif (ticking) return;\n\t\t\tticking = true;\n\t\t\tvoid healthyTick().finally(() => {\n\t\t\t\tticking = false;\n\t\t\t});\n\t\t}, config.settings.watcherPollMs);\n\t\ttimer.unref?.();\n\t};\n\n\tconst declaredParentIsAlive = async (): Promise<boolean> => {\n\t\t// PID liveness alone is not process identity: a reused PID could otherwise keep a worker\n\t\t// attached to an unrelated process forever. The parent session's own fresh master entry binds\n\t\t// PID to a durable identity and proves that that exact session is still heartbeating.\n\t\tif (!currentParentSessionId || !config.isProcessAlive(currentParentPid)) return false;\n\t\tconst parent = await readEntry(config.agentDir, buildEntryId(\"master\", currentParentSessionId));\n\t\tif (!parent || parent.role !== \"master\" || parent.sessionId !== currentParentSessionId) return false;\n\t\tif (parent.pid !== currentParentPid || parent.status !== \"running\") return false;\n\t\tconst heartbeatAt = Date.parse(parent.heartbeatAt);\n\t\tconst maxAge = config.settings.heartbeatMs * 2 + config.settings.watcherPollMs;\n\t\treturn Number.isFinite(heartbeatAt) && now() - heartbeatAt <= maxAge;\n\t};\n\n\tconst healthyTick = async (): Promise<void> => {\n\t\tif (stopped) return;\n\t\tif (!(await declaredParentIsAlive())) {\n\t\t\tawait enterWindDown();\n\t\t\treturn;\n\t\t}\n\t\t// Still healthy: also poll for a master-initiated cooperative-cleanup directive.\n\t\tconst fresh = await readEntry(config.agentDir, entry.entryId);\n\t\tif (!fresh) return;\n\t\tconst directive = pollWorkerDirective(fresh, currentParentPid, { isPidAlive: config.isProcessAlive });\n\t\tif (directive.code !== \"user_cleanup\") return;\n\t\tawait persist(\n\t\t\tbeginWindDown(fresh, \"user_cleanup\", nowIso(now)),\n\t\t\t\"failed to write a master-requested worker wind-down\",\n\t\t);\n\t\tconfig.notify(\"process-matrix: the parent session requested a cooperative cleanup. Winding down.\");\n\t\tstop();\n\t\tconfig.requestExit();\n\t};\n\n\tconst enterWindDown = async (): Promise<void> => {\n\t\tif (timer) {\n\t\t\tclearInterval(timer);\n\t\t\ttimer = undefined;\n\t\t}\n\t\tconst windDownAt = nowIso(now);\n\t\tconst resumable: ResumablePayload = { lastCode: \"resumable\" };\n\t\tif (laneKey !== undefined) resumable.laneKey = laneKey;\n\t\tawait persist(\n\t\t\tmarkResumable(beginWindDown(entry, \"parent_lost\", windDownAt), resumable, windDownAt),\n\t\t\t\"failed to write worker wind-down\",\n\t\t);\n\t\tconfig.notify(\n\t\t\t`process-matrix: parent process (pid ${currentParentPid}) is gone. Winding down gracefully; this task is resumable.`,\n\t\t);\n\t\tstartGraceWatch();\n\t};\n\n\tconst startGraceWatch = (): void => {\n\t\tconst graceDeadline = now() + config.settings.adoptionGraceMs;\n\t\ttimer = setInterval(() => {\n\t\t\tif (ticking) return;\n\t\t\tticking = true;\n\t\t\tvoid graceTick(graceDeadline).finally(() => {\n\t\t\t\tticking = false;\n\t\t\t});\n\t\t}, config.settings.watcherPollMs);\n\t\ttimer.unref?.();\n\t};\n\n\tconst graceTick = async (graceDeadline: number): Promise<void> => {\n\t\tif (stopped) return;\n\t\tconst fresh = await readEntry(config.agentDir, entry.entryId);\n\t\tif (fresh) {\n\t\t\tconst directive = pollWorkerDirective(fresh, currentParentPid, { isPidAlive: config.isProcessAlive });\n\t\t\tif (directive.code === \"adopt\" && fresh.parentSessionId) {\n\t\t\t\t// The adopting master persists its session id with the pid. Require both on the next\n\t\t\t\t// healthy tick; accepting a pid-only adoption would reintroduce the PID-reuse bug.\n\t\t\t\tawait persist(\n\t\t\t\t\tapplyAdoption(fresh, { parentPid: directive.parentPid, parentSessionId: fresh.parentSessionId }),\n\t\t\t\t\t\"failed to write worker adoption\",\n\t\t\t\t);\n\t\t\t\tconfig.notify(`process-matrix: adopted by a new parent (pid ${directive.parentPid}). Resuming.`);\n\t\t\t\tcurrentParentPid = directive.parentPid;\n\t\t\t\tcurrentParentSessionId = fresh.parentSessionId;\n\t\t\t\tif (timer) {\n\t\t\t\t\tclearInterval(timer);\n\t\t\t\t\ttimer = undefined;\n\t\t\t\t}\n\t\t\t\tstartHealthyWatch();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (directive.code === \"user_cleanup\") {\n\t\t\t\tstop();\n\t\t\t\tconfig.requestExit();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif (now() >= graceDeadline) {\n\t\t\tstop();\n\t\t\tconfig.requestExit();\n\t\t}\n\t};\n\n\tstartHealthyWatch();\n\n\treturn { stop };\n}\n"]}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/core/process-matrix/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,EACN,YAAY,EACZ,WAAW,EACX,SAAS,EACT,sBAAsB,EACtB,UAAU,EACV,qBAAqB,EACrB,yBAAyB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,UAAU,EACV,aAAa,EACb,YAAY,EACZ,iCAAiC,EACjC,mBAAmB,EACnB,eAAe,GACf,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACN,uBAAuB,EACvB,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,GACf,MAAM,wBAAwB,CAAC;AA2ChC,MAAM,WAAW,GAA+B,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAC,CAAC,EAAE,CAAC;AACnE,MAAM,CAAC,MAAM,qCAAqC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;AAE3E,SAAS,aAAa,CAAC,KAAc,EAAU;IAC9C,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAAA,CAC9D;AAED,SAAS,MAAM,CAAC,GAAiB,EAAU;IAC1C,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AAAA,CACrC;AAED,SAAS,iBAAiB,CAAC,MAAkC,EAAE,IAAY,EAAQ;IAClF,IAAI,CAAC;QACJ,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC;YACnE,MAAM,CAAC,YAAY,EAAE,CAAC,6CAA6C,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAAA,CAC3F,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,YAAY,EAAE,CAAC,6CAA6C,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;AAAA,CACD;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC9C,MAAkC,EACI;IACtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC;IACjD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACnC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IAEjC,IAAI,CAAC;QACJ,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAC;QACrG,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,MAAM,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,MAAM,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,YAAY,EAAE,CAAC,4CAA4C,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1F,OAAO,WAAW,CAAC;IACpB,CAAC;AAAA,CACD;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E,KAAK,UAAU,iBAAiB,CAC/B,MAAkC,EAClC,GAAiB,EACqB;IACtC,IAAI,KAAK,GAAG,gBAAgB,CAAC;QAC5B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,QAAQ,EAAE,UAAU,EAAE;QACtB,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC;KAChB,CAAC,CAAC;IACH,IAAI,CAAC;QACJ,MAAM,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,YAAY,EAAE,CAAC,oDAAoD,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnG,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,IAAI,aAAwC,CAAC;IAC7C,MAAM,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;IACvC,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACxC,IAAI,OAAO,IAAI,CAAC,SAAS,IAAI,aAAa;YAAE,OAAO;QACnD,MAAM,QAAQ,GAAG,KAAK,CAAC;QACvB,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACnD,aAAa,GAAG,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC;aACtF,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YAClB,IAAI,OAAO,EAAE,CAAC;gBACb,KAAK,GAAG,IAAI,CAAC;gBACb,OAAO;YACR,CAAC;YACD,SAAS,GAAG,KAAK,CAAC;YAClB,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjB,aAAa,CAAC,cAAc,CAAC,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YACjC,MAAM,CAAC,YAAY,EAAE,CAAC,4EAA4E,CAAC,CAAC;QAAA,CACpG,CAAC;aACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC;YAC1B,MAAM,CAAC,YAAY,EAAE,CAAC,qDAAqD,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAAA,CACnG,CAAC;aACD,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,aAAa,GAAG,SAAS,CAAC;QAAA,CAC1B,CAAC,CAAC;IAAA,CACJ,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAChC,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC;IAEzB,iGAAiG;IACjG,qFAAqF;IACrF,MAAM,WAAW,GAAG,GAAS,EAAE,CAAC;QAC/B,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9C,IAAI,yBAAyB,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC;gBAAE,KAAK,GAAG,MAAM,CAAC;QAC/E,CAAC;QAAC,MAAM,CAAC;YACR,sCAAsC;QACvC,CAAC;IAAA,CACD,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAElC,MAAM,WAAW,GAAG,yBAAyB,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC;QACrG,MAAM,CAAC,YAAY,EAAE,CAAC,uCAAuC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAAA,CACrF,CAAC,CAAC;IAEH,OAAO;QACN,KAAK,CAAC,IAAI,GAAG;YACZ,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjB,aAAa,CAAC,cAAc,CAAC,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YACjC,MAAM,aAAa,CAAC;YACpB,IAAI,SAAS,EAAE,CAAC;gBACf,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC9C,IAAI,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC;oBAAE,KAAK,GAAG,MAAM,CAAC;YAChG,CAAC;YACD,MAAM,WAAW,CAAC;QAAA,CAClB;KACD,CAAC;AAAA,CACF;AAED,KAAK,UAAU,yBAAyB,CACvC,MAAkC,EAClC,GAAiB,EACjB,MAAmB,EACH;IAChB,IAAI,OAA6B,CAAC;IAClC,IAAI,CAAC;QACJ,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,YAAY,EAAE,CAAC,0DAA0D,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACxG,OAAO;IACR,CAAC;IACD,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO;IAC3B,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,EAAE;QAC3C,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC;QACtE,GAAG,EAAE,GAAG,EAAE;QACV,cAAc,EAAE,qCAAqC;KACrD,CAAC,CAAC;IACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAClF,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAClE,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC7D,OAAO,CAAC,GAAG,CACV,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAChD,OAAO,QAAQ,CAAC,CAAC,CAAC,sBAAsB,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAAA,CAC5E,CAAC,CACF;QACD,OAAO,CAAC,GAAG,CACV,UAAU,CAAC,IAAI;aACb,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;aACzD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YACf,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACtD,OAAO,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAAA,CACjG,CAAC,CACH;KACD,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO;IAC3B,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAChE,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAC1D,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,YAAY,EAAE,CACpB,6BAA6B,cAAc,8BAA8B,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAC7G,CAAC;IACH,CAAC;IACD,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,CAAC,YAAY,EAAE,CACpB,0BAA0B,WAAW,4BAA4B,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAClG,CAAC;IACH,CAAC;IACD,MAAM,cAAc,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC1D,MAAM,4BAA4B,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACxE,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO;IAC3B,MAAM,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AAAA,CACzD;AAED,KAAK,UAAU,4BAA4B,CAC1C,MAAkC,EAClC,OAA6B,EAC7B,GAAiB,EACjB,MAAmB,EACH;IAChB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,IACC,MAAM,CAAC,OAAO;YACd,KAAK,CAAC,MAAM,KAAK,QAAQ;YACzB,CAAC,KAAK,CAAC,QAAQ;YACf,KAAK,CAAC,QAAQ,CAAC,uBAAuB;YACtC,KAAK,CAAC,eAAe,KAAK,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS;YAE9D,SAAS;QACV,IAAI,CAAC;YACJ,MAAM,MAAM,CAAC,MAAM,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC,CAAC;YACvD,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,YAAY,EAAE,CACpB,0DAA0D,KAAK,CAAC,OAAO,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,CAClG,CAAC;YACF,SAAS;QACV,CAAC;QACD,IAAI,CAAC;YACJ,MAAM,SAAS,GAAG,iCAAiC,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACxE,IAAI,CAAC,CAAC,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;gBACtF,MAAM,CAAC,YAAY,EAAE,CACpB,uEAAuE,KAAK,CAAC,OAAO,EAAE,CACtF,CAAC;YACH,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,YAAY,EAAE,CACpB,8DAA8D,KAAK,CAAC,OAAO,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,CACtG,CAAC;QACH,CAAC;IACF,CAAC;AAAA,CACD;AAED,SAAS,0BAA0B,CAAC,KAAyB,EAAU;IACtE,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,OAAO,iCAAiC,KAAK,CAAC,KAAK,CAAC,OAAO,2CAA2C,QAAQ,EAAE,IAAI,IAAI,MAAM,YAAY,QAAQ,EAAE,MAAM,IAAI,MAAM,oDAAoD,CAAC;AAAA,CACzN;AAED,KAAK,UAAU,aAAa,CAC3B,MAAkC,EAClC,OAA6B,EAC7B,GAAiB,EACjB,MAAmB,EACH;IAChB,MAAM,OAAO,GAAG,qBAAqB,CAAC,OAAO,EAAE;QAC9C,UAAU,EAAE,MAAM,CAAC,cAAc;QACjC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS;KAClD,CAAC,CAAC;IACH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEjC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO;QAC3B,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtE,MAAM,kBAAkB,GAAG,gBAAgB,KAAK,SAAS,CAAC;QAC1D,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACzB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBACnB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;oBACzD,SAAS;gBACV,CAAC;gBACD,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC;gBACjC,IAAI,CAAC,OAAO,EAAE,CAAC;oBACd,MAAM,CAAC,YAAY,EAAE,CACpB,+BAA+B,MAAM,CAAC,OAAO,6DAA6D,CAC1G,CAAC;oBACF,SAAS;gBACV,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CACxC,gBAAgB,OAAO,CAAC,KAAK,CAAC,OAAO,8BAA8B,CACnE,CAAC;gBACF,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO;oBAAE,SAAS;YACzC,CAAC;YACD,MAAM,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAC/C,SAAS;QACV,CAAC;QAED,IAAI,kBAAkB,EAAE,CAAC;YACxB,MAAM,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAC9C,SAAS;QACV,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACnB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;YACzD,SAAS;QACV,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,aAAa,CACvC,gBAAgB,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,eAAe,IAAI,MAAM,IAAI,CAChG,CAAC;QACF,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO;QAC3B,IAAI,KAAK,EAAE,CAAC;YACX,MAAM,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAC9C,SAAS;QACV,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,mBAAmB,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;QAC5F,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO;YAAE,SAAS;QACzC,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC;YACJ,IAAI,CAAC,CAAC,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;gBAC1F,MAAM,CAAC,YAAY,EAAE,CAAC,2CAA2C,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;YAC5F,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,YAAY,EAAE,CACpB,+CAA+C,MAAM,CAAC,OAAO,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,CACxF,CAAC;QACH,CAAC;IACF,CAAC;AAAA,CACD;AAED,SAAS,4BAA4B,CACpC,MAAkC,EAClC,MAA0B,EACL;IACrB,IAAI,MAAM,CAAC,eAAe,KAAK,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS;QAAE,OAAO,wBAAwB,CAAC;IACrG,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC;IACpC,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC;IACjD,IAAI,YAAY,KAAK,SAAS,IAAI,cAAc,KAAK,SAAS,IAAI,YAAY,KAAK,cAAc,EAAE,CAAC;QACnG,OAAO,sCAAsC,CAAC;IAC/C,CAAC;IACD,IAAI,CAAC,cAAc,IAAI,YAAY,CAAC,KAAK,MAAM,CAAC,OAAO;QAAE,OAAO,+CAA+C,CAAC;IAChH,IAAI,MAAM,CAAC,sBAAsB,KAAK,KAAK;QAAE,OAAO,uDAAuD,CAAC;IAC5G,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,sBAAsB,CAAC,MAAkC,EAAE,MAA0B,EAAE,MAAc,EAAQ;IACrH,MAAM,CAAC,YAAY,EAAE,CACpB,4CAA4C,MAAM,CAAC,OAAO,KAAK,MAAM,kEAAkE,CACvI,CAAC;AAAA,CACF;AAED,KAAK,UAAU,eAAe,CAC7B,MAAkC,EAClC,MAA0B,EAC1B,MAAmB,EACH;IAChB,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO;IAC3B,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,EAAE;QACrC,SAAS,EAAE,OAAO,CAAC,GAAG;QACtB,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS;KACrD,CAAC,CAAC;IACH,IAAI,CAAC;QACJ,IAAI,CAAC,CAAC,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YAAE,OAAO;QAC7F,IAAI,MAAM,CAAC,OAAO;YAAE,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACnG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,YAAY,EAAE,CAAC,gDAAgD,MAAM,CAAC,OAAO,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClH,CAAC;AAAA,CACD;AAED,KAAK,UAAU,gBAAgB,CAC9B,MAAkC,EAClC,MAA0B,EAC1B,MAAmB,EACH;IAChB,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO;IAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC;IACjC,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACtC,MAAM,CAAC,YAAY,EAAE,CACpB,+BAA+B,MAAM,CAAC,OAAO,gFAAgF,CAC7H,CAAC;QACF,OAAO;IACR,CAAC;IACD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,EAAE;QACrC,SAAS,EAAE,OAAO,CAAC,GAAG;QACtB,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS;KACrD,CAAC,CAAC;IACH,IAAI,QAA+D,CAAC;IACpE,IAAI,CAAC;QACJ,IAAI,CAAC,CAAC,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YAAE,OAAO;QAC7F,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YAC9E,OAAO;QACR,CAAC;QACD,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YAC9E,MAAM,CAAC,YAAY,EAAE,CAAC,oCAAoC,MAAM,CAAC,OAAO,KAAK,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;YACrG,OAAO;QACR,CAAC;QACD,QAAQ,GAAG,aAAa,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,CAAC;YACJ,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/E,CAAC;QAAC,MAAM,CAAC;YACR,qEAAqE;QACtE,CAAC;QACD,MAAM,CAAC,YAAY,EAAE,CAAC,oCAAoC,MAAM,CAAC,OAAO,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACrG,OAAO;IACR,CAAC;IACD,MAAM,aAAa,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC;IACxD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,6FAA6F;YAC7F,6FAA6F;YAC7F,eAAe;YACf,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;QACvF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,YAAY,EAAE,CACpB,2DAA2D,MAAM,CAAC,OAAO,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,CACpG,CAAC;QACH,CAAC;IACF,CAAC;SAAM,CAAC;QACP,MAAM,CAAC,YAAY,EAAE,CACpB,kCAAkC,MAAM,CAAC,OAAO,sEAAsE,CACtH,CAAC;IACH,CAAC;IACD,KAAK,QAAQ,CAAC,UAAU,CAAC,IAAI,CAC5B,CAAC,MAAM,EAAE,EAAE,CAAC,4BAA4B,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EACxF,CAAC,KAAc,EAAE,EAAE,CAAC;QACnB,MAAM,CAAC,YAAY,EAAE,CACpB,iCAAiC,OAAO,CAAC,KAAK,CAAC,OAAO,4BAA4B,aAAa,CAAC,KAAK,CAAC,EAAE,CACxG,CAAC;IAAA,CACF,CACD,CAAC;AAAA,CACF;AAED,KAAK,UAAU,4BAA4B,CAC1C,MAAkC,EAClC,OAA2B,EAC3B,cAAkC,EAClC,MAA8D,EAC9D,QAAqB,EACL;IAChB,IAAI,CAAC;QACJ,MAAM,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC3D,IAAI,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;YACtF,IAAI,QAAQ,CAAC,OAAO;gBAAE,OAAO;YAC7B,MAAM,2BAA2B,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC9D,OAAO;QACR,CAAC;QACD,MAAM,cAAc,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACzE,IAAI,cAAc,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC;YACzC,MAAM,kBAAkB,GAAG,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;YAC5E,IAAI,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,kBAAkB,CAAC,EAAE,CAAC;gBACvG,IAAI,QAAQ,CAAC,OAAO;oBAAE,OAAO;gBAC7B,MAAM,2BAA2B,CAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,CAAC,CAAC;gBACxE,OAAO;YACR,CAAC;QACF,CAAC;QACD,8FAA8F;QAC9F,8FAA8F;QAC9F,uEAAuE;QACvE,MAAM,gBAAgB,GAAG,YAAY,CAAC,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACnG,IAAI,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,gBAAgB,CAAC,EAAE,CAAC;YACrG,IAAI,QAAQ,CAAC,OAAO;gBAAE,OAAO;YAC7B,MAAM,2BAA2B,CAAC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,CAAC,CAAC;YACtE,OAAO;QACR,CAAC;QACD,IAAI,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC;YACxF,IAAI,QAAQ,CAAC,OAAO;gBAAE,OAAO;YAC7B,MAAM,2BAA2B,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC9D,OAAO;QACR,CAAC;QACD,MAAM,CAAC,YAAY,EAAE,CAAC,sDAAsD,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAChG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,YAAY,EAAE,CACpB,0DAA0D,OAAO,CAAC,OAAO,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,CACpG,CAAC;IACH,CAAC;AAAA,CACD;AAED,KAAK,UAAU,2BAA2B,CACzC,MAAkC,EAClC,QAA4B,EAC5B,QAAqB,EACL;IAChB,IAAI,QAAQ,CAAC,OAAO;QAAE,OAAO;IAC7B,IAAI,CAAC;QACJ,MAAM,MAAM,CAAC,MAAM,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1D,IAAI,QAAQ,CAAC,OAAO;YAAE,OAAO;QAC7B,MAAM,SAAS,GAAG,iCAAiC,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;QACxF,IAAI,CAAC,CAAC,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;YAC5F,MAAM,CAAC,YAAY,EAAE,CACpB,uEAAuE,QAAQ,CAAC,OAAO,EAAE,CACzF,CAAC;QACH,CAAC;IACF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,YAAY,EAAE,CACpB,0DAA0D,QAAQ,CAAC,OAAO,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,CACrG,CAAC;IACH,CAAC;AAAA,CACD;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E,KAAK,UAAU,iBAAiB,CAC/B,MAAkC,EAClC,gBAAwB,EACxB,GAAiB,EACqB;IACtC,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAC;IAC7C,MAAM,OAAO,GAAG,CAAC,iBAAiB,EAAE,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC;IAC3F,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,SAAS,CAAC;IAC5E,MAAM,OAAO,GAAG,uBAAuB,EAAE,CAAC;IAC1C,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,eAAe,CAAC;IAClE,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CAClB,8BAA8B,cAAc,IAAI,MAAM,iCAAiC,OAAO,IAAI,MAAM,IAAI,CAC5G,CAAC;IACH,CAAC;IAED,IAAI,KAAK,GAAG,gBAAgB,CAAC;QAC5B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,QAAQ,EAAE,UAAU,EAAE;QACtB,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC;QAChB,SAAS,EAAE,gBAAgB;QAC3B,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrD,CAAC,CAAC;IACH,IAAI,CAAC;QACJ,MAAM,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,YAAY,EAAE,CAAC,oDAAoD,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnG,CAAC;IAED,IAAI,gBAAgB,GAAG,gBAAgB,CAAC;IACxC,IAAI,sBAAsB,GAAG,eAAe,CAAC;IAC7C,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,KAAiC,CAAC;IACtC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,uBAAuB,GAAG,KAAK,CAAC;IACpC,MAAM,WAAW,GAAG,CAAC,IAAI,GAAkB,IAAI,EAAQ,EAAE,CAAC;QACzD,IAAI,uBAAuB;YAAE,OAAO;QACpC,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1E,IAAI,yBAAyB,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC;gBAAE,KAAK,GAAG,QAAQ,CAAC;QACnF,CAAC;QAAC,MAAM,CAAC;YACR,8DAA8D;QAC/D,CAAC;IAAA,CACD,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAElC,MAAM,IAAI,GAAG,GAAS,EAAE,CAAC;QACxB,IAAI,OAAO;YAAE,OAAO;QACpB,OAAO,GAAG,IAAI,CAAC;QACf,IAAI,KAAK;YAAE,aAAa,CAAC,KAAK,CAAC,CAAC;QAChC,KAAK,GAAG,SAAS,CAAC;QAClB,IAAI,CAAC,uBAAuB;YAAE,WAAW,EAAE,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAAA,CACjC,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,EACpB,QAA4B,EAC5B,IAAwB,EACxB,cAAsB,EACH,EAAE,CAAC;QACtB,IAAI,CAAC;YACJ,IAAI,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;gBACpF,KAAK,GAAG,IAAI,CAAC;gBACb,OAAO,IAAI,CAAC;YACb,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;YACnE,IAAI,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG;gBAAE,KAAK,GAAG,OAAO,CAAC;iBAC7C,CAAC;gBACL,OAAO,GAAG,IAAI,CAAC;gBACf,IAAI,KAAK;oBAAE,aAAa,CAAC,KAAK,CAAC,CAAC;gBAChC,KAAK,GAAG,SAAS,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;gBACjC,MAAM,CAAC,YAAY,EAAE,CAAC,4EAA4E,CAAC,CAAC;YACrG,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,YAAY,EAAE,CAAC,mBAAmB,cAAc,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACrF,CAAC;QACD,OAAO,KAAK,CAAC;IAAA,CACb,CAAC;IAEF,MAAM,iBAAiB,GAAG,GAAS,EAAE,CAAC;QACrC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YACzB,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,KAAK,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gBAChC,OAAO,GAAG,KAAK,CAAC;YAAA,CAChB,CAAC,CAAC;QAAA,CACH,EAAE,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAClC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAAA,CAChB,CAAC;IAEF,MAAM,qBAAqB,GAAG,KAAK,IAAsB,EAAE,CAAC;QAC3D,yFAAyF;QACzF,8FAA8F;QAC9F,sFAAsF;QACtF,IAAI,CAAC,sBAAsB,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,gBAAgB,CAAC;YAAE,OAAO,KAAK,CAAC;QACtF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC,CAAC;QAChG,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,KAAK,sBAAsB;YACzG,OAAO,KAAK,CAAC;QACd,IAAI,MAAM,CAAC,GAAG,KAAK,gBAAgB,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACjF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC/E,OAAO,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,GAAG,EAAE,GAAG,WAAW,IAAI,MAAM,CAAC;IAAA,CACrE,CAAC;IAEF,MAAM,WAAW,GAAG,KAAK,IAAmB,EAAE,CAAC;QAC9C,IAAI,OAAO;YAAE,OAAO;QACpB,IAAI,CAAC,CAAC,MAAM,qBAAqB,EAAE,CAAC,EAAE,CAAC;YACtC,MAAM,aAAa,EAAE,CAAC;YACtB,OAAO;QACR,CAAC;QACD,iFAAiF;QACjF,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9D,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;QACtG,IAAI,SAAS,CAAC,IAAI,KAAK,cAAc;YAAE,OAAO;QAC9C,IACC,CAAC,CAAC,MAAM,OAAO,CACd,KAAK,EACL,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EACjD,qDAAqD,CACrD,CAAC;YAEF,OAAO;QACR,iBAAiB,CAAC,MAAM,EAAE,mFAAmF,CAAC,CAAC;QAC/G,IAAI,EAAE,CAAC;QACP,MAAM,CAAC,WAAW,EAAE,CAAC;IAAA,CACrB,CAAC;IAEF,MAAM,aAAa,GAAG,KAAK,IAAmB,EAAE,CAAC;QAChD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC;QACvB,MAAM,SAAS,GAAqB,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACpG,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS;YAAE,SAAS,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QACzE,IAAI,QAAQ,CAAC,WAAW,KAAK,SAAS;YAAE,SAAS,CAAC,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;QACrF,MAAM,SAAS,GAAG,aAAa,CAAC,aAAa,CAAC,QAAQ,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QAC3G,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,kCAAkC,CAAC,CAAC;YAAE,OAAO;QACtF,IAAI,KAAK;YAAE,aAAa,CAAC,KAAK,CAAC,CAAC;QAChC,KAAK,GAAG,SAAS,CAAC;QAClB,uBAAuB,GAAG,IAAI,CAAC;QAC/B,iBAAiB,CAChB,MAAM,EACN,uCAAuC,gBAAgB,6DAA6D,CACpH,CAAC;QACF,eAAe,EAAE,CAAC;IAAA,CAClB,CAAC;IAEF,MAAM,eAAe,GAAG,GAAS,EAAE,CAAC;QACnC,MAAM,aAAa,GAAG,GAAG,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC9D,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YACzB,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,KAAK,SAAS,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gBAC3C,OAAO,GAAG,KAAK,CAAC;YAAA,CAChB,CAAC,CAAC;QAAA,CACH,EAAE,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAClC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAAA,CAChB,CAAC;IAEF,MAAM,SAAS,GAAG,KAAK,EAAE,aAAqB,EAAiB,EAAE,CAAC;QACjE,IAAI,OAAO;YAAE,OAAO;QACpB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9D,IAAI,KAAK,EAAE,CAAC;YACX,MAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;YACtG,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;gBACzD,qFAAqF;gBACrF,mFAAmF;gBACnF,IACC,CAAC,CAAC,MAAM,OAAO,CACd,KAAK,EACL,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE,CAAC,EAChG,iCAAiC,CACjC,CAAC;oBAEF,OAAO;gBACR,iBAAiB,CAChB,MAAM,EACN,gDAAgD,SAAS,CAAC,SAAS,cAAc,CACjF,CAAC;gBACF,gBAAgB,GAAG,SAAS,CAAC,SAAS,CAAC;gBACvC,sBAAsB,GAAG,KAAK,CAAC,eAAe,CAAC;gBAC/C,uBAAuB,GAAG,KAAK,CAAC;gBAChC,IAAI,KAAK,EAAE,CAAC;oBACX,aAAa,CAAC,KAAK,CAAC,CAAC;oBACrB,KAAK,GAAG,SAAS,CAAC;gBACnB,CAAC;gBACD,iBAAiB,EAAE,CAAC;gBACpB,OAAO;YACR,CAAC;YACD,IAAI,SAAS,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBACvC,IAAI,EAAE,CAAC;gBACP,MAAM,CAAC,WAAW,EAAE,CAAC;gBACrB,OAAO;YACR,CAAC;QACF,CAAC;QACD,IAAI,GAAG,EAAE,IAAI,aAAa,EAAE,CAAC;YAC5B,IAAI,EAAE,CAAC;YACP,MAAM,CAAC,WAAW,EAAE,CAAC;QACtB,CAAC;IAAA,CACD,CAAC;IAEF,iBAAiB,EAAE,CAAC;IAEpB,OAAO,EAAE,IAAI,EAAE,CAAC;AAAA,CAChB","sourcesContent":["/**\n * Process-matrix runtime composition: the pieces main.ts wires together for durable,\n * restart-surviving master/worker process supervision.\n *\n * Contract:\n * - A WORKER is any process launched with a known parent (`PI_PARENT_PID` -- set by the\n * `--parent-pid` CLI flag, or directly by a launcher such as tmux dispatch). It self-registers\n * its OWN entry (the single writer of that entry during normal operation) and watches its\n * parent's liveness. On parent death it winds down GRACEFULLY -- never silently -- leaving a\n * `resumable` payload, then exits on its own after a bounded grace window (during which it may\n * instead be adopted by a new parent). \"No new turns\" after that point is automatic: a dead\n * parent injects no further follow-ups, so the worker simply runs out of work to do.\n * - A MASTER is everything else (no known parent). On startup it scans the matrix for orphaned\n * workers (workers whose recorded parent is dead). Workers owned by this exact resumed session\n * are restored automatically; foreign workers remain owner-gated interactively and report-only\n * headlessly.\n *\n * Sanctioned exceptions to \"a worker's entry is written only by that worker\": an exact resumed\n * parent may restore its recorded ownership, and an owner may explicitly approve adoption or\n * cooperative cleanup of a foreign orphan. The worker later confirms/applies the directive via\n * `pollWorkerDirective` and re-writes its own entry -- see `docs/process-matrix.md`. Outside these\n * identity/approval-fenced handshakes, a master NEVER writes another session's entry, and nothing\n * here ever kills a process directly.\n */\n\nimport { hostname as osHostname } from \"node:os\";\nimport { isAgentIdentity } from \"../orchestration/agent-resume.ts\";\nimport type { AgentIdentityContract } from \"../orchestration/contracts.ts\";\nimport { getParentPid, getParentSessionId, getProcessTaskRef } from \"../process-identity.ts\";\nimport type { ResolvedProcessMatrixSettings } from \"../settings-manager.ts\";\nimport { getBoundWorktreeLaneKey } from \"../worktree-sync/runtime.ts\";\nimport type { ProcessMatrixEntry, ResumablePayload } from \"./codes.ts\";\nimport {\n\tbuildEntryId,\n\tlistEntries,\n\treadEntry,\n\tremoveEntryIfUnchanged,\n\twriteEntry,\n\twriteEntryIfUnchanged,\n\twriteEntryIfUnchangedSync,\n} from \"./store.ts\";\nimport {\n\tapplyAdoption,\n\tapplyHeartbeat,\n\tbeginWindDown,\n\tbuildMasterEntry,\n\tbuildWorkerEntry,\n\tdetectOrphanedWorkers,\n\tmarkClosed,\n\tmarkResumable,\n\tmarkTerminal,\n\tmarkTerminalNotificationDelivered,\n\tpollWorkerDirective,\n\treconcileMatrix,\n} from \"./supervisor.ts\";\n\nexport {\n\tgetOrchestrationAgentId,\n\tgetParentPid,\n\tgetParentSessionId,\n\tgetProcessTaskRef,\n\tPI_ORCHESTRATION_AGENT_ID_ENV,\n\tPI_PARENT_PID_ENV,\n\tPI_PARENT_SESSION_ENV,\n\tPI_TASK_REF_ENV,\n} from \"../process-identity.ts\";\n\nexport interface ProcessMatrixRuntimeConfig {\n\tagentDir: string;\n\t/** Canonical logical identity for this process and any exact-session resume. */\n\tagent: AgentIdentityContract;\n\t/** Whether an interactive UI is available to ask the owner (see `promptConfirm`). */\n\thasUI: boolean;\n\tsettings: ResolvedProcessMatrixSettings;\n\tisProcessAlive: (pid: number) => boolean;\n\tnow?: () => number;\n\t/** Structural notice injection into the running session (host `sendCustomMessage` seam). */\n\tnotify: (text: string) => void | Promise<void>;\n\t/** Diagnostics sink (never throws into the session). */\n\tonDiagnostic?: (message: string) => void;\n\t/** The ask seam: resolves false on decline AND on any non-interactive/non-TTY caller. */\n\tpromptConfirm: (message: string) => Promise<boolean>;\n\t/** Cooperative self-exit -- called by a worker once wound down (grace expiry or a\n\t * master-granted cleanup directive). Never called for the master's own lifecycle. */\n\trequestExit: () => void;\n\t/** Stable goal/task identity. Automatic recovery requires an exact match. */\n\ttaskRef?: string;\n\ttaskSummary?: string;\n\t/** False for terminal/blocked owner state; recovery then remains explicit-owner gated. */\n\tallowAutomaticRecovery?: boolean;\n\t/** Starts a replacement OS process for a dead resumable worker. Completion is an event-driven\n\t * terminal signal; worker product remains in its persisted session/artifacts. */\n\tresumeWorker?: (payload: ResumablePayload) => Promise<ResumeWorkerLaunchOutcome>;\n}\n\nexport type ResumeWorkerLaunchOutcome =\n\t| {\n\t\t\tstarted: true;\n\t\t\t/** OS identity of this specific replacement process, used to fence its terminal handoff. */\n\t\t\tpid: number;\n\t\t\tcompletion: Promise<{ code: number | null; signal: NodeJS.Signals | null }>;\n\t }\n\t| { started: false; reason: string };\n\nexport interface ProcessMatrixRuntimeHandle {\n\tstop(): Promise<void> | void;\n}\n\nconst NOOP_HANDLE: ProcessMatrixRuntimeHandle = { stop: () => {} };\nexport const PROCESS_MATRIX_RESUMABLE_RETENTION_MS = 30 * 24 * 60 * 60_000;\n\nfunction describeError(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction nowIso(now: () => number): string {\n\treturn new Date(now()).toISOString();\n}\n\nfunction emitRuntimeNotice(config: ProcessMatrixRuntimeConfig, text: string): void {\n\ttry {\n\t\tvoid Promise.resolve(config.notify(text)).catch((error: unknown) => {\n\t\t\tconfig.onDiagnostic?.(`process-matrix: failed to notify session: ${describeError(error)}`);\n\t\t});\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(`process-matrix: failed to notify session: ${describeError(error)}`);\n\t}\n}\n\n/**\n * Start the per-session process-matrix runtime. No-op when disabled (byte-identical to not\n * calling this at all). Never throws: a broken store must surface as a diagnostic, not a startup\n * crash.\n */\nexport async function startProcessMatrixRuntime(\n\tconfig: ProcessMatrixRuntimeConfig,\n): Promise<ProcessMatrixRuntimeHandle> {\n\tif (!config.settings.enabled) return NOOP_HANDLE;\n\tconst now = config.now ?? Date.now;\n\tconst parentPid = getParentPid();\n\n\ttry {\n\t\tif (!isAgentIdentity(config.agent)) throw new TypeError(\"Process-matrix agent identity is invalid.\");\n\t\tif (parentPid !== undefined) {\n\t\t\treturn await startWorkerBranch(config, parentPid, now);\n\t\t}\n\t\treturn await startMasterBranch(config, now);\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(`process-matrix: runtime failed to start: ${describeError(error)}`);\n\t\treturn NOOP_HANDLE;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Master branch\n// ---------------------------------------------------------------------------\n\nasync function startMasterBranch(\n\tconfig: ProcessMatrixRuntimeConfig,\n\tnow: () => number,\n): Promise<ProcessMatrixRuntimeHandle> {\n\tlet entry = buildMasterEntry({\n\t\tagent: config.agent,\n\t\tpid: process.pid,\n\t\thostname: osHostname(),\n\t\tnow: nowIso(now),\n\t});\n\ttry {\n\t\tawait writeEntry(config.agentDir, entry);\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(`process-matrix: failed to register master entry: ${describeError(error)}`);\n\t}\n\n\tlet stopped = false;\n\tlet ownsEntry = true;\n\tlet heartbeatTask: Promise<void> | undefined;\n\tconst lifetime = new AbortController();\n\tconst heartbeatTimer = setInterval(() => {\n\t\tif (stopped || !ownsEntry || heartbeatTask) return;\n\t\tconst expected = entry;\n\t\tconst next = applyHeartbeat(expected, nowIso(now));\n\t\theartbeatTask = writeEntryIfUnchanged(config.agentDir, expected.entryId, expected, next)\n\t\t\t.then((written) => {\n\t\t\t\tif (written) {\n\t\t\t\t\tentry = next;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\townsEntry = false;\n\t\t\t\tlifetime.abort();\n\t\t\t\tclearInterval(heartbeatTimer);\n\t\t\t\tprocess.off(\"exit\", closeOnExit);\n\t\t\t\tconfig.onDiagnostic?.(\"process-matrix: master entry ownership moved to a newer process generation\");\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconfig.onDiagnostic?.(`process-matrix: failed to write master heartbeat: ${describeError(error)}`);\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\theartbeatTask = undefined;\n\t\t\t});\n\t}, config.settings.heartbeatMs);\n\theartbeatTimer.unref?.();\n\n\t// Best-effort close on process exit. A SIGKILLed master leaving \"running\" is fine -- reconcile's\n\t// own dead-pid detection covers it; this only makes the common clean-exit case tidy.\n\tconst closeOnExit = (): void => {\n\t\tif (!ownsEntry) return;\n\t\ttry {\n\t\t\tconst closed = markClosed(entry, nowIso(now));\n\t\t\tif (writeEntryIfUnchangedSync(config.agentDir, entry, closed)) entry = closed;\n\t\t} catch {\n\t\t\t// Best-effort only -- see module doc.\n\t\t}\n\t};\n\tprocess.once(\"exit\", closeOnExit);\n\n\tconst maintenance = reconcileAndRunOrphanScan(config, now, lifetime.signal).catch((error: unknown) => {\n\t\tconfig.onDiagnostic?.(`process-matrix: maintenance failed: ${describeError(error)}`);\n\t});\n\n\treturn {\n\t\tasync stop() {\n\t\t\tif (stopped) return;\n\t\t\tstopped = true;\n\t\t\tlifetime.abort();\n\t\t\tclearInterval(heartbeatTimer);\n\t\t\tprocess.off(\"exit\", closeOnExit);\n\t\t\tawait heartbeatTask;\n\t\t\tif (ownsEntry) {\n\t\t\t\tconst closed = markClosed(entry, nowIso(now));\n\t\t\t\tif (await writeEntryIfUnchanged(config.agentDir, entry.entryId, entry, closed)) entry = closed;\n\t\t\t}\n\t\t\tawait maintenance;\n\t\t},\n\t};\n}\n\nasync function reconcileAndRunOrphanScan(\n\tconfig: ProcessMatrixRuntimeConfig,\n\tnow: () => number,\n\tsignal: AbortSignal,\n): Promise<void> {\n\tlet entries: ProcessMatrixEntry[];\n\ttry {\n\t\tentries = await listEntries(config.agentDir);\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(`process-matrix: reconciliation failed to list entries: ${describeError(error)}`);\n\t\treturn;\n\t}\n\tif (signal.aborted) return;\n\tconst reconciled = reconcileMatrix(entries, {\n\t\tisPidAlive: (pid) => pid === process.pid || config.isProcessAlive(pid),\n\t\tnow: now(),\n\t\tresumableTtlMs: PROCESS_MATRIX_RESUMABLE_RETENTION_MS,\n\t});\n\tconst originalByEntryId = new Map(entries.map((entry) => [entry.entryId, entry]));\n\tconst recoveredEntryIdSet = new Set(reconciled.recoveredEntryIds);\n\tconst [prunedOutcomes, recoveredOutcomes] = await Promise.all([\n\t\tPromise.all(\n\t\t\treconciled.prunedEntryIds.map((entryId) => {\n\t\t\t\tconst original = originalByEntryId.get(entryId);\n\t\t\t\treturn original ? removeEntryIfUnchanged(config.agentDir, original) : false;\n\t\t\t}),\n\t\t),\n\t\tPromise.all(\n\t\t\treconciled.kept\n\t\t\t\t.filter((entry) => recoveredEntryIdSet.has(entry.entryId))\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tconst original = originalByEntryId.get(entry.entryId);\n\t\t\t\t\treturn original ? writeEntryIfUnchanged(config.agentDir, entry.entryId, original, entry) : false;\n\t\t\t\t}),\n\t\t),\n\t]);\n\tif (signal.aborted) return;\n\tconst recoveredCount = recoveredOutcomes.filter(Boolean).length;\n\tconst prunedCount = prunedOutcomes.filter(Boolean).length;\n\tif (recoveredCount > 0) {\n\t\tconfig.onDiagnostic?.(\n\t\t\t`process-matrix: recovered ${recoveredCount} interrupted Pi worker entr${recoveredCount === 1 ? \"y\" : \"ies\"}`,\n\t\t);\n\t}\n\tif (prunedCount > 0) {\n\t\tconfig.onDiagnostic?.(\n\t\t\t`process-matrix: pruned ${prunedCount} terminal or expired entr${prunedCount === 1 ? \"y\" : \"ies\"}`,\n\t\t);\n\t}\n\tconst currentEntries = await listEntries(config.agentDir);\n\tawait deliverTerminalNotifications(config, currentEntries, now, signal);\n\tif (signal.aborted) return;\n\tawait runOrphanScan(config, currentEntries, now, signal);\n}\n\nasync function deliverTerminalNotifications(\n\tconfig: ProcessMatrixRuntimeConfig,\n\tentries: ProcessMatrixEntry[],\n\tnow: () => number,\n\tsignal: AbortSignal,\n): Promise<void> {\n\tfor (const entry of entries) {\n\t\tif (\n\t\t\tsignal.aborted ||\n\t\t\tentry.status !== \"closed\" ||\n\t\t\t!entry.terminal ||\n\t\t\tentry.terminal.notificationDeliveredAt ||\n\t\t\tentry.parentSessionId !== config.agent.resumeContext.sessionId\n\t\t)\n\t\t\tcontinue;\n\t\ttry {\n\t\t\tawait config.notify(formatTerminalNotification(entry));\n\t\t\tif (signal.aborted) return;\n\t\t} catch (error) {\n\t\t\tconfig.onDiagnostic?.(\n\t\t\t\t`process-matrix: failed to deliver terminal handoff for ${entry.entryId}: ${describeError(error)}`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst delivered = markTerminalNotificationDelivered(entry, nowIso(now));\n\t\t\tif (!(await writeEntryIfUnchanged(config.agentDir, entry.entryId, entry, delivered))) {\n\t\t\t\tconfig.onDiagnostic?.(\n\t\t\t\t\t`process-matrix: terminal handoff changed before acknowledgement for ${entry.entryId}`,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconfig.onDiagnostic?.(\n\t\t\t\t`process-matrix: failed to acknowledge terminal handoff for ${entry.entryId}: ${describeError(error)}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction formatTerminalNotification(entry: ProcessMatrixEntry): string {\n\tconst terminal = entry.terminal;\n\treturn `process-matrix: resumed agent ${entry.agent.agentId} reached a terminal process state (code ${terminal?.code ?? \"none\"}, signal ${terminal?.signal ?? \"none\"}). Inspect its persisted result before continuing.`;\n}\n\nasync function runOrphanScan(\n\tconfig: ProcessMatrixRuntimeConfig,\n\tentries: ProcessMatrixEntry[],\n\tnow: () => number,\n\tsignal: AbortSignal,\n): Promise<void> {\n\tconst orphans = detectOrphanedWorkers(entries, {\n\t\tisPidAlive: config.isProcessAlive,\n\t\townSessionId: config.agent.resumeContext.sessionId,\n\t});\n\tif (orphans.length === 0) return;\n\n\tfor (const orphan of orphans) {\n\t\tif (signal.aborted) return;\n\t\tconst recoveryBoundary = getAutomaticRecoveryBoundary(config, orphan);\n\t\tconst exactResumedParent = recoveryBoundary === undefined;\n\t\tif (!config.isProcessAlive(orphan.pid)) {\n\t\t\tif (!exactResumedParent) {\n\t\t\t\tif (!config.hasUI) {\n\t\t\t\t\treportOwnerGatedOrphan(config, orphan, recoveryBoundary);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst payload = orphan.resumable;\n\t\t\t\tif (!payload) {\n\t\t\t\t\tconfig.onDiagnostic?.(\n\t\t\t\t\t\t`process-matrix: dead worker ${orphan.entryId} is not resumable because its launch context is unavailable`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst resume = await config.promptConfirm(\n\t\t\t\t\t`resume agent ${payload.agent.agentId} from its persisted session?`,\n\t\t\t\t);\n\t\t\t\tif (!resume || signal.aborted) continue;\n\t\t\t}\n\t\t\tawait resumeDeadOrphan(config, orphan, signal);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (exactResumedParent) {\n\t\t\tawait adoptLiveOrphan(config, orphan, signal);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!config.hasUI) {\n\t\t\treportOwnerGatedOrphan(config, orphan, recoveryBoundary);\n\t\t\tcontinue;\n\t\t}\n\t\tconst adopt = await config.promptConfirm(\n\t\t\t`adopt worker ${orphan.entryId} (lane ${orphan.agent.resumeContext.worktreeLaneKey ?? \"none\"})?`,\n\t\t);\n\t\tif (signal.aborted) return;\n\t\tif (adopt) {\n\t\t\tawait adoptLiveOrphan(config, orphan, signal);\n\t\t\tcontinue;\n\t\t}\n\t\tconst cleanup = await config.promptConfirm(`clean up worker ${orphan.entryId} gracefully?`);\n\t\tif (!cleanup || signal.aborted) continue;\n\t\tconst windingDown = beginWindDown(orphan, \"user_cleanup\", nowIso(now));\n\t\ttry {\n\t\t\tif (!(await writeEntryIfUnchanged(config.agentDir, orphan.entryId, orphan, windingDown))) {\n\t\t\t\tconfig.onDiagnostic?.(`process-matrix: cleanup skipped because ${orphan.entryId} changed`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconfig.onDiagnostic?.(\n\t\t\t\t`process-matrix: failed to write cleanup for ${orphan.entryId}: ${describeError(error)}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction getAutomaticRecoveryBoundary(\n\tconfig: ProcessMatrixRuntimeConfig,\n\torphan: ProcessMatrixEntry,\n): string | undefined {\n\tif (orphan.parentSessionId !== config.agent.resumeContext.sessionId) return \"foreign parent session\";\n\tconst entryTaskRef = orphan.taskRef;\n\tconst payloadTaskRef = orphan.resumable?.taskRef;\n\tif (entryTaskRef !== undefined && payloadTaskRef !== undefined && entryTaskRef !== payloadTaskRef) {\n\t\treturn \"inconsistent persisted task identity\";\n\t}\n\tif ((payloadTaskRef ?? entryTaskRef) !== config.taskRef) return \"task identity does not match the current goal\";\n\tif (config.allowAutomaticRecovery === false) return \"current goal state does not permit automatic recovery\";\n\treturn undefined;\n}\n\nfunction reportOwnerGatedOrphan(config: ProcessMatrixRuntimeConfig, orphan: ProcessMatrixEntry, reason: string): void {\n\tconfig.onDiagnostic?.(\n\t\t`process-matrix: found owner-gated orphan ${orphan.entryId} (${reason}; report-only, non-interactive; nothing written, nothing killed)`,\n\t);\n}\n\nasync function adoptLiveOrphan(\n\tconfig: ProcessMatrixRuntimeConfig,\n\torphan: ProcessMatrixEntry,\n\tsignal: AbortSignal,\n): Promise<void> {\n\tif (signal.aborted) return;\n\tconst adopted = applyAdoption(orphan, {\n\t\tparentPid: process.pid,\n\t\tparentSessionId: config.agent.resumeContext.sessionId,\n\t});\n\ttry {\n\t\tif (!(await writeEntryIfUnchanged(config.agentDir, orphan.entryId, orphan, adopted))) return;\n\t\tif (signal.aborted) await writeEntryIfUnchanged(config.agentDir, orphan.entryId, adopted, orphan);\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(`process-matrix: failed to write adoption for ${orphan.entryId}: ${describeError(error)}`);\n\t}\n}\n\nasync function resumeDeadOrphan(\n\tconfig: ProcessMatrixRuntimeConfig,\n\torphan: ProcessMatrixEntry,\n\tsignal: AbortSignal,\n): Promise<void> {\n\tif (signal.aborted) return;\n\tconst payload = orphan.resumable;\n\tif (!payload || !config.resumeWorker) {\n\t\tconfig.onDiagnostic?.(\n\t\t\t`process-matrix: dead worker ${orphan.entryId} is not resumable because its launch context or resume launcher is unavailable`,\n\t\t);\n\t\treturn;\n\t}\n\tconst claimed = applyAdoption(orphan, {\n\t\tparentPid: process.pid,\n\t\tparentSessionId: config.agent.resumeContext.sessionId,\n\t});\n\tlet launched: Extract<ResumeWorkerLaunchOutcome, { started: true }>;\n\ttry {\n\t\tif (!(await writeEntryIfUnchanged(config.agentDir, orphan.entryId, orphan, claimed))) return;\n\t\tif (signal.aborted) {\n\t\t\tawait writeEntryIfUnchanged(config.agentDir, orphan.entryId, claimed, orphan);\n\t\t\treturn;\n\t\t}\n\t\tconst launchOutcome = await config.resumeWorker(payload);\n\t\tif (!launchOutcome.started) {\n\t\t\tawait writeEntryIfUnchanged(config.agentDir, orphan.entryId, claimed, orphan);\n\t\t\tconfig.onDiagnostic?.(`process-matrix: failed to resume ${orphan.entryId}: ${launchOutcome.reason}`);\n\t\t\treturn;\n\t\t}\n\t\tlaunched = launchOutcome;\n\t} catch (error) {\n\t\ttry {\n\t\t\tawait writeEntryIfUnchanged(config.agentDir, orphan.entryId, claimed, orphan);\n\t\t} catch {\n\t\t\t// The original resumable record remains the intended recovery state.\n\t\t}\n\t\tconfig.onDiagnostic?.(`process-matrix: failed to resume ${orphan.entryId}: ${describeError(error)}`);\n\t\treturn;\n\t}\n\tconst launchedEntry = { ...claimed, pid: launched.pid };\n\tif (!signal.aborted) {\n\t\ttry {\n\t\t\t// Bridge the interval before the replacement can self-register. Without its real PID here, a\n\t\t\t// restarted master can mistake this live replacement for the original dead process and spawn\n\t\t\t// a duplicate.\n\t\t\tawait writeEntryIfUnchanged(config.agentDir, claimed.entryId, claimed, launchedEntry);\n\t\t} catch (error) {\n\t\t\tconfig.onDiagnostic?.(\n\t\t\t\t`process-matrix: failed to record resumed worker pid for ${orphan.entryId}: ${describeError(error)}`,\n\t\t\t);\n\t\t}\n\t} else {\n\t\tconfig.onDiagnostic?.(\n\t\t\t`process-matrix: resumed worker ${orphan.entryId} launched after owner shutdown; preserving its terminal handoff only`,\n\t\t);\n\t}\n\tvoid launched.completion.then(\n\t\t(result) => persistResumedWorkerTerminal(config, launchedEntry, claimed, result, signal),\n\t\t(error: unknown) => {\n\t\t\tconfig.onDiagnostic?.(\n\t\t\t\t`process-matrix: resumed agent ${payload.agent.agentId} terminal signal failed: ${describeError(error)}`,\n\t\t\t);\n\t\t},\n\t);\n}\n\nasync function persistResumedWorkerTerminal(\n\tconfig: ProcessMatrixRuntimeConfig,\n\tclaimed: ProcessMatrixEntry,\n\tpreLaunchClaim: ProcessMatrixEntry,\n\tresult: { code: number | null; signal: NodeJS.Signals | null },\n\tlifetime: AbortSignal,\n): Promise<void> {\n\ttry {\n\t\tconst observedAt = new Date().toISOString();\n\t\tconst terminal = markTerminal(claimed, result, observedAt);\n\t\tif (await writeEntryIfUnchanged(config.agentDir, claimed.entryId, claimed, terminal)) {\n\t\t\tif (lifetime.aborted) return;\n\t\t\tawait notifyResumedWorkerTerminal(config, terminal, lifetime);\n\t\t\treturn;\n\t\t}\n\t\tconst selfRegistered = await readEntry(config.agentDir, claimed.entryId);\n\t\tif (selfRegistered?.pid === claimed.pid) {\n\t\t\tconst registeredTerminal = markTerminal(selfRegistered, result, observedAt);\n\t\t\tif (await writeEntryIfUnchanged(config.agentDir, claimed.entryId, selfRegistered, registeredTerminal)) {\n\t\t\t\tif (lifetime.aborted) return;\n\t\t\t\tawait notifyResumedWorkerTerminal(config, registeredTerminal, lifetime);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t// If recording the spawned PID failed (or shutdown won the race immediately after spawn), the\n\t\t// untouched pre-launch claim proves no newer process has taken this logical entry. Upgrade it\n\t\t// to the actual exited process before persisting its terminal handoff.\n\t\tconst fallbackTerminal = markTerminal({ ...preLaunchClaim, pid: claimed.pid }, result, observedAt);\n\t\tif (await writeEntryIfUnchanged(config.agentDir, claimed.entryId, preLaunchClaim, fallbackTerminal)) {\n\t\t\tif (lifetime.aborted) return;\n\t\t\tawait notifyResumedWorkerTerminal(config, fallbackTerminal, lifetime);\n\t\t\treturn;\n\t\t}\n\t\tif (await writeEntryIfUnchanged(config.agentDir, claimed.entryId, undefined, terminal)) {\n\t\t\tif (lifetime.aborted) return;\n\t\t\tawait notifyResumedWorkerTerminal(config, terminal, lifetime);\n\t\t\treturn;\n\t\t}\n\t\tconfig.onDiagnostic?.(`process-matrix: ignored stale terminal handoff for ${claimed.entryId}`);\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(\n\t\t\t`process-matrix: failed to persist terminal handoff for ${claimed.entryId}: ${describeError(error)}`,\n\t\t);\n\t}\n}\n\nasync function notifyResumedWorkerTerminal(\n\tconfig: ProcessMatrixRuntimeConfig,\n\tterminal: ProcessMatrixEntry,\n\tlifetime: AbortSignal,\n): Promise<void> {\n\tif (lifetime.aborted) return;\n\ttry {\n\t\tawait config.notify(formatTerminalNotification(terminal));\n\t\tif (lifetime.aborted) return;\n\t\tconst delivered = markTerminalNotificationDelivered(terminal, new Date().toISOString());\n\t\tif (!(await writeEntryIfUnchanged(config.agentDir, terminal.entryId, terminal, delivered))) {\n\t\t\tconfig.onDiagnostic?.(\n\t\t\t\t`process-matrix: terminal handoff changed before acknowledgement for ${terminal.entryId}`,\n\t\t\t);\n\t\t}\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(\n\t\t\t`process-matrix: failed to deliver terminal handoff for ${terminal.entryId}: ${describeError(error)}`,\n\t\t);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Worker branch\n// ---------------------------------------------------------------------------\n\nasync function startWorkerBranch(\n\tconfig: ProcessMatrixRuntimeConfig,\n\tinitialParentPid: number,\n\tnow: () => number,\n): Promise<ProcessMatrixRuntimeHandle> {\n\tconst parentSessionId = getParentSessionId();\n\tconst taskRef = (getProcessTaskRef() ?? config.taskRef)?.trim().slice(0, 512) || undefined;\n\tconst taskSummary = config.taskSummary?.trim().slice(0, 2_000) || undefined;\n\tconst laneKey = getBoundWorktreeLaneKey();\n\tconst contextLaneKey = config.agent.resumeContext.worktreeLaneKey;\n\tif (laneKey !== contextLaneKey) {\n\t\tthrow new TypeError(\n\t\t\t`Process-matrix agent lane '${contextLaneKey ?? \"none\"}' does not match active lane '${laneKey ?? \"none\"}'.`,\n\t\t);\n\t}\n\n\tlet entry = buildWorkerEntry({\n\t\tagent: config.agent,\n\t\tpid: process.pid,\n\t\thostname: osHostname(),\n\t\tnow: nowIso(now),\n\t\tparentPid: initialParentPid,\n\t\t...(parentSessionId !== undefined ? { parentSessionId } : {}),\n\t\t...(taskRef !== undefined ? { taskRef } : {}),\n\t\t...(taskSummary !== undefined ? { taskSummary } : {}),\n\t});\n\ttry {\n\t\tawait writeEntry(config.agentDir, entry);\n\t} catch (error) {\n\t\tconfig.onDiagnostic?.(`process-matrix: failed to register worker entry: ${describeError(error)}`);\n\t}\n\n\tlet currentParentPid = initialParentPid;\n\tlet currentParentSessionId = parentSessionId;\n\tlet stopped = false;\n\tlet timer: NodeJS.Timeout | undefined;\n\tlet ticking = false;\n\tlet preserveResumableOnExit = false;\n\tconst closeOnExit = (code: number | null = null): void => {\n\t\tif (preserveResumableOnExit) return;\n\t\ttry {\n\t\t\tconst terminal = markTerminal(entry, { code, signal: null }, nowIso(now));\n\t\t\tif (writeEntryIfUnchangedSync(config.agentDir, entry, terminal)) entry = terminal;\n\t\t} catch {\n\t\t\t// Best-effort. Dead-pid reconciliation remains authoritative.\n\t\t}\n\t};\n\tprocess.once(\"exit\", closeOnExit);\n\n\tconst stop = (): void => {\n\t\tif (stopped) return;\n\t\tstopped = true;\n\t\tif (timer) clearInterval(timer);\n\t\ttimer = undefined;\n\t\tif (!preserveResumableOnExit) closeOnExit();\n\t\tprocess.off(\"exit\", closeOnExit);\n\t};\n\n\tconst persist = async (\n\t\texpected: ProcessMatrixEntry,\n\t\tnext: ProcessMatrixEntry,\n\t\tfailureContext: string,\n\t): Promise<boolean> => {\n\t\ttry {\n\t\t\tif (await writeEntryIfUnchanged(config.agentDir, expected.entryId, expected, next)) {\n\t\t\t\tentry = next;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tconst current = await readEntry(config.agentDir, expected.entryId);\n\t\t\tif (current?.pid === process.pid) entry = current;\n\t\t\telse {\n\t\t\t\tstopped = true;\n\t\t\t\tif (timer) clearInterval(timer);\n\t\t\t\ttimer = undefined;\n\t\t\t\tprocess.off(\"exit\", closeOnExit);\n\t\t\t\tconfig.onDiagnostic?.(\"process-matrix: worker entry ownership moved to a newer process generation\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconfig.onDiagnostic?.(`process-matrix: ${failureContext}: ${describeError(error)}`);\n\t\t}\n\t\treturn false;\n\t};\n\n\tconst startHealthyWatch = (): void => {\n\t\ttimer = setInterval(() => {\n\t\t\tif (ticking) return;\n\t\t\tticking = true;\n\t\t\tvoid healthyTick().finally(() => {\n\t\t\t\tticking = false;\n\t\t\t});\n\t\t}, config.settings.watcherPollMs);\n\t\ttimer.unref?.();\n\t};\n\n\tconst declaredParentIsAlive = async (): Promise<boolean> => {\n\t\t// PID liveness alone is not process identity: a reused PID could otherwise keep a worker\n\t\t// attached to an unrelated process forever. The parent session's own fresh master entry binds\n\t\t// PID to a durable identity and proves that that exact session is still heartbeating.\n\t\tif (!currentParentSessionId || !config.isProcessAlive(currentParentPid)) return false;\n\t\tconst parent = await readEntry(config.agentDir, buildEntryId(\"master\", currentParentSessionId));\n\t\tif (!parent || parent.role !== \"master\" || parent.agent.resumeContext.sessionId !== currentParentSessionId)\n\t\t\treturn false;\n\t\tif (parent.pid !== currentParentPid || parent.status !== \"running\") return false;\n\t\tconst heartbeatAt = Date.parse(parent.heartbeatAt);\n\t\tconst maxAge = config.settings.heartbeatMs * 2 + config.settings.watcherPollMs;\n\t\treturn Number.isFinite(heartbeatAt) && now() - heartbeatAt <= maxAge;\n\t};\n\n\tconst healthyTick = async (): Promise<void> => {\n\t\tif (stopped) return;\n\t\tif (!(await declaredParentIsAlive())) {\n\t\t\tawait enterWindDown();\n\t\t\treturn;\n\t\t}\n\t\t// Still healthy: also poll for a master-initiated cooperative-cleanup directive.\n\t\tconst fresh = await readEntry(config.agentDir, entry.entryId);\n\t\tif (!fresh) return;\n\t\tconst directive = pollWorkerDirective(fresh, currentParentPid, { isPidAlive: config.isProcessAlive });\n\t\tif (directive.code !== \"user_cleanup\") return;\n\t\tif (\n\t\t\t!(await persist(\n\t\t\t\tfresh,\n\t\t\t\tbeginWindDown(fresh, \"user_cleanup\", nowIso(now)),\n\t\t\t\t\"failed to write a master-requested worker wind-down\",\n\t\t\t))\n\t\t)\n\t\t\treturn;\n\t\temitRuntimeNotice(config, \"process-matrix: the parent session requested a cooperative cleanup. Winding down.\");\n\t\tstop();\n\t\tconfig.requestExit();\n\t};\n\n\tconst enterWindDown = async (): Promise<void> => {\n\t\tconst windDownAt = nowIso(now);\n\t\tconst expected = entry;\n\t\tconst resumable: ResumablePayload = { lastCode: \"resumable\", agent: structuredClone(config.agent) };\n\t\tif (expected.taskRef !== undefined) resumable.taskRef = expected.taskRef;\n\t\tif (expected.taskSummary !== undefined) resumable.taskSummary = expected.taskSummary;\n\t\tconst woundDown = markResumable(beginWindDown(expected, \"parent_lost\", windDownAt), resumable, windDownAt);\n\t\tif (!(await persist(expected, woundDown, \"failed to write worker wind-down\"))) return;\n\t\tif (timer) clearInterval(timer);\n\t\ttimer = undefined;\n\t\tpreserveResumableOnExit = true;\n\t\temitRuntimeNotice(\n\t\t\tconfig,\n\t\t\t`process-matrix: parent process (pid ${currentParentPid}) is gone. Winding down gracefully; this task is resumable.`,\n\t\t);\n\t\tstartGraceWatch();\n\t};\n\n\tconst startGraceWatch = (): void => {\n\t\tconst graceDeadline = now() + config.settings.adoptionGraceMs;\n\t\ttimer = setInterval(() => {\n\t\t\tif (ticking) return;\n\t\t\tticking = true;\n\t\t\tvoid graceTick(graceDeadline).finally(() => {\n\t\t\t\tticking = false;\n\t\t\t});\n\t\t}, config.settings.watcherPollMs);\n\t\ttimer.unref?.();\n\t};\n\n\tconst graceTick = async (graceDeadline: number): Promise<void> => {\n\t\tif (stopped) return;\n\t\tconst fresh = await readEntry(config.agentDir, entry.entryId);\n\t\tif (fresh) {\n\t\t\tconst directive = pollWorkerDirective(fresh, currentParentPid, { isPidAlive: config.isProcessAlive });\n\t\t\tif (directive.code === \"adopt\" && fresh.parentSessionId) {\n\t\t\t\t// The adopting master persists its session id with the pid. Require both on the next\n\t\t\t\t// healthy tick; accepting a pid-only adoption would reintroduce the PID-reuse bug.\n\t\t\t\tif (\n\t\t\t\t\t!(await persist(\n\t\t\t\t\t\tfresh,\n\t\t\t\t\t\tapplyAdoption(fresh, { parentPid: directive.parentPid, parentSessionId: fresh.parentSessionId }),\n\t\t\t\t\t\t\"failed to write worker adoption\",\n\t\t\t\t\t))\n\t\t\t\t)\n\t\t\t\t\treturn;\n\t\t\t\temitRuntimeNotice(\n\t\t\t\t\tconfig,\n\t\t\t\t\t`process-matrix: adopted by a new parent (pid ${directive.parentPid}). Resuming.`,\n\t\t\t\t);\n\t\t\t\tcurrentParentPid = directive.parentPid;\n\t\t\t\tcurrentParentSessionId = fresh.parentSessionId;\n\t\t\t\tpreserveResumableOnExit = false;\n\t\t\t\tif (timer) {\n\t\t\t\t\tclearInterval(timer);\n\t\t\t\t\ttimer = undefined;\n\t\t\t\t}\n\t\t\t\tstartHealthyWatch();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (directive.code === \"user_cleanup\") {\n\t\t\t\tstop();\n\t\t\t\tconfig.requestExit();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif (now() >= graceDeadline) {\n\t\t\tstop();\n\t\t\tconfig.requestExit();\n\t\t}\n\t};\n\n\tstartHealthyWatch();\n\n\treturn { stop };\n}\n"]}
@@ -16,7 +16,10 @@ export declare function buildEntryId(role: ProcessRole, sessionId: string): stri
16
16
  export declare function readEntry(agentDir: string, entryId: string): Promise<ProcessMatrixEntry | undefined>;
17
17
  export declare function listEntries(agentDir: string): Promise<ProcessMatrixEntry[]>;
18
18
  export declare function writeEntry(agentDir: string, entry: ProcessMatrixEntry): Promise<void>;
19
- /** Sync counterpart for the `process.on("exit")` best-effort master close -- see `runtime.ts`. */
20
- export declare function writeEntrySync(agentDir: string, entry: ProcessMatrixEntry): void;
19
+ /** Atomically replace one entry only when its full persisted value still equals `expected`. */
20
+ export declare function writeEntryIfUnchanged(agentDir: string, entryId: string, expected: ProcessMatrixEntry | undefined, next: ProcessMatrixEntry): Promise<boolean>;
21
+ /** Sync conditional replacement for best-effort `process.on("exit")` terminal writes. */
22
+ export declare function writeEntryIfUnchangedSync(agentDir: string, expected: ProcessMatrixEntry, next: ProcessMatrixEntry): boolean;
21
23
  export declare function removeEntry(agentDir: string, entryId: string): Promise<void>;
24
+ export declare function removeEntryIfUnchanged(agentDir: string, expected: ProcessMatrixEntry): Promise<boolean>;
22
25
  //# sourceMappingURL=store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/core/process-matrix/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAElE,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEzE;AAiBD,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAE1G;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAcjF;AAMD,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3F;AAED,kGAAkG;AAClG,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAEhF;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMlF","sourcesContent":["/**\n * Process-matrix on-disk store: one file per process (`state/process-matrix/<entryId>.json`),\n * durable across restarts and crashes (see `agent-paths.ts` -- this is machine state, not\n * transient `work/`).\n *\n * Each entry is owned by the process it describes: a master writes and heartbeats its OWN entry,\n * a worker self-registers and heartbeats its OWN entry (see `runtime.ts`'s module doc for the one\n * sanctioned, ask-gated exception during orphan adoption/cleanup). A missing or corrupt entry file\n * reads as absent -- never an error -- matching `worktree-sync/store.ts`'s store doctrine.\n */\n\nimport { promises as fsPromises } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { stateFile } from \"../agent-paths.ts\";\nimport { writeFileAtomic, writeFileAtomicSync } from \"../util/atomic-file.ts\";\nimport type { ProcessMatrixEntry, ProcessRole } from \"./codes.ts\";\n\nexport function processMatrixDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"process-matrix\");\n}\n\nexport function entryPath(agentDir: string, entryId: string): string {\n\treturn join(processMatrixDir(agentDir), `${entryId}.json`);\n}\n\n/** Stable entry identity: one entry per (role, sessionId) pair. */\nexport function buildEntryId(role: ProcessRole, sessionId: string): string {\n\treturn `${role}-${sessionId}`;\n}\n\nasync function readJsonFile<T>(filePath: string): Promise<T | undefined> {\n\tlet raw: string;\n\ttry {\n\t\traw = await fsPromises.readFile(filePath, \"utf-8\");\n\t} catch {\n\t\treturn undefined;\n\t}\n\ttry {\n\t\treturn JSON.parse(raw) as T;\n\t} catch {\n\t\t// Corrupt entry files are treated as absent -- reconcile/re-registration rebuilds them.\n\t\treturn undefined;\n\t}\n}\n\nexport async function readEntry(agentDir: string, entryId: string): Promise<ProcessMatrixEntry | undefined> {\n\treturn readJsonFile<ProcessMatrixEntry>(entryPath(agentDir, entryId));\n}\n\nexport async function listEntries(agentDir: string): Promise<ProcessMatrixEntry[]> {\n\tlet names: string[];\n\ttry {\n\t\tnames = await fsPromises.readdir(processMatrixDir(agentDir));\n\t} catch {\n\t\treturn [];\n\t}\n\tconst entries: ProcessMatrixEntry[] = [];\n\tfor (const name of names.sort()) {\n\t\tif (!name.endsWith(\".json\")) continue;\n\t\tconst entry = await readJsonFile<ProcessMatrixEntry>(join(processMatrixDir(agentDir), name));\n\t\tif (entry?.entryId) entries.push(entry);\n\t}\n\treturn entries;\n}\n\nfunction serialize(entry: ProcessMatrixEntry): string {\n\treturn `${JSON.stringify(entry, null, \"\\t\")}\\n`;\n}\n\nexport async function writeEntry(agentDir: string, entry: ProcessMatrixEntry): Promise<void> {\n\tawait writeFileAtomic(entryPath(agentDir, entry.entryId), serialize(entry));\n}\n\n/** Sync counterpart for the `process.on(\"exit\")` best-effort master close -- see `runtime.ts`. */\nexport function writeEntrySync(agentDir: string, entry: ProcessMatrixEntry): void {\n\twriteFileAtomicSync(entryPath(agentDir, entry.entryId), serialize(entry));\n}\n\nexport async function removeEntry(agentDir: string, entryId: string): Promise<void> {\n\ttry {\n\t\tawait fsPromises.rm(entryPath(agentDir, entryId), { force: true });\n\t} catch {\n\t\t// Best-effort; a missing file is already the desired end state.\n\t}\n}\n"]}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/core/process-matrix/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAiB,MAAM,YAAY,CAAC;AAoBjF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEzE;AA4ED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAG1G;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAcjF;AAUD,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3F;AAED,+FAA+F;AAC/F,wBAAsB,qBAAqB,CAC1C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,kBAAkB,GAAG,SAAS,EACxC,IAAI,EAAE,kBAAkB,GACtB,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED,yFAAyF;AACzF,wBAAgB,yBAAyB,CACxC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,kBAAkB,EAC5B,IAAI,EAAE,kBAAkB,GACtB,OAAO,CAeT;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQlF;AAED,wBAAsB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ7G","sourcesContent":["/**\n * Process-matrix on-disk store: one file per process (`state/process-matrix/<entryId>.json`),\n * durable across restarts and crashes (see `agent-paths.ts` -- this is machine state, not\n * transient `work/`).\n *\n * Each entry is owned by the process it describes: a master writes and heartbeats its OWN entry,\n * a worker self-registers and heartbeats its OWN entry (see `runtime.ts`'s module doc for the one\n * sanctioned, ask-gated exception during orphan adoption/cleanup). A missing or corrupt entry file\n * reads as absent -- never an error -- matching `worktree-sync/store.ts`'s store doctrine.\n */\n\nimport { promises as fsPromises, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport { stateFile } from \"../agent-paths.ts\";\nimport { isAgentIdentity } from \"../orchestration/agent-resume.ts\";\nimport { withFileLock, withFileLockSync, writeFileAtomic, writeFileAtomicSync } from \"../util/atomic-file.ts\";\nimport { isPlainRecord } from \"../util/value-guards.ts\";\nimport type { ProcessMatrixEntry, ProcessRole, ProcessStatus } from \"./codes.ts\";\n\nfunction isProcessStatus(value: unknown): value is ProcessStatus {\n\treturn (\n\t\tvalue === \"running\" ||\n\t\tvalue === \"winding_down\" ||\n\t\tvalue === \"resumable\" ||\n\t\tvalue === \"adopted\" ||\n\t\tvalue === \"closed\"\n\t);\n}\n\nfunction isOptionalString(value: unknown, maxLength: number): boolean {\n\treturn value === undefined || (typeof value === \"string\" && value.length <= maxLength);\n}\n\nfunction isTimestamp(value: unknown): value is string {\n\treturn typeof value === \"string\" && Number.isFinite(Date.parse(value));\n}\n\nexport function processMatrixDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"process-matrix\");\n}\n\nexport function entryPath(agentDir: string, entryId: string): string {\n\treturn join(processMatrixDir(agentDir), `${entryId}.json`);\n}\n\n/** Stable entry identity: one entry per (role, sessionId) pair. */\nexport function buildEntryId(role: ProcessRole, sessionId: string): string {\n\treturn `${role}-${sessionId}`;\n}\n\nasync function readJsonFile(filePath: string): Promise<unknown> {\n\tlet raw: string;\n\ttry {\n\t\traw = await fsPromises.readFile(filePath, \"utf-8\");\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn parseJson(raw);\n}\n\nfunction readJsonFileSync(filePath: string): unknown {\n\tlet raw: string;\n\ttry {\n\t\traw = readFileSync(filePath, \"utf-8\");\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn parseJson(raw);\n}\n\nfunction parseJson(raw: string): unknown {\n\ttry {\n\t\treturn JSON.parse(raw) as unknown;\n\t} catch {\n\t\t// Corrupt entry files are treated as absent -- reconcile/re-registration rebuilds them.\n\t\treturn undefined;\n\t}\n}\n\nfunction isProcessMatrixEntry(value: unknown): value is ProcessMatrixEntry {\n\tif (!isPlainRecord(value) || !isAgentIdentity(value.agent) || (value.role !== \"master\" && value.role !== \"worker\"))\n\t\treturn false;\n\tconst sessionId = value.agent.resumeContext.sessionId;\n\tif (\n\t\tvalue.resumable !== undefined &&\n\t\t(!isPlainRecord(value.resumable) ||\n\t\t\t!isAgentIdentity(value.resumable.agent) ||\n\t\t\t!isDeepStrictEqual(value.resumable.agent, value.agent) ||\n\t\t\t!isProcessStatus(value.resumable.lastCode) ||\n\t\t\t!isOptionalString(value.resumable.taskRef, 512) ||\n\t\t\t!isOptionalString(value.resumable.taskSummary, 2_000))\n\t)\n\t\treturn false;\n\tif (\n\t\tvalue.terminal !== undefined &&\n\t\t(!isPlainRecord(value.terminal) ||\n\t\t\t!(value.terminal.code === null || Number.isSafeInteger(value.terminal.code)) ||\n\t\t\t!(\n\t\t\t\tvalue.terminal.signal === null ||\n\t\t\t\t(typeof value.terminal.signal === \"string\" && value.terminal.signal.length <= 100)\n\t\t\t) ||\n\t\t\t!isTimestamp(value.terminal.observedAt) ||\n\t\t\t!(value.terminal.notificationDeliveredAt === undefined || isTimestamp(value.terminal.notificationDeliveredAt)))\n\t)\n\t\treturn false;\n\tif (value.terminal !== undefined && value.status !== \"closed\") return false;\n\tif (value.status === \"resumable\" && value.resumable === undefined) return false;\n\treturn (\n\t\tvalue.entryId === buildEntryId(value.role, sessionId) &&\n\t\tNumber.isSafeInteger(value.pid) &&\n\t\ttypeof value.hostname === \"string\" &&\n\t\tvalue.hostname.length <= 255 &&\n\t\tisTimestamp(value.startedAt) &&\n\t\tisTimestamp(value.heartbeatAt) &&\n\t\tisProcessStatus(value.status) &&\n\t\t(value.parentPid === undefined || (Number.isSafeInteger(value.parentPid) && Number(value.parentPid) > 0)) &&\n\t\tisOptionalString(value.parentSessionId, 512) &&\n\t\tisOptionalString(value.tmuxSession, 512) &&\n\t\t(value.tmuxPanePid === undefined || Number.isSafeInteger(value.tmuxPanePid)) &&\n\t\tisOptionalString(value.taskRef, 512) &&\n\t\tisOptionalString(value.taskSummary, 2_000)\n\t);\n}\n\nexport async function readEntry(agentDir: string, entryId: string): Promise<ProcessMatrixEntry | undefined> {\n\tconst value = await readJsonFile(entryPath(agentDir, entryId));\n\treturn isProcessMatrixEntry(value) ? value : undefined;\n}\n\nexport async function listEntries(agentDir: string): Promise<ProcessMatrixEntry[]> {\n\tlet names: string[];\n\ttry {\n\t\tnames = await fsPromises.readdir(processMatrixDir(agentDir));\n\t} catch {\n\t\treturn [];\n\t}\n\tconst entries: ProcessMatrixEntry[] = [];\n\tfor (const name of names.sort()) {\n\t\tif (!name.endsWith(\".json\")) continue;\n\t\tconst entry = await readJsonFile(join(processMatrixDir(agentDir), name));\n\t\tif (isProcessMatrixEntry(entry)) entries.push(entry);\n\t}\n\treturn entries;\n}\n\nfunction serialize(entry: ProcessMatrixEntry): string {\n\treturn `${JSON.stringify(entry, null, \"\\t\")}\\n`;\n}\n\nasync function withEntryLock<T>(agentDir: string, entryId: string, operation: () => Promise<T>): Promise<T> {\n\treturn withFileLock(entryPath(agentDir, entryId), operation);\n}\n\nexport async function writeEntry(agentDir: string, entry: ProcessMatrixEntry): Promise<void> {\n\tawait withEntryLock(agentDir, entry.entryId, async () => {\n\t\tawait writeFileAtomic(entryPath(agentDir, entry.entryId), serialize(entry));\n\t});\n}\n\n/** Atomically replace one entry only when its full persisted value still equals `expected`. */\nexport async function writeEntryIfUnchanged(\n\tagentDir: string,\n\tentryId: string,\n\texpected: ProcessMatrixEntry | undefined,\n\tnext: ProcessMatrixEntry,\n): Promise<boolean> {\n\tif (next.entryId !== entryId) {\n\t\tthrow new TypeError(`Process-matrix replacement entry '${next.entryId}' does not match '${entryId}'.`);\n\t}\n\treturn withEntryLock(agentDir, entryId, async () => {\n\t\tconst value = await readJsonFile(entryPath(agentDir, entryId));\n\t\tconst current = isProcessMatrixEntry(value) ? value : undefined;\n\t\tif (!isDeepStrictEqual(current, expected)) return false;\n\t\tawait writeFileAtomic(entryPath(agentDir, entryId), serialize(next));\n\t\treturn true;\n\t});\n}\n\n/** Sync conditional replacement for best-effort `process.on(\"exit\")` terminal writes. */\nexport function writeEntryIfUnchangedSync(\n\tagentDir: string,\n\texpected: ProcessMatrixEntry,\n\tnext: ProcessMatrixEntry,\n): boolean {\n\tif (next.entryId !== expected.entryId) {\n\t\tthrow new TypeError(`Process-matrix replacement entry '${next.entryId}' does not match '${expected.entryId}'.`);\n\t}\n\treturn withFileLockSync(\n\t\tentryPath(agentDir, expected.entryId),\n\t\t() => {\n\t\t\tconst value = readJsonFileSync(entryPath(agentDir, expected.entryId));\n\t\t\tconst current = isProcessMatrixEntry(value) ? value : undefined;\n\t\t\tif (!isDeepStrictEqual(current, expected)) return false;\n\t\t\twriteFileAtomicSync(entryPath(agentDir, expected.entryId), serialize(next));\n\t\t\treturn true;\n\t\t},\n\t\t{ retries: 0 },\n\t);\n}\n\nexport async function removeEntry(agentDir: string, entryId: string): Promise<void> {\n\tawait withEntryLock(agentDir, entryId, async () => {\n\t\ttry {\n\t\t\tawait fsPromises.rm(entryPath(agentDir, entryId), { force: true });\n\t\t} catch {\n\t\t\t// Best-effort; a missing file is already the desired end state.\n\t\t}\n\t});\n}\n\nexport async function removeEntryIfUnchanged(agentDir: string, expected: ProcessMatrixEntry): Promise<boolean> {\n\treturn withEntryLock(agentDir, expected.entryId, async () => {\n\t\tconst value = await readJsonFile(entryPath(agentDir, expected.entryId));\n\t\tconst current = isProcessMatrixEntry(value) ? value : undefined;\n\t\tif (!isDeepStrictEqual(current, expected)) return false;\n\t\tawait fsPromises.rm(entryPath(agentDir, expected.entryId), { force: true });\n\t\treturn true;\n\t});\n}\n"]}
@@ -8,10 +8,26 @@
8
8
  * sanctioned, ask-gated exception during orphan adoption/cleanup). A missing or corrupt entry file
9
9
  * reads as absent -- never an error -- matching `worktree-sync/store.ts`'s store doctrine.
10
10
  */
11
- import { promises as fsPromises } from "node:fs";
11
+ import { promises as fsPromises, readFileSync } from "node:fs";
12
12
  import { join } from "node:path";
13
+ import { isDeepStrictEqual } from "node:util";
13
14
  import { stateFile } from "../agent-paths.js";
14
- import { writeFileAtomic, writeFileAtomicSync } from "../util/atomic-file.js";
15
+ import { isAgentIdentity } from "../orchestration/agent-resume.js";
16
+ import { withFileLock, withFileLockSync, writeFileAtomic, writeFileAtomicSync } from "../util/atomic-file.js";
17
+ import { isPlainRecord } from "../util/value-guards.js";
18
+ function isProcessStatus(value) {
19
+ return (value === "running" ||
20
+ value === "winding_down" ||
21
+ value === "resumable" ||
22
+ value === "adopted" ||
23
+ value === "closed");
24
+ }
25
+ function isOptionalString(value, maxLength) {
26
+ return value === undefined || (typeof value === "string" && value.length <= maxLength);
27
+ }
28
+ function isTimestamp(value) {
29
+ return typeof value === "string" && Number.isFinite(Date.parse(value));
30
+ }
15
31
  export function processMatrixDir(agentDir) {
16
32
  return stateFile(agentDir, "process-matrix");
17
33
  }
@@ -30,6 +46,19 @@ async function readJsonFile(filePath) {
30
46
  catch {
31
47
  return undefined;
32
48
  }
49
+ return parseJson(raw);
50
+ }
51
+ function readJsonFileSync(filePath) {
52
+ let raw;
53
+ try {
54
+ raw = readFileSync(filePath, "utf-8");
55
+ }
56
+ catch {
57
+ return undefined;
58
+ }
59
+ return parseJson(raw);
60
+ }
61
+ function parseJson(raw) {
33
62
  try {
34
63
  return JSON.parse(raw);
35
64
  }
@@ -38,8 +67,47 @@ async function readJsonFile(filePath) {
38
67
  return undefined;
39
68
  }
40
69
  }
70
+ function isProcessMatrixEntry(value) {
71
+ if (!isPlainRecord(value) || !isAgentIdentity(value.agent) || (value.role !== "master" && value.role !== "worker"))
72
+ return false;
73
+ const sessionId = value.agent.resumeContext.sessionId;
74
+ if (value.resumable !== undefined &&
75
+ (!isPlainRecord(value.resumable) ||
76
+ !isAgentIdentity(value.resumable.agent) ||
77
+ !isDeepStrictEqual(value.resumable.agent, value.agent) ||
78
+ !isProcessStatus(value.resumable.lastCode) ||
79
+ !isOptionalString(value.resumable.taskRef, 512) ||
80
+ !isOptionalString(value.resumable.taskSummary, 2_000)))
81
+ return false;
82
+ if (value.terminal !== undefined &&
83
+ (!isPlainRecord(value.terminal) ||
84
+ !(value.terminal.code === null || Number.isSafeInteger(value.terminal.code)) ||
85
+ !(value.terminal.signal === null ||
86
+ (typeof value.terminal.signal === "string" && value.terminal.signal.length <= 100)) ||
87
+ !isTimestamp(value.terminal.observedAt) ||
88
+ !(value.terminal.notificationDeliveredAt === undefined || isTimestamp(value.terminal.notificationDeliveredAt))))
89
+ return false;
90
+ if (value.terminal !== undefined && value.status !== "closed")
91
+ return false;
92
+ if (value.status === "resumable" && value.resumable === undefined)
93
+ return false;
94
+ return (value.entryId === buildEntryId(value.role, sessionId) &&
95
+ Number.isSafeInteger(value.pid) &&
96
+ typeof value.hostname === "string" &&
97
+ value.hostname.length <= 255 &&
98
+ isTimestamp(value.startedAt) &&
99
+ isTimestamp(value.heartbeatAt) &&
100
+ isProcessStatus(value.status) &&
101
+ (value.parentPid === undefined || (Number.isSafeInteger(value.parentPid) && Number(value.parentPid) > 0)) &&
102
+ isOptionalString(value.parentSessionId, 512) &&
103
+ isOptionalString(value.tmuxSession, 512) &&
104
+ (value.tmuxPanePid === undefined || Number.isSafeInteger(value.tmuxPanePid)) &&
105
+ isOptionalString(value.taskRef, 512) &&
106
+ isOptionalString(value.taskSummary, 2_000));
107
+ }
41
108
  export async function readEntry(agentDir, entryId) {
42
- return readJsonFile(entryPath(agentDir, entryId));
109
+ const value = await readJsonFile(entryPath(agentDir, entryId));
110
+ return isProcessMatrixEntry(value) ? value : undefined;
43
111
  }
44
112
  export async function listEntries(agentDir) {
45
113
  let names;
@@ -54,7 +122,7 @@ export async function listEntries(agentDir) {
54
122
  if (!name.endsWith(".json"))
55
123
  continue;
56
124
  const entry = await readJsonFile(join(processMatrixDir(agentDir), name));
57
- if (entry?.entryId)
125
+ if (isProcessMatrixEntry(entry))
58
126
  entries.push(entry);
59
127
  }
60
128
  return entries;
@@ -62,19 +130,60 @@ export async function listEntries(agentDir) {
62
130
  function serialize(entry) {
63
131
  return `${JSON.stringify(entry, null, "\t")}\n`;
64
132
  }
65
- export async function writeEntry(agentDir, entry) {
66
- await writeFileAtomic(entryPath(agentDir, entry.entryId), serialize(entry));
133
+ async function withEntryLock(agentDir, entryId, operation) {
134
+ return withFileLock(entryPath(agentDir, entryId), operation);
67
135
  }
68
- /** Sync counterpart for the `process.on("exit")` best-effort master close -- see `runtime.ts`. */
69
- export function writeEntrySync(agentDir, entry) {
70
- writeFileAtomicSync(entryPath(agentDir, entry.entryId), serialize(entry));
136
+ export async function writeEntry(agentDir, entry) {
137
+ await withEntryLock(agentDir, entry.entryId, async () => {
138
+ await writeFileAtomic(entryPath(agentDir, entry.entryId), serialize(entry));
139
+ });
71
140
  }
72
- export async function removeEntry(agentDir, entryId) {
73
- try {
74
- await fsPromises.rm(entryPath(agentDir, entryId), { force: true });
141
+ /** Atomically replace one entry only when its full persisted value still equals `expected`. */
142
+ export async function writeEntryIfUnchanged(agentDir, entryId, expected, next) {
143
+ if (next.entryId !== entryId) {
144
+ throw new TypeError(`Process-matrix replacement entry '${next.entryId}' does not match '${entryId}'.`);
75
145
  }
76
- catch {
77
- // Best-effort; a missing file is already the desired end state.
146
+ return withEntryLock(agentDir, entryId, async () => {
147
+ const value = await readJsonFile(entryPath(agentDir, entryId));
148
+ const current = isProcessMatrixEntry(value) ? value : undefined;
149
+ if (!isDeepStrictEqual(current, expected))
150
+ return false;
151
+ await writeFileAtomic(entryPath(agentDir, entryId), serialize(next));
152
+ return true;
153
+ });
154
+ }
155
+ /** Sync conditional replacement for best-effort `process.on("exit")` terminal writes. */
156
+ export function writeEntryIfUnchangedSync(agentDir, expected, next) {
157
+ if (next.entryId !== expected.entryId) {
158
+ throw new TypeError(`Process-matrix replacement entry '${next.entryId}' does not match '${expected.entryId}'.`);
78
159
  }
160
+ return withFileLockSync(entryPath(agentDir, expected.entryId), () => {
161
+ const value = readJsonFileSync(entryPath(agentDir, expected.entryId));
162
+ const current = isProcessMatrixEntry(value) ? value : undefined;
163
+ if (!isDeepStrictEqual(current, expected))
164
+ return false;
165
+ writeFileAtomicSync(entryPath(agentDir, expected.entryId), serialize(next));
166
+ return true;
167
+ }, { retries: 0 });
168
+ }
169
+ export async function removeEntry(agentDir, entryId) {
170
+ await withEntryLock(agentDir, entryId, async () => {
171
+ try {
172
+ await fsPromises.rm(entryPath(agentDir, entryId), { force: true });
173
+ }
174
+ catch {
175
+ // Best-effort; a missing file is already the desired end state.
176
+ }
177
+ });
178
+ }
179
+ export async function removeEntryIfUnchanged(agentDir, expected) {
180
+ return withEntryLock(agentDir, expected.entryId, async () => {
181
+ const value = await readJsonFile(entryPath(agentDir, expected.entryId));
182
+ const current = isProcessMatrixEntry(value) ? value : undefined;
183
+ if (!isDeepStrictEqual(current, expected))
184
+ return false;
185
+ await fsPromises.rm(entryPath(agentDir, expected.entryId), { force: true });
186
+ return true;
187
+ });
79
188
  }
80
189
  //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/core/process-matrix/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Process-matrix on-disk store: one file per process (`state/process-matrix/<entryId>.json`),\n * durable across restarts and crashes (see `agent-paths.ts` -- this is machine state, not\n * transient `work/`).\n *\n * Each entry is owned by the process it describes: a master writes and heartbeats its OWN entry,\n * a worker self-registers and heartbeats its OWN entry (see `runtime.ts`'s module doc for the one\n * sanctioned, ask-gated exception during orphan adoption/cleanup). A missing or corrupt entry file\n * reads as absent -- never an error -- matching `worktree-sync/store.ts`'s store doctrine.\n */\n\nimport { promises as fsPromises } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { stateFile } from \"../agent-paths.ts\";\nimport { writeFileAtomic, writeFileAtomicSync } from \"../util/atomic-file.ts\";\nimport type { ProcessMatrixEntry, ProcessRole } from \"./codes.ts\";\n\nexport function processMatrixDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"process-matrix\");\n}\n\nexport function entryPath(agentDir: string, entryId: string): string {\n\treturn join(processMatrixDir(agentDir), `${entryId}.json`);\n}\n\n/** Stable entry identity: one entry per (role, sessionId) pair. */\nexport function buildEntryId(role: ProcessRole, sessionId: string): string {\n\treturn `${role}-${sessionId}`;\n}\n\nasync function readJsonFile<T>(filePath: string): Promise<T | undefined> {\n\tlet raw: string;\n\ttry {\n\t\traw = await fsPromises.readFile(filePath, \"utf-8\");\n\t} catch {\n\t\treturn undefined;\n\t}\n\ttry {\n\t\treturn JSON.parse(raw) as T;\n\t} catch {\n\t\t// Corrupt entry files are treated as absent -- reconcile/re-registration rebuilds them.\n\t\treturn undefined;\n\t}\n}\n\nexport async function readEntry(agentDir: string, entryId: string): Promise<ProcessMatrixEntry | undefined> {\n\treturn readJsonFile<ProcessMatrixEntry>(entryPath(agentDir, entryId));\n}\n\nexport async function listEntries(agentDir: string): Promise<ProcessMatrixEntry[]> {\n\tlet names: string[];\n\ttry {\n\t\tnames = await fsPromises.readdir(processMatrixDir(agentDir));\n\t} catch {\n\t\treturn [];\n\t}\n\tconst entries: ProcessMatrixEntry[] = [];\n\tfor (const name of names.sort()) {\n\t\tif (!name.endsWith(\".json\")) continue;\n\t\tconst entry = await readJsonFile<ProcessMatrixEntry>(join(processMatrixDir(agentDir), name));\n\t\tif (entry?.entryId) entries.push(entry);\n\t}\n\treturn entries;\n}\n\nfunction serialize(entry: ProcessMatrixEntry): string {\n\treturn `${JSON.stringify(entry, null, \"\\t\")}\\n`;\n}\n\nexport async function writeEntry(agentDir: string, entry: ProcessMatrixEntry): Promise<void> {\n\tawait writeFileAtomic(entryPath(agentDir, entry.entryId), serialize(entry));\n}\n\n/** Sync counterpart for the `process.on(\"exit\")` best-effort master close -- see `runtime.ts`. */\nexport function writeEntrySync(agentDir: string, entry: ProcessMatrixEntry): void {\n\twriteFileAtomicSync(entryPath(agentDir, entry.entryId), serialize(entry));\n}\n\nexport async function removeEntry(agentDir: string, entryId: string): Promise<void> {\n\ttry {\n\t\tawait fsPromises.rm(entryPath(agentDir, entryId), { force: true });\n\t} catch {\n\t\t// Best-effort; a missing file is already the desired end state.\n\t}\n}\n"]}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/core/process-matrix/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Process-matrix on-disk store: one file per process (`state/process-matrix/<entryId>.json`),\n * durable across restarts and crashes (see `agent-paths.ts` -- this is machine state, not\n * transient `work/`).\n *\n * Each entry is owned by the process it describes: a master writes and heartbeats its OWN entry,\n * a worker self-registers and heartbeats its OWN entry (see `runtime.ts`'s module doc for the one\n * sanctioned, ask-gated exception during orphan adoption/cleanup). A missing or corrupt entry file\n * reads as absent -- never an error -- matching `worktree-sync/store.ts`'s store doctrine.\n */\n\nimport { promises as fsPromises, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport { stateFile } from \"../agent-paths.ts\";\nimport { isAgentIdentity } from \"../orchestration/agent-resume.ts\";\nimport { withFileLock, withFileLockSync, writeFileAtomic, writeFileAtomicSync } from \"../util/atomic-file.ts\";\nimport { isPlainRecord } from \"../util/value-guards.ts\";\nimport type { ProcessMatrixEntry, ProcessRole, ProcessStatus } from \"./codes.ts\";\n\nfunction isProcessStatus(value: unknown): value is ProcessStatus {\n\treturn (\n\t\tvalue === \"running\" ||\n\t\tvalue === \"winding_down\" ||\n\t\tvalue === \"resumable\" ||\n\t\tvalue === \"adopted\" ||\n\t\tvalue === \"closed\"\n\t);\n}\n\nfunction isOptionalString(value: unknown, maxLength: number): boolean {\n\treturn value === undefined || (typeof value === \"string\" && value.length <= maxLength);\n}\n\nfunction isTimestamp(value: unknown): value is string {\n\treturn typeof value === \"string\" && Number.isFinite(Date.parse(value));\n}\n\nexport function processMatrixDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"process-matrix\");\n}\n\nexport function entryPath(agentDir: string, entryId: string): string {\n\treturn join(processMatrixDir(agentDir), `${entryId}.json`);\n}\n\n/** Stable entry identity: one entry per (role, sessionId) pair. */\nexport function buildEntryId(role: ProcessRole, sessionId: string): string {\n\treturn `${role}-${sessionId}`;\n}\n\nasync function readJsonFile(filePath: string): Promise<unknown> {\n\tlet raw: string;\n\ttry {\n\t\traw = await fsPromises.readFile(filePath, \"utf-8\");\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn parseJson(raw);\n}\n\nfunction readJsonFileSync(filePath: string): unknown {\n\tlet raw: string;\n\ttry {\n\t\traw = readFileSync(filePath, \"utf-8\");\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn parseJson(raw);\n}\n\nfunction parseJson(raw: string): unknown {\n\ttry {\n\t\treturn JSON.parse(raw) as unknown;\n\t} catch {\n\t\t// Corrupt entry files are treated as absent -- reconcile/re-registration rebuilds them.\n\t\treturn undefined;\n\t}\n}\n\nfunction isProcessMatrixEntry(value: unknown): value is ProcessMatrixEntry {\n\tif (!isPlainRecord(value) || !isAgentIdentity(value.agent) || (value.role !== \"master\" && value.role !== \"worker\"))\n\t\treturn false;\n\tconst sessionId = value.agent.resumeContext.sessionId;\n\tif (\n\t\tvalue.resumable !== undefined &&\n\t\t(!isPlainRecord(value.resumable) ||\n\t\t\t!isAgentIdentity(value.resumable.agent) ||\n\t\t\t!isDeepStrictEqual(value.resumable.agent, value.agent) ||\n\t\t\t!isProcessStatus(value.resumable.lastCode) ||\n\t\t\t!isOptionalString(value.resumable.taskRef, 512) ||\n\t\t\t!isOptionalString(value.resumable.taskSummary, 2_000))\n\t)\n\t\treturn false;\n\tif (\n\t\tvalue.terminal !== undefined &&\n\t\t(!isPlainRecord(value.terminal) ||\n\t\t\t!(value.terminal.code === null || Number.isSafeInteger(value.terminal.code)) ||\n\t\t\t!(\n\t\t\t\tvalue.terminal.signal === null ||\n\t\t\t\t(typeof value.terminal.signal === \"string\" && value.terminal.signal.length <= 100)\n\t\t\t) ||\n\t\t\t!isTimestamp(value.terminal.observedAt) ||\n\t\t\t!(value.terminal.notificationDeliveredAt === undefined || isTimestamp(value.terminal.notificationDeliveredAt)))\n\t)\n\t\treturn false;\n\tif (value.terminal !== undefined && value.status !== \"closed\") return false;\n\tif (value.status === \"resumable\" && value.resumable === undefined) return false;\n\treturn (\n\t\tvalue.entryId === buildEntryId(value.role, sessionId) &&\n\t\tNumber.isSafeInteger(value.pid) &&\n\t\ttypeof value.hostname === \"string\" &&\n\t\tvalue.hostname.length <= 255 &&\n\t\tisTimestamp(value.startedAt) &&\n\t\tisTimestamp(value.heartbeatAt) &&\n\t\tisProcessStatus(value.status) &&\n\t\t(value.parentPid === undefined || (Number.isSafeInteger(value.parentPid) && Number(value.parentPid) > 0)) &&\n\t\tisOptionalString(value.parentSessionId, 512) &&\n\t\tisOptionalString(value.tmuxSession, 512) &&\n\t\t(value.tmuxPanePid === undefined || Number.isSafeInteger(value.tmuxPanePid)) &&\n\t\tisOptionalString(value.taskRef, 512) &&\n\t\tisOptionalString(value.taskSummary, 2_000)\n\t);\n}\n\nexport async function readEntry(agentDir: string, entryId: string): Promise<ProcessMatrixEntry | undefined> {\n\tconst value = await readJsonFile(entryPath(agentDir, entryId));\n\treturn isProcessMatrixEntry(value) ? value : undefined;\n}\n\nexport async function listEntries(agentDir: string): Promise<ProcessMatrixEntry[]> {\n\tlet names: string[];\n\ttry {\n\t\tnames = await fsPromises.readdir(processMatrixDir(agentDir));\n\t} catch {\n\t\treturn [];\n\t}\n\tconst entries: ProcessMatrixEntry[] = [];\n\tfor (const name of names.sort()) {\n\t\tif (!name.endsWith(\".json\")) continue;\n\t\tconst entry = await readJsonFile(join(processMatrixDir(agentDir), name));\n\t\tif (isProcessMatrixEntry(entry)) entries.push(entry);\n\t}\n\treturn entries;\n}\n\nfunction serialize(entry: ProcessMatrixEntry): string {\n\treturn `${JSON.stringify(entry, null, \"\\t\")}\\n`;\n}\n\nasync function withEntryLock<T>(agentDir: string, entryId: string, operation: () => Promise<T>): Promise<T> {\n\treturn withFileLock(entryPath(agentDir, entryId), operation);\n}\n\nexport async function writeEntry(agentDir: string, entry: ProcessMatrixEntry): Promise<void> {\n\tawait withEntryLock(agentDir, entry.entryId, async () => {\n\t\tawait writeFileAtomic(entryPath(agentDir, entry.entryId), serialize(entry));\n\t});\n}\n\n/** Atomically replace one entry only when its full persisted value still equals `expected`. */\nexport async function writeEntryIfUnchanged(\n\tagentDir: string,\n\tentryId: string,\n\texpected: ProcessMatrixEntry | undefined,\n\tnext: ProcessMatrixEntry,\n): Promise<boolean> {\n\tif (next.entryId !== entryId) {\n\t\tthrow new TypeError(`Process-matrix replacement entry '${next.entryId}' does not match '${entryId}'.`);\n\t}\n\treturn withEntryLock(agentDir, entryId, async () => {\n\t\tconst value = await readJsonFile(entryPath(agentDir, entryId));\n\t\tconst current = isProcessMatrixEntry(value) ? value : undefined;\n\t\tif (!isDeepStrictEqual(current, expected)) return false;\n\t\tawait writeFileAtomic(entryPath(agentDir, entryId), serialize(next));\n\t\treturn true;\n\t});\n}\n\n/** Sync conditional replacement for best-effort `process.on(\"exit\")` terminal writes. */\nexport function writeEntryIfUnchangedSync(\n\tagentDir: string,\n\texpected: ProcessMatrixEntry,\n\tnext: ProcessMatrixEntry,\n): boolean {\n\tif (next.entryId !== expected.entryId) {\n\t\tthrow new TypeError(`Process-matrix replacement entry '${next.entryId}' does not match '${expected.entryId}'.`);\n\t}\n\treturn withFileLockSync(\n\t\tentryPath(agentDir, expected.entryId),\n\t\t() => {\n\t\t\tconst value = readJsonFileSync(entryPath(agentDir, expected.entryId));\n\t\t\tconst current = isProcessMatrixEntry(value) ? value : undefined;\n\t\t\tif (!isDeepStrictEqual(current, expected)) return false;\n\t\t\twriteFileAtomicSync(entryPath(agentDir, expected.entryId), serialize(next));\n\t\t\treturn true;\n\t\t},\n\t\t{ retries: 0 },\n\t);\n}\n\nexport async function removeEntry(agentDir: string, entryId: string): Promise<void> {\n\tawait withEntryLock(agentDir, entryId, async () => {\n\t\ttry {\n\t\t\tawait fsPromises.rm(entryPath(agentDir, entryId), { force: true });\n\t\t} catch {\n\t\t\t// Best-effort; a missing file is already the desired end state.\n\t\t}\n\t});\n}\n\nexport async function removeEntryIfUnchanged(agentDir: string, expected: ProcessMatrixEntry): Promise<boolean> {\n\treturn withEntryLock(agentDir, expected.entryId, async () => {\n\t\tconst value = await readJsonFile(entryPath(agentDir, expected.entryId));\n\t\tconst current = isProcessMatrixEntry(value) ? value : undefined;\n\t\tif (!isDeepStrictEqual(current, expected)) return false;\n\t\tawait fsPromises.rm(entryPath(agentDir, expected.entryId), { force: true });\n\t\treturn true;\n\t});\n}\n"]}
@@ -5,25 +5,26 @@
5
5
  * detection, wind-down, adoption, reconcile) is deterministically testable without real timers or
6
6
  * real processes. `runtime.ts` is the only caller that supplies real deps and real I/O.
7
7
  */
8
- import type { ProcessMatrixEntry, ReconcileMatrixResult, ResumablePayload, WindDownReason, WorkerDirective } from "./codes.ts";
8
+ import type { AgentIdentityContract } from "../orchestration/contracts.ts";
9
+ import type { ProcessMatrixEntry, ProcessTerminalHandoff, ReconcileMatrixResult, ResumablePayload, WindDownReason, WorkerDirective } from "./codes.ts";
9
10
  export interface BuildMasterEntryFacts {
10
- sessionId: string;
11
+ agent: AgentIdentityContract;
11
12
  pid: number;
12
13
  hostname: string;
13
14
  now: string;
14
15
  }
15
16
  export declare function buildMasterEntry(facts: BuildMasterEntryFacts): ProcessMatrixEntry;
16
17
  export interface BuildWorkerEntryFacts {
17
- sessionId: string;
18
+ agent: AgentIdentityContract;
18
19
  pid: number;
19
20
  hostname: string;
20
21
  now: string;
21
22
  parentPid: number;
22
23
  parentSessionId?: string;
23
- laneKey?: string;
24
24
  tmuxSession?: string;
25
25
  tmuxPanePid?: number;
26
26
  taskRef?: string;
27
+ taskSummary?: string;
27
28
  }
28
29
  export declare function buildWorkerEntry(facts: BuildWorkerEntryFacts): ProcessMatrixEntry;
29
30
  export declare function applyHeartbeat(entry: ProcessMatrixEntry, now: string): ProcessMatrixEntry;
@@ -40,6 +41,8 @@ export declare function detectOrphanedWorkers(entries: ProcessMatrixEntry[], dep
40
41
  export declare function beginWindDown(entry: ProcessMatrixEntry, reason: WindDownReason, now: string): ProcessMatrixEntry;
41
42
  export declare function markResumable(entry: ProcessMatrixEntry, payload: ResumablePayload, now: string): ProcessMatrixEntry;
42
43
  export declare function markClosed(entry: ProcessMatrixEntry, now: string): ProcessMatrixEntry;
44
+ export declare function markTerminal(entry: ProcessMatrixEntry, terminal: Pick<ProcessTerminalHandoff, "code" | "signal">, now: string): ProcessMatrixEntry;
45
+ export declare function markTerminalNotificationDelivered(entry: ProcessMatrixEntry, now: string): ProcessMatrixEntry;
43
46
  export interface AdoptionFacts {
44
47
  parentPid: number;
45
48
  parentSessionId?: string;
@@ -64,9 +67,9 @@ export interface ReconcileMatrixDeps {
64
67
  resumableTtlMs: number;
65
68
  }
66
69
  /**
67
- * Prune `closed` entries and any `running`/`winding_down` entry whose OWN pid is dead (a crashed
68
- * process that never reached `closed`). `resumable`/`adopted` entries are kept until they age past
69
- * `resumableTtlMs` -- they carry a payload a future session may still pick up.
70
+ * Prune `closed` entries and unrecoverable dead processes. A dead Pi worker that was interrupted
71
+ * before persisting its own resumable transition is repaired from its already-durable logical-agent
72
+ * identity. `resumable`/`adopted` entries are kept until they age past `resumableTtlMs`.
70
73
  */
71
74
  export declare function reconcileMatrix(entries: ProcessMatrixEntry[], deps: ReconcileMatrixDeps): ReconcileMatrixResult;
72
75
  //# sourceMappingURL=supervisor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../../../src/core/process-matrix/supervisor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACX,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,qBAAqB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,kBAAkB,CAWjF;AAED,MAAM,WAAW,qBAAqB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,kBAAkB,CAkBjF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAEzF;AAED,MAAM,WAAW,yBAAyB;IACzC,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACrC,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,kBAAkB,EAAE,EAC7B,IAAI,EAAE,yBAAyB,GAC7B,kBAAkB,EAAE,CAQtB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAEhH;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAEnH;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAErF;AAED,MAAM,WAAW,aAAa;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,mGAAmG;AACnG,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,aAAa,GAAG,kBAAkB,CAKpG;AAED,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAClC,UAAU,EAAE,kBAAkB,EAC9B,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,IAAI,EAAE,uBAAuB,GAC3B,eAAe,CAUjB;AAED,MAAM,WAAW,mBAAmB;IACnC,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACrC,kFAAkF;IAClF,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,IAAI,EAAE,mBAAmB,GAAG,qBAAqB,CAyB/G","sourcesContent":["/**\n * Process-matrix supervisor: PURE state-transition functions over `ProcessMatrixEntry`. Every\n * function here takes its notion of \"now\" and process liveness as an explicit argument/dependency\n * -- no `Date.now()`, no `process.kill` inside this module -- so the whole lifecycle (orphan\n * detection, wind-down, adoption, reconcile) is deterministically testable without real timers or\n * real processes. `runtime.ts` is the only caller that supplies real deps and real I/O.\n */\n\nimport type {\n\tProcessMatrixEntry,\n\tReconcileMatrixResult,\n\tResumablePayload,\n\tWindDownReason,\n\tWorkerDirective,\n} from \"./codes.ts\";\nimport { buildEntryId } from \"./store.ts\";\n\nexport interface BuildMasterEntryFacts {\n\tsessionId: string;\n\tpid: number;\n\thostname: string;\n\tnow: string;\n}\n\nexport function buildMasterEntry(facts: BuildMasterEntryFacts): ProcessMatrixEntry {\n\treturn {\n\t\tentryId: buildEntryId(\"master\", facts.sessionId),\n\t\trole: \"master\",\n\t\tpid: facts.pid,\n\t\tsessionId: facts.sessionId,\n\t\thostname: facts.hostname,\n\t\tstartedAt: facts.now,\n\t\theartbeatAt: facts.now,\n\t\tstatus: \"running\",\n\t};\n}\n\nexport interface BuildWorkerEntryFacts {\n\tsessionId: string;\n\tpid: number;\n\thostname: string;\n\tnow: string;\n\tparentPid: number;\n\tparentSessionId?: string;\n\tlaneKey?: string;\n\ttmuxSession?: string;\n\ttmuxPanePid?: number;\n\ttaskRef?: string;\n}\n\nexport function buildWorkerEntry(facts: BuildWorkerEntryFacts): ProcessMatrixEntry {\n\tconst entry: ProcessMatrixEntry = {\n\t\tentryId: buildEntryId(\"worker\", facts.sessionId),\n\t\trole: \"worker\",\n\t\tpid: facts.pid,\n\t\tsessionId: facts.sessionId,\n\t\thostname: facts.hostname,\n\t\tstartedAt: facts.now,\n\t\theartbeatAt: facts.now,\n\t\tstatus: \"running\",\n\t\tparentPid: facts.parentPid,\n\t};\n\tif (facts.parentSessionId !== undefined) entry.parentSessionId = facts.parentSessionId;\n\tif (facts.laneKey !== undefined) entry.laneKey = facts.laneKey;\n\tif (facts.tmuxSession !== undefined) entry.tmuxSession = facts.tmuxSession;\n\tif (facts.tmuxPanePid !== undefined) entry.tmuxPanePid = facts.tmuxPanePid;\n\tif (facts.taskRef !== undefined) entry.taskRef = facts.taskRef;\n\treturn entry;\n}\n\nexport function applyHeartbeat(entry: ProcessMatrixEntry, now: string): ProcessMatrixEntry {\n\treturn { ...entry, heartbeatAt: now };\n}\n\nexport interface DetectOrphanedWorkersDeps {\n\tisPidAlive: (pid: number) => boolean;\n\t/** This session's own sessionId -- never treat yourself as an orphan you found. */\n\townSessionId?: string;\n}\n\n/**\n * Worker entries whose `parentPid` is dead, excluding this session's own entry and anything\n * already `closed` (a closed worker isn't \"orphaned\", it's already done).\n */\nexport function detectOrphanedWorkers(\n\tentries: ProcessMatrixEntry[],\n\tdeps: DetectOrphanedWorkersDeps,\n): ProcessMatrixEntry[] {\n\treturn entries.filter((entry) => {\n\t\tif (entry.role !== \"worker\") return false;\n\t\tif (entry.status === \"closed\") return false;\n\t\tif (deps.ownSessionId !== undefined && entry.sessionId === deps.ownSessionId) return false;\n\t\tif (entry.parentPid === undefined) return false;\n\t\treturn !deps.isPidAlive(entry.parentPid);\n\t});\n}\n\nexport function beginWindDown(entry: ProcessMatrixEntry, reason: WindDownReason, now: string): ProcessMatrixEntry {\n\treturn { ...entry, status: \"winding_down\", windDownReason: reason, heartbeatAt: now };\n}\n\nexport function markResumable(entry: ProcessMatrixEntry, payload: ResumablePayload, now: string): ProcessMatrixEntry {\n\treturn { ...entry, status: \"resumable\", resumable: payload, heartbeatAt: now };\n}\n\nexport function markClosed(entry: ProcessMatrixEntry, now: string): ProcessMatrixEntry {\n\treturn { ...entry, status: \"closed\", heartbeatAt: now };\n}\n\nexport interface AdoptionFacts {\n\tparentPid: number;\n\tparentSessionId?: string;\n}\n\n/** Claim (or reclaim) an entry under a new parent: back to `running`, wind-down reason cleared. */\nexport function applyAdoption(entry: ProcessMatrixEntry, adoption: AdoptionFacts): ProcessMatrixEntry {\n\tconst next: ProcessMatrixEntry = { ...entry, status: \"running\", parentPid: adoption.parentPid };\n\tdelete next.windDownReason;\n\tif (adoption.parentSessionId !== undefined) next.parentSessionId = adoption.parentSessionId;\n\treturn next;\n}\n\nexport interface PollWorkerDirectiveDeps {\n\tisPidAlive: (pid: number) => boolean;\n}\n\n/**\n * A worker calls this against its OWN freshly re-read entry to learn whether a master wrote a\n * directive into it: an adoption (a new, live `parentPid` the worker didn't already know about)\n * or a cooperative cleanup request (`windDownReason === \"user_cleanup\"`). `knownParentPid` is the\n * parent the worker itself currently believes it has -- an unchanged, still-known parentPid never\n * counts as a new adoption.\n */\nexport function pollWorkerDirective(\n\tfreshEntry: ProcessMatrixEntry,\n\tknownParentPid: number | undefined,\n\tdeps: PollWorkerDirectiveDeps,\n): WorkerDirective {\n\tif (freshEntry.windDownReason === \"user_cleanup\") return { code: \"user_cleanup\" };\n\tif (\n\t\tfreshEntry.parentPid !== undefined &&\n\t\tfreshEntry.parentPid !== knownParentPid &&\n\t\tdeps.isPidAlive(freshEntry.parentPid)\n\t) {\n\t\treturn { code: \"adopt\", parentPid: freshEntry.parentPid };\n\t}\n\treturn { code: \"none\" };\n}\n\nexport interface ReconcileMatrixDeps {\n\tisPidAlive: (pid: number) => boolean;\n\t/** Epoch ms \"now\", compared against a resumable/adopted entry's `heartbeatAt`. */\n\tnow: number;\n\tresumableTtlMs: number;\n}\n\n/**\n * Prune `closed` entries and any `running`/`winding_down` entry whose OWN pid is dead (a crashed\n * process that never reached `closed`). `resumable`/`adopted` entries are kept until they age past\n * `resumableTtlMs` -- they carry a payload a future session may still pick up.\n */\nexport function reconcileMatrix(entries: ProcessMatrixEntry[], deps: ReconcileMatrixDeps): ReconcileMatrixResult {\n\tconst kept: ProcessMatrixEntry[] = [];\n\tconst prunedEntryIds: string[] = [];\n\tfor (const entry of entries) {\n\t\tif (entry.status === \"closed\") {\n\t\t\tprunedEntryIds.push(entry.entryId);\n\t\t\tcontinue;\n\t\t}\n\t\tif (entry.status === \"running\" || entry.status === \"winding_down\") {\n\t\t\tif (!deps.isPidAlive(entry.pid)) {\n\t\t\t\tprunedEntryIds.push(entry.entryId);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tkept.push(entry);\n\t\t\tcontinue;\n\t\t}\n\t\t// resumable / adopted: TTL-gated on the entry's own last heartbeat.\n\t\tconst heartbeatMs = Date.parse(entry.heartbeatAt);\n\t\tif (Number.isFinite(heartbeatMs) && deps.now - heartbeatMs > deps.resumableTtlMs) {\n\t\t\tprunedEntryIds.push(entry.entryId);\n\t\t\tcontinue;\n\t\t}\n\t\tkept.push(entry);\n\t}\n\treturn { code: \"reconciled\", kept, prunedEntryIds };\n}\n"]}
1
+ {"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../../../src/core/process-matrix/supervisor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Process-matrix supervisor: PURE state-transition functions over `ProcessMatrixEntry`. Every\n * function here takes its notion of \"now\" and process liveness as an explicit argument/dependency\n * -- no `Date.now()`, no `process.kill` inside this module -- so the whole lifecycle (orphan\n * detection, wind-down, adoption, reconcile) is deterministically testable without real timers or\n * real processes. `runtime.ts` is the only caller that supplies real deps and real I/O.\n */\n\nimport type { AgentIdentityContract } from \"../orchestration/contracts.ts\";\nimport type {\n\tProcessMatrixEntry,\n\tProcessTerminalHandoff,\n\tReconcileMatrixResult,\n\tResumablePayload,\n\tWindDownReason,\n\tWorkerDirective,\n} from \"./codes.ts\";\nimport { buildEntryId } from \"./store.ts\";\n\nexport interface BuildMasterEntryFacts {\n\tagent: AgentIdentityContract;\n\tpid: number;\n\thostname: string;\n\tnow: string;\n}\n\nexport function buildMasterEntry(facts: BuildMasterEntryFacts): ProcessMatrixEntry {\n\treturn {\n\t\tentryId: buildEntryId(\"master\", facts.agent.resumeContext.sessionId),\n\t\trole: \"master\",\n\t\tagent: structuredClone(facts.agent),\n\t\tpid: facts.pid,\n\t\thostname: facts.hostname,\n\t\tstartedAt: facts.now,\n\t\theartbeatAt: facts.now,\n\t\tstatus: \"running\",\n\t};\n}\n\nexport interface BuildWorkerEntryFacts {\n\tagent: AgentIdentityContract;\n\tpid: number;\n\thostname: string;\n\tnow: string;\n\tparentPid: number;\n\tparentSessionId?: string;\n\ttmuxSession?: string;\n\ttmuxPanePid?: number;\n\ttaskRef?: string;\n\ttaskSummary?: string;\n}\n\nexport function buildWorkerEntry(facts: BuildWorkerEntryFacts): ProcessMatrixEntry {\n\tconst entry: ProcessMatrixEntry = {\n\t\tentryId: buildEntryId(\"worker\", facts.agent.resumeContext.sessionId),\n\t\trole: \"worker\",\n\t\tagent: structuredClone(facts.agent),\n\t\tpid: facts.pid,\n\t\thostname: facts.hostname,\n\t\tstartedAt: facts.now,\n\t\theartbeatAt: facts.now,\n\t\tstatus: \"running\",\n\t\tparentPid: facts.parentPid,\n\t};\n\tif (facts.parentSessionId !== undefined) entry.parentSessionId = facts.parentSessionId;\n\tif (facts.tmuxSession !== undefined) entry.tmuxSession = facts.tmuxSession;\n\tif (facts.tmuxPanePid !== undefined) entry.tmuxPanePid = facts.tmuxPanePid;\n\tif (facts.taskRef !== undefined) entry.taskRef = facts.taskRef;\n\tif (facts.taskSummary !== undefined) entry.taskSummary = facts.taskSummary;\n\treturn entry;\n}\n\nexport function applyHeartbeat(entry: ProcessMatrixEntry, now: string): ProcessMatrixEntry {\n\treturn { ...entry, heartbeatAt: now };\n}\n\nexport interface DetectOrphanedWorkersDeps {\n\tisPidAlive: (pid: number) => boolean;\n\t/** This session's own sessionId -- never treat yourself as an orphan you found. */\n\townSessionId?: string;\n}\n\n/**\n * Worker entries whose `parentPid` is dead, excluding this session's own entry and anything\n * already `closed` (a closed worker isn't \"orphaned\", it's already done).\n */\nexport function detectOrphanedWorkers(\n\tentries: ProcessMatrixEntry[],\n\tdeps: DetectOrphanedWorkersDeps,\n): ProcessMatrixEntry[] {\n\treturn entries.filter((entry) => {\n\t\tif (entry.role !== \"worker\") return false;\n\t\tif (entry.status === \"closed\") return false;\n\t\tif (deps.ownSessionId !== undefined && entry.agent.resumeContext.sessionId === deps.ownSessionId) return false;\n\t\tif (entry.parentPid === undefined) return false;\n\t\treturn !deps.isPidAlive(entry.parentPid);\n\t});\n}\n\nexport function beginWindDown(entry: ProcessMatrixEntry, reason: WindDownReason, now: string): ProcessMatrixEntry {\n\treturn { ...entry, status: \"winding_down\", windDownReason: reason, heartbeatAt: now };\n}\n\nexport function markResumable(entry: ProcessMatrixEntry, payload: ResumablePayload, now: string): ProcessMatrixEntry {\n\treturn { ...entry, status: \"resumable\", resumable: payload, heartbeatAt: now };\n}\n\nexport function markClosed(entry: ProcessMatrixEntry, now: string): ProcessMatrixEntry {\n\treturn { ...entry, status: \"closed\", heartbeatAt: now };\n}\n\nexport function markTerminal(\n\tentry: ProcessMatrixEntry,\n\tterminal: Pick<ProcessTerminalHandoff, \"code\" | \"signal\">,\n\tnow: string,\n): ProcessMatrixEntry {\n\treturn {\n\t\t...markClosed(entry, now),\n\t\tterminal: { code: terminal.code, signal: terminal.signal, observedAt: now },\n\t};\n}\n\nexport function markTerminalNotificationDelivered(entry: ProcessMatrixEntry, now: string): ProcessMatrixEntry {\n\tif (!entry.terminal) return entry;\n\treturn { ...entry, terminal: { ...entry.terminal, notificationDeliveredAt: now } };\n}\n\nexport interface AdoptionFacts {\n\tparentPid: number;\n\tparentSessionId?: string;\n}\n\n/** Claim (or reclaim) an entry under a new parent: back to `running`, wind-down reason cleared. */\nexport function applyAdoption(entry: ProcessMatrixEntry, adoption: AdoptionFacts): ProcessMatrixEntry {\n\tconst next: ProcessMatrixEntry = { ...entry, status: \"running\", parentPid: adoption.parentPid };\n\tdelete next.windDownReason;\n\tif (adoption.parentSessionId !== undefined) next.parentSessionId = adoption.parentSessionId;\n\treturn next;\n}\n\nexport interface PollWorkerDirectiveDeps {\n\tisPidAlive: (pid: number) => boolean;\n}\n\n/**\n * A worker calls this against its OWN freshly re-read entry to learn whether a master wrote a\n * directive into it: an adoption (a new, live `parentPid` the worker didn't already know about)\n * or a cooperative cleanup request (`windDownReason === \"user_cleanup\"`). `knownParentPid` is the\n * parent the worker itself currently believes it has -- an unchanged, still-known parentPid never\n * counts as a new adoption.\n */\nexport function pollWorkerDirective(\n\tfreshEntry: ProcessMatrixEntry,\n\tknownParentPid: number | undefined,\n\tdeps: PollWorkerDirectiveDeps,\n): WorkerDirective {\n\tif (freshEntry.windDownReason === \"user_cleanup\") return { code: \"user_cleanup\" };\n\tif (\n\t\tfreshEntry.parentPid !== undefined &&\n\t\tfreshEntry.parentPid !== knownParentPid &&\n\t\tdeps.isPidAlive(freshEntry.parentPid)\n\t) {\n\t\treturn { code: \"adopt\", parentPid: freshEntry.parentPid };\n\t}\n\treturn { code: \"none\" };\n}\n\nexport interface ReconcileMatrixDeps {\n\tisPidAlive: (pid: number) => boolean;\n\t/** Epoch ms \"now\", compared against a resumable/adopted entry's `heartbeatAt`. */\n\tnow: number;\n\tresumableTtlMs: number;\n}\n\n/**\n * Prune `closed` entries and unrecoverable dead processes. A dead Pi worker that was interrupted\n * before persisting its own resumable transition is repaired from its already-durable logical-agent\n * identity. `resumable`/`adopted` entries are kept until they age past `resumableTtlMs`.\n */\nexport function reconcileMatrix(entries: ProcessMatrixEntry[], deps: ReconcileMatrixDeps): ReconcileMatrixResult {\n\tconst kept: ProcessMatrixEntry[] = [];\n\tconst prunedEntryIds: string[] = [];\n\tconst recoveredEntryIds: string[] = [];\n\tfor (const entry of entries) {\n\t\tif (entry.status === \"closed\") {\n\t\t\tconst terminalAt = Date.parse(entry.terminal?.observedAt ?? entry.heartbeatAt);\n\t\t\tconst terminalExpired = !Number.isFinite(terminalAt) || deps.now - terminalAt > deps.resumableTtlMs;\n\t\t\tif (entry.terminal && !entry.terminal.notificationDeliveredAt && !terminalExpired) kept.push(entry);\n\t\t\telse prunedEntryIds.push(entry.entryId);\n\t\t\tcontinue;\n\t\t}\n\t\tif (entry.status === \"running\" || entry.status === \"winding_down\") {\n\t\t\tif (!deps.isPidAlive(entry.pid)) {\n\t\t\t\tif (entry.role === \"worker\" && entry.agent.resumeContext.provider === \"pi\") {\n\t\t\t\t\tconst payload: ResumablePayload = {\n\t\t\t\t\t\tagent: structuredClone(entry.agent),\n\t\t\t\t\t\tlastCode: \"resumable\",\n\t\t\t\t\t};\n\t\t\t\t\tif (entry.taskRef !== undefined) payload.taskRef = entry.taskRef;\n\t\t\t\t\tif (entry.taskSummary !== undefined) payload.taskSummary = entry.taskSummary;\n\t\t\t\t\tkept.push(markResumable(entry, payload, new Date(deps.now).toISOString()));\n\t\t\t\t\trecoveredEntryIds.push(entry.entryId);\n\t\t\t\t} else {\n\t\t\t\t\tprunedEntryIds.push(entry.entryId);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tkept.push(entry);\n\t\t\tcontinue;\n\t\t}\n\t\t// resumable / adopted: TTL-gated on the entry's own last heartbeat.\n\t\tconst heartbeatMs = Date.parse(entry.heartbeatAt);\n\t\tif (!Number.isFinite(heartbeatMs) || deps.now - heartbeatMs > deps.resumableTtlMs) {\n\t\t\tprunedEntryIds.push(entry.entryId);\n\t\t\tcontinue;\n\t\t}\n\t\tkept.push(entry);\n\t}\n\treturn { code: \"reconciled\", kept, prunedEntryIds, recoveredEntryIds };\n}\n"]}