@amsterdamdatalabs/enact-operator 0.1.2

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 (377) hide show
  1. package/README.md +33 -0
  2. package/dist/index.d.ts +24 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +24 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lanes/autopilot/index.d.ts +95 -0
  7. package/dist/lanes/autopilot/index.d.ts.map +1 -0
  8. package/dist/lanes/autopilot/index.js +499 -0
  9. package/dist/lanes/autopilot/index.js.map +1 -0
  10. package/dist/lanes/ralph/index.d.ts +118 -0
  11. package/dist/lanes/ralph/index.d.ts.map +1 -0
  12. package/dist/lanes/ralph/index.js +680 -0
  13. package/dist/lanes/ralph/index.js.map +1 -0
  14. package/dist/lanes/team/index.d.ts +110 -0
  15. package/dist/lanes/team/index.d.ts.map +1 -0
  16. package/dist/lanes/team/index.js +748 -0
  17. package/dist/lanes/team/index.js.map +1 -0
  18. package/dist/lanes/team/roles.d.ts +15 -0
  19. package/dist/lanes/team/roles.d.ts.map +1 -0
  20. package/dist/lanes/team/roles.js +89 -0
  21. package/dist/lanes/team/roles.js.map +1 -0
  22. package/dist/lanes/ultrawork/burst.d.ts +69 -0
  23. package/dist/lanes/ultrawork/burst.d.ts.map +1 -0
  24. package/dist/lanes/ultrawork/burst.js +254 -0
  25. package/dist/lanes/ultrawork/burst.js.map +1 -0
  26. package/dist/lanes/ultrawork/index.d.ts +159 -0
  27. package/dist/lanes/ultrawork/index.d.ts.map +1 -0
  28. package/dist/lanes/ultrawork/index.js +919 -0
  29. package/dist/lanes/ultrawork/index.js.map +1 -0
  30. package/dist/lanes/ultrawork/phases.d.ts +57 -0
  31. package/dist/lanes/ultrawork/phases.d.ts.map +1 -0
  32. package/dist/lanes/ultrawork/phases.js +116 -0
  33. package/dist/lanes/ultrawork/phases.js.map +1 -0
  34. package/dist/mcp/activation.d.ts +5 -0
  35. package/dist/mcp/activation.d.ts.map +1 -0
  36. package/dist/mcp/activation.js +234 -0
  37. package/dist/mcp/activation.js.map +1 -0
  38. package/dist/mcp/cli.d.ts +11 -0
  39. package/dist/mcp/cli.d.ts.map +1 -0
  40. package/dist/mcp/cli.js +140 -0
  41. package/dist/mcp/cli.js.map +1 -0
  42. package/dist/mcp/continuation.d.ts +5 -0
  43. package/dist/mcp/continuation.d.ts.map +1 -0
  44. package/dist/mcp/continuation.js +360 -0
  45. package/dist/mcp/continuation.js.map +1 -0
  46. package/dist/mcp/jobs.d.ts +5 -0
  47. package/dist/mcp/jobs.d.ts.map +1 -0
  48. package/dist/mcp/jobs.js +212 -0
  49. package/dist/mcp/jobs.js.map +1 -0
  50. package/dist/mcp/laneSupport.d.ts +19 -0
  51. package/dist/mcp/laneSupport.d.ts.map +1 -0
  52. package/dist/mcp/laneSupport.js +21 -0
  53. package/dist/mcp/laneSupport.js.map +1 -0
  54. package/dist/mcp/lanes/autopilot.d.ts +5 -0
  55. package/dist/mcp/lanes/autopilot.d.ts.map +1 -0
  56. package/dist/mcp/lanes/autopilot.js +227 -0
  57. package/dist/mcp/lanes/autopilot.js.map +1 -0
  58. package/dist/mcp/lanes/ralph.d.ts +5 -0
  59. package/dist/mcp/lanes/ralph.d.ts.map +1 -0
  60. package/dist/mcp/lanes/ralph.js +392 -0
  61. package/dist/mcp/lanes/ralph.js.map +1 -0
  62. package/dist/mcp/lanes/team.d.ts +5 -0
  63. package/dist/mcp/lanes/team.d.ts.map +1 -0
  64. package/dist/mcp/lanes/team.js +413 -0
  65. package/dist/mcp/lanes/team.js.map +1 -0
  66. package/dist/mcp/lanes/ultrawork.d.ts +5 -0
  67. package/dist/mcp/lanes/ultrawork.d.ts.map +1 -0
  68. package/dist/mcp/lanes/ultrawork.js +497 -0
  69. package/dist/mcp/lanes/ultrawork.js.map +1 -0
  70. package/dist/mcp/linkage.d.ts +5 -0
  71. package/dist/mcp/linkage.d.ts.map +1 -0
  72. package/dist/mcp/linkage.js +126 -0
  73. package/dist/mcp/linkage.js.map +1 -0
  74. package/dist/mcp/planning.d.ts +5 -0
  75. package/dist/mcp/planning.d.ts.map +1 -0
  76. package/dist/mcp/planning.js +584 -0
  77. package/dist/mcp/planning.js.map +1 -0
  78. package/dist/mcp/rpcTransport.d.ts +17 -0
  79. package/dist/mcp/rpcTransport.d.ts.map +1 -0
  80. package/dist/mcp/rpcTransport.js +90 -0
  81. package/dist/mcp/rpcTransport.js.map +1 -0
  82. package/dist/mcp/schemas/ralphVerify.d.ts +32 -0
  83. package/dist/mcp/schemas/ralphVerify.d.ts.map +1 -0
  84. package/dist/mcp/schemas/ralphVerify.js +20 -0
  85. package/dist/mcp/schemas/ralphVerify.js.map +1 -0
  86. package/dist/mcp/server.d.ts +5 -0
  87. package/dist/mcp/server.d.ts.map +1 -0
  88. package/dist/mcp/server.js +176 -0
  89. package/dist/mcp/server.js.map +1 -0
  90. package/dist/mcp/system.d.ts +5 -0
  91. package/dist/mcp/system.d.ts.map +1 -0
  92. package/dist/mcp/system.js +445 -0
  93. package/dist/mcp/system.js.map +1 -0
  94. package/dist/mcp/toolFilter.d.ts +2 -0
  95. package/dist/mcp/toolFilter.d.ts.map +1 -0
  96. package/dist/mcp/toolFilter.js +2 -0
  97. package/dist/mcp/toolFilter.js.map +1 -0
  98. package/dist/mcp/toolPartitions.d.ts +20 -0
  99. package/dist/mcp/toolPartitions.d.ts.map +1 -0
  100. package/dist/mcp/toolPartitions.js +280 -0
  101. package/dist/mcp/toolPartitions.js.map +1 -0
  102. package/dist/mcp/toolRuntime.d.ts +9 -0
  103. package/dist/mcp/toolRuntime.d.ts.map +1 -0
  104. package/dist/mcp/toolRuntime.js +179 -0
  105. package/dist/mcp/toolRuntime.js.map +1 -0
  106. package/dist/mcp/workflow.d.ts +12 -0
  107. package/dist/mcp/workflow.d.ts.map +1 -0
  108. package/dist/mcp/workflow.js +723 -0
  109. package/dist/mcp/workflow.js.map +1 -0
  110. package/dist/operator/hooks/hookDispatcher.d.ts +39 -0
  111. package/dist/operator/hooks/hookDispatcher.d.ts.map +1 -0
  112. package/dist/operator/hooks/hookDispatcher.js +58 -0
  113. package/dist/operator/hooks/hookDispatcher.js.map +1 -0
  114. package/dist/operator/hooks/hookGating.d.ts +28 -0
  115. package/dist/operator/hooks/hookGating.d.ts.map +1 -0
  116. package/dist/operator/hooks/hookGating.js +61 -0
  117. package/dist/operator/hooks/hookGating.js.map +1 -0
  118. package/dist/operator/hooks/hooks.d.ts +20 -0
  119. package/dist/operator/hooks/hooks.d.ts.map +1 -0
  120. package/dist/operator/hooks/hooks.js +124 -0
  121. package/dist/operator/hooks/hooks.js.map +1 -0
  122. package/dist/operator/hooks/toolGuardHooks.d.ts +86 -0
  123. package/dist/operator/hooks/toolGuardHooks.d.ts.map +1 -0
  124. package/dist/operator/hooks/toolGuardHooks.js +163 -0
  125. package/dist/operator/hooks/toolGuardHooks.js.map +1 -0
  126. package/dist/operator/hud.d.ts +115 -0
  127. package/dist/operator/hud.d.ts.map +1 -0
  128. package/dist/operator/hud.js +229 -0
  129. package/dist/operator/hud.js.map +1 -0
  130. package/dist/operator/missions.d.ts +125 -0
  131. package/dist/operator/missions.d.ts.map +1 -0
  132. package/dist/operator/missions.js +304 -0
  133. package/dist/operator/missions.js.map +1 -0
  134. package/dist/operator/operatorCore.d.ts +11 -0
  135. package/dist/operator/operatorCore.d.ts.map +1 -0
  136. package/dist/operator/operatorCore.js +9 -0
  137. package/dist/operator/operatorCore.js.map +1 -0
  138. package/dist/operator/operatorRuntimeCore.d.ts +17 -0
  139. package/dist/operator/operatorRuntimeCore.d.ts.map +1 -0
  140. package/dist/operator/operatorRuntimeCore.js +17 -0
  141. package/dist/operator/operatorRuntimeCore.js.map +1 -0
  142. package/dist/operator/runtime.d.ts +74 -0
  143. package/dist/operator/runtime.d.ts.map +1 -0
  144. package/dist/operator/runtime.js +357 -0
  145. package/dist/operator/runtime.js.map +1 -0
  146. package/dist/shared/core/bootstrap.d.ts +16 -0
  147. package/dist/shared/core/bootstrap.d.ts.map +1 -0
  148. package/dist/shared/core/bootstrap.js +77 -0
  149. package/dist/shared/core/bootstrap.js.map +1 -0
  150. package/dist/shared/core/contract.d.ts +71 -0
  151. package/dist/shared/core/contract.d.ts.map +1 -0
  152. package/dist/shared/core/contract.js +452 -0
  153. package/dist/shared/core/contract.js.map +1 -0
  154. package/dist/shared/core/events.d.ts +57 -0
  155. package/dist/shared/core/events.d.ts.map +1 -0
  156. package/dist/shared/core/events.js +36 -0
  157. package/dist/shared/core/events.js.map +1 -0
  158. package/dist/shared/core/jobs.d.ts +46 -0
  159. package/dist/shared/core/jobs.d.ts.map +1 -0
  160. package/dist/shared/core/jobs.js +137 -0
  161. package/dist/shared/core/jobs.js.map +1 -0
  162. package/dist/shared/core/json.d.ts +12 -0
  163. package/dist/shared/core/json.d.ts.map +1 -0
  164. package/dist/shared/core/json.js +52 -0
  165. package/dist/shared/core/json.js.map +1 -0
  166. package/dist/shared/core/layoutMigration.d.ts +11 -0
  167. package/dist/shared/core/layoutMigration.d.ts.map +1 -0
  168. package/dist/shared/core/layoutMigration.js +56 -0
  169. package/dist/shared/core/layoutMigration.js.map +1 -0
  170. package/dist/shared/core/lifecycle.d.ts +61 -0
  171. package/dist/shared/core/lifecycle.d.ts.map +1 -0
  172. package/dist/shared/core/lifecycle.js +123 -0
  173. package/dist/shared/core/lifecycle.js.map +1 -0
  174. package/dist/shared/core/packagePaths.d.ts +2 -0
  175. package/dist/shared/core/packagePaths.d.ts.map +1 -0
  176. package/dist/shared/core/packagePaths.js +9 -0
  177. package/dist/shared/core/packagePaths.js.map +1 -0
  178. package/dist/shared/core/terminology.d.ts +38 -0
  179. package/dist/shared/core/terminology.d.ts.map +1 -0
  180. package/dist/shared/core/terminology.js +54 -0
  181. package/dist/shared/core/terminology.js.map +1 -0
  182. package/dist/shared/core/types.d.ts +30 -0
  183. package/dist/shared/core/types.d.ts.map +1 -0
  184. package/dist/shared/core/types.js +2 -0
  185. package/dist/shared/core/types.js.map +1 -0
  186. package/dist/shared/diagnostics/doctor.d.ts +19 -0
  187. package/dist/shared/diagnostics/doctor.d.ts.map +1 -0
  188. package/dist/shared/diagnostics/doctor.js +82 -0
  189. package/dist/shared/diagnostics/doctor.js.map +1 -0
  190. package/dist/shared/diagnostics/hostRollout.d.ts +16 -0
  191. package/dist/shared/diagnostics/hostRollout.d.ts.map +1 -0
  192. package/dist/shared/diagnostics/hostRollout.js +78 -0
  193. package/dist/shared/diagnostics/hostRollout.js.map +1 -0
  194. package/dist/shared/observability/emit.d.ts +3 -0
  195. package/dist/shared/observability/emit.d.ts.map +1 -0
  196. package/dist/shared/observability/emit.js +17 -0
  197. package/dist/shared/observability/emit.js.map +1 -0
  198. package/dist/shared/observability/testWorkspace.d.ts +4 -0
  199. package/dist/shared/observability/testWorkspace.d.ts.map +1 -0
  200. package/dist/shared/observability/testWorkspace.js +35 -0
  201. package/dist/shared/observability/testWorkspace.js.map +1 -0
  202. package/dist/shared/state/installRegistry.d.ts +22 -0
  203. package/dist/shared/state/installRegistry.d.ts.map +1 -0
  204. package/dist/shared/state/installRegistry.js +51 -0
  205. package/dist/shared/state/installRegistry.js.map +1 -0
  206. package/dist/shared/state/session.d.ts +18 -0
  207. package/dist/shared/state/session.d.ts.map +1 -0
  208. package/dist/shared/state/session.js +127 -0
  209. package/dist/shared/state/session.js.map +1 -0
  210. package/dist/shared/state/state.d.ts +16 -0
  211. package/dist/shared/state/state.d.ts.map +1 -0
  212. package/dist/shared/state/state.js +91 -0
  213. package/dist/shared/state/state.js.map +1 -0
  214. package/dist/shared/state/tasks.d.ts +113 -0
  215. package/dist/shared/state/tasks.d.ts.map +1 -0
  216. package/dist/shared/state/tasks.js +274 -0
  217. package/dist/shared/state/tasks.js.map +1 -0
  218. package/dist/shared/workflow/activation/activeSkill.d.ts +46 -0
  219. package/dist/shared/workflow/activation/activeSkill.d.ts.map +1 -0
  220. package/dist/shared/workflow/activation/activeSkill.js +158 -0
  221. package/dist/shared/workflow/activation/activeSkill.js.map +1 -0
  222. package/dist/shared/workflow/activation/gateProfiles.d.ts +26 -0
  223. package/dist/shared/workflow/activation/gateProfiles.d.ts.map +1 -0
  224. package/dist/shared/workflow/activation/gateProfiles.js +102 -0
  225. package/dist/shared/workflow/activation/gateProfiles.js.map +1 -0
  226. package/dist/shared/workflow/activation/modeMatrix.d.ts +28 -0
  227. package/dist/shared/workflow/activation/modeMatrix.d.ts.map +1 -0
  228. package/dist/shared/workflow/activation/modeMatrix.js +91 -0
  229. package/dist/shared/workflow/activation/modeMatrix.js.map +1 -0
  230. package/dist/shared/workflow/activation/skillActivation.d.ts +74 -0
  231. package/dist/shared/workflow/activation/skillActivation.d.ts.map +1 -0
  232. package/dist/shared/workflow/activation/skillActivation.js +485 -0
  233. package/dist/shared/workflow/activation/skillActivation.js.map +1 -0
  234. package/dist/shared/workflow/activation/skillVariant.d.ts +18 -0
  235. package/dist/shared/workflow/activation/skillVariant.d.ts.map +1 -0
  236. package/dist/shared/workflow/activation/skillVariant.js +44 -0
  237. package/dist/shared/workflow/activation/skillVariant.js.map +1 -0
  238. package/dist/shared/workflow/authority/authority.d.ts +34 -0
  239. package/dist/shared/workflow/authority/authority.d.ts.map +1 -0
  240. package/dist/shared/workflow/authority/authority.js +64 -0
  241. package/dist/shared/workflow/authority/authority.js.map +1 -0
  242. package/dist/shared/workflow/closure/closureManifest.d.ts +39 -0
  243. package/dist/shared/workflow/closure/closureManifest.d.ts.map +1 -0
  244. package/dist/shared/workflow/closure/closureManifest.js +62 -0
  245. package/dist/shared/workflow/closure/closureManifest.js.map +1 -0
  246. package/dist/shared/workflow/closure/closureRequirements.d.ts +12 -0
  247. package/dist/shared/workflow/closure/closureRequirements.d.ts.map +1 -0
  248. package/dist/shared/workflow/closure/closureRequirements.js +30 -0
  249. package/dist/shared/workflow/closure/closureRequirements.js.map +1 -0
  250. package/dist/shared/workflow/closure/contractParity.d.ts +24 -0
  251. package/dist/shared/workflow/closure/contractParity.d.ts.map +1 -0
  252. package/dist/shared/workflow/closure/contractParity.js +238 -0
  253. package/dist/shared/workflow/closure/contractParity.js.map +1 -0
  254. package/dist/shared/workflow/closure/contractParityContext.d.ts +8 -0
  255. package/dist/shared/workflow/closure/contractParityContext.d.ts.map +1 -0
  256. package/dist/shared/workflow/closure/contractParityContext.js +50 -0
  257. package/dist/shared/workflow/closure/contractParityContext.js.map +1 -0
  258. package/dist/shared/workflow/closure/scopeGuard.d.ts +11 -0
  259. package/dist/shared/workflow/closure/scopeGuard.d.ts.map +1 -0
  260. package/dist/shared/workflow/closure/scopeGuard.js +69 -0
  261. package/dist/shared/workflow/closure/scopeGuard.js.map +1 -0
  262. package/dist/shared/workflow/closure/ultragoalArtifact.d.ts +13 -0
  263. package/dist/shared/workflow/closure/ultragoalArtifact.d.ts.map +1 -0
  264. package/dist/shared/workflow/closure/ultragoalArtifact.js +31 -0
  265. package/dist/shared/workflow/closure/ultragoalArtifact.js.map +1 -0
  266. package/dist/shared/workflow/closure/workflowReconcile.d.ts +70 -0
  267. package/dist/shared/workflow/closure/workflowReconcile.d.ts.map +1 -0
  268. package/dist/shared/workflow/closure/workflowReconcile.js +267 -0
  269. package/dist/shared/workflow/closure/workflowReconcile.js.map +1 -0
  270. package/dist/shared/workflow/continuation/continuation.d.ts +109 -0
  271. package/dist/shared/workflow/continuation/continuation.d.ts.map +1 -0
  272. package/dist/shared/workflow/continuation/continuation.js +550 -0
  273. package/dist/shared/workflow/continuation/continuation.js.map +1 -0
  274. package/dist/shared/workflow/continuation/continuationEventReservations.d.ts +17 -0
  275. package/dist/shared/workflow/continuation/continuationEventReservations.d.ts.map +1 -0
  276. package/dist/shared/workflow/continuation/continuationEventReservations.js +88 -0
  277. package/dist/shared/workflow/continuation/continuationEventReservations.js.map +1 -0
  278. package/dist/shared/workflow/continuation/continuationFollowUp.d.ts +114 -0
  279. package/dist/shared/workflow/continuation/continuationFollowUp.d.ts.map +1 -0
  280. package/dist/shared/workflow/continuation/continuationFollowUp.js +330 -0
  281. package/dist/shared/workflow/continuation/continuationFollowUp.js.map +1 -0
  282. package/dist/shared/workflow/continuation/continuationOrchestrator.d.ts +66 -0
  283. package/dist/shared/workflow/continuation/continuationOrchestrator.d.ts.map +1 -0
  284. package/dist/shared/workflow/continuation/continuationOrchestrator.js +144 -0
  285. package/dist/shared/workflow/continuation/continuationOrchestrator.js.map +1 -0
  286. package/dist/shared/workflow/continuation/hookContinuation.d.ts +44 -0
  287. package/dist/shared/workflow/continuation/hookContinuation.d.ts.map +1 -0
  288. package/dist/shared/workflow/continuation/hookContinuation.js +85 -0
  289. package/dist/shared/workflow/continuation/hookContinuation.js.map +1 -0
  290. package/dist/shared/workflow/continuation/stopPolicy.d.ts +38 -0
  291. package/dist/shared/workflow/continuation/stopPolicy.d.ts.map +1 -0
  292. package/dist/shared/workflow/continuation/stopPolicy.js +435 -0
  293. package/dist/shared/workflow/continuation/stopPolicy.js.map +1 -0
  294. package/dist/shared/workflow/continuation/stopVerdict.d.ts +31 -0
  295. package/dist/shared/workflow/continuation/stopVerdict.d.ts.map +1 -0
  296. package/dist/shared/workflow/continuation/stopVerdict.js +98 -0
  297. package/dist/shared/workflow/continuation/stopVerdict.js.map +1 -0
  298. package/dist/shared/workflow/delegation/delegatedSession.d.ts +118 -0
  299. package/dist/shared/workflow/delegation/delegatedSession.d.ts.map +1 -0
  300. package/dist/shared/workflow/delegation/delegatedSession.js +496 -0
  301. package/dist/shared/workflow/delegation/delegatedSession.js.map +1 -0
  302. package/dist/shared/workflow/delegation/delegationPrompt.d.ts +3 -0
  303. package/dist/shared/workflow/delegation/delegationPrompt.d.ts.map +1 -0
  304. package/dist/shared/workflow/delegation/delegationPrompt.js +15 -0
  305. package/dist/shared/workflow/delegation/delegationPrompt.js.map +1 -0
  306. package/dist/shared/workflow/delegation/sessionTasks.d.ts +40 -0
  307. package/dist/shared/workflow/delegation/sessionTasks.d.ts.map +1 -0
  308. package/dist/shared/workflow/delegation/sessionTasks.js +73 -0
  309. package/dist/shared/workflow/delegation/sessionTasks.js.map +1 -0
  310. package/dist/shared/workflow/delegation/subagentRuntime.d.ts +26 -0
  311. package/dist/shared/workflow/delegation/subagentRuntime.d.ts.map +1 -0
  312. package/dist/shared/workflow/delegation/subagentRuntime.js +231 -0
  313. package/dist/shared/workflow/delegation/subagentRuntime.js.map +1 -0
  314. package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.d.ts +79 -0
  315. package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.d.ts.map +1 -0
  316. package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.js +166 -0
  317. package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.js.map +1 -0
  318. package/dist/shared/workflow/delivery/finalWave.d.ts +57 -0
  319. package/dist/shared/workflow/delivery/finalWave.d.ts.map +1 -0
  320. package/dist/shared/workflow/delivery/finalWave.js +123 -0
  321. package/dist/shared/workflow/delivery/finalWave.js.map +1 -0
  322. package/dist/shared/workflow/delivery/lifecyclePushMap.d.ts +68 -0
  323. package/dist/shared/workflow/delivery/lifecyclePushMap.d.ts.map +1 -0
  324. package/dist/shared/workflow/delivery/lifecyclePushMap.js +82 -0
  325. package/dist/shared/workflow/delivery/lifecyclePushMap.js.map +1 -0
  326. package/dist/shared/workflow/delivery/prSidecar.d.ts +7 -0
  327. package/dist/shared/workflow/delivery/prSidecar.d.ts.map +1 -0
  328. package/dist/shared/workflow/delivery/prSidecar.js +4 -0
  329. package/dist/shared/workflow/delivery/prSidecar.js.map +1 -0
  330. package/dist/shared/workflow/delivery/reviewStaleness.d.ts +37 -0
  331. package/dist/shared/workflow/delivery/reviewStaleness.d.ts.map +1 -0
  332. package/dist/shared/workflow/delivery/reviewStaleness.js +94 -0
  333. package/dist/shared/workflow/delivery/reviewStaleness.js.map +1 -0
  334. package/dist/shared/workflow/planning/hyperplan.d.ts +40 -0
  335. package/dist/shared/workflow/planning/hyperplan.d.ts.map +1 -0
  336. package/dist/shared/workflow/planning/hyperplan.js +133 -0
  337. package/dist/shared/workflow/planning/hyperplan.js.map +1 -0
  338. package/dist/shared/workflow/planning/notepad.d.ts +17 -0
  339. package/dist/shared/workflow/planning/notepad.d.ts.map +1 -0
  340. package/dist/shared/workflow/planning/notepad.js +84 -0
  341. package/dist/shared/workflow/planning/notepad.js.map +1 -0
  342. package/dist/shared/workflow/planning/planFormat.d.ts +3 -0
  343. package/dist/shared/workflow/planning/planFormat.d.ts.map +1 -0
  344. package/dist/shared/workflow/planning/planFormat.js +14 -0
  345. package/dist/shared/workflow/planning/planFormat.js.map +1 -0
  346. package/package.json +155 -0
  347. package/runtime/hooks/_continuation.mjs +2 -0
  348. package/runtime/hooks/_lib.mjs +2 -0
  349. package/runtime/hooks/_toolGuards.mjs +2 -0
  350. package/runtime/hooks/lanes/resolveSkillActivation.mjs +241 -0
  351. package/runtime/hooks/lanes/user-prompt-submit.mjs +326 -0
  352. package/runtime/hooks/layout-dir.mjs +2 -0
  353. package/runtime/hooks/lifecycle/pre-compact.mjs +121 -0
  354. package/runtime/hooks/lifecycle/session-start.mjs +356 -0
  355. package/runtime/hooks/lifecycle/stop.mjs +223 -0
  356. package/runtime/hooks/observability.mjs +2 -0
  357. package/runtime/hooks/post-tool-use-failure.mjs +5 -0
  358. package/runtime/hooks/post-tool-use.mjs +4 -0
  359. package/runtime/hooks/pre-compact.mjs +4 -0
  360. package/runtime/hooks/pre-tool-use.mjs +4 -0
  361. package/runtime/hooks/resolveSkillActivation.mjs +4 -0
  362. package/runtime/hooks/root-dir.mjs +2 -0
  363. package/runtime/hooks/session-start.mjs +4 -0
  364. package/runtime/hooks/shared/_continuation.mjs +341 -0
  365. package/runtime/hooks/shared/_lib.mjs +60 -0
  366. package/runtime/hooks/shared/_toolGuards.mjs +237 -0
  367. package/runtime/hooks/shared/config.mjs +143 -0
  368. package/runtime/hooks/shared/layout-dir.mjs +12 -0
  369. package/runtime/hooks/shared/observability.mjs +257 -0
  370. package/runtime/hooks/shared/root-dir.mjs +9 -0
  371. package/runtime/hooks/stop.mjs +4 -0
  372. package/runtime/hooks/subagent-tracker.mjs +4 -0
  373. package/runtime/hooks/subagents/subagent-tracker.mjs +106 -0
  374. package/runtime/hooks/tools/post-tool-use-failure.mjs +251 -0
  375. package/runtime/hooks/tools/post-tool-use.mjs +205 -0
  376. package/runtime/hooks/tools/pre-tool-use.mjs +268 -0
  377. package/runtime/hooks/user-prompt-submit.mjs +4 -0
@@ -0,0 +1,748 @@
1
+ import { appendFileSync, existsSync } from 'node:fs';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { execFileSync } from 'node:child_process';
4
+ import { basename } from 'node:path';
5
+ import { z } from 'zod';
6
+ import { ensureLayout, layoutPath, readJsonFile, validateJsonFile, writeJson, appendLedger, createReview, listInbox, listReviews, pushInboxItem, resolveInboxItems, updateInboxItems, updateReview, upsertInboxItem, createTask, getTask, listTasks, updateTask, canAutoClose, } from '../../operator/operatorRuntimeCore.js';
7
+ import { clearContinuationState, readContinuationState, refreshContinuationTeamSignals, touchContinuationActivity, } from '../../shared/workflow/continuation/continuation.js';
8
+ import { acknowledgeContinuationFollowUp, buildTeamMessageFollowUpDedupeKey, enqueueContinuationFollowUp, } from '../../shared/workflow/continuation/continuationFollowUp.js';
9
+ import { getRalph } from '../../lanes/ralph/index.js';
10
+ import { getUltrawork } from '../../lanes/ultrawork/index.js';
11
+ import { touchDelegatedSession, registerDelegatedSession } from '../../shared/workflow/delegation/delegatedSession.js';
12
+ const TEAM_SCHEMA_VERSION = 1;
13
+ const OperatorTeamExecutorSchema = z.object({
14
+ id: z.string(),
15
+ agentId: z.string(),
16
+ role: z.string(),
17
+ status: z.enum(['idle', 'busy', 'offline', 'stale']),
18
+ assignedTaskIds: z.array(z.string()).optional(),
19
+ pendingInjectedMessageIds: z.array(z.string()),
20
+ lastInjectedTurnMarker: z.string().nullable(),
21
+ leaseExpiresAt: z.string().nullable(),
22
+ lastHeartbeatAt: z.string().nullable(),
23
+ lastLifecycleSource: z.string().nullable().optional(),
24
+ orphanReason: z.string().nullable().optional(),
25
+ continuationId: z.string().nullable().optional(),
26
+ runtime: z.object({
27
+ backend: z.enum(['tmux', 'mock']),
28
+ sessionName: z.string().nullable(),
29
+ windowName: z.string().nullable(),
30
+ command: z.string().nullable(),
31
+ logFile: z.string(),
32
+ }),
33
+ }).transform((executor) => ({
34
+ ...executor,
35
+ assignedTaskIds: executor.assignedTaskIds ?? executor.assignedTaskIds ?? [],
36
+ }));
37
+ const OperatorTeamMessageSchema = z.object({
38
+ id: z.string(),
39
+ subject: z.string(),
40
+ body: z.string(),
41
+ kind: z.enum(['inbox', 'review', 'system']),
42
+ from: z.string().optional(),
43
+ to: z.string().optional(),
44
+ createdAt: z.string(),
45
+ });
46
+ const OperatorTeamStateSchema = z.object({
47
+ schemaVersion: z.literal(TEAM_SCHEMA_VERSION),
48
+ id: z.string(),
49
+ name: z.string(),
50
+ active: z.boolean(),
51
+ baseBranch: z.string(),
52
+ backend: z.object({
53
+ kind: z.enum(['tmux', 'mock']),
54
+ available: z.boolean(),
55
+ sessionName: z.string().nullable(),
56
+ degradedReason: z.string().optional(),
57
+ }),
58
+ executors: z.array(OperatorTeamExecutorSchema),
59
+ taskQueue: z.array(z.string()).optional(),
60
+ messages: z.array(OperatorTeamMessageSchema),
61
+ createdAt: z.string(),
62
+ updatedAt: z.string(),
63
+ }).transform((state) => ({
64
+ ...state,
65
+ taskQueue: state.taskQueue ?? state.taskQueue ?? [],
66
+ }));
67
+ function now() {
68
+ return new Date().toISOString();
69
+ }
70
+ function teamFile(root) {
71
+ return layoutPath(root, 'team', 'team.json');
72
+ }
73
+ function teamLogFile(root, executorId) {
74
+ return layoutPath(root, 'team', 'logs', `${executorId}.log`);
75
+ }
76
+ function slug(value) {
77
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '').slice(0, 32);
78
+ }
79
+ function tmuxAvailable() {
80
+ if (process.env.VITEST) {
81
+ return false;
82
+ }
83
+ try {
84
+ execFileSync('sh', ['-lc', 'command -v tmux'], { stdio: 'ignore' });
85
+ return true;
86
+ }
87
+ catch {
88
+ return false;
89
+ }
90
+ }
91
+ function ensureTmuxSession(sessionName) {
92
+ try {
93
+ execFileSync('tmux', ['has-session', '-t', sessionName], { stdio: 'ignore' });
94
+ }
95
+ catch {
96
+ execFileSync('tmux', ['new-session', '-d', '-s', sessionName, '-n', 'operator'], { stdio: 'ignore' });
97
+ }
98
+ }
99
+ function createTmuxWindow(sessionName, windowName, command) {
100
+ try {
101
+ execFileSync('tmux', ['new-window', '-t', sessionName, '-n', windowName, command], { stdio: 'ignore' });
102
+ }
103
+ catch {
104
+ // best effort — tmux session may already be gone
105
+ }
106
+ }
107
+ function autopilotActiveOnDisk(root) {
108
+ const path = layoutPath(root, 'state', 'autopilot.json');
109
+ if (!existsSync(path)) {
110
+ return false;
111
+ }
112
+ const raw = readJsonFile(path);
113
+ if (raw === undefined || raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
114
+ return false;
115
+ }
116
+ return Boolean(raw.active);
117
+ }
118
+ function teamLaneOwnsContinuation(root) {
119
+ return !getRalph(root)?.active && !getUltrawork(root)?.active && !autopilotActiveOnDisk(root);
120
+ }
121
+ function teamContinuationPayload(team) {
122
+ return {
123
+ id: team.id,
124
+ active: team.active,
125
+ taskQueue: team.taskQueue,
126
+ executors: team.executors.map((executor) => ({
127
+ pendingInjectedMessageIds: executor.pendingInjectedMessageIds,
128
+ assignedTaskIds: executor.assignedTaskIds,
129
+ })),
130
+ };
131
+ }
132
+ function reconcileExecutor(executor) {
133
+ if (executor.leaseExpiresAt && Date.parse(executor.leaseExpiresAt) < Date.now() && executor.status === 'busy') {
134
+ return { ...executor, status: 'stale' };
135
+ }
136
+ return executor;
137
+ }
138
+ function resolveRecipientExecutors(team, recipient) {
139
+ if (!recipient || recipient === 'all' || recipient === '*') {
140
+ return team.executors;
141
+ }
142
+ return team.executors.filter((executor) => executor.id === recipient
143
+ || executor.agentId === recipient
144
+ || executor.role === recipient);
145
+ }
146
+ function normalizeTeamState(state) {
147
+ if (!state)
148
+ return null;
149
+ return {
150
+ ...state,
151
+ schemaVersion: TEAM_SCHEMA_VERSION,
152
+ executors: Array.isArray(state.executors)
153
+ ? state.executors.map((executor) => {
154
+ const assignedTaskIds = Array.isArray(executor.assignedTaskIds)
155
+ ? executor.assignedTaskIds
156
+ : Array.isArray(executor.assignedTaskIds)
157
+ ? executor.assignedTaskIds
158
+ : [];
159
+ return {
160
+ ...executor,
161
+ assignedTaskIds,
162
+ pendingInjectedMessageIds: Array.isArray(executor.pendingInjectedMessageIds) ? executor.pendingInjectedMessageIds : [],
163
+ lastInjectedTurnMarker: typeof executor.lastInjectedTurnMarker === 'string' ? executor.lastInjectedTurnMarker : null,
164
+ };
165
+ })
166
+ : [],
167
+ taskQueue: Array.isArray(state.taskQueue)
168
+ ? state.taskQueue
169
+ : Array.isArray(state.taskQueue)
170
+ ? state.taskQueue
171
+ : [],
172
+ messages: Array.isArray(state.messages) ? state.messages : [],
173
+ };
174
+ }
175
+ function migrateTeamState(raw) {
176
+ if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
177
+ throw new Error('Team state must be an object.');
178
+ }
179
+ const state = raw;
180
+ const schemaVersion = typeof state.schemaVersion === 'number' ? state.schemaVersion : 0;
181
+ if (schemaVersion !== 0 && schemaVersion !== TEAM_SCHEMA_VERSION) {
182
+ throw new Error(`Unsupported team schemaVersion ${schemaVersion}.`);
183
+ }
184
+ return normalizeTeamState({
185
+ ...state,
186
+ schemaVersion: TEAM_SCHEMA_VERSION,
187
+ });
188
+ }
189
+ function load(root) {
190
+ const path = teamFile(root);
191
+ const raw = readJsonFile(path);
192
+ if (raw === undefined) {
193
+ return null;
194
+ }
195
+ return normalizeTeamState(validateJsonFile(path, migrateTeamState(raw), OperatorTeamStateSchema));
196
+ }
197
+ function save(root, state) {
198
+ const next = normalizeTeamState({ ...state, updatedAt: now() });
199
+ writeJson(teamFile(root), next);
200
+ return next;
201
+ }
202
+ export function probeTmux() {
203
+ return { available: tmuxAvailable() };
204
+ }
205
+ export function createTeam(root, name, executors, baseBranch = 'main', options) {
206
+ ensureLayout(root);
207
+ const tmuxReady = tmuxAvailable();
208
+ const sessionName = `operator-${slug(basename(root))}-${slug(name)}`;
209
+ if (tmuxReady)
210
+ ensureTmuxSession(sessionName);
211
+ const teamId = `team_${randomUUID().slice(0, 10)}`;
212
+ const state = save(root, {
213
+ schemaVersion: TEAM_SCHEMA_VERSION,
214
+ id: teamId,
215
+ name,
216
+ active: true,
217
+ baseBranch,
218
+ backend: {
219
+ kind: tmuxReady ? 'tmux' : 'mock',
220
+ available: tmuxReady,
221
+ sessionName: tmuxReady ? sessionName : null,
222
+ ...(tmuxReady ? {} : { degradedReason: 'tmux not installed, using mock runtime' }),
223
+ },
224
+ executors: executors.map((executor) => {
225
+ const ds = registerDelegatedSession(root, {
226
+ kind: 'team_executor',
227
+ externalRef: `${teamId}:${executor.id}`,
228
+ parentLane: 'team',
229
+ parentLaneId: teamId,
230
+ reuseActive: false,
231
+ metadata: { teamId, executorId: executor.id, source: 'operator_team_init' },
232
+ });
233
+ return {
234
+ id: executor.id,
235
+ role: executor.role,
236
+ agentId: executor.agentId ?? executor.id,
237
+ status: 'idle',
238
+ assignedTaskIds: [],
239
+ pendingInjectedMessageIds: [],
240
+ lastInjectedTurnMarker: null,
241
+ leaseExpiresAt: null,
242
+ lastHeartbeatAt: null,
243
+ continuationId: ds.continuationId,
244
+ runtime: {
245
+ backend: tmuxReady ? 'tmux' : 'mock',
246
+ sessionName: tmuxReady ? sessionName : null,
247
+ windowName: null,
248
+ command: null,
249
+ logFile: teamLogFile(root, executor.id),
250
+ },
251
+ };
252
+ }),
253
+ taskQueue: [],
254
+ messages: [],
255
+ createdAt: now(),
256
+ updatedAt: now(),
257
+ });
258
+ appendLedger(root, { kind: 'executor', action: 'team_init', detail: `Created team ${name} with ${executors.length} executors` });
259
+ upsertInboxItem(root, {
260
+ kind: 'system',
261
+ subject: 'Operator team initialized',
262
+ body: tmuxReady ? `tmux session ${sessionName} ready` : 'tmux missing, using mock runtime',
263
+ status: 'open',
264
+ });
265
+ clearContinuationState(root, 'team initialized', 'operator_team_init');
266
+ if (options?.initialTaskTitle?.trim()) {
267
+ queueTeamTask(root, options.initialTaskTitle.trim(), options.initialOwner ?? 'operator');
268
+ return readTeam(root) ?? state;
269
+ }
270
+ return state;
271
+ }
272
+ export function readTeam(root) {
273
+ const team = load(root);
274
+ if (!team)
275
+ return null;
276
+ return {
277
+ ...team,
278
+ executors: team.executors.map(reconcileExecutor),
279
+ };
280
+ }
281
+ export function resumeTeam(root) {
282
+ ensureLayout(root);
283
+ const state = load(root);
284
+ if (!state)
285
+ return null;
286
+ if (state.backend.available && state.backend.sessionName)
287
+ ensureTmuxSession(state.backend.sessionName);
288
+ appendLedger(root, { kind: 'executor', action: 'team_resume', detail: `Resumed team ${state.name}` });
289
+ const executors = state.executors.map((ex) => {
290
+ const e = reconcileExecutor({ ...ex });
291
+ let orphanReason = e.orphanReason ?? null;
292
+ if (e.status === 'stale') {
293
+ orphanReason = orphanReason ?? 'lease-expired-or-missed-heartbeat';
294
+ }
295
+ if (state.backend.kind === 'tmux' && !state.backend.available && e.runtime.backend === 'tmux') {
296
+ orphanReason = orphanReason ?? 'tmux-backend-unavailable';
297
+ }
298
+ return {
299
+ ...e,
300
+ lastLifecycleSource: 'operator_team_resume',
301
+ orphanReason,
302
+ };
303
+ });
304
+ const patched = { ...state, active: true, executors };
305
+ const next = save(root, patched);
306
+ for (const ex of executors) {
307
+ if (ex.continuationId) {
308
+ try {
309
+ touchDelegatedSession(root, ex.continuationId, { source: 'operator_team_resume' });
310
+ }
311
+ catch {
312
+ // executor row may predate Phase 3 registry
313
+ }
314
+ }
315
+ }
316
+ const cont = readContinuationState(root);
317
+ const orphanIds = executors.filter((e) => e.orphanReason).map((e) => e.id).sort();
318
+ const orphanExecutorContinuations = executors
319
+ .filter((e) => e.orphanReason && e.continuationId)
320
+ .map((e) => ({ executorId: e.id, continuationId: e.continuationId }));
321
+ if (orphanIds.length > 0) {
322
+ const keyPart = orphanIds.join(',');
323
+ enqueueContinuationFollowUp(root, {
324
+ sessionId: cont.lastSessionId,
325
+ dedupeKey: `followup:team-resume:${state.id}:${keyPart}`,
326
+ trigger: 'team-resume',
327
+ lane: 'team',
328
+ laneId: state.id,
329
+ prompt: `Team resumed with executor anomaly flags (${keyPart}). Inspect operator_team_status_detailed, reconcile leases or stale executors, and run operator_team_heartbeat or operator_team_spawn as needed.`,
330
+ metadata: {
331
+ orphanExecutorIds: orphanIds,
332
+ orphanExecutorContinuations,
333
+ source: 'operator_team_resume',
334
+ },
335
+ });
336
+ }
337
+ if (teamLaneOwnsContinuation(root)) {
338
+ refreshContinuationTeamSignals(root, teamContinuationPayload(next), listTasks(root), listInbox(root), 'operator_team_resume', 'team resume');
339
+ }
340
+ else {
341
+ touchContinuationActivity(root, 'operator_team_resume');
342
+ }
343
+ return next;
344
+ }
345
+ export function shutdownTeam(root) {
346
+ ensureLayout(root);
347
+ const state = load(root);
348
+ if (!state)
349
+ return null;
350
+ if (state.backend.available && state.backend.sessionName) {
351
+ try {
352
+ execFileSync('tmux', ['kill-session', '-t', state.backend.sessionName], { stdio: 'ignore' });
353
+ }
354
+ catch {
355
+ // best effort — tmux session may already be gone
356
+ }
357
+ }
358
+ appendLedger(root, { kind: 'executor', action: 'team_shutdown', detail: `Shut down team ${state.name}` });
359
+ updateInboxItems(root, (item) => item.status === 'open', 'resolved');
360
+ const next = save(root, { ...state, active: false });
361
+ clearContinuationState(root, 'team shutdown', 'operator_team_shutdown');
362
+ return next;
363
+ }
364
+ export function spawnTeamExecutor(root, executorId, command) {
365
+ ensureLayout(root);
366
+ const team = load(root);
367
+ if (!team)
368
+ return null;
369
+ const executor = team.executors.find((entry) => entry.id === executorId);
370
+ if (!executor)
371
+ return null;
372
+ const executorCommand = command ?? `printf 'Operator executor ${executorId} ready\n'; while true; do sleep 3600; done`;
373
+ if (team.backend.available && team.backend.sessionName) {
374
+ createTmuxWindow(team.backend.sessionName, executorId, executorCommand);
375
+ executor.runtime.windowName = executorId;
376
+ }
377
+ executor.runtime.command = executorCommand;
378
+ executor.lastHeartbeatAt = now();
379
+ appendExecutorLog(root, executorId, `spawn ${executorCommand}`);
380
+ appendLedger(root, { kind: 'executor', action: 'executor_spawn', detail: `Spawned executor ${executorId}`, executorId });
381
+ return save(root, team);
382
+ }
383
+ export function appendExecutorLog(root, executorId, line) {
384
+ ensureLayout(root);
385
+ appendFileSync(teamLogFile(root, executorId), `${now()} ${line}\n`, 'utf8');
386
+ }
387
+ export function enqueueTeamTask(root, taskId) {
388
+ ensureLayout(root);
389
+ const team = load(root);
390
+ if (!team || team.taskQueue.includes(taskId))
391
+ return team;
392
+ team.taskQueue.push(taskId);
393
+ updateTask(root, taskId, { status: 'queued' });
394
+ appendLedger(root, { kind: 'task', action: 'task_enqueued', detail: `Queued ${taskId}`, taskId });
395
+ const next = save(root, team);
396
+ clearContinuationState(root, `team queued ${taskId}`, 'operator_team_queue');
397
+ return next;
398
+ }
399
+ export function claimTeamTask(root, taskId, executorId) {
400
+ ensureLayout(root);
401
+ const team = load(root);
402
+ if (!team)
403
+ return null;
404
+ const executor = team.executors.find((entry) => entry.id === executorId);
405
+ if (!executor || !team.taskQueue.includes(taskId))
406
+ return null;
407
+ executor.status = 'busy';
408
+ if (!executor.assignedTaskIds.includes(taskId)) {
409
+ executor.assignedTaskIds.push(taskId);
410
+ }
411
+ executor.lastHeartbeatAt = now();
412
+ executor.leaseExpiresAt = new Date(Date.now() + 20 * 60 * 1000).toISOString();
413
+ team.taskQueue = team.taskQueue.filter((entry) => entry !== taskId);
414
+ updateTask(root, taskId, { owner: executorId, status: 'in_progress', claimedAt: now(), reviewStatus: 'none' }, executorId);
415
+ appendExecutorLog(root, executorId, `claim ${taskId}`);
416
+ appendLedger(root, { kind: 'task', action: 'task_claim', detail: `Executor ${executorId} claimed ${taskId}`, executorId, taskId });
417
+ const next = save(root, team);
418
+ clearContinuationState(root, `team claimed ${taskId}`, 'operator_team_claim');
419
+ return next;
420
+ }
421
+ export function completeTeamTask(root, taskId, executorId, result) {
422
+ ensureLayout(root);
423
+ const team = load(root);
424
+ if (!team)
425
+ return null;
426
+ const executor = team.executors.find((entry) => entry.id === executorId);
427
+ if (!executor || !executor.assignedTaskIds.includes(taskId))
428
+ return null;
429
+ executor.status = 'idle';
430
+ executor.assignedTaskIds = executor.assignedTaskIds.filter((entry) => entry !== taskId);
431
+ executor.lastHeartbeatAt = now();
432
+ executor.leaseExpiresAt = null;
433
+ appendExecutorLog(root, executorId, `complete ${taskId}: ${result}`);
434
+ const wiBeforeComplete = getTask(root, taskId);
435
+ const previousStatus = wiBeforeComplete?.status ?? 'in_progress';
436
+ updateTask(root, taskId, {
437
+ status: 'review',
438
+ result,
439
+ reviewStatus: 'pending',
440
+ notes: [...(wiBeforeComplete?.notes ?? []), result],
441
+ }, executorId);
442
+ createReview(root, { taskId, reviewer: 'reviewer', summary: result });
443
+ pushInboxItem(root, {
444
+ kind: 'review',
445
+ subject: `Review requested for ${taskId}`,
446
+ body: result,
447
+ taskId,
448
+ from: executorId,
449
+ to: 'reviewer',
450
+ });
451
+ appendLedger(root, { kind: 'task', action: 'task_complete', detail: `Executor ${executorId} completed ${taskId}`, executorId, taskId });
452
+ const next = save(root, team);
453
+ clearContinuationState(root, `team completed ${taskId}`, 'operator_team_complete');
454
+ return next;
455
+ }
456
+ export function recordTeamReview(root, input) {
457
+ ensureLayout(root);
458
+ const team = load(root);
459
+ if (!team)
460
+ return null;
461
+ const taskId = input.taskId;
462
+ if (!taskId) {
463
+ throw new Error('recordTeamReview: taskId is required');
464
+ }
465
+ const existing = listReviews(root).find((review) => review.taskId === taskId && review.status === 'pending');
466
+ if (existing) {
467
+ updateReview(root, existing.id, {
468
+ reviewer: input.reviewer,
469
+ status: input.status,
470
+ summary: input.notes,
471
+ notes: [...existing.notes, input.notes],
472
+ });
473
+ }
474
+ else {
475
+ createReview(root, {
476
+ taskId,
477
+ reviewer: input.reviewer,
478
+ status: input.status,
479
+ summary: input.notes,
480
+ notes: [input.notes],
481
+ });
482
+ }
483
+ if (input.status === 'approved') {
484
+ const wi = getTask(root, taskId);
485
+ if (!wi) {
486
+ throw new Error(`recordTeamReview: Task ${taskId} not found — cannot auto-complete on reviewer approval.`);
487
+ }
488
+ if (!canAutoClose(wi)) {
489
+ // Cross-repo or Epic — defer auto-complete; emit ledger entry.
490
+ // Stop-policy §I4 and closure-policy coercion already enforce this; this is defense-in-depth.
491
+ appendLedger(root, {
492
+ kind: 'task_close_deferred',
493
+ action: 'team_review_approved_no_autoclose',
494
+ detail: `Team reviewer approved task "${taskId}" but auto-close is blocked (closureScope=${wi.closureScope ?? 'undefined'}, kind=${wi.kind ?? 'undefined'}). Operator must call operator_task_acknowledge_close to record manual close.`,
495
+ metadata: { taskId, closureScope: wi.closureScope, kind: wi.kind, reason: 'cross-repo-manual-close' },
496
+ });
497
+ updateTask(root, taskId, { reviewStatus: 'approved' }, input.reviewer);
498
+ }
499
+ else {
500
+ updateTask(root, taskId, { status: 'completed', reviewStatus: 'approved', completedAt: now() }, input.reviewer);
501
+ }
502
+ resolveInboxItems(root, taskId);
503
+ }
504
+ else if (input.status === 'changes_requested') {
505
+ updateTask(root, taskId, {
506
+ status: 'blocked',
507
+ reviewStatus: 'changes_requested',
508
+ blockers: [...(getTask(root, taskId)?.blockers ?? []), input.notes],
509
+ }, input.reviewer);
510
+ }
511
+ else {
512
+ updateTask(root, taskId, { status: 'review', reviewStatus: 'pending' }, input.reviewer);
513
+ }
514
+ team.messages.push({
515
+ id: `msg_${randomUUID().slice(0, 10)}`,
516
+ subject: `Review ${input.status}`,
517
+ body: input.notes,
518
+ kind: 'review',
519
+ from: input.reviewer,
520
+ createdAt: now(),
521
+ });
522
+ appendLedger(root, {
523
+ kind: 'review',
524
+ action: `review_${input.status}`,
525
+ detail: `${input.reviewer} marked ${input.taskId} as ${input.status}`,
526
+ actor: input.reviewer,
527
+ taskId: input.taskId,
528
+ });
529
+ const next = save(root, team);
530
+ clearContinuationState(root, `team review ${input.status} for ${input.taskId}`, 'operator_team_review');
531
+ return next;
532
+ }
533
+ export function pushTeamMessage(root, input) {
534
+ ensureLayout(root);
535
+ const team = load(root);
536
+ if (!team)
537
+ return null;
538
+ const message = {
539
+ id: `msg_${randomUUID().slice(0, 10)}`,
540
+ createdAt: now(),
541
+ ...input,
542
+ };
543
+ team.messages.push(message);
544
+ const recipients = resolveRecipientExecutors(team, input.to);
545
+ for (const executor of recipients) {
546
+ if (!executor.pendingInjectedMessageIds.includes(message.id)) {
547
+ executor.pendingInjectedMessageIds.push(message.id);
548
+ }
549
+ executor.lastInjectedTurnMarker = message.id;
550
+ }
551
+ pushInboxItem(root, {
552
+ kind: input.kind === 'review' ? 'review' : 'inbox',
553
+ subject: input.subject,
554
+ body: input.body,
555
+ from: input.from,
556
+ to: input.to,
557
+ });
558
+ appendLedger(root, {
559
+ kind: 'executor',
560
+ action: 'team_message',
561
+ detail: `${input.subject}: ${input.body}`,
562
+ metadata: {
563
+ messageId: message.id,
564
+ pendingRecipientIds: recipients.map((executor) => executor.id),
565
+ },
566
+ });
567
+ const next = save(root, team);
568
+ const cont = readContinuationState(root);
569
+ const continuationIds = recipients
570
+ .map((executor) => executor.continuationId)
571
+ .filter((id) => typeof id === 'string' && id.length > 0);
572
+ enqueueContinuationFollowUp(root, {
573
+ sessionId: cont.lastSessionId,
574
+ dedupeKey: buildTeamMessageFollowUpDedupeKey(team.id, message.id),
575
+ trigger: 'team-message',
576
+ lane: 'team',
577
+ laneId: team.id,
578
+ prompt: `Pending injected team message "${message.id}" (${input.subject}): acknowledge with operator_team_message_ack once the executor has applied it.`,
579
+ metadata: {
580
+ teamMessageId: message.id,
581
+ teamId: team.id,
582
+ source: 'operator_team_message',
583
+ ...(continuationIds.length > 0 ? { continuationIds } : {}),
584
+ },
585
+ });
586
+ if (teamLaneOwnsContinuation(root)) {
587
+ refreshContinuationTeamSignals(root, teamContinuationPayload(next), listTasks(root), listInbox(root), 'operator_team_message', `team message ${message.id}`);
588
+ }
589
+ else {
590
+ touchContinuationActivity(root, 'operator_team_message');
591
+ }
592
+ return next;
593
+ }
594
+ export function acknowledgeTeamMessage(root, executorId, messageId) {
595
+ ensureLayout(root);
596
+ const team = load(root);
597
+ if (!team)
598
+ return null;
599
+ const executor = team.executors.find((entry) => entry.id === executorId);
600
+ if (!executor)
601
+ return null;
602
+ executor.pendingInjectedMessageIds = executor.pendingInjectedMessageIds.filter((id) => id !== messageId);
603
+ if (executor.lastInjectedTurnMarker === messageId) {
604
+ executor.lastInjectedTurnMarker = executor.pendingInjectedMessageIds.at(-1) ?? null;
605
+ }
606
+ const message = team.messages.find((entry) => entry.id === messageId);
607
+ if (message) {
608
+ updateInboxItems(root, (item) => item.status === 'open'
609
+ && item.subject === message.subject
610
+ && item.body === message.body
611
+ && item.from === message.from
612
+ && item.to === message.to
613
+ && item.kind === (message.kind === 'review' ? 'review' : 'inbox'), 'acknowledged');
614
+ }
615
+ appendLedger(root, {
616
+ kind: 'executor',
617
+ action: 'team_message_ack',
618
+ detail: `${executorId} acknowledged ${messageId}`,
619
+ executorId,
620
+ metadata: { messageId },
621
+ });
622
+ acknowledgeContinuationFollowUp(root, {
623
+ dedupeKey: buildTeamMessageFollowUpDedupeKey(team.id, messageId),
624
+ reason: `executor ${executorId} acknowledged ${messageId}`,
625
+ source: 'operator_team_message_ack',
626
+ });
627
+ const next = save(root, team);
628
+ if (teamLaneOwnsContinuation(root)) {
629
+ refreshContinuationTeamSignals(root, teamContinuationPayload(next), listTasks(root), listInbox(root), 'operator_team_message_ack', `team message ack ${messageId}`);
630
+ }
631
+ else {
632
+ touchContinuationActivity(root, 'operator_team_message_ack');
633
+ }
634
+ return next;
635
+ }
636
+ export function readTeamLogs(root, executorId, limit = 50) {
637
+ try {
638
+ // best effort — log file may not yet exist if executor has never been active
639
+ return execFileSync('sh', ['-lc', `tail -n ${limit} "${teamLogFile(root, executorId)}"`], {
640
+ encoding: 'utf8',
641
+ stdio: ['ignore', 'pipe', 'ignore'],
642
+ })
643
+ .trim()
644
+ .split('\n')
645
+ .filter(Boolean);
646
+ }
647
+ catch {
648
+ return [];
649
+ }
650
+ }
651
+ export function readTeamInbox(root) {
652
+ return listInbox(root);
653
+ }
654
+ export function listTeamTasks(root, filters = {}) {
655
+ return listTasks(root).filter((task) => {
656
+ if (task.kind !== 'team')
657
+ return false;
658
+ if (filters.status && task.status !== filters.status)
659
+ return false;
660
+ if (filters.owner && task.owner !== filters.owner)
661
+ return false;
662
+ return true;
663
+ });
664
+ }
665
+ export async function awaitTeamState(root, options = {}) {
666
+ const timeoutMs = options.timeoutMs ?? 5_000;
667
+ const pollMs = options.pollMs ?? 250;
668
+ const deadline = Date.now() + timeoutMs;
669
+ while (Date.now() < deadline) {
670
+ const team = readTeam(root);
671
+ if (!team)
672
+ return null;
673
+ if (!options.taskId)
674
+ return team;
675
+ const task = getTask(root, options.taskId);
676
+ if (task && ['review', 'completed', 'blocked', 'failed'].includes(task.status)) {
677
+ return team;
678
+ }
679
+ await new Promise((resolve) => setTimeout(resolve, pollMs));
680
+ }
681
+ return readTeam(root);
682
+ }
683
+ export function queueTeamTask(root, title, owner = 'operator') {
684
+ ensureLayout(root);
685
+ const task = createTask(root, { title, kind: 'team', priority: 'high' });
686
+ enqueueTeamTask(root, task.id);
687
+ pushInboxItem(root, {
688
+ kind: 'inbox',
689
+ subject: 'Task queued',
690
+ body: `${title} queued by ${owner}`,
691
+ taskId: task.id,
692
+ from: owner,
693
+ });
694
+ return task;
695
+ }
696
+ /**
697
+ * Reads executor.pendingInjectedMessageIds, resolves the corresponding messages
698
+ * from team.messages, and returns them as structured content to be prepended to
699
+ * the member's next prompt.
700
+ *
701
+ * Called at turn-build time to surface any pending mailbox messages before
702
+ * the executor's task payload.
703
+ */
704
+ export function buildMemberTurnInjection(executor, team) {
705
+ if (executor.pendingInjectedMessageIds.length === 0) {
706
+ return { messages: [] };
707
+ }
708
+ const pendingSet = new Set(executor.pendingInjectedMessageIds);
709
+ const messages = team.messages
710
+ .filter((msg) => pendingSet.has(msg.id))
711
+ .map((msg) => ({
712
+ id: msg.id,
713
+ subject: msg.subject,
714
+ body: msg.body,
715
+ kind: msg.kind,
716
+ from: msg.from,
717
+ }));
718
+ return { messages };
719
+ }
720
+ export function heartbeatTeamExecutor(root, executorId, note) {
721
+ ensureLayout(root);
722
+ const state = load(root);
723
+ if (!state)
724
+ return null;
725
+ const executors = state.executors.map((executor) => {
726
+ if (executor.id !== executorId)
727
+ return executor;
728
+ appendExecutorLog(root, executorId, `heartbeat${note ? ` ${note}` : ''}`);
729
+ return {
730
+ ...executor,
731
+ lastHeartbeatAt: now(),
732
+ status: (executor.status === 'stale' ? (executor.assignedTaskIds.length ? 'busy' : 'idle') : executor.status),
733
+ };
734
+ });
735
+ appendLedger(root, { kind: 'executor', action: 'executor_heartbeat', detail: `Heartbeat from ${executorId}`, executorId });
736
+ const next = save(root, { ...state, executors });
737
+ const hb = next.executors.find((e) => e.id === executorId);
738
+ if (hb?.continuationId) {
739
+ try {
740
+ touchDelegatedSession(root, hb.continuationId, { source: 'operator_team_heartbeat' });
741
+ }
742
+ catch {
743
+ // executor may predate delegated-session registry
744
+ }
745
+ }
746
+ return next;
747
+ }
748
+ //# sourceMappingURL=index.js.map