@agimon-ai/doompi-team 0.0.1-alpha.0

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 (520) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +46 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.cjs +1 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.mjs +1 -0
  5. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateMetadata.cjs +1 -0
  6. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateMetadata.mjs +1 -0
  7. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateParam.cjs +1 -0
  8. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateParam.mjs +1 -0
  9. package/dist/_virtual/_rolldown/runtime.cjs +1 -0
  10. package/dist/_virtual/_rolldown/runtime.mjs +1 -0
  11. package/dist/agents/discovery.cjs +2 -0
  12. package/dist/agents/discovery.cjs.map +1 -0
  13. package/dist/agents/discovery.mjs +2 -0
  14. package/dist/agents/discovery.mjs.map +1 -0
  15. package/dist/agents/frontmatter.cjs +10 -0
  16. package/dist/agents/frontmatter.cjs.map +1 -0
  17. package/dist/agents/frontmatter.mjs +10 -0
  18. package/dist/agents/frontmatter.mjs.map +1 -0
  19. package/dist/agents/loader.cjs +2 -0
  20. package/dist/agents/loader.cjs.map +1 -0
  21. package/dist/agents/loader.mjs +2 -0
  22. package/dist/agents/loader.mjs.map +1 -0
  23. package/dist/agents/memory.cjs +3 -0
  24. package/dist/agents/memory.cjs.map +1 -0
  25. package/dist/agents/memory.mjs +3 -0
  26. package/dist/agents/memory.mjs.map +1 -0
  27. package/dist/agents/projectRoot.cjs +2 -0
  28. package/dist/agents/projectRoot.cjs.map +1 -0
  29. package/dist/agents/projectRoot.mjs +2 -0
  30. package/dist/agents/projectRoot.mjs.map +1 -0
  31. package/dist/agents/settings.cjs +2 -0
  32. package/dist/agents/settings.cjs.map +1 -0
  33. package/dist/agents/settings.mjs +2 -0
  34. package/dist/agents/settings.mjs.map +1 -0
  35. package/dist/agents/skills.cjs +0 -0
  36. package/dist/agents/skills.cjs.map +1 -0
  37. package/dist/agents/skills.mjs +5 -0
  38. package/dist/agents/skills.mjs.map +1 -0
  39. package/dist/agents/types.d.cts +121 -0
  40. package/dist/agents/types.d.cts.map +1 -0
  41. package/dist/agents/types.d.mts +121 -0
  42. package/dist/agents/types.d.mts.map +1 -0
  43. package/dist/api/backgroundWork.cjs +1 -0
  44. package/dist/api/backgroundWork.d.cts +2 -0
  45. package/dist/api/backgroundWork.d.mts +2 -0
  46. package/dist/api/backgroundWork.mjs +1 -0
  47. package/dist/api/capabilityCeiling.cjs +1 -0
  48. package/dist/api/capabilityCeiling.d.cts +3 -0
  49. package/dist/api/capabilityCeiling.d.mts +3 -0
  50. package/dist/api/capabilityCeiling.mjs +2 -0
  51. package/dist/api/capabilityCeiling.mjs.map +1 -0
  52. package/dist/api/delegation.cjs +1 -0
  53. package/dist/api/delegation.d.cts +2 -0
  54. package/dist/api/delegation.d.mts +2 -0
  55. package/dist/api/delegation.mjs +1 -0
  56. package/dist/api/teamSnapshot.cjs +1 -0
  57. package/dist/api/teamSnapshot.d.cts +2 -0
  58. package/dist/api/teamSnapshot.d.mts +2 -0
  59. package/dist/api/teamSnapshot.mjs +2 -0
  60. package/dist/api/teamSnapshot.mjs.map +1 -0
  61. package/dist/container/bindOrRebind.cjs +2 -0
  62. package/dist/container/bindOrRebind.cjs.map +1 -0
  63. package/dist/container/bindOrRebind.mjs +2 -0
  64. package/dist/container/bindOrRebind.mjs.map +1 -0
  65. package/dist/container/globalBridge.cjs +2 -0
  66. package/dist/container/globalBridge.cjs.map +1 -0
  67. package/dist/container/globalBridge.d.cts +19 -0
  68. package/dist/container/globalBridge.d.cts.map +1 -0
  69. package/dist/container/globalBridge.d.mts +19 -0
  70. package/dist/container/globalBridge.d.mts.map +1 -0
  71. package/dist/container/globalBridge.mjs +2 -0
  72. package/dist/container/globalBridge.mjs.map +1 -0
  73. package/dist/container/index.cjs +2 -0
  74. package/dist/container/index.cjs.map +1 -0
  75. package/dist/container/index.d.cts +38 -0
  76. package/dist/container/index.d.cts.map +1 -0
  77. package/dist/container/index.d.mts +38 -0
  78. package/dist/container/index.d.mts.map +1 -0
  79. package/dist/container/index.mjs +2 -0
  80. package/dist/container/index.mjs.map +1 -0
  81. package/dist/container/modules/agents.cjs +2 -0
  82. package/dist/container/modules/agents.cjs.map +1 -0
  83. package/dist/container/modules/agents.d.cts +1 -0
  84. package/dist/container/modules/agents.d.mts +1 -0
  85. package/dist/container/modules/agents.mjs +2 -0
  86. package/dist/container/modules/agents.mjs.map +1 -0
  87. package/dist/container/modules/core.cjs +2 -0
  88. package/dist/container/modules/core.cjs.map +1 -0
  89. package/dist/container/modules/core.d.cts +1 -0
  90. package/dist/container/modules/core.d.mts +1 -0
  91. package/dist/container/modules/core.mjs +2 -0
  92. package/dist/container/modules/core.mjs.map +1 -0
  93. package/dist/container/modules/extensions.cjs +2 -0
  94. package/dist/container/modules/extensions.cjs.map +1 -0
  95. package/dist/container/modules/extensions.mjs +2 -0
  96. package/dist/container/modules/extensions.mjs.map +1 -0
  97. package/dist/container/modules/intercom.cjs +2 -0
  98. package/dist/container/modules/intercom.cjs.map +1 -0
  99. package/dist/container/modules/intercom.mjs +2 -0
  100. package/dist/container/modules/intercom.mjs.map +1 -0
  101. package/dist/container/modules/runs.cjs +2 -0
  102. package/dist/container/modules/runs.cjs.map +1 -0
  103. package/dist/container/modules/runs.mjs +2 -0
  104. package/dist/container/modules/runs.mjs.map +1 -0
  105. package/dist/container/types.cjs +2 -0
  106. package/dist/container/types.cjs.map +1 -0
  107. package/dist/container/types.d.cts +45 -0
  108. package/dist/container/types.d.cts.map +1 -0
  109. package/dist/container/types.d.mts +45 -0
  110. package/dist/container/types.d.mts.map +1 -0
  111. package/dist/container/types.mjs +2 -0
  112. package/dist/container/types.mjs.map +1 -0
  113. package/dist/env.cjs +2 -0
  114. package/dist/env.cjs.map +1 -0
  115. package/dist/env.d.cts +65 -0
  116. package/dist/env.d.cts.map +1 -0
  117. package/dist/env.d.mts +65 -0
  118. package/dist/env.d.mts.map +1 -0
  119. package/dist/env.mjs +2 -0
  120. package/dist/env.mjs.map +1 -0
  121. package/dist/extension.cjs +2 -0
  122. package/dist/extension.cjs.map +1 -0
  123. package/dist/extension.mjs +2 -0
  124. package/dist/extension.mjs.map +1 -0
  125. package/dist/extensions/config.cjs +2 -0
  126. package/dist/extensions/config.cjs.map +1 -0
  127. package/dist/extensions/config.mjs +2 -0
  128. package/dist/extensions/config.mjs.map +1 -0
  129. package/dist/extensions/delegationBridge.cjs +2 -0
  130. package/dist/extensions/delegationBridge.cjs.map +1 -0
  131. package/dist/extensions/delegationBridge.mjs +2 -0
  132. package/dist/extensions/delegationBridge.mjs.map +1 -0
  133. package/dist/extensions/doom.cjs +2 -0
  134. package/dist/extensions/doom.cjs.map +1 -0
  135. package/dist/extensions/doom.d.cts +8 -0
  136. package/dist/extensions/doom.d.cts.map +1 -0
  137. package/dist/extensions/doom.d.mts +8 -0
  138. package/dist/extensions/doom.d.mts.map +1 -0
  139. package/dist/extensions/doom.mjs +2 -0
  140. package/dist/extensions/doom.mjs.map +1 -0
  141. package/dist/extensions/fablePlanBridge.cjs +2 -0
  142. package/dist/extensions/fablePlanBridge.cjs.map +1 -0
  143. package/dist/extensions/fablePlanBridge.mjs +2 -0
  144. package/dist/extensions/fablePlanBridge.mjs.map +1 -0
  145. package/dist/extensions/managementActions.cjs +2 -0
  146. package/dist/extensions/managementActions.cjs.map +1 -0
  147. package/dist/extensions/managementActions.mjs +2 -0
  148. package/dist/extensions/managementActions.mjs.map +1 -0
  149. package/dist/extensions/operationJournal.cjs +2 -0
  150. package/dist/extensions/operationJournal.cjs.map +1 -0
  151. package/dist/extensions/operationJournal.mjs +2 -0
  152. package/dist/extensions/operationJournal.mjs.map +1 -0
  153. package/dist/extensions/orchestratorPrompt.cjs +35 -0
  154. package/dist/extensions/orchestratorPrompt.cjs.map +1 -0
  155. package/dist/extensions/orchestratorPrompt.mjs +35 -0
  156. package/dist/extensions/orchestratorPrompt.mjs.map +1 -0
  157. package/dist/extensions/pi.cjs +2 -0
  158. package/dist/extensions/pi.cjs.map +1 -0
  159. package/dist/extensions/pi.d.cts +2 -0
  160. package/dist/extensions/pi.d.mts +2 -0
  161. package/dist/extensions/pi.mjs +2 -0
  162. package/dist/extensions/pi.mjs.map +1 -0
  163. package/dist/extensions/schemas.cjs +1 -0
  164. package/dist/extensions/schemas.mjs +2 -0
  165. package/dist/extensions/schemas.mjs.map +1 -0
  166. package/dist/extensions/spawnPlan.cjs +3 -0
  167. package/dist/extensions/spawnPlan.cjs.map +1 -0
  168. package/dist/extensions/spawnPlan.mjs +3 -0
  169. package/dist/extensions/spawnPlan.mjs.map +1 -0
  170. package/dist/extensions/standard.cjs +2 -0
  171. package/dist/extensions/standard.cjs.map +1 -0
  172. package/dist/extensions/standard.d.cts +8 -0
  173. package/dist/extensions/standard.d.cts.map +1 -0
  174. package/dist/extensions/standard.d.mts +8 -0
  175. package/dist/extensions/standard.d.mts.map +1 -0
  176. package/dist/extensions/standard.mjs +2 -0
  177. package/dist/extensions/standard.mjs.map +1 -0
  178. package/dist/extensions/statusViews.cjs +7 -0
  179. package/dist/extensions/statusViews.cjs.map +1 -0
  180. package/dist/extensions/statusViews.mjs +7 -0
  181. package/dist/extensions/statusViews.mjs.map +1 -0
  182. package/dist/extensions/subagentPromptRuntime.cjs +18 -0
  183. package/dist/extensions/subagentPromptRuntime.cjs.map +1 -0
  184. package/dist/extensions/subagentPromptRuntime.d.cts +58 -0
  185. package/dist/extensions/subagentPromptRuntime.d.cts.map +1 -0
  186. package/dist/extensions/subagentPromptRuntime.d.mts +58 -0
  187. package/dist/extensions/subagentPromptRuntime.d.mts.map +1 -0
  188. package/dist/extensions/subagentPromptRuntime.mjs +18 -0
  189. package/dist/extensions/subagentPromptRuntime.mjs.map +1 -0
  190. package/dist/extensions/subagentPromptRuntimeEntry.cjs +2 -0
  191. package/dist/extensions/subagentPromptRuntimeEntry.cjs.map +1 -0
  192. package/dist/extensions/subagentPromptRuntimeEntry.d.cts +2 -0
  193. package/dist/extensions/subagentPromptRuntimeEntry.d.mts +2 -0
  194. package/dist/extensions/subagentPromptRuntimeEntry.mjs +2 -0
  195. package/dist/extensions/subagentPromptRuntimeEntry.mjs.map +1 -0
  196. package/dist/extensions/subagentTool.cjs +7 -0
  197. package/dist/extensions/subagentTool.cjs.map +1 -0
  198. package/dist/extensions/subagentTool.mjs +7 -0
  199. package/dist/extensions/subagentTool.mjs.map +1 -0
  200. package/dist/extensions/toolDescription.cjs +2 -0
  201. package/dist/extensions/toolDescription.cjs.map +1 -0
  202. package/dist/extensions/toolDescription.mjs +2 -0
  203. package/dist/extensions/toolDescription.mjs.map +1 -0
  204. package/dist/index.cjs +2 -0
  205. package/dist/index.cjs.map +1 -0
  206. package/dist/index.d.cts +34 -0
  207. package/dist/index.d.cts.map +1 -0
  208. package/dist/index.d.mts +34 -0
  209. package/dist/index.d.mts.map +1 -0
  210. package/dist/index.mjs +2 -0
  211. package/dist/index.mjs.map +1 -0
  212. package/dist/intercom/intercomBridge.cjs +2 -0
  213. package/dist/intercom/intercomBridge.cjs.map +1 -0
  214. package/dist/intercom/intercomBridge.mjs +2 -0
  215. package/dist/intercom/intercomBridge.mjs.map +1 -0
  216. package/dist/intercom/nativeTeamChannel.cjs +5 -0
  217. package/dist/intercom/nativeTeamChannel.cjs.map +1 -0
  218. package/dist/intercom/nativeTeamChannel.d.cts +22 -0
  219. package/dist/intercom/nativeTeamChannel.d.cts.map +1 -0
  220. package/dist/intercom/nativeTeamChannel.d.mts +22 -0
  221. package/dist/intercom/nativeTeamChannel.d.mts.map +1 -0
  222. package/dist/intercom/nativeTeamChannel.mjs +5 -0
  223. package/dist/intercom/nativeTeamChannel.mjs.map +1 -0
  224. package/dist/intercom/supervisorControlChannel.cjs +2 -0
  225. package/dist/intercom/supervisorControlChannel.cjs.map +1 -0
  226. package/dist/intercom/supervisorControlChannel.mjs +2 -0
  227. package/dist/intercom/supervisorControlChannel.mjs.map +1 -0
  228. package/dist/protocol/backgroundWork.cjs +2 -0
  229. package/dist/protocol/backgroundWork.cjs.map +1 -0
  230. package/dist/protocol/backgroundWork.d.cts +52 -0
  231. package/dist/protocol/backgroundWork.d.cts.map +1 -0
  232. package/dist/protocol/backgroundWork.d.mts +52 -0
  233. package/dist/protocol/backgroundWork.d.mts.map +1 -0
  234. package/dist/protocol/backgroundWork.mjs +2 -0
  235. package/dist/protocol/backgroundWork.mjs.map +1 -0
  236. package/dist/protocol/capabilityCeiling.cjs +2 -0
  237. package/dist/protocol/capabilityCeiling.cjs.map +1 -0
  238. package/dist/protocol/capabilityCeiling.d.cts +51 -0
  239. package/dist/protocol/capabilityCeiling.d.cts.map +1 -0
  240. package/dist/protocol/capabilityCeiling.d.mts +51 -0
  241. package/dist/protocol/capabilityCeiling.d.mts.map +1 -0
  242. package/dist/protocol/capabilityCeiling.mjs +2 -0
  243. package/dist/protocol/capabilityCeiling.mjs.map +1 -0
  244. package/dist/protocol/delegation.cjs +2 -0
  245. package/dist/protocol/delegation.cjs.map +1 -0
  246. package/dist/protocol/delegation.d.cts +269 -0
  247. package/dist/protocol/delegation.d.cts.map +1 -0
  248. package/dist/protocol/delegation.d.mts +269 -0
  249. package/dist/protocol/delegation.d.mts.map +1 -0
  250. package/dist/protocol/delegation.mjs +2 -0
  251. package/dist/protocol/delegation.mjs.map +1 -0
  252. package/dist/runs/background/asyncExecution.cjs +2 -0
  253. package/dist/runs/background/asyncExecution.cjs.map +1 -0
  254. package/dist/runs/background/asyncExecution.mjs +2 -0
  255. package/dist/runs/background/asyncExecution.mjs.map +1 -0
  256. package/dist/runs/background/asyncJobTracker.cjs +2 -0
  257. package/dist/runs/background/asyncJobTracker.cjs.map +1 -0
  258. package/dist/runs/background/asyncJobTracker.mjs +2 -0
  259. package/dist/runs/background/asyncJobTracker.mjs.map +1 -0
  260. package/dist/runs/background/cliRunnerEntry.cjs +2 -0
  261. package/dist/runs/background/cliRunnerEntry.cjs.map +1 -0
  262. package/dist/runs/background/cliRunnerEntry.d.cts +1 -0
  263. package/dist/runs/background/cliRunnerEntry.d.mts +1 -0
  264. package/dist/runs/background/cliRunnerEntry.mjs +2 -0
  265. package/dist/runs/background/cliRunnerEntry.mjs.map +1 -0
  266. package/dist/runs/background/completionBatcher.cjs +2 -0
  267. package/dist/runs/background/completionBatcher.cjs.map +1 -0
  268. package/dist/runs/background/completionBatcher.mjs +2 -0
  269. package/dist/runs/background/completionBatcher.mjs.map +1 -0
  270. package/dist/runs/background/notify.cjs +4 -0
  271. package/dist/runs/background/notify.cjs.map +1 -0
  272. package/dist/runs/background/notify.mjs +4 -0
  273. package/dist/runs/background/notify.mjs.map +1 -0
  274. package/dist/runs/background/parentWatchdog.cjs +2 -0
  275. package/dist/runs/background/parentWatchdog.cjs.map +1 -0
  276. package/dist/runs/background/parentWatchdog.mjs +2 -0
  277. package/dist/runs/background/parentWatchdog.mjs.map +1 -0
  278. package/dist/runs/background/processTerminal.cjs +2 -0
  279. package/dist/runs/background/processTerminal.cjs.map +1 -0
  280. package/dist/runs/background/processTerminal.mjs +2 -0
  281. package/dist/runs/background/processTerminal.mjs.map +1 -0
  282. package/dist/runs/background/resultWatcher.cjs +2 -0
  283. package/dist/runs/background/resultWatcher.cjs.map +1 -0
  284. package/dist/runs/background/resultWatcher.mjs +2 -0
  285. package/dist/runs/background/resultWatcher.mjs.map +1 -0
  286. package/dist/runs/background/runIdResolver.cjs +2 -0
  287. package/dist/runs/background/runIdResolver.cjs.map +1 -0
  288. package/dist/runs/background/runIdResolver.mjs +2 -0
  289. package/dist/runs/background/runIdResolver.mjs.map +1 -0
  290. package/dist/runs/background/runnerBootstrap.cjs +2 -0
  291. package/dist/runs/background/runnerBootstrap.cjs.map +1 -0
  292. package/dist/runs/background/runnerBootstrap.mjs +2 -0
  293. package/dist/runs/background/runnerBootstrap.mjs.map +1 -0
  294. package/dist/runs/background/runnerExecution.cjs +2 -0
  295. package/dist/runs/background/runnerExecution.cjs.map +1 -0
  296. package/dist/runs/background/runnerExecution.mjs +2 -0
  297. package/dist/runs/background/runnerExecution.mjs.map +1 -0
  298. package/dist/runs/background/runnerReporting.cjs +3 -0
  299. package/dist/runs/background/runnerReporting.cjs.map +1 -0
  300. package/dist/runs/background/runnerReporting.mjs +3 -0
  301. package/dist/runs/background/runnerReporting.mjs.map +1 -0
  302. package/dist/runs/background/runnerTeamMembership.cjs +2 -0
  303. package/dist/runs/background/runnerTeamMembership.cjs.map +1 -0
  304. package/dist/runs/background/runnerTeamMembership.mjs +2 -0
  305. package/dist/runs/background/runnerTeamMembership.mjs.map +1 -0
  306. package/dist/runs/background/spawnHandshake.cjs +2 -0
  307. package/dist/runs/background/spawnHandshake.cjs.map +1 -0
  308. package/dist/runs/background/spawnHandshake.mjs +2 -0
  309. package/dist/runs/background/spawnHandshake.mjs.map +1 -0
  310. package/dist/runs/background/staleRunReconciler.cjs +2 -0
  311. package/dist/runs/background/staleRunReconciler.cjs.map +1 -0
  312. package/dist/runs/background/staleRunReconciler.mjs +2 -0
  313. package/dist/runs/background/staleRunReconciler.mjs.map +1 -0
  314. package/dist/runs/background/statusReader.cjs +2 -0
  315. package/dist/runs/background/statusReader.cjs.map +1 -0
  316. package/dist/runs/background/statusReader.mjs +2 -0
  317. package/dist/runs/background/statusReader.mjs.map +1 -0
  318. package/dist/runs/background/statusWriter.cjs +2 -0
  319. package/dist/runs/background/statusWriter.cjs.map +1 -0
  320. package/dist/runs/background/statusWriter.mjs +2 -0
  321. package/dist/runs/background/statusWriter.mjs.map +1 -0
  322. package/dist/runs/background/subagentWait.cjs +2 -0
  323. package/dist/runs/background/subagentWait.cjs.map +1 -0
  324. package/dist/runs/background/subagentWait.mjs +2 -0
  325. package/dist/runs/background/subagentWait.mjs.map +1 -0
  326. package/dist/runs/background/terminalPersistence.cjs +2 -0
  327. package/dist/runs/background/terminalPersistence.cjs.map +1 -0
  328. package/dist/runs/background/terminalPersistence.mjs +2 -0
  329. package/dist/runs/background/terminalPersistence.mjs.map +1 -0
  330. package/dist/runs/registry/processGroup.cjs +2 -0
  331. package/dist/runs/registry/processGroup.cjs.map +1 -0
  332. package/dist/runs/registry/processGroup.mjs +2 -0
  333. package/dist/runs/registry/processGroup.mjs.map +1 -0
  334. package/dist/runs/registry/runRegistry.cjs +2 -0
  335. package/dist/runs/registry/runRegistry.cjs.map +1 -0
  336. package/dist/runs/registry/runRegistry.mjs +2 -0
  337. package/dist/runs/registry/runRegistry.mjs.map +1 -0
  338. package/dist/runs/registry/sessionLifecycle.cjs +2 -0
  339. package/dist/runs/registry/sessionLifecycle.cjs.map +1 -0
  340. package/dist/runs/registry/sessionLifecycle.mjs +2 -0
  341. package/dist/runs/registry/sessionLifecycle.mjs.map +1 -0
  342. package/dist/runs/registry/suspendedRuns.cjs +4 -0
  343. package/dist/runs/registry/suspendedRuns.cjs.map +1 -0
  344. package/dist/runs/registry/suspendedRuns.mjs +4 -0
  345. package/dist/runs/registry/suspendedRuns.mjs.map +1 -0
  346. package/dist/runs/sdkRunnerEntry.cjs +2 -0
  347. package/dist/runs/sdkRunnerEntry.cjs.map +1 -0
  348. package/dist/runs/sdkRunnerEntry.d.cts +1 -0
  349. package/dist/runs/sdkRunnerEntry.d.mts +1 -0
  350. package/dist/runs/sdkRunnerEntry.mjs +2 -0
  351. package/dist/runs/sdkRunnerEntry.mjs.map +1 -0
  352. package/dist/runs/shared/claudeFableProfile.cjs +4 -0
  353. package/dist/runs/shared/claudeFableProfile.cjs.map +1 -0
  354. package/dist/runs/shared/claudeFableProfile.mjs +4 -0
  355. package/dist/runs/shared/claudeFableProfile.mjs.map +1 -0
  356. package/dist/runs/shared/depthGuard.cjs +2 -0
  357. package/dist/runs/shared/depthGuard.cjs.map +1 -0
  358. package/dist/runs/shared/depthGuard.mjs +2 -0
  359. package/dist/runs/shared/depthGuard.mjs.map +1 -0
  360. package/dist/runs/shared/mcpDirectToolAllowlist.cjs +2 -0
  361. package/dist/runs/shared/mcpDirectToolAllowlist.cjs.map +1 -0
  362. package/dist/runs/shared/mcpDirectToolAllowlist.mjs +2 -0
  363. package/dist/runs/shared/mcpDirectToolAllowlist.mjs.map +1 -0
  364. package/dist/runs/shared/modelFallback.cjs +2 -0
  365. package/dist/runs/shared/modelFallback.cjs.map +1 -0
  366. package/dist/runs/shared/modelFallback.mjs +2 -0
  367. package/dist/runs/shared/modelFallback.mjs.map +1 -0
  368. package/dist/runs/shared/modelScope.cjs +2 -0
  369. package/dist/runs/shared/modelScope.cjs.map +1 -0
  370. package/dist/runs/shared/modelScope.mjs +2 -0
  371. package/dist/runs/shared/modelScope.mjs.map +1 -0
  372. package/dist/runs/shared/nestedPath.cjs +2 -0
  373. package/dist/runs/shared/nestedPath.cjs.map +1 -0
  374. package/dist/runs/shared/nestedPath.mjs +2 -0
  375. package/dist/runs/shared/nestedPath.mjs.map +1 -0
  376. package/dist/runs/shared/piArgs.cjs +2 -0
  377. package/dist/runs/shared/piArgs.cjs.map +1 -0
  378. package/dist/runs/shared/piArgs.mjs +2 -0
  379. package/dist/runs/shared/piArgs.mjs.map +1 -0
  380. package/dist/runs/shared/piSpawn.cjs +2 -0
  381. package/dist/runs/shared/piSpawn.cjs.map +1 -0
  382. package/dist/runs/shared/piSpawn.mjs +2 -0
  383. package/dist/runs/shared/piSpawn.mjs.map +1 -0
  384. package/dist/runs/shared/runWithConcurrency.cjs +2 -0
  385. package/dist/runs/shared/runWithConcurrency.cjs.map +1 -0
  386. package/dist/runs/shared/runWithConcurrency.mjs +2 -0
  387. package/dist/runs/shared/runWithConcurrency.mjs.map +1 -0
  388. package/dist/runs/shared/runtimeRegistry.cjs +2 -0
  389. package/dist/runs/shared/runtimeRegistry.cjs.map +1 -0
  390. package/dist/runs/shared/runtimeRegistry.mjs +2 -0
  391. package/dist/runs/shared/runtimeRegistry.mjs.map +1 -0
  392. package/dist/runs/shared/structuredOutput.cjs +2 -0
  393. package/dist/runs/shared/structuredOutput.cjs.map +1 -0
  394. package/dist/runs/shared/structuredOutput.mjs +2 -0
  395. package/dist/runs/shared/structuredOutput.mjs.map +1 -0
  396. package/dist/runs/shared/toolAvailability.cjs +2 -0
  397. package/dist/runs/shared/toolAvailability.cjs.map +1 -0
  398. package/dist/runs/shared/toolAvailability.mjs +2 -0
  399. package/dist/runs/shared/toolAvailability.mjs.map +1 -0
  400. package/dist/runs/shared/toolBudget.cjs +2 -0
  401. package/dist/runs/shared/toolBudget.cjs.map +1 -0
  402. package/dist/runs/shared/toolBudget.mjs +2 -0
  403. package/dist/runs/shared/toolBudget.mjs.map +1 -0
  404. package/dist/shared/artifacts.cjs +2 -0
  405. package/dist/shared/artifacts.cjs.map +1 -0
  406. package/dist/shared/artifacts.mjs +2 -0
  407. package/dist/shared/artifacts.mjs.map +1 -0
  408. package/dist/shared/atomicJson.cjs +2 -0
  409. package/dist/shared/atomicJson.cjs.map +1 -0
  410. package/dist/shared/atomicJson.mjs +2 -0
  411. package/dist/shared/atomicJson.mjs.map +1 -0
  412. package/dist/shared/boundedKeySet.cjs +2 -0
  413. package/dist/shared/boundedKeySet.cjs.map +1 -0
  414. package/dist/shared/boundedKeySet.mjs +2 -0
  415. package/dist/shared/boundedKeySet.mjs.map +1 -0
  416. package/dist/shared/childTranscript.cjs +5 -0
  417. package/dist/shared/childTranscript.cjs.map +1 -0
  418. package/dist/shared/childTranscript.mjs +5 -0
  419. package/dist/shared/childTranscript.mjs.map +1 -0
  420. package/dist/shared/configDir.cjs +2 -0
  421. package/dist/shared/configDir.cjs.map +1 -0
  422. package/dist/shared/configDir.mjs +2 -0
  423. package/dist/shared/configDir.mjs.map +1 -0
  424. package/dist/shared/errors.cjs +2 -0
  425. package/dist/shared/errors.cjs.map +1 -0
  426. package/dist/shared/errors.mjs +2 -0
  427. package/dist/shared/errors.mjs.map +1 -0
  428. package/dist/shared/fileSystemRetry.cjs +2 -0
  429. package/dist/shared/fileSystemRetry.cjs.map +1 -0
  430. package/dist/shared/fileSystemRetry.mjs +2 -0
  431. package/dist/shared/fileSystemRetry.mjs.map +1 -0
  432. package/dist/shared/formatters.cjs +2 -0
  433. package/dist/shared/formatters.cjs.map +1 -0
  434. package/dist/shared/formatters.mjs +2 -0
  435. package/dist/shared/formatters.mjs.map +1 -0
  436. package/dist/shared/lruCache.cjs +2 -0
  437. package/dist/shared/lruCache.cjs.map +1 -0
  438. package/dist/shared/lruCache.mjs +2 -0
  439. package/dist/shared/lruCache.mjs.map +1 -0
  440. package/dist/shared/modelInfo.cjs +2 -0
  441. package/dist/shared/modelInfo.cjs.map +1 -0
  442. package/dist/shared/modelInfo.mjs +2 -0
  443. package/dist/shared/modelInfo.mjs.map +1 -0
  444. package/dist/shared/modelResolution.cjs +2 -0
  445. package/dist/shared/modelResolution.cjs.map +1 -0
  446. package/dist/shared/modelResolution.mjs +2 -0
  447. package/dist/shared/modelResolution.mjs.map +1 -0
  448. package/dist/shared/paths.cjs +2 -0
  449. package/dist/shared/paths.cjs.map +1 -0
  450. package/dist/shared/paths.mjs +2 -0
  451. package/dist/shared/paths.mjs.map +1 -0
  452. package/dist/shared/pollScheduler.cjs +2 -0
  453. package/dist/shared/pollScheduler.cjs.map +1 -0
  454. package/dist/shared/pollScheduler.mjs +2 -0
  455. package/dist/shared/pollScheduler.mjs.map +1 -0
  456. package/dist/shared/scopeOwner.cjs +2 -0
  457. package/dist/shared/scopeOwner.cjs.map +1 -0
  458. package/dist/shared/scopeOwner.mjs +2 -0
  459. package/dist/shared/scopeOwner.mjs.map +1 -0
  460. package/dist/shared/versioned.cjs +2 -0
  461. package/dist/shared/versioned.cjs.map +1 -0
  462. package/dist/shared/versioned.mjs +2 -0
  463. package/dist/shared/versioned.mjs.map +1 -0
  464. package/dist/slash/chainExpression.cjs +2 -0
  465. package/dist/slash/chainExpression.cjs.map +1 -0
  466. package/dist/slash/chainExpression.mjs +2 -0
  467. package/dist/slash/chainExpression.mjs.map +1 -0
  468. package/dist/slash/doctor.cjs +5 -0
  469. package/dist/slash/doctor.cjs.map +1 -0
  470. package/dist/slash/doctor.mjs +5 -0
  471. package/dist/slash/doctor.mjs.map +1 -0
  472. package/dist/slash/slashCommands.cjs +4 -0
  473. package/dist/slash/slashCommands.cjs.map +1 -0
  474. package/dist/slash/slashCommands.mjs +4 -0
  475. package/dist/slash/slashCommands.mjs.map +1 -0
  476. package/dist/slash/spawnRequestMapping.cjs +2 -0
  477. package/dist/slash/spawnRequestMapping.cjs.map +1 -0
  478. package/dist/slash/spawnRequestMapping.mjs +2 -0
  479. package/dist/slash/spawnRequestMapping.mjs.map +1 -0
  480. package/dist/slash/subagentLaunch.cjs +2 -0
  481. package/dist/slash/subagentLaunch.cjs.map +1 -0
  482. package/dist/slash/subagentLaunch.mjs +2 -0
  483. package/dist/slash/subagentLaunch.mjs.map +1 -0
  484. package/dist/tui/agentCatalog.cjs +2 -0
  485. package/dist/tui/agentCatalog.cjs.map +1 -0
  486. package/dist/tui/agentCatalog.mjs +2 -0
  487. package/dist/tui/agentCatalog.mjs.map +1 -0
  488. package/dist/tui/agentResourceProjection.cjs +2 -0
  489. package/dist/tui/agentResourceProjection.cjs.map +1 -0
  490. package/dist/tui/agentResourceProjection.mjs +2 -0
  491. package/dist/tui/agentResourceProjection.mjs.map +1 -0
  492. package/dist/tui/completionNotice.cjs +5 -0
  493. package/dist/tui/completionNotice.cjs.map +1 -0
  494. package/dist/tui/completionNotice.mjs +5 -0
  495. package/dist/tui/completionNotice.mjs.map +1 -0
  496. package/dist/tui/fleet.cjs +3 -0
  497. package/dist/tui/fleet.cjs.map +1 -0
  498. package/dist/tui/fleet.mjs +3 -0
  499. package/dist/tui/fleet.mjs.map +1 -0
  500. package/dist/tui/fleetAgentView.cjs +2 -0
  501. package/dist/tui/fleetAgentView.cjs.map +1 -0
  502. package/dist/tui/fleetAgentView.mjs +2 -0
  503. package/dist/tui/fleetAgentView.mjs.map +1 -0
  504. package/dist/tui/fleetStatus.cjs +2 -0
  505. package/dist/tui/fleetStatus.cjs.map +1 -0
  506. package/dist/tui/fleetStatus.mjs +2 -0
  507. package/dist/tui/fleetStatus.mjs.map +1 -0
  508. package/dist/tui/fleetTranscript.cjs +5 -0
  509. package/dist/tui/fleetTranscript.cjs.map +1 -0
  510. package/dist/tui/fleetTranscript.mjs +5 -0
  511. package/dist/tui/fleetTranscript.mjs.map +1 -0
  512. package/dist/tui/register.cjs +2 -0
  513. package/dist/tui/register.cjs.map +1 -0
  514. package/dist/tui/register.mjs +2 -0
  515. package/dist/tui/register.mjs.map +1 -0
  516. package/dist/types.d.cts +59 -0
  517. package/dist/types.d.cts.map +1 -0
  518. package/dist/types.d.mts +59 -0
  519. package/dist/types.d.mts.map +1 -0
  520. package/package.json +86 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeTeamChannel.cjs","names":["path","scopeTeamDir","requireCurrentSessionScope","fs","parseVersioned","invalidRequest","DoomTeamExpectedError","SUBAGENT_TEAM_ID_ENV","SUBAGENT_TEAM_ROOT_SESSION_ENV","SUBAGENT_TEAM_MAIN_MEMBER_ENV","SUBAGENT_TEAM_MEMBER_ID_ENV","SUBAGENT_TEAM_MEMBER_TOKEN_ENV","BoundedKeySet","LruCache","tryCurrentSessionScope"],"sources":["../../src/intercom/nativeTeamChannel.ts"],"sourcesContent":["/**\n * Peer messaging between the named members of one root session's team.\n *\n * A team is every agent process descended from a single root session. Each\n * member owns an inbox directory; peers drop message files into it and the\n * member's poll loop delivers them into its own agent turn. `ask` blocks the\n * sender until the recipient writes a reply file.\n *\n * DESIGN PATTERNS:\n * - A member's name IS its id. Names are what an operator and a model both use\n * to address a teammate, so a second opaque identifier would only ever be a\n * translation layer that can drift\n * - Deliver, then mark seen. Delivery is the side effect that must not be lost,\n * so nothing is recorded as handled until the transport has accepted it\n * - Every record on disk carries a version through `parseVersioned`, so a\n * process running an older build skips a record it cannot read rather than\n * misreading it\n * - One writer per file. A member writes only its own member record, its own\n * heartbeat and other members' inboxes. No file is read-modify-written by two\n * processes, so no update can be lost\n *\n * PERFORMANCE:\n * - The poll skips a file by name before opening it, so an inbox that has\n * accumulated files that are not for us costs one readdir per poll rather than\n * one parse per file per poll\n * - Dead members' directories are swept on a timer, which is what stops that\n * readdir from growing for the life of a long session\n *\n * SEVEN FAILURE MODES THIS MODULE IS BUILT AROUND. Each is called out again at\n * the code that handles it, because each one is a plausible \"simplification\"\n * that would silently reintroduce message loss:\n * 1. Marking a message seen before delivering it loses it permanently when the\n * transport throws, because a seen message is never retried.\n * 2. Ordering by wall-clock alone reorders two messages from the same sender\n * written in the same millisecond.\n * 3. Leaving a file that is not addressed to us unseen re-parses it on every\n * poll, forever.\n * 4. Putting the sender's token in the envelope hands every recipient the value\n * it needs to impersonate that sender.\n * 5. An unbounded seen set grows for the life of the session.\n * 6. Read-modify-writing a shared heartbeat file lets a stale writer resurrect\n * a dead member.\n * 7. Never collecting dead members leaves their inboxes and records on disk.\n *\n * AVOID:\n * - Any module-level mutable state; the runtime owns everything stateful so a\n * second session in the same process cannot inherit the first one's inbox\n * - Deleting a file that failed validation because of a team mismatch; that file\n * belongs to another session and is not ours to destroy\n * - Treating an atomic write as a lock. It prevents a torn read, nothing else\n */\n\nimport { createHash, randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { ExtensionAPI, ToolDefinition } from '@earendil-works/pi-coding-agent';\nimport { injectable } from 'inversify';\nimport type { TSchema } from 'typebox';\nimport {\n SUBAGENT_TEAM_ID_ENV,\n SUBAGENT_TEAM_MAIN_MEMBER_ENV,\n SUBAGENT_TEAM_MEMBER_ID_ENV,\n SUBAGENT_TEAM_MEMBER_TOKEN_ENV,\n SUBAGENT_TEAM_ROOT_SESSION_ENV,\n} from '../env.ts';\nimport { writePrivateAtomicJson } from '../shared/atomicJson.ts';\nimport { BoundedKeySet } from '../shared/boundedKeySet.ts';\nimport { LruCache } from '../shared/lruCache.ts';\nimport { requireCurrentSessionScope, scopeTeamDir, tryCurrentSessionScope } from '../shared/paths.ts';\nimport { parseVersioned } from '../shared/versioned.ts';\nimport { DoomTeamExpectedError, invalidRequest } from '../shared/errors.ts';\n\n/** Wire literal. The model calls the tool by this name, so it is not renamed. */\nexport const NATIVE_TEAM_TOOL_NAME = 'intercom';\n\n/** Wire literals. Present in every envelope so a foreign file is recognisable. */\nconst TEAM_MESSAGE_TYPE = 'subagent.team.message';\nconst TEAM_REPLY_TYPE = 'subagent.team.reply';\n/** Custom message types the host renders. */\nconst TEAM_MESSAGE_CUSTOM_TYPE = 'intercom_message';\nconst TEAM_UNDELIVERABLE_CUSTOM_TYPE = 'intercom_undeliverable';\n\nconst MEMBERS_DIR = 'members';\nconst HEARTBEATS_DIR = 'heartbeats';\nconst INBOXES_DIR = 'inboxes';\nconst REPLIES_DIR = 'replies';\nconst RECEIPTS_DIR = 'receipts';\nconst TEAM_FILE = 'team.json';\nconst JSON_FILE_SUFFIX = '.json';\n\n/** Reserved for the root session. A child that asks for it is refused. */\nconst MAIN_MEMBER_ID = 'main';\n/** Substituted when a derived name would land on the reserved root name. */\nconst RESERVED_NAME_FALLBACK = 'main-agent';\nconst FALLBACK_MEMBER_NAME = 'agent';\nconst MAX_MEMBER_NAME_LENGTH = 48;\nconst FANOUT_SUFFIX_SEPARATOR = '-';\n/** Fanout suffixes are 1-based, so the first child of a fanout reads as `-1`. */\nconst FIRST_FANOUT_ORDINAL = 1;\n\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst MAX_MESSAGE_BYTES = 64 * 1024;\nconst MAX_TASK_ID_BYTES = 256;\nconst MAX_TASK_SUBJECT_BYTES = 4 * 1024;\nconst MESSAGE_TTL_MS = 24 * 60 * 60 * 1000;\nconst DEFAULT_ASK_TIMEOUT_MS = 10 * 60 * 1000;\nconst HEARTBEAT_INTERVAL_MS = 5_000;\n/**\n * Exported: `task-board.ts` gates a claim guard on the same staleness window,\n * and must never drift from it. Two definitions of \"how stale is too stale\"\n * would let a claim guard and this module's own liveness check disagree about\n * who is alive.\n */\nexport const HEARTBEAT_STALE_MS = 30_000;\nconst CHANNEL_POLL_MS = 250;\nconst REPLY_POLL_MS = 250;\n\n/**\n * How many times one message may fail delivery before it is given up on.\n *\n * The retry exists for a transient host refusal, and the bound exists because a\n * message the host will never accept would otherwise be re-delivered on every\n * poll for the life of the session, starving every message behind it.\n */\nconst MAX_DELIVERY_ATTEMPTS = 5;\nconst FIRST_DELIVERY_ATTEMPT = 1;\n/** Comfortably above the number of inbox files that can be live at once. */\nconst SEEN_FILE_CAPACITY = 1024;\nconst DELIVERY_ATTEMPT_CAPACITY = 256;\nconst UNDELIVERABLE_HISTORY_LIMIT = 32;\n\nconst TEAM_GC_INTERVAL_MS = 60_000;\n/**\n * How long past its liveness deadline a member's state is kept.\n *\n * Deliberately much larger than `HEARTBEAT_STALE_MS`: a member that is merely\n * slow to start, or stopped at a breakpoint, must not have its inbox deleted\n * out from under a peer that is mid-`ask`.\n */\nconst TEAM_GC_GRACE_MS = 5 * 60 * 1000;\n\nconst TEAM_ROOT_VERSION = 1;\nconst MEMBER_RECORD_VERSION = 1;\nconst HEARTBEAT_RECORD_VERSION = 1;\n/**\n * Version 2 of the envelope. Version 1 carried the sender's token and had no\n * sequence number; both are load-bearing changes, so an old envelope is\n * rejected rather than read with the missing fields defaulted.\n */\nconst ENVELOPE_VERSION = 2;\n\nconst TEAM_ACTIONS = ['members', 'send', 'ask', 'reply', 'pending'] as const;\nconst SAFE_ID_PATTERN = /^[A-Za-z0-9._-]{1,256}$/;\nconst UNSAFE_NAME_CHARS = /[^a-z0-9._-]+/g;\nconst SURROUNDING_SEPARATORS = /^[-.]+|[-.]+$/g;\nconst TEAM_ID_HASH_LENGTH = 32;\nconst TOKEN_BYTES = 32;\nconst HASH_ALGORITHM = 'sha256';\nconst RECEIPT_VERSION = 1;\nconst RECEIPT_DELIVERED = 'delivered';\nconst RECEIPT_FAILED = 'failed';\nconst TEAM_ID_PREFIX = 'session-';\n\nexport type TeamMemberRole = 'main' | 'subagent';\n\nexport interface TeamRootContext {\n version: typeof TEAM_ROOT_VERSION;\n teamId: string;\n rootSessionId: string;\n mainMemberId: string;\n}\n\nexport interface TeamTaskMetadata {\n id: string;\n subject: string;\n}\n\nexport interface TeamMemberContext extends TeamRootContext {\n memberId: string;\n token: string;\n role: TeamMemberRole;\n agent?: string;\n runId?: string;\n childIndex?: number;\n parentMemberId?: string;\n task?: TeamTaskMetadata;\n}\n\ninterface TeamRecord extends TeamRootContext {\n createdAt: number;\n updatedAt: number;\n}\n\n/**\n * The member's durable identity.\n *\n * FIX 6: no `heartbeatAt`. Liveness moved to a per-member file so that writing a\n * heartbeat never rewrites identity, and so a writer can only ever affect its\n * own liveness.\n */\nexport interface TeamMemberRecord extends Omit<TeamMemberContext, 'token' | 'version'> {\n version: typeof MEMBER_RECORD_VERSION;\n tokenHash: string;\n pid: number;\n active: boolean;\n joinedAt: number;\n leftAt?: number;\n}\n\nexport interface NativeTeamMemberSnapshot {\n name: string;\n role: TeamMemberRole;\n agent?: string;\n runId?: string;\n task?: TeamTaskMetadata;\n}\n\nexport interface NativeTeamSnapshot {\n members: NativeTeamMemberSnapshot[];\n}\n\n/**\n * One member's liveness, in a file only that member writes.\n *\n * FIX 6: the predecessor kept `heartbeatAt` inside the member record and\n * refreshed it with a read-modify-write. Two writers racing that read could\n * republish a stale snapshot, which resurrected a member that had already\n * marked itself inactive. `tokenHash` is repeated here so a heartbeat left\n * behind by a previous owner of the same name does not count for the new one.\n */\nexport interface TeamHeartbeatRecord {\n version: typeof HEARTBEAT_RECORD_VERSION;\n memberId: string;\n tokenHash: string;\n pid: number;\n heartbeatAt: number;\n}\n\ntype TeamMessageKind = 'send' | 'ask';\n\n/**\n * FIX 4: `senderTokenHash`, never the token itself.\n *\n * The predecessor embedded the sender's bearer token, so every recipient came\n * out of a single message holding the value that authenticates that sender to\n * `assertCurrentMember`, to `dispose`, and to any future capability keyed on it.\n * A hash is enough for the recipient's actual question, which is only \"does this\n * match the tokenHash in the sender's member record\". What it deliberately does\n * NOT claim is unforgeability against a process that can already write into this\n * team directory: everyone in the team runs as the same OS user, so the\n * boundary here is the token, not the directory.\n */\ninterface TeamMessageEnvelope {\n type: typeof TEAM_MESSAGE_TYPE;\n version: typeof ENVELOPE_VERSION;\n id: string;\n teamId: string;\n kind: TeamMessageKind;\n fromMemberId: string;\n toMemberId: string;\n senderTokenHash: string;\n /**\n * FIX 2: monotonic per sender, assigned in the order the sender queued.\n *\n * `createdAt` has millisecond resolution, so two messages from one sender in\n * the same millisecond are indistinguishable by time and were delivered in\n * whatever order the directory happened to list them.\n */\n seq: number;\n message: string;\n createdAt: number;\n expiresAt: number;\n}\n\ninterface TeamReplyEnvelope {\n type: typeof TEAM_REPLY_TYPE;\n version: typeof ENVELOPE_VERSION;\n requestId: string;\n teamId: string;\n fromMemberId: string;\n toMemberId: string;\n senderTokenHash: string;\n message: string;\n createdAt: number;\n}\n\n/** A message the transport refused often enough that it was given up on. */\nexport interface UndeliverableTeamMessage {\n messageId: string;\n fromMemberId: string;\n kind: TeamMessageKind;\n attempts: number;\n reason: string;\n at: number;\n}\n\ninterface TeamToolParams {\n action: (typeof TEAM_ACTIONS)[number];\n to?: string;\n message?: string;\n requestId?: string;\n timeoutMs?: number;\n}\n\n/**\n * Hand-written JSON Schema rather than a TypeBox builder, so the wire shape is\n * readable in one place. The cast is the reason `execute` narrows its params\n * with a real guard instead of trusting the static type.\n */\nconst TeamToolParamsSchema = {\n oneOf: [\n ...(['members', 'pending'] as const).map((action) => ({\n type: 'object',\n properties: { action: { const: action } },\n required: ['action'],\n additionalProperties: false,\n })),\n {\n type: 'object',\n properties: { action: { const: 'send' }, to: { type: 'string' }, message: { type: 'string' } },\n required: ['action', 'to', 'message'],\n additionalProperties: false,\n },\n {\n type: 'object',\n properties: {\n action: { const: 'ask' },\n to: { type: 'string' },\n message: { type: 'string' },\n timeoutMs: { type: 'integer', minimum: 1 },\n },\n required: ['action', 'to', 'message'],\n additionalProperties: false,\n },\n {\n type: 'object',\n properties: { action: { const: 'reply' }, requestId: { type: 'string' }, message: { type: 'string' } },\n required: ['action', 'requestId', 'message'],\n additionalProperties: false,\n },\n ],\n} as unknown as TSchema;\n\n// ---------------------------------------------------------------------------\n// Narrowing helpers. Everything read off disk or out of a tool call arrives as\n// `unknown` and is narrowed by one of these; nothing is asserted into shape.\n// ---------------------------------------------------------------------------\n\nfunction isSafeId(value: unknown): value is string {\n return typeof value === 'string' && SAFE_ID_PATTERN.test(value);\n}\n\nfunction isInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value);\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nfunction isOptionalString(value: unknown): value is string | undefined {\n return value === undefined || typeof value === 'string';\n}\n\nfunction isOptionalInteger(value: unknown): value is number | undefined {\n return value === undefined || isInteger(value);\n}\n\nfunction isMemberRole(value: unknown): value is TeamMemberRole {\n return value === 'main' || value === 'subagent';\n}\n\nfunction isMessageKind(value: unknown): value is TeamMessageKind {\n return value === 'send' || value === 'ask';\n}\n\nfunction withinBytes(value: string, limit: number): boolean {\n return Buffer.byteLength(value, 'utf-8') <= limit;\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction textEnv(name: string): string | undefined {\n const value = process.env[name]?.trim();\n return value ? value : undefined;\n}\n\nfunction hash(value: string): string {\n return createHash(HASH_ALGORITHM).update(value).digest('hex');\n}\n\nfunction newToken(): string {\n return randomBytes(TOKEN_BYTES).toString('base64url');\n}\n\nfunction teamIdForSession(rootSessionId: string): string {\n return `${TEAM_ID_PREFIX}${hash(rootSessionId).slice(0, TEAM_ID_HASH_LENGTH)}`;\n}\n\n// ---------------------------------------------------------------------------\n// Member names. A name is the id, so naming rules are identity rules.\n// ---------------------------------------------------------------------------\n\n/**\n * Reduce any label to a usable member name.\n *\n * Lowercase because a name is typed by hand and by a model, and two members\n * differing only in case would be two identities that read as one.\n */\nexport function normalizeTeamMemberName(raw: string): string {\n const normalized = raw\n .trim()\n .toLowerCase()\n .replace(UNSAFE_NAME_CHARS, FANOUT_SUFFIX_SEPARATOR)\n .replace(SURROUNDING_SEPARATORS, '')\n .slice(0, MAX_MEMBER_NAME_LENGTH)\n .replace(SURROUNDING_SEPARATORS, '');\n return normalized || FALLBACK_MEMBER_NAME;\n}\n\n/** Append `-1`..`-N` while keeping the whole name inside the length budget. */\nfunction withFanoutOrdinal(base: string, fanoutIndex: number): string {\n const suffix = `${FANOUT_SUFFIX_SEPARATOR}${fanoutIndex + FIRST_FANOUT_ORDINAL}`;\n const room = MAX_MEMBER_NAME_LENGTH - suffix.length;\n const trimmed = base.slice(0, Math.max(room, 0)).replace(SURROUNDING_SEPARATORS, '');\n return `${trimmed || FALLBACK_MEMBER_NAME}${suffix}`;\n}\n\n/**\n * `main` belongs to the root session and to nothing else.\n *\n * An explicit request for it is an error, because silently handing the caller a\n * different name would leave it addressing a member that does not exist. A name\n * that merely derived to `main` is substituted instead, since the caller never\n * asked for that name and cannot act on the refusal.\n */\nfunction guardReservedName(name: string, explicit: boolean): string {\n if (name !== MAIN_MEMBER_ID) return name;\n if (explicit) throw new Error(`Native team member name '${MAIN_MEMBER_ID}' is reserved for the root session.`);\n return RESERVED_NAME_FALLBACK;\n}\n\n// ---------------------------------------------------------------------------\n// Paths\n// ---------------------------------------------------------------------------\n\n/**\n * This team's directory, under the owning session's scope.\n *\n * A team is every agent descended from one root session, so the team tree\n * belongs inside that session's scope rather than in a parallel\n * `team-channels/` root shared by every concurrent session. The `teamId`\n * segment is kept even though a scope holds exactly one team: it is the value\n * every record on disk is validated against (see `readNativeTeamRootFromEnvironment`),\n * so keeping path and record agreeing costs one segment and removes a way for\n * a stale tree to be read as the current one.\n */\nexport function teamDir(teamId: string): string {\n if (!isSafeId(teamId)) throw new Error('Invalid native team id.');\n return path.join(scopeTeamDir(requireCurrentSessionScope()), teamId);\n}\n\nfunction memberPath(root: TeamRootContext, memberId: string): string {\n if (!isSafeId(memberId)) throw new Error('Invalid native team member id.');\n return path.join(teamDir(root.teamId), MEMBERS_DIR, `${memberId}${JSON_FILE_SUFFIX}`);\n}\n\nfunction heartbeatPath(root: TeamRootContext, memberId: string): string {\n if (!isSafeId(memberId)) throw new Error('Invalid native team member id.');\n return path.join(teamDir(root.teamId), HEARTBEATS_DIR, `${memberId}${JSON_FILE_SUFFIX}`);\n}\n\nfunction inboxDir(root: TeamRootContext, memberId: string): string {\n if (!isSafeId(memberId)) throw new Error('Invalid native team member id.');\n return path.join(teamDir(root.teamId), INBOXES_DIR, memberId);\n}\n\nfunction messageFileName(messageId: string): string {\n return `${messageId}${JSON_FILE_SUFFIX}`;\n}\n\nfunction messagePath(root: TeamRootContext, memberId: string, messageId: string): string {\n if (!isSafeId(messageId)) throw new Error('Invalid native team message id.');\n return path.join(inboxDir(root, memberId), messageFileName(messageId));\n}\n\nfunction replyPath(root: TeamRootContext, requestId: string): string {\n if (!isSafeId(requestId)) throw new Error('Invalid native team request id.');\n return path.join(teamDir(root.teamId), REPLIES_DIR, `${requestId}${JSON_FILE_SUFFIX}`);\n}\n\nfunction receiptPath(root: TeamRootContext, senderId: string, messageId: string): string {\n if (!isSafeId(senderId) || !isSafeId(messageId)) throw new Error('Invalid intercom receipt identity.');\n return path.join(teamDir(root.teamId), RECEIPTS_DIR, senderId, `${messageId}${JSON_FILE_SUFFIX}`);\n}\n\nfunction operationMessageId(memberId: string, operationId: string): string {\n return createHash(HASH_ALGORITHM).update(`${memberId}:${operationId}`).digest('hex');\n}\n\nfunction ensureTeamDirectories(root: TeamRootContext): void {\n const rootDir = teamDir(root.teamId);\n for (const child of [MEMBERS_DIR, HEARTBEATS_DIR, INBOXES_DIR, REPLIES_DIR, RECEIPTS_DIR]) {\n fs.mkdirSync(path.join(rootDir, child), { recursive: true, mode: PRIVATE_DIRECTORY_MODE });\n }\n}\n\nfunction readJsonRecord(file: string): Record<string, unknown> | undefined {\n try {\n const parsed: unknown = JSON.parse(fs.readFileSync(file, 'utf-8'));\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : undefined;\n } catch {\n // A missing, half-written or corrupt file is a normal state for a directory\n // several processes write to. The caller treats undefined as \"not readable\n // yet\" and either retries on the next poll or removes the file.\n return undefined;\n }\n}\n\nfunction removeFile(file: string): boolean {\n try {\n fs.rmSync(file, { force: true });\n return true;\n } catch (error) {\n // Already gone counts as removed. Anything else is reported so a caller\n // that must not re-deliver can tell the difference.\n return (error as NodeJS.ErrnoException).code === 'ENOENT';\n }\n}\n\nfunction removeDirectory(dir: string): void {\n try {\n fs.rmSync(dir, { recursive: true, force: true });\n } catch {\n // Best effort. A directory that resists removal is retried by the next\n // sweep; failing the sweep would stop the rest of the cleanup.\n }\n}\n\n// ---------------------------------------------------------------------------\n// Record parsing\n// ---------------------------------------------------------------------------\n\nfunction parseTeamRecord(value: Record<string, unknown> | undefined): TeamRecord | undefined {\n const versioned = parseVersioned(value, [TEAM_ROOT_VERSION]);\n if (!versioned.ok || !value) return undefined;\n if (\n !isSafeId(value.teamId) ||\n !isNonEmptyString(value.rootSessionId) ||\n value.mainMemberId !== MAIN_MEMBER_ID ||\n !isFiniteNumber(value.createdAt) ||\n !isFiniteNumber(value.updatedAt)\n )\n return undefined;\n return {\n version: TEAM_ROOT_VERSION,\n teamId: value.teamId,\n rootSessionId: value.rootSessionId,\n mainMemberId: MAIN_MEMBER_ID,\n createdAt: value.createdAt,\n updatedAt: value.updatedAt,\n };\n}\n\nfunction parseTaskMetadata(value: unknown): TeamTaskMetadata | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const task: Record<string, unknown> = value as Record<string, unknown>;\n if (!isNonEmptyString(task.id) || !isNonEmptyString(task.subject)) return undefined;\n if (!withinBytes(task.id, MAX_TASK_ID_BYTES) || !withinBytes(task.subject, MAX_TASK_SUBJECT_BYTES)) return undefined;\n return { id: task.id, subject: task.subject };\n}\n\nfunction parseMemberRecord(value: Record<string, unknown> | undefined): TeamMemberRecord | undefined {\n const versioned = parseVersioned(value, [MEMBER_RECORD_VERSION]);\n if (!versioned.ok || !value) return undefined;\n if (\n !isSafeId(value.teamId) ||\n !isNonEmptyString(value.rootSessionId) ||\n !isNonEmptyString(value.mainMemberId) ||\n !isSafeId(value.memberId) ||\n !isMemberRole(value.role) ||\n !isNonEmptyString(value.tokenHash) ||\n !isInteger(value.pid) ||\n typeof value.active !== 'boolean' ||\n !isFiniteNumber(value.joinedAt) ||\n !isOptionalString(value.agent) ||\n !isOptionalString(value.runId) ||\n !isOptionalInteger(value.childIndex) ||\n !isOptionalString(value.parentMemberId)\n )\n return undefined;\n const task = value.task === undefined ? undefined : parseTaskMetadata(value.task);\n if (value.task !== undefined && !task) return undefined;\n return {\n version: MEMBER_RECORD_VERSION,\n teamId: value.teamId,\n rootSessionId: value.rootSessionId,\n mainMemberId: value.mainMemberId,\n memberId: value.memberId,\n role: value.role,\n tokenHash: value.tokenHash,\n pid: value.pid,\n active: value.active,\n joinedAt: value.joinedAt,\n ...(isFiniteNumber(value.leftAt) ? { leftAt: value.leftAt } : {}),\n ...(value.agent !== undefined ? { agent: value.agent } : {}),\n ...(value.runId !== undefined ? { runId: value.runId } : {}),\n ...(value.childIndex !== undefined ? { childIndex: value.childIndex } : {}),\n ...(value.parentMemberId !== undefined ? { parentMemberId: value.parentMemberId } : {}),\n ...(task ? { task } : {}),\n };\n}\n\nfunction parseHeartbeatRecord(value: Record<string, unknown> | undefined): TeamHeartbeatRecord | undefined {\n const versioned = parseVersioned(value, [HEARTBEAT_RECORD_VERSION]);\n if (!versioned.ok || !value) return undefined;\n if (\n !isSafeId(value.memberId) ||\n !isNonEmptyString(value.tokenHash) ||\n !isInteger(value.pid) ||\n !isFiniteNumber(value.heartbeatAt)\n )\n return undefined;\n return {\n version: HEARTBEAT_RECORD_VERSION,\n memberId: value.memberId,\n tokenHash: value.tokenHash,\n pid: value.pid,\n heartbeatAt: value.heartbeatAt,\n };\n}\n\nfunction parseMessageEnvelope(value: Record<string, unknown> | undefined): TeamMessageEnvelope | undefined {\n const versioned = parseVersioned(value, [ENVELOPE_VERSION]);\n if (!versioned.ok || !value) return undefined;\n if (\n value.type !== TEAM_MESSAGE_TYPE ||\n !isSafeId(value.id) ||\n !isSafeId(value.teamId) ||\n !isMessageKind(value.kind) ||\n !isSafeId(value.fromMemberId) ||\n !isSafeId(value.toMemberId) ||\n !isNonEmptyString(value.senderTokenHash) ||\n !isInteger(value.seq) ||\n typeof value.message !== 'string' ||\n !withinBytes(value.message, MAX_MESSAGE_BYTES) ||\n !isFiniteNumber(value.createdAt) ||\n !isFiniteNumber(value.expiresAt)\n )\n return undefined;\n return {\n type: TEAM_MESSAGE_TYPE,\n version: ENVELOPE_VERSION,\n id: value.id,\n teamId: value.teamId,\n kind: value.kind,\n fromMemberId: value.fromMemberId,\n toMemberId: value.toMemberId,\n senderTokenHash: value.senderTokenHash,\n seq: value.seq,\n message: value.message,\n createdAt: value.createdAt,\n expiresAt: value.expiresAt,\n };\n}\n\nfunction parseReplyEnvelope(value: Record<string, unknown> | undefined): TeamReplyEnvelope | undefined {\n const versioned = parseVersioned(value, [ENVELOPE_VERSION]);\n if (!versioned.ok || !value) return undefined;\n if (\n value.type !== TEAM_REPLY_TYPE ||\n !isSafeId(value.requestId) ||\n !isSafeId(value.teamId) ||\n !isSafeId(value.fromMemberId) ||\n !isSafeId(value.toMemberId) ||\n !isNonEmptyString(value.senderTokenHash) ||\n typeof value.message !== 'string' ||\n !withinBytes(value.message, MAX_MESSAGE_BYTES) ||\n !isFiniteNumber(value.createdAt)\n )\n return undefined;\n return {\n type: TEAM_REPLY_TYPE,\n version: ENVELOPE_VERSION,\n requestId: value.requestId,\n teamId: value.teamId,\n fromMemberId: value.fromMemberId,\n toMemberId: value.toMemberId,\n senderTokenHash: value.senderTokenHash,\n message: value.message,\n createdAt: value.createdAt,\n };\n}\n\nfunction parseTeamToolParams(raw: unknown): TeamToolParams {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw invalidRequest('Intercom params must be an object.', 'Use one documented intercom action shape.');\n }\n const params: Record<string, unknown> = raw as Record<string, unknown>;\n const action = TEAM_ACTIONS.find((candidate) => candidate === params.action);\n if (!action) {\n throw new DoomTeamExpectedError(\n 'unsupported_operation',\n `Unsupported intercom action: ${String(params.action)}.`,\n false,\n 'Use members, send, ask, pending, or reply.',\n );\n }\n if (!isOptionalString(params.to) || !isOptionalString(params.message) || !isOptionalString(params.requestId))\n throw invalidRequest(\n 'Intercom to, message and requestId values must be strings.',\n 'Correct the action fields and retry.',\n );\n if (params.timeoutMs !== undefined && (!isInteger(params.timeoutMs) || params.timeoutMs < 1)) {\n throw invalidRequest('Intercom timeoutMs must be a positive integer.', 'Correct timeoutMs and retry.');\n }\n const allowed = new Set(\n action === 'members' || action === 'pending'\n ? ['action']\n : action === 'reply'\n ? ['action', 'requestId', 'message']\n : action === 'ask'\n ? ['action', 'to', 'message', 'timeoutMs']\n : ['action', 'to', 'message'],\n );\n const unknown = Object.keys(params).filter((field) => !allowed.has(field));\n if (unknown.length) {\n throw invalidRequest(\n `Intercom action '${action}' does not accept: ${unknown.join(', ')}.`,\n 'Remove unknown fields and retry.',\n );\n }\n return {\n action,\n ...(params.to !== undefined ? { to: params.to } : {}),\n ...(params.message !== undefined ? { message: params.message } : {}),\n ...(params.requestId !== undefined ? { requestId: params.requestId } : {}),\n ...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Liveness\n//\n// `readMember`, `readHeartbeat` and `processAlive` are exported: they are the\n// only readers of the member and heartbeat record formats this module owns,\n// and `task-board.ts` reads through them for its own claim guard rather than\n// keeping a second parser for the same on-disk shape. What is NOT exported is\n// `memberIsActive`: it encodes THIS module's own liveness policy (fall back to\n// `leftAt ?? joinedAt` when there is no heartbeat yet, because a member that\n// has only just registered deserves a grace period before it is judged dead).\n// `task-board.ts` needs a different policy for the same readers -- a missing\n// heartbeat reads as dead, because it only ever gates a claim or a prune, and\n// \"unknown means dead\" is the safe direction there. Sharing the predicate\n// itself instead of the readers would force one of those two correct policies\n// to lose.\n// ---------------------------------------------------------------------------\n\nexport function readMember(root: TeamRootContext, memberId: string): TeamMemberRecord | undefined {\n return parseMemberRecord(readJsonRecord(memberPath(root, memberId)));\n}\n\nexport function readHeartbeat(root: TeamRootContext, member: TeamMemberRecord): TeamHeartbeatRecord | undefined {\n const record = parseHeartbeatRecord(readJsonRecord(heartbeatPath(root, member.memberId)));\n // A heartbeat left by a previous owner of this name proves nothing about the\n // member that holds it now, which is exactly the resurrection FIX 6 targets.\n if (!record || record.memberId !== member.memberId || record.tokenHash !== member.tokenHash) return undefined;\n return record;\n}\n\nexport function processAlive(pid: number): boolean {\n if (pid === process.pid) return true;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n // EPERM means the pid exists and belongs to someone else, which still\n // answers the question being asked.\n return (error as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\n/** Last moment this member proved it was running, from its own writes only. */\nfunction lastProofOfLife(root: TeamRootContext, member: TeamMemberRecord): number {\n return readHeartbeat(root, member)?.heartbeatAt ?? member.leftAt ?? member.joinedAt;\n}\n\nfunction memberIsActive(root: TeamRootContext, member: TeamMemberRecord, now: number): boolean {\n return member.active && processAlive(member.pid) && now - lastProofOfLife(root, member) <= HEARTBEAT_STALE_MS;\n}\n\nfunction writeMemberRecord(record: TeamMemberRecord): void {\n fs.mkdirSync(inboxDir(record, record.memberId), { recursive: true, mode: PRIVATE_DIRECTORY_MODE });\n writePrivateAtomicJson(memberPath(record, record.memberId), record);\n}\n\nfunction writeHeartbeat(root: TeamRootContext, member: TeamMemberRecord, at: number): void {\n const record: TeamHeartbeatRecord = {\n version: HEARTBEAT_RECORD_VERSION,\n memberId: member.memberId,\n tokenHash: member.tokenHash,\n pid: member.pid,\n heartbeatAt: at,\n };\n writePrivateAtomicJson(heartbeatPath(root, member.memberId), record);\n}\n\n/** Exported: `task-board.ts` walks this to find every member's task claim without duplicating the readdir + parse. */\nexport function listMemberRecords(root: TeamRootContext): TeamMemberRecord[] {\n const dir = path.join(teamDir(root.teamId), MEMBERS_DIR);\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n // No members directory means no team on disk yet, which is not an error for\n // a caller that is only asking who is around.\n return [];\n }\n return entries\n .filter((entry) => entry.isFile() && entry.name.endsWith(JSON_FILE_SUFFIX))\n .map((entry) => parseMemberRecord(readJsonRecord(path.join(dir, entry.name))))\n .filter((member): member is TeamMemberRecord => Boolean(member))\n .filter((member) => member.teamId === root.teamId && member.rootSessionId === root.rootSessionId);\n}\n\nfunction listActiveMembers(root: TeamRootContext, now: number): TeamMemberRecord[] {\n return listMemberRecords(root)\n .filter((member) => memberIsActive(root, member, now))\n .sort((left, right) => left.joinedAt - right.joinedAt || left.memberId.localeCompare(right.memberId));\n}\n\nexport function readActiveNativeTeamSnapshot(now = Date.now()): NativeTeamSnapshot | undefined {\n const root = readNativeTeamRootFromEnvironment();\n if (!root) return undefined;\n return { members: listActiveMembers(root, now).map(publicMember) };\n}\n\n/**\n * FIX 7: drop the state of members that are long gone.\n *\n * Without this, every inbox directory and member record a session ever created\n * stays on disk, so `listMemberRecords` and the inbox readdir both grow for the\n * life of the machine's temp directory. The liveness rule is the same one used\n * everywhere else, plus a grace period, so nothing here can collect a member\n * that a peer still considers reachable.\n */\nfunction collectDeadMembers(root: TeamRootContext, selfMemberId: string, now: number): number {\n let collected = 0;\n for (const member of listMemberRecords(root)) {\n if (member.memberId === selfMemberId) continue;\n if (memberIsActive(root, member, now)) continue;\n if (now - lastProofOfLife(root, member) <= HEARTBEAT_STALE_MS + TEAM_GC_GRACE_MS) continue;\n removeDirectory(inboxDir(root, member.memberId));\n removeFile(heartbeatPath(root, member.memberId));\n removeFile(memberPath(root, member.memberId));\n collected += 1;\n }\n return collected;\n}\n\n// ---------------------------------------------------------------------------\n// Team and membership lifecycle\n// ---------------------------------------------------------------------------\n\nexport function ensureNativeTeamRoot(rootSessionId: string): TeamRootContext {\n const normalizedSessionId = rootSessionId.trim();\n if (!normalizedSessionId) throw new Error('A root session id is required for native team communication.');\n const root: TeamRootContext = {\n version: TEAM_ROOT_VERSION,\n teamId: teamIdForSession(normalizedSessionId),\n rootSessionId: normalizedSessionId,\n mainMemberId: MAIN_MEMBER_ID,\n };\n ensureTeamDirectories(root);\n const file = path.join(teamDir(root.teamId), TEAM_FILE);\n const existing = parseTeamRecord(readJsonRecord(file));\n if (existing && existing.rootSessionId !== normalizedSessionId)\n throw new Error('Native team identity collision detected.');\n const now = Date.now();\n const record: TeamRecord = { ...root, createdAt: existing?.createdAt ?? now, updatedAt: now };\n writePrivateAtomicJson(file, record);\n return root;\n}\n\nexport function nativeTeamRootEnvironment(root: TeamRootContext): Record<string, string> {\n return {\n [SUBAGENT_TEAM_ID_ENV]: root.teamId,\n [SUBAGENT_TEAM_ROOT_SESSION_ENV]: root.rootSessionId,\n [SUBAGENT_TEAM_MAIN_MEMBER_ENV]: root.mainMemberId,\n };\n}\n\n/**\n * The environment a child needs to act as this member.\n *\n * The token travels only to the process that IS this member, which is what\n * makes FIX 4 coherent: the secret goes down the spawn path, never sideways in\n * an envelope.\n */\nexport function nativeTeamMemberEnvironment(context: TeamMemberContext): Record<string, string> {\n return {\n ...nativeTeamRootEnvironment(context),\n [SUBAGENT_TEAM_MEMBER_ID_ENV]: context.memberId,\n [SUBAGENT_TEAM_MEMBER_TOKEN_ENV]: context.token,\n };\n}\n\nexport function clearNativeTeamMemberEnvironment(): Record<string, undefined> {\n return {\n [SUBAGENT_TEAM_MEMBER_ID_ENV]: undefined,\n [SUBAGENT_TEAM_MEMBER_TOKEN_ENV]: undefined,\n };\n}\n\nexport function applyNativeTeamRootEnvironment(root: TeamRootContext): void {\n Object.assign(process.env, nativeTeamRootEnvironment(root));\n}\n\nexport function clearNativeTeamRootEnvironment(root?: TeamRootContext): void {\n if (root && process.env[SUBAGENT_TEAM_ID_ENV] !== root.teamId) return;\n delete process.env[SUBAGENT_TEAM_ID_ENV];\n delete process.env[SUBAGENT_TEAM_ROOT_SESSION_ENV];\n delete process.env[SUBAGENT_TEAM_MAIN_MEMBER_ENV];\n}\n\nexport function readNativeTeamRootFromEnvironment(): TeamRootContext | undefined {\n const teamId = textEnv(SUBAGENT_TEAM_ID_ENV);\n const rootSessionId = textEnv(SUBAGENT_TEAM_ROOT_SESSION_ENV);\n const mainMemberId = textEnv(SUBAGENT_TEAM_MAIN_MEMBER_ENV);\n if (!teamId || !isSafeId(teamId) || !rootSessionId || mainMemberId !== MAIN_MEMBER_ID) return undefined;\n if (teamId !== teamIdForSession(rootSessionId)) return undefined;\n const record = parseTeamRecord(readJsonRecord(path.join(teamDir(teamId), TEAM_FILE)));\n if (!record || record.rootSessionId !== rootSessionId || record.teamId !== teamId) return undefined;\n return { version: TEAM_ROOT_VERSION, teamId, rootSessionId, mainMemberId };\n}\n\nfunction validateTaskMetadata(task: TeamTaskMetadata | undefined): TeamTaskMetadata | undefined {\n if (!task) return undefined;\n const id = task.id.trim();\n const subject = task.subject.trim();\n if (!id || !withinBytes(id, MAX_TASK_ID_BYTES))\n throw new Error(`Native team task id must be between 1 and ${MAX_TASK_ID_BYTES} bytes.`);\n if (!subject || !withinBytes(subject, MAX_TASK_SUBJECT_BYTES))\n throw new Error(`Native team task subject must be between 1 and ${MAX_TASK_SUBJECT_BYTES} bytes.`);\n return { id, subject };\n}\n\nexport interface RegisterNativeTeamMemberInput {\n root: TeamRootContext;\n role: TeamMemberRole;\n /** Explicit name. Becomes the member id verbatim once normalized. */\n name?: string;\n agent?: string;\n runId?: string;\n childIndex?: number;\n /** Present when this member is child N of a fanout; drives the `-N` suffix. */\n fanoutIndex?: number;\n parentMemberId?: string;\n task?: TeamTaskMetadata;\n pid?: number;\n}\n\n/**\n * Resolve the member id, which is also the member's name.\n *\n * Precedence is explicit name, then the agent name, because the caller that\n * passed a name meant it, while an agent name is only a sensible default.\n */\nfunction resolveMemberId(input: RegisterNativeTeamMemberInput): string {\n if (input.role === 'main') return input.root.mainMemberId;\n const explicit = input.name !== undefined;\n if (!explicit && !input.agent) throw new Error('An intercom member needs a name or an agent to derive one from.');\n const base = guardReservedName(normalizeTeamMemberName(input.name ?? input.agent ?? FALLBACK_MEMBER_NAME), explicit);\n if (input.runId) {\n const suffix = normalizeTeamMemberName(input.runId).slice(0, 8);\n const room = MAX_MEMBER_NAME_LENGTH - suffix.length - FANOUT_SUFFIX_SEPARATOR.length;\n return `${base.slice(0, room).replace(SURROUNDING_SEPARATORS, '') || FALLBACK_MEMBER_NAME}-${suffix}`;\n }\n return input.fanoutIndex === undefined ? base : withFanoutOrdinal(base, input.fanoutIndex);\n}\n\n/**\n * Claim a name and join the team. Latest claimant wins.\n *\n * Taking a name over rotates the token, so the previous holder's next\n * `assertCurrentMember` fails and it stops acting as that member. Its inbox is\n * purged in the same step: those messages were addressed to a different process\n * with a different task, and delivering them to the new holder would be worse\n * than dropping them, since the sender is still alive to be told.\n */\nexport function registerNativeTeamMember(input: RegisterNativeTeamMemberInput): {\n context: TeamMemberContext;\n dispose: () => void;\n} {\n const memberId = resolveMemberId(input);\n if (!isSafeId(memberId)) throw new Error('A safe native team member id is required.');\n const memberToken = newToken();\n const tokenHash = hash(memberToken);\n const now = Date.now();\n const task = validateTaskMetadata(input.task);\n const context: TeamMemberContext = {\n ...input.root,\n memberId,\n token: memberToken,\n role: input.role,\n ...(input.agent ? { agent: input.agent } : {}),\n ...(input.runId ? { runId: input.runId } : {}),\n ...(input.childIndex !== undefined ? { childIndex: input.childIndex } : {}),\n ...(input.parentMemberId ? { parentMemberId: input.parentMemberId } : {}),\n ...(task ? { task } : {}),\n };\n const previous = readMember(input.root, memberId);\n if (previous && previous.tokenHash !== tokenHash) removeDirectory(inboxDir(input.root, memberId));\n\n const { token: _unusedToken, version: _unusedVersion, ...identity } = context;\n const record: TeamMemberRecord = {\n ...identity,\n version: MEMBER_RECORD_VERSION,\n tokenHash,\n pid: input.pid ?? process.pid,\n active: true,\n joinedAt: now,\n };\n writeMemberRecord(record);\n writeHeartbeat(input.root, record, now);\n\n let disposed = false;\n return {\n context,\n dispose: () => {\n if (disposed) return;\n disposed = true;\n const current = readMember(input.root, memberId);\n // The name may already have been taken over. Writing then would hand the\n // new holder an inactive record it never asked for.\n if (!current || current.tokenHash !== tokenHash) return;\n const leftAt = Date.now();\n writeMemberRecord({ ...current, active: false, leftAt });\n writeHeartbeat(input.root, current, leftAt);\n },\n };\n}\n\nexport function readNativeTeamMemberFromEnvironment(): TeamMemberContext | undefined {\n const root = readNativeTeamRootFromEnvironment();\n const memberId = textEnv(SUBAGENT_TEAM_MEMBER_ID_ENV);\n const memberToken = textEnv(SUBAGENT_TEAM_MEMBER_TOKEN_ENV);\n if (!root || !memberId || !isSafeId(memberId) || !memberToken) return undefined;\n const member = readMember(root, memberId);\n if (!member || member.teamId !== root.teamId || member.rootSessionId !== root.rootSessionId) return undefined;\n if (member.tokenHash !== hash(memberToken) || !member.active) return undefined;\n return {\n ...root,\n memberId,\n token: memberToken,\n role: member.role,\n ...(member.agent ? { agent: member.agent } : {}),\n ...(member.runId ? { runId: member.runId } : {}),\n ...(member.childIndex !== undefined ? { childIndex: member.childIndex } : {}),\n ...(member.parentMemberId ? { parentMemberId: member.parentMemberId } : {}),\n ...(member.task ? { task: member.task } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Messaging\n// ---------------------------------------------------------------------------\n\nfunction assertCurrentMember(context: TeamMemberContext, now: number): TeamMemberRecord {\n const member = readMember(context, context.memberId);\n if (!member || member.tokenHash !== hash(context.token) || !memberIsActive(context, member, now))\n throw new Error('This native team member is no longer active.');\n return member;\n}\n\nfunction resolveTarget(context: TeamMemberContext, to: string | undefined, now: number): TeamMemberRecord {\n const query = to?.trim();\n if (!query) throw invalidRequest('to is required for intercom send and ask.', 'Provide an explicit recipient.');\n const members = listActiveMembers(context, now).filter((member) => member.memberId !== context.memberId);\n const normalized = normalizeTeamMemberName(query);\n // The name is the id, so an id match is the answer whenever there is one.\n const exact = members.find((member) => member.memberId === query || member.memberId === normalized);\n if (exact) return exact;\n const lowered = query.toLowerCase();\n const matches = members.filter(\n (member) =>\n member.agent?.toLowerCase() === lowered ||\n member.runId?.toLowerCase() === lowered ||\n (lowered === MAIN_MEMBER_ID && member.role === 'main'),\n );\n if (matches.length === 1) return matches[0] as TeamMemberRecord;\n if (matches.length > 1) {\n throw new DoomTeamExpectedError(\n 'recipient_ambiguous',\n `Multiple active intercom members match '${query}': ${matches.map((member) => member.memberId).join(', ')}.`,\n false,\n 'Retry with one exact member id.',\n );\n }\n throw new DoomTeamExpectedError(\n 'recipient_not_found',\n `Active intercom member '${query}' was not found.`,\n true,\n 'Call intercom({\"action\":\"members\"}) and retry with an active member id.',\n );\n}\n\nfunction validateMessage(message: string | undefined): string {\n const normalized = message?.trim();\n if (!normalized)\n throw invalidRequest('message is required for intercom communication.', 'Provide a nonblank message.');\n if (!withinBytes(normalized, MAX_MESSAGE_BYTES)) {\n throw invalidRequest('Intercom message exceeds 64 KiB.', 'Shorten the message and retry.');\n }\n return normalized;\n}\n\n/**\n * Does this envelope really come from the member it names?\n *\n * FIX 4: compares hashes. The caller separately knows the file was found in its\n * own inbox directory, which is the other half of the check the predecessor\n * replaced with a bearer token it then leaked to the recipient.\n */\nfunction senderAuthenticated(root: TeamRootContext, memberId: string, senderTokenHash: string): boolean {\n const member = readMember(root, memberId);\n return Boolean(member && member.tokenHash === senderTokenHash);\n}\n\ninterface InboxScan {\n /** Deliverable, ordered per FIX 2. */\n messages: TeamMessageEnvelope[];\n /**\n * Files that parsed but belong to another team or another member.\n *\n * FIX 3: they are NOT removed, because they are not ours to destroy, and they\n * are reported so the caller can mark them seen. The predecessor left them in\n * place and unmarked, so every poll re-read and re-parsed every one of them.\n */\n foreignFiles: string[];\n}\n\nfunction scanInbox(context: TeamMemberContext, now: number, skip?: (fileName: string) => boolean): InboxScan {\n const dir = inboxDir(context, context.memberId);\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n // The inbox is created at registration; a missing one means this member has\n // been collected or has not finished joining, and there is nothing to read.\n return { messages: [], foreignFiles: [] };\n }\n const messages: TeamMessageEnvelope[] = [];\n const foreignFiles: string[] = [];\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(JSON_FILE_SUFFIX)) continue;\n // Checked before the file is opened: this is what keeps an already-handled\n // file from costing a read and a parse on every poll.\n if (skip?.(entry.name)) continue;\n const file = path.join(dir, entry.name);\n const envelope = parseMessageEnvelope(readJsonRecord(file));\n if (!envelope) {\n // Unparseable JSON in our own inbox is corrupt, not foreign: the atomic\n // writer's partial files are named `.tmp` and never seen here.\n removeFile(file);\n continue;\n }\n if (envelope.teamId !== context.teamId || envelope.toMemberId !== context.memberId) {\n foreignFiles.push(entry.name);\n continue;\n }\n if (envelope.expiresAt < now || !senderAuthenticated(context, envelope.fromMemberId, envelope.senderTokenHash)) {\n // Ours, and unusable: expired past its TTL, or from a member whose record\n // is gone so the message can never be authenticated.\n removeFile(file);\n continue;\n }\n messages.push(envelope);\n }\n return { messages: orderBySenderSequence(messages), foreignFiles };\n}\n\n/** The minimum a caller needs to know an ask exists, is addressed to a member, and is unanswered. */\nexport interface PendingTeamAsk {\n id: string;\n fromMemberId: string;\n createdAt: number;\n}\n\n/**\n * Unanswered `ask`s addressed to `targetMemberId`, for a runner-side caller\n * that is not `targetMemberId` itself and does not hold its token (for\n * example a deliverable guard checking on a subagent it spawned).\n *\n * READ-ONLY, DELIBERATELY NOT `scanInbox`: `scanInbox` deletes a corrupt file,\n * an expired file, and a file whose sender no longer authenticates, as a side\n * effect of scanning. That is correct for a poll loop, which owns the inbox\n * and is allowed to clean it up, but it is exactly wrong for a diagnostic\n * read: consuming a message as a side effect of merely asking about it would\n * make the message vanish for its real recipient, which is a worse bug than\n * the one this function exists to answer. This function only ever SKIPS a\n * file it cannot use when deciding what to report; it never calls\n * `removeFile` and never touches any in-memory \"seen\" state (it has no access\n * to another process's runtime instance to touch even if it wanted to). Do\n * not refactor this to share the scan loop with `scanInbox` -- that would\n * reintroduce the deletion as a side effect of a read.\n *\n * \"Unanswered\" needs no extra flag and none should be added: `replyToRequest`\n * removes the request file on reply, and `waitForReply`'s `finally` removes\n * it on timeout or cancellation too, so a valid, unexpired, sender-\n * authenticated `ask` file still sitting in the inbox always means nobody has\n * replied to it yet. A separate `answered` boolean would just be a second\n * place that fact could go stale.\n *\n * AUTHENTICATION: `caller` must be a currently active member of this exact\n * team, verified the same way every tool action verifies its caller\n * (`assertCurrentMember`). This is DELIBERATELY NARROWER than the plain\n * `TeamRootContext` the other exported readers (`readMember`, `readHeartbeat`,\n * `listMemberRecords`) accept, and that narrowing is not an inconsistency to\n * \"fix\" by loosening this to match them: a `TeamRootContext` is cheap to\n * reconstruct from a bare `rootSessionId` (`teamIdForSession` is a pure\n * function of it), so those readers' bar is really \"knows or can guess a\n * session id\". That is an acceptable bar for a static roster (who exists,\n * their role, their task) -- the same thing `list`/`status` already hand to\n * any member. It is not an acceptable bar for this function: who is asking\n * whom, and when, is a live activity signal, not roster data, so this\n * requires proof the caller is a real, currently-registered member with a\n * token that hashes to what is on disk. It deliberately does NOT require\n * `targetMemberId`'s own token: requiring that would mean handing it out to a\n * process that is not that member, which is exactly the impersonation\n * capability removing `senderToken` from the envelope (FIX 4) was there to\n * prevent. Do not let a future \"simplification\" walk either of those back.\n */\nexport function pendingAsksAddressedTo(\n caller: TeamMemberContext,\n targetMemberId: string,\n now: number,\n): PendingTeamAsk[] {\n assertCurrentMember(caller, now);\n if (!isSafeId(targetMemberId)) return [];\n const dir = inboxDir(caller, targetMemberId);\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n // No inbox for this member: nothing pending, not an error.\n return [];\n }\n const pending: PendingTeamAsk[] = [];\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(JSON_FILE_SUFFIX)) continue;\n const envelope = parseMessageEnvelope(readJsonRecord(path.join(dir, entry.name)));\n if (!envelope || envelope.kind !== 'ask') continue;\n if (envelope.teamId !== caller.teamId || envelope.toMemberId !== targetMemberId) continue;\n if (envelope.expiresAt < now) continue;\n if (!senderAuthenticated(caller, envelope.fromMemberId, envelope.senderTokenHash)) continue;\n pending.push({ id: envelope.id, fromMemberId: envelope.fromMemberId, createdAt: envelope.createdAt });\n }\n return pending.sort((left, right) => left.createdAt - right.createdAt || left.id.localeCompare(right.id));\n}\n\n/**\n * FIX 2: order within a sender by `seq`, and between senders by time.\n *\n * Implemented as a merge of per-sender queues rather than one comparator,\n * because \"same sender by seq, different senders by createdAt\" is not a\n * transitive relation and `Array.sort` on it would produce an order that\n * depends on the initial file listing.\n */\nfunction orderBySenderSequence(messages: TeamMessageEnvelope[]): TeamMessageEnvelope[] {\n const bySender = new Map<string, TeamMessageEnvelope[]>();\n for (const envelope of messages) {\n const queue = bySender.get(envelope.fromMemberId);\n if (queue) queue.push(envelope);\n else bySender.set(envelope.fromMemberId, [envelope]);\n }\n const queues: TeamMessageEnvelope[][] = [];\n for (const queue of bySender.values()) {\n queue.sort((left, right) => left.seq - right.seq);\n queues.push(queue);\n }\n const ordered: TeamMessageEnvelope[] = [];\n for (;;) {\n let chosen: TeamMessageEnvelope[] | undefined;\n let chosenHead: TeamMessageEnvelope | undefined;\n for (const queue of queues) {\n const head = queue[0];\n if (!head) continue;\n if (\n !chosenHead ||\n head.createdAt < chosenHead.createdAt ||\n (head.createdAt === chosenHead.createdAt && head.fromMemberId < chosenHead.fromMemberId)\n ) {\n chosen = queue;\n chosenHead = head;\n }\n }\n if (!chosen || !chosenHead) break;\n chosen.shift();\n ordered.push(chosenHead);\n }\n return ordered;\n}\n\nfunction formatMember(member: TeamMemberRecord): string {\n const identity = member.role === 'main' ? MAIN_MEMBER_ID : (member.agent ?? member.memberId);\n const run = member.runId ? ` [${member.runId}]` : '';\n const task = member.task ? `, task ${member.task.id}: ${member.task.subject}` : '';\n return `- ${member.memberId}: ${identity}${run}${task}`;\n}\n\nfunction publicMember(member: TeamMemberRecord): NativeTeamMemberSnapshot {\n return {\n name: member.memberId,\n role: member.role,\n ...(member.agent ? { agent: member.agent } : {}),\n ...(member.runId ? { runId: member.runId } : {}),\n ...(member.task ? { task: member.task } : {}),\n };\n}\n\nfunction delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error('Native team request cancelled.'));\n return;\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n const cleanup = (): void => {\n if (timer) clearTimeout(timer);\n signal?.removeEventListener('abort', onAbort);\n };\n const onAbort = (): void => {\n cleanup();\n reject(new Error('Native team request cancelled.'));\n };\n timer = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nfunction formatIncomingMessage(context: TeamMemberContext, envelope: TeamMessageEnvelope): string {\n const sender = readMember(context, envelope.fromMemberId);\n const identity = `${envelope.fromMemberId}${sender?.agent ? ` (${sender.agent})` : ''}`;\n const task = sender?.task ? `, task ${sender.task.id}` : '';\n const lines = [`${envelope.kind === 'ask' ? 'Question' : 'Message'} from ${identity}${task}.`];\n lines.push('', envelope.message);\n if (envelope.kind === 'ask') {\n lines.push(\n '',\n `Reply with ${NATIVE_TEAM_TOOL_NAME}({ action: \"reply\", requestId: \"${envelope.id}\", message: \"...\" }).`,\n );\n }\n return lines.join('\\n');\n}\n\nfunction hasTool(pi: ExtensionAPI, name: string): boolean {\n try {\n return pi.getAllTools().some((tool) => tool.name === name);\n } catch {\n // Tool enumeration is unavailable before the host binds its context. Saying\n // \"not registered\" is safe: registerTool is idempotent for our name.\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Runtime\n// ---------------------------------------------------------------------------\n\nexport interface NativeTeamRuntime {\n bindMainSession(rootSessionId: string): TeamMemberContext;\n bindChildFromEnvironment(): TeamMemberContext | undefined;\n current(): TeamMemberContext | undefined;\n /** Messages given up on after `MAX_DELIVERY_ATTEMPTS`, most recent last. */\n undeliverable(): readonly UndeliverableTeamMessage[];\n dispose(): void;\n}\n\n/** Timing and limits, supplied by the service so tests can subclass and vary. */\ninterface TeamRuntimeOptions {\n pollIntervalMs: number;\n replyPollIntervalMs: number;\n heartbeatIntervalMs: number;\n gcIntervalMs: number;\n askTimeoutMs: number;\n maxDeliveryAttempts: number;\n now: () => number;\n}\n\nclass TeamChannelRuntime implements NativeTeamRuntime {\n private context: TeamMemberContext | undefined;\n private ownedMembershipDispose: (() => void) | undefined;\n private poller: ReturnType<typeof setInterval> | undefined;\n private lastHeartbeatAt = 0;\n private lastGcAt = 0;\n /** FIX 5: bounded. Keyed by file name so FIX 3 can skip before opening. */\n private readonly seenFiles = new BoundedKeySet<string>(SEEN_FILE_CAPACITY);\n private readonly deliveryAttempts = new LruCache<string, number>(DELIVERY_ATTEMPT_CAPACITY);\n private readonly undeliverableMessages: UndeliverableTeamMessage[] = [];\n /** FIX 2: this member's outbound counter, monotonic for its whole lifetime. */\n private outboundSeq = 0;\n\n constructor(\n private readonly pi: ExtensionAPI,\n private readonly options: TeamRuntimeOptions,\n ) {\n if (hasTool(pi, NATIVE_TEAM_TOOL_NAME)) {\n throw new Error(\n `[tool_conflict] A foreign '${NATIVE_TEAM_TOOL_NAME}' tool is already registered. ` +\n 'Recovery: disable the competing extension and reload Doom Team.',\n );\n }\n pi.registerTool(this.buildTool());\n }\n\n current(): TeamMemberContext | undefined {\n return this.context;\n }\n\n undeliverable(): readonly UndeliverableTeamMessage[] {\n return this.undeliverableMessages;\n }\n\n bindMainSession(rootSessionId: string): TeamMemberContext {\n const root = ensureNativeTeamRoot(rootSessionId);\n applyNativeTeamRootEnvironment(root);\n const membership = registerNativeTeamMember({ root, role: 'main' });\n return this.startBinding(membership.context, membership.dispose);\n }\n\n bindChildFromEnvironment(): TeamMemberContext | undefined {\n const childContext = readNativeTeamMemberFromEnvironment();\n if (!childContext) return undefined;\n if (this.context?.memberId === childContext.memberId && this.context.token === childContext.token)\n return this.context;\n return this.startBinding(childContext);\n }\n\n dispose(): void {\n const previous = this.context;\n this.stopBinding();\n if (previous?.role === 'main') clearNativeTeamRootEnvironment(previous);\n }\n\n private startBinding(nextContext: TeamMemberContext, dispose?: () => void): TeamMemberContext {\n this.stopBinding();\n this.context = nextContext;\n this.ownedMembershipDispose = dispose;\n this.poll();\n this.poller = setInterval(() => {\n this.poll();\n }, this.options.pollIntervalMs);\n this.poller.unref?.();\n return nextContext;\n }\n\n private stopBinding(): void {\n if (this.poller) clearInterval(this.poller);\n this.poller = undefined;\n this.ownedMembershipDispose?.();\n this.ownedMembershipDispose = undefined;\n this.seenFiles.clear();\n this.deliveryAttempts.clear();\n this.lastHeartbeatAt = 0;\n this.lastGcAt = 0;\n this.outboundSeq = 0;\n this.context = undefined;\n }\n\n private poll(): void {\n const context = this.context;\n if (!context) return;\n const now = this.options.now();\n this.heartbeat(context, now);\n this.collectGarbageIfDue(context, now);\n const scan = scanInbox(context, now, (fileName) => this.seenFiles.has(fileName));\n // FIX 3: skipped from here on, at the cost of one Set entry rather than a\n // read and a parse on every future poll.\n for (const fileName of scan.foreignFiles) this.seenFiles.add(fileName);\n for (const envelope of scan.messages) this.deliverOnce(context, envelope);\n }\n\n /**\n * FIX 1: deliver, then mark seen. Never the other way round.\n *\n * The predecessor added the id to its seen set and then called an unguarded\n * `deliver`. A throw from the host left the message marked as handled while it\n * had never been shown to anyone, and since it was seen it was never retried:\n * the message was lost with no trace. Here a failure leaves the file unseen so\n * the next poll retries it, and the attempt count is what stops a message the\n * host will never accept from blocking the inbox forever.\n */\n private deliverOnce(context: TeamMemberContext, envelope: TeamMessageEnvelope): void {\n const fileName = messageFileName(envelope.id);\n try {\n this.deliver(context, envelope);\n } catch (error) {\n const attempts = (this.deliveryAttempts.get(fileName) ?? 0) + FIRST_DELIVERY_ATTEMPT;\n if (attempts < this.options.maxDeliveryAttempts) {\n this.deliveryAttempts.set(fileName, attempts);\n return;\n }\n this.deliveryAttempts.delete(fileName);\n this.seenFiles.add(fileName);\n this.reportUndeliverable(context, envelope, attempts, error);\n return;\n }\n this.seenFiles.add(fileName);\n this.deliveryAttempts.delete(fileName);\n writePrivateAtomicJson(receiptPath(context, envelope.fromMemberId, envelope.id), {\n version: RECEIPT_VERSION,\n messageId: envelope.id,\n state: RECEIPT_DELIVERED,\n deliveredAt: this.options.now(),\n });\n // An `ask` file has to survive delivery: `replyToRequest` reads it back to\n // prove the reply answers a real question.\n if (envelope.kind === 'send') removeFile(messagePath(context, context.memberId, envelope.id));\n }\n\n private deliver(context: TeamMemberContext, envelope: TeamMessageEnvelope): void {\n const content = formatIncomingMessage(context, envelope);\n if (context.role === 'subagent') {\n // A subagent is mid-task, so the message is steered into the running turn\n // rather than starting a new one.\n this.pi.sendUserMessage(content, { deliverAs: 'steer' });\n return;\n }\n this.pi.sendMessage(\n {\n customType: TEAM_MESSAGE_CUSTOM_TYPE,\n content,\n display: true,\n details: {\n id: envelope.id,\n kind: envelope.kind,\n from: envelope.fromMemberId,\n to: envelope.toMemberId,\n seq: envelope.seq,\n },\n },\n { triggerTurn: true, deliverAs: 'steer' },\n );\n }\n\n private reportUndeliverable(\n context: TeamMemberContext,\n envelope: TeamMessageEnvelope,\n attempts: number,\n error: unknown,\n ): void {\n const record: UndeliverableTeamMessage = {\n messageId: envelope.id,\n fromMemberId: envelope.fromMemberId,\n kind: envelope.kind,\n attempts,\n reason: errorText(error),\n at: this.options.now(),\n };\n this.undeliverableMessages.push(record);\n writePrivateAtomicJson(receiptPath(context, envelope.fromMemberId, envelope.id), {\n version: RECEIPT_VERSION,\n messageId: envelope.id,\n state: RECEIPT_FAILED,\n reason: record.reason,\n failedAt: record.at,\n });\n while (this.undeliverableMessages.length > UNDELIVERABLE_HISTORY_LIMIT) this.undeliverableMessages.shift();\n try {\n this.pi.sendMessage(\n {\n customType: TEAM_UNDELIVERABLE_CUSTOM_TYPE,\n content: `Native team message ${envelope.id} from ${envelope.fromMemberId} could not be delivered after ${attempts} attempts: ${record.reason}`,\n display: true,\n details: { ...record },\n },\n { triggerTurn: true, deliverAs: 'steer' },\n );\n } catch {\n // The notice travels over the transport that just refused the message, so\n // it can fail for the same reason. `undeliverable()` is then the only\n // record, and rethrowing here would abort the poll and stall every other\n // sender's messages behind this one.\n }\n }\n\n /** FIX 6: writes only this member's own heartbeat file. */\n private heartbeat(context: TeamMemberContext, now: number): void {\n if (now - this.lastHeartbeatAt < this.options.heartbeatIntervalMs) return;\n const member = readMember(context, context.memberId);\n if (!member || member.tokenHash !== hash(context.token) || !member.active) return;\n this.lastHeartbeatAt = now;\n writeHeartbeat(context, member, now);\n }\n\n private collectGarbageIfDue(context: TeamMemberContext, now: number): void {\n if (now - this.lastGcAt < this.options.gcIntervalMs) return;\n this.lastGcAt = now;\n try {\n collectDeadMembers(context, context.memberId, now);\n } catch (error) {\n // FIX 7 is housekeeping, not delivery. A sweep that fails is retried on\n // the next interval; letting it escape would stop the poll that delivers\n // messages, which is strictly worse than a directory left on disk.\n this.undeliverableMessages.push({\n messageId: '',\n fromMemberId: context.memberId,\n kind: 'send',\n attempts: 0,\n reason: `Native team directory sweep failed: ${errorText(error)}`,\n at: now,\n });\n while (this.undeliverableMessages.length > UNDELIVERABLE_HISTORY_LIMIT) this.undeliverableMessages.shift();\n }\n }\n\n private nextSeq(): number {\n this.outboundSeq += 1;\n return this.outboundSeq;\n }\n\n private queueMessage(\n context: TeamMemberContext,\n target: TeamMemberRecord,\n kind: TeamMessageKind,\n message: string,\n now: number,\n messageId: string,\n ): TeamMessageEnvelope {\n assertCurrentMember(context, now);\n if (!memberIsActive(context, target, now))\n throw new Error(`Native team member '${target.memberId}' is no longer active.`);\n const envelope: TeamMessageEnvelope = {\n type: TEAM_MESSAGE_TYPE,\n version: ENVELOPE_VERSION,\n id: messageId,\n teamId: context.teamId,\n kind,\n fromMemberId: context.memberId,\n toMemberId: target.memberId,\n senderTokenHash: hash(context.token),\n seq: this.nextSeq(),\n message,\n createdAt: now,\n expiresAt: now + MESSAGE_TTL_MS,\n };\n fs.mkdirSync(inboxDir(context, target.memberId), { recursive: true, mode: PRIVATE_DIRECTORY_MODE });\n writePrivateAtomicJson(messagePath(context, target.memberId, envelope.id), envelope);\n return envelope;\n }\n\n private replyToRequest(\n context: TeamMemberContext,\n requestId: string | undefined,\n message: string,\n now: number,\n ): TeamReplyEnvelope {\n if (!requestId || !isSafeId(requestId)) throw new Error('requestId must be a valid intercom request id.');\n assertCurrentMember(context, now);\n const requestFile = messagePath(context, context.memberId, requestId);\n const request = parseMessageEnvelope(readJsonRecord(requestFile));\n if (\n !request ||\n request.kind !== 'ask' ||\n request.teamId !== context.teamId ||\n request.toMemberId !== context.memberId ||\n !senderAuthenticated(context, request.fromMemberId, request.senderTokenHash)\n )\n throw new DoomTeamExpectedError(\n 'recipient_not_found',\n `No pending intercom ask matches requestId '${requestId}'.`,\n false,\n 'Call intercom({\"action\":\"pending\"}) and retry with an exact requestId.',\n );\n const reply: TeamReplyEnvelope = {\n type: TEAM_REPLY_TYPE,\n version: ENVELOPE_VERSION,\n requestId,\n teamId: context.teamId,\n fromMemberId: context.memberId,\n toMemberId: request.fromMemberId,\n senderTokenHash: hash(context.token),\n message,\n createdAt: now,\n };\n writePrivateAtomicJson(replyPath(context, requestId), reply);\n removeFile(requestFile);\n this.seenFiles.delete(messageFileName(requestId));\n return reply;\n }\n\n private async waitForReply(\n context: TeamMemberContext,\n target: TeamMemberRecord,\n request: TeamMessageEnvelope,\n signal: AbortSignal | undefined,\n timeoutMs?: number,\n ): Promise<TeamReplyEnvelope> {\n const file = replyPath(context, request.id);\n const deadline = this.options.now() + (timeoutMs ?? this.options.askTimeoutMs);\n while (this.options.now() <= deadline) {\n if (signal?.aborted) throw new Error('Native team request cancelled.');\n const reply = parseReplyEnvelope(readJsonRecord(file));\n if (\n reply &&\n reply.teamId === context.teamId &&\n reply.requestId === request.id &&\n reply.fromMemberId === target.memberId &&\n reply.toMemberId === context.memberId &&\n senderAuthenticated(context, reply.fromMemberId, reply.senderTokenHash)\n ) {\n removeFile(file);\n return reply;\n }\n const currentTarget = readMember(context, target.memberId);\n if (!currentTarget || !memberIsActive(context, currentTarget, this.options.now()))\n throw new DoomTeamExpectedError(\n 'communication_unavailable',\n `Intercom member '${target.memberId}' became unreachable before replying.`,\n true,\n 'Call intercom({\"action\":\"members\"}) and decide whether to retry with an active member.',\n );\n await delay(this.options.replyPollIntervalMs, signal);\n }\n throw new DoomTeamExpectedError(\n 'reply_timeout',\n `Timed out waiting for intercom member '${target.memberId}' to reply.`,\n true,\n 'Check member status before deciding whether to ask again.',\n );\n }\n\n private buildTool(): ToolDefinition<typeof TeamToolParamsSchema, Record<string, unknown>> {\n return {\n name: NATIVE_TEAM_TOOL_NAME,\n label: 'Intercom',\n description:\n 'Communicate with active agents in this root session. Use members, send, ask, pending, or reply. The stable root identity is main.',\n promptGuidelines: [\n 'Send only new progress, blockers, or decisions. Do not repeat the task brief, sender task, or delegation instructions because the recipient already has them.',\n ],\n parameters: TeamToolParamsSchema,\n execute: async (operationId, rawParams, signal, onUpdate): Promise<AgentToolResult<Record<string, unknown>>> => {\n const context = this.context;\n if (!context) {\n throw new DoomTeamExpectedError(\n 'communication_unavailable',\n 'Intercom is not active for this session.',\n true,\n 'Wait for session startup or reload Doom Team.',\n );\n }\n const params = parseTeamToolParams(rawParams);\n const now = this.options.now();\n assertCurrentMember(context, now);\n\n if (params.action === 'members') {\n const members = listActiveMembers(context, now);\n return {\n content: [\n { type: 'text', text: members.length ? members.map(formatMember).join('\\n') : 'No active members.' },\n ],\n details: { members: members.map(publicMember) },\n };\n }\n if (params.action === 'pending') {\n // Deliberately scans without the seen filter: a pending ask has been\n // delivered already, so filtering by seen would hide every one of them.\n const asks = scanInbox(context, now).messages.filter((message) => message.kind === 'ask');\n const lines = asks.map(\n (ask) =>\n `- ${ask.id}: from ${ask.fromMemberId}. Reply with ${NATIVE_TEAM_TOOL_NAME}({ action: \"reply\", requestId: \"${ask.id}\", message: \"...\" }).`,\n );\n return {\n content: [{ type: 'text', text: lines.length ? lines.join('\\n') : 'No pending native team asks.' }],\n details: { pending: asks.map((ask) => ({ id: ask.id, from: ask.fromMemberId, message: ask.message })) },\n };\n }\n\n const message = validateMessage(params.message);\n if (params.action === 'reply') {\n const reply = this.replyToRequest(context, params.requestId, message, now);\n return {\n content: [{ type: 'text', text: `Replied to native team request ${reply.requestId}.` }],\n details: { requestId: reply.requestId, to: reply.toMemberId },\n };\n }\n\n const target = resolveTarget(context, params.to, now);\n if (params.action === 'ask') {\n onUpdate?.({\n content: [{ type: 'text', text: `Waiting for ${target.memberId} to reply...` }],\n details: { action: 'ask', to: target.memberId, partial: true },\n });\n }\n const messageId = operationMessageId(context.memberId, operationId);\n const existingReceipt = readJsonRecord(receiptPath(context, context.memberId, messageId));\n if (existingReceipt?.state === RECEIPT_FAILED) {\n const reason = typeof existingReceipt.reason === 'string' ? existingReceipt.reason : 'unknown error';\n throw new DoomTeamExpectedError(\n 'delivery_unconfirmed',\n `Intercom message ${messageId} failed: ${reason}`,\n false,\n 'Call intercom({\"action\":\"members\"}) and do not resend automatically.',\n );\n }\n if (params.action === 'send' && existingReceipt?.state === RECEIPT_DELIVERED) {\n return {\n content: [{ type: 'text', text: `Message ${messageId} delivered to ${target.memberId}.` }],\n details: { state: RECEIPT_DELIVERED, delivered: true, messageId, to: target.memberId },\n };\n }\n const request = this.queueMessage(context, target, params.action, message, now, messageId);\n if (params.action === 'send') {\n return {\n content: [\n {\n type: 'text',\n text: `Message ${request.id} queued for ${target.memberId}; delivery is not yet confirmed. Do not resend.`,\n },\n ],\n details: {\n state: 'queued',\n delivered: false,\n messageId: request.id,\n to: target.memberId,\n seq: request.seq,\n },\n };\n }\n try {\n const reply = await this.waitForReply(context, target, request, signal, params.timeoutMs);\n return {\n content: [{ type: 'text', text: `Reply from ${target.memberId}:\\n${reply.message}` }],\n details: { requestId: request.id, from: target.memberId, reply: reply.message },\n };\n } finally {\n // Whether it was answered, timed out or cancelled, the ask must not\n // stay in the target's inbox waiting for a reply nobody is reading.\n removeFile(messagePath(context, target.memberId, request.id));\n }\n },\n };\n }\n}\n\nexport interface INativeTeamChannelService {\n /** Create (or reuse) the runtime bound to one host instance. */\n createRuntime(pi: ExtensionAPI): NativeTeamRuntime;\n /** Bind this process as a team member when its environment says it is one. */\n registerClient(pi: ExtensionAPI): void;\n}\n\n/**\n * Owner of every team runtime in the process.\n *\n * WHY THIS IS A SERVICE AND NOT A MODULE-LEVEL WEAKMAP:\n * The predecessor kept the per-host runtime registry in a module-level WeakMap,\n * so the registry outlived any single session and could not be reset between\n * tests or between two sessions in one process. Timing lives here too: the\n * container resolves this by type and inversify cannot supply a primitive, so\n * intervals are protected members that a test subclass overrides, not\n * constructor arguments.\n */\n@injectable()\nexport class NativeTeamChannelService implements INativeTeamChannelService {\n private readonly runtimes = new WeakMap<ExtensionAPI, NativeTeamRuntime>();\n\n protected readonly pollIntervalMs: number = CHANNEL_POLL_MS;\n protected readonly replyPollIntervalMs: number = REPLY_POLL_MS;\n protected readonly heartbeatIntervalMs: number = HEARTBEAT_INTERVAL_MS;\n protected readonly gcIntervalMs: number = TEAM_GC_INTERVAL_MS;\n protected readonly askTimeoutMs: number = DEFAULT_ASK_TIMEOUT_MS;\n protected readonly maxDeliveryAttempts: number = MAX_DELIVERY_ATTEMPTS;\n\n protected now(): number {\n return Date.now();\n }\n\n createRuntime(pi: ExtensionAPI): NativeTeamRuntime {\n const existing = this.runtimes.get(pi);\n if (existing) return existing;\n const runtime = new TeamChannelRuntime(pi, {\n pollIntervalMs: this.pollIntervalMs,\n replyPollIntervalMs: this.replyPollIntervalMs,\n heartbeatIntervalMs: this.heartbeatIntervalMs,\n gcIntervalMs: this.gcIntervalMs,\n askTimeoutMs: this.askTimeoutMs,\n maxDeliveryAttempts: this.maxDeliveryAttempts,\n now: () => this.now(),\n });\n this.runtimes.set(pi, runtime);\n pi.on('session_shutdown', () => {\n this.runtimes.get(pi)?.dispose();\n });\n return runtime;\n }\n\n registerClient(pi: ExtensionAPI): void {\n // Checked BEFORE readNativeTeamMemberFromEnvironment, which is not\n // scope-free: it resolves `teamDir()` and so requires a scope just to\n // answer \"not a member\". Activation runs before `session_start`, and the\n // parent puts its own PI_SUBAGENT_TEAM_* vars on `process.env`\n // (`applyNativeTeamRootEnvironment`), so a reload re-enters here with team\n // env set and no scope yet. No scope means this process is not a bound\n // child - a real one adopts its scope from the spawn environment first.\n if (!tryCurrentSessionScope()) return;\n if (!readNativeTeamMemberFromEnvironment()) return;\n this.createRuntime(pi).bindChildFromEnvironment();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+
3
+ //#region src/intercom/nativeTeamChannel.d.ts
4
+ type TeamMemberRole = 'main' | 'subagent';
5
+ interface TeamTaskMetadata {
6
+ id: string;
7
+ subject: string;
8
+ }
9
+ interface NativeTeamMemberSnapshot {
10
+ name: string;
11
+ role: TeamMemberRole;
12
+ agent?: string;
13
+ runId?: string;
14
+ task?: TeamTaskMetadata;
15
+ }
16
+ interface NativeTeamSnapshot {
17
+ members: NativeTeamMemberSnapshot[];
18
+ }
19
+ declare function readActiveNativeTeamSnapshot(now?: number): NativeTeamSnapshot | undefined;
20
+ //#endregion
21
+ export { NativeTeamMemberSnapshot, NativeTeamSnapshot, readActiveNativeTeamSnapshot };
22
+ //# sourceMappingURL=nativeTeamChannel.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeTeamChannel.d.cts","names":[],"sources":["../../src/intercom/nativeTeamChannel.ts"],"mappings":";;;KAoKY,cAAA;AAAA,UASK,gBAAA;EACf,EAAA;EACA,OAAA;AAAA;AAAA,UAmCe,wBAAA;EACf,IAAA;EACA,IAAA,EAAM,cAAA;EACN,KAAA;EACA,KAAA;EACA,IAAA,GAAO,gBAAA;AAAA;AAAA,UAGQ,kBAAA;EACf,OAAA,EAAS,wBAAA;AAAA;AAAA,iBA6mBK,4BAAA,CAA6B,GAAA,YAAmB,kBAAA"}
@@ -0,0 +1,22 @@
1
+ import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+
3
+ //#region src/intercom/nativeTeamChannel.d.ts
4
+ type TeamMemberRole = 'main' | 'subagent';
5
+ interface TeamTaskMetadata {
6
+ id: string;
7
+ subject: string;
8
+ }
9
+ interface NativeTeamMemberSnapshot {
10
+ name: string;
11
+ role: TeamMemberRole;
12
+ agent?: string;
13
+ runId?: string;
14
+ task?: TeamTaskMetadata;
15
+ }
16
+ interface NativeTeamSnapshot {
17
+ members: NativeTeamMemberSnapshot[];
18
+ }
19
+ declare function readActiveNativeTeamSnapshot(now?: number): NativeTeamSnapshot | undefined;
20
+ //#endregion
21
+ export { NativeTeamMemberSnapshot, NativeTeamSnapshot, readActiveNativeTeamSnapshot };
22
+ //# sourceMappingURL=nativeTeamChannel.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeTeamChannel.d.mts","names":[],"sources":["../../src/intercom/nativeTeamChannel.ts"],"mappings":";;;KAoKY,cAAA;AAAA,UASK,gBAAA;EACf,EAAA;EACA,OAAA;AAAA;AAAA,UAmCe,wBAAA;EACf,IAAA;EACA,IAAA,EAAM,cAAA;EACN,KAAA;EACA,KAAA;EACA,IAAA,GAAO,gBAAA;AAAA;AAAA,UAGQ,kBAAA;EACf,OAAA,EAAS,wBAAA;AAAA;AAAA,iBA6mBK,4BAAA,CAA6B,GAAA,YAAmB,kBAAA"}
@@ -0,0 +1,5 @@
1
+ import{__esmMin as e}from"../_virtual/_rolldown/runtime.mjs";import{LruCache as t,init_lruCache as n}from"../shared/lruCache.mjs";import{init_atomicJson as r,writePrivateAtomicJson as i}from"../shared/atomicJson.mjs";import{__decorate as a,init_decorate as o}from"../_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.mjs";import{SUBAGENT_TEAM_ID_ENV as s,SUBAGENT_TEAM_MAIN_MEMBER_ENV as c,SUBAGENT_TEAM_MEMBER_ID_ENV as l,SUBAGENT_TEAM_MEMBER_TOKEN_ENV as u,SUBAGENT_TEAM_ROOT_SESSION_ENV as d,init_env as ee}from"../env.mjs";import{init_paths as te,requireCurrentSessionScope as ne,scopeTeamDir as re,tryCurrentSessionScope as ie}from"../shared/paths.mjs";import{DoomTeamExpectedError as f,init_errors as ae,invalidRequest as p}from"../shared/errors.mjs";import{init_versioned as oe,parseVersioned as m}from"../shared/versioned.mjs";import{BoundedKeySet as se,init_boundedKeySet as ce}from"../shared/boundedKeySet.mjs";import*as h from"node:fs";import*as g from"node:path";import{injectable as le}from"inversify";import{createHash as ue,randomBytes as de}from"node:crypto";function _(e){return typeof e==`string`&&Nt.test(e)}function v(e){return typeof e==`number`&&Number.isInteger(e)}function y(e){return typeof e==`number`&&Number.isFinite(e)}function b(e){return typeof e==`string`&&e.trim().length>0}function x(e){return e===void 0||typeof e==`string`}function fe(e){return e===void 0||v(e)}function pe(e){return e===`main`||e===`subagent`}function me(e){return e===`send`||e===`ask`}function S(e,t){return Buffer.byteLength(e,`utf-8`)<=t}function he(e){return e instanceof Error?e.message:String(e)}function C(e){return process.env[e]?.trim()||void 0}function w(e){return ue(Lt).update(e).digest(`hex`)}function ge(){return de(It).toString(`base64url`)}function _e(e){return`${Bt}${w(e).slice(0,Ft)}`}function ve(e){return e.trim().toLowerCase().replace(Pt,vt).replace(Z,``).slice(0,H).replace(Z,``)||V}function ye(e,t){let n=`${vt}${t+yt}`,r=H-n.length;return`${e.slice(0,Math.max(r,0)).replace(Z,``)||V}${n}`}function be(e,t){if(e!==B)return e;if(t)throw Error(`Native team member name '${B}' is reserved for the root session.`);return _t}function T(e){if(!_(e))throw Error(`Invalid native team id.`);return g.join(re(ne()),e)}function xe(e,t){if(!_(t))throw Error(`Invalid native team member id.`);return g.join(T(e.teamId),R,`${t}${z}`)}function E(e,t){if(!_(t))throw Error(`Invalid native team member id.`);return g.join(T(e.teamId),ft,`${t}${z}`)}function D(e,t){if(!_(t))throw Error(`Invalid native team member id.`);return g.join(T(e.teamId),pt,t)}function Se(e){return`${e}${z}`}function O(e,t,n){if(!_(n))throw Error(`Invalid native team message id.`);return g.join(D(e,t),Se(n))}function Ce(e,t){if(!_(t))throw Error(`Invalid native team request id.`);return g.join(T(e.teamId),mt,`${t}${z}`)}function k(e,t,n){if(!_(t)||!_(n))throw Error(`Invalid intercom receipt identity.`);return g.join(T(e.teamId),ht,t,`${n}${z}`)}function we(e,t){return ue(Lt).update(`${e}:${t}`).digest(`hex`)}function Te(e){let t=T(e.teamId);for(let e of[R,ft,pt,mt,ht])h.mkdirSync(g.join(t,e),{recursive:!0,mode:U})}function A(e){try{let t=JSON.parse(h.readFileSync(e,`utf-8`));return t&&typeof t==`object`&&!Array.isArray(t)?t:void 0}catch{return}}function j(e){try{return h.rmSync(e,{force:!0}),!0}catch(e){return e.code===`ENOENT`}}function Ee(e){try{h.rmSync(e,{recursive:!0,force:!0})}catch{}}function De(e){if(!(!m(e,[q]).ok||!e)&&!(!_(e.teamId)||!b(e.rootSessionId)||e.mainMemberId!==B||!y(e.createdAt)||!y(e.updatedAt)))return{version:q,teamId:e.teamId,rootSessionId:e.rootSessionId,mainMemberId:B,createdAt:e.createdAt,updatedAt:e.updatedAt}}function Oe(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e;if(!(!b(t.id)||!b(t.subject))&&!(!S(t.id,G)||!S(t.subject,K)))return{id:t.id,subject:t.subject}}function ke(e){if(!m(e,[J]).ok||!e||!_(e.teamId)||!b(e.rootSessionId)||!b(e.mainMemberId)||!_(e.memberId)||!pe(e.role)||!b(e.tokenHash)||!v(e.pid)||typeof e.active!=`boolean`||!y(e.joinedAt)||!x(e.agent)||!x(e.runId)||!fe(e.childIndex)||!x(e.parentMemberId))return;let t=e.task===void 0?void 0:Oe(e.task);if(!(e.task!==void 0&&!t))return{version:J,teamId:e.teamId,rootSessionId:e.rootSessionId,mainMemberId:e.mainMemberId,memberId:e.memberId,role:e.role,tokenHash:e.tokenHash,pid:e.pid,active:e.active,joinedAt:e.joinedAt,...y(e.leftAt)?{leftAt:e.leftAt}:{},...e.agent===void 0?{}:{agent:e.agent},...e.runId===void 0?{}:{runId:e.runId},...e.childIndex===void 0?{}:{childIndex:e.childIndex},...e.parentMemberId===void 0?{}:{parentMemberId:e.parentMemberId},...t?{task:t}:{}}}function Ae(e){if(!(!m(e,[Y]).ok||!e)&&!(!_(e.memberId)||!b(e.tokenHash)||!v(e.pid)||!y(e.heartbeatAt)))return{version:Y,memberId:e.memberId,tokenHash:e.tokenHash,pid:e.pid,heartbeatAt:e.heartbeatAt}}function je(e){if(!(!m(e,[X]).ok||!e)&&!(e.type!==I||!_(e.id)||!_(e.teamId)||!me(e.kind)||!_(e.fromMemberId)||!_(e.toMemberId)||!b(e.senderTokenHash)||!v(e.seq)||typeof e.message!=`string`||!S(e.message,W)||!y(e.createdAt)||!y(e.expiresAt)))return{type:I,version:X,id:e.id,teamId:e.teamId,kind:e.kind,fromMemberId:e.fromMemberId,toMemberId:e.toMemberId,senderTokenHash:e.senderTokenHash,seq:e.seq,message:e.message,createdAt:e.createdAt,expiresAt:e.expiresAt}}function Me(e){if(!(!m(e,[X]).ok||!e)&&!(e.type!==L||!_(e.requestId)||!_(e.teamId)||!_(e.fromMemberId)||!_(e.toMemberId)||!b(e.senderTokenHash)||typeof e.message!=`string`||!S(e.message,W)||!y(e.createdAt)))return{type:L,version:X,requestId:e.requestId,teamId:e.teamId,fromMemberId:e.fromMemberId,toMemberId:e.toMemberId,senderTokenHash:e.senderTokenHash,message:e.message,createdAt:e.createdAt}}function Ne(e){if(!e||typeof e!=`object`||Array.isArray(e))throw p(`Intercom params must be an object.`,`Use one documented intercom action shape.`);let t=e,n=Mt.find(e=>e===t.action);if(!n)throw new f(`unsupported_operation`,`Unsupported intercom action: ${String(t.action)}.`,!1,`Use members, send, ask, pending, or reply.`);if(!x(t.to)||!x(t.message)||!x(t.requestId))throw p(`Intercom to, message and requestId values must be strings.`,`Correct the action fields and retry.`);if(t.timeoutMs!==void 0&&(!v(t.timeoutMs)||t.timeoutMs<1))throw p(`Intercom timeoutMs must be a positive integer.`,`Correct timeoutMs and retry.`);let r=new Set(n===`members`||n===`pending`?[`action`]:n===`reply`?[`action`,`requestId`,`message`]:n===`ask`?[`action`,`to`,`message`,`timeoutMs`]:[`action`,`to`,`message`]),i=Object.keys(t).filter(e=>!r.has(e));if(i.length)throw p(`Intercom action '${n}' does not accept: ${i.join(`, `)}.`,`Remove unknown fields and retry.`);return{action:n,...t.to===void 0?{}:{to:t.to},...t.message===void 0?{}:{message:t.message},...t.requestId===void 0?{}:{requestId:t.requestId},...t.timeoutMs===void 0?{}:{timeoutMs:t.timeoutMs}}}function M(e,t){return ke(A(xe(e,t)))}function Pe(e,t){let n=Ae(A(E(e,t.memberId)));if(!(!n||n.memberId!==t.memberId||n.tokenHash!==t.tokenHash))return n}function Fe(e){if(e===process.pid)return!0;try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}function Ie(e,t){return Pe(e,t)?.heartbeatAt??t.leftAt??t.joinedAt}function N(e,t,n){return t.active&&Fe(t.pid)&&n-Ie(e,t)<=3e4}function Le(e){h.mkdirSync(D(e,e.memberId),{recursive:!0,mode:U}),i(xe(e,e.memberId),e)}function Re(e,t,n){let r={version:Y,memberId:t.memberId,tokenHash:t.tokenHash,pid:t.pid,heartbeatAt:n};i(E(e,t.memberId),r)}function ze(e){let t=g.join(T(e.teamId),R),n;try{n=h.readdirSync(t,{withFileTypes:!0})}catch{return[]}return n.filter(e=>e.isFile()&&e.name.endsWith(z)).map(e=>ke(A(g.join(t,e.name)))).filter(e=>!!e).filter(t=>t.teamId===e.teamId&&t.rootSessionId===e.rootSessionId)}function P(e,t){return ze(e).filter(n=>N(e,n,t)).sort((e,t)=>e.joinedAt-t.joinedAt||e.memberId.localeCompare(t.memberId))}function Be(e=Date.now()){let t=Je();if(t)return{members:P(t,e).map(ot)}}function Ve(e,t,n){let r=0;for(let i of ze(e))i.memberId!==t&&(N(e,i,n)||n-Ie(e,i)<=3e4+jt||(Ee(D(e,i.memberId)),j(E(e,i.memberId)),j(xe(e,i.memberId)),r+=1));return r}function He(e){let t=e.trim();if(!t)throw Error(`A root session id is required for native team communication.`);let n={version:q,teamId:_e(t),rootSessionId:t,mainMemberId:B};Te(n);let r=g.join(T(n.teamId),gt),a=De(A(r));if(a&&a.rootSessionId!==t)throw Error(`Native team identity collision detected.`);let o=Date.now();return i(r,{...n,createdAt:a?.createdAt??o,updatedAt:o}),n}function Ue(e){return{[s]:e.teamId,[d]:e.rootSessionId,[c]:e.mainMemberId}}function We(e){return{...Ue(e),[l]:e.memberId,[u]:e.token}}function Ge(){return{[l]:void 0,[u]:void 0}}function Ke(e){Object.assign(process.env,Ue(e))}function qe(e){e&&process.env.PI_SUBAGENT_TEAM_ID!==e.teamId||(delete process.env[s],delete process.env[d],delete process.env[c])}function Je(){let e=C(s),t=C(d),n=C(c);if(!e||!_(e)||!t||n!==B||e!==_e(t))return;let r=De(A(g.join(T(e),gt)));if(!(!r||r.rootSessionId!==t||r.teamId!==e))return{version:q,teamId:e,rootSessionId:t,mainMemberId:n}}function Ye(e){if(!e)return;let t=e.id.trim(),n=e.subject.trim();if(!t||!S(t,G))throw Error(`Native team task id must be between 1 and ${G} bytes.`);if(!n||!S(n,K))throw Error(`Native team task subject must be between 1 and ${K} bytes.`);return{id:t,subject:n}}function Xe(e){if(e.role===`main`)return e.root.mainMemberId;let t=e.name!==void 0;if(!t&&!e.agent)throw Error(`An intercom member needs a name or an agent to derive one from.`);let n=be(ve(e.name??e.agent??V),t);if(e.runId){let t=ve(e.runId).slice(0,8),r=H-t.length-1;return`${n.slice(0,r).replace(Z,``)||V}-${t}`}return e.fanoutIndex===void 0?n:ye(n,e.fanoutIndex)}function Ze(e){let t=Xe(e);if(!_(t))throw Error(`A safe native team member id is required.`);let n=ge(),r=w(n),i=Date.now(),a=Ye(e.task),o={...e.root,memberId:t,token:n,role:e.role,...e.agent?{agent:e.agent}:{},...e.runId?{runId:e.runId}:{},...e.childIndex===void 0?{}:{childIndex:e.childIndex},...e.parentMemberId?{parentMemberId:e.parentMemberId}:{},...a?{task:a}:{}},s=M(e.root,t);s&&s.tokenHash!==r&&Ee(D(e.root,t));let{token:c,version:l,...u}=o,d={...u,version:J,tokenHash:r,pid:e.pid??process.pid,active:!0,joinedAt:i};Le(d),Re(e.root,d,i);let ee=!1;return{context:o,dispose:()=>{if(ee)return;ee=!0;let n=M(e.root,t);if(!n||n.tokenHash!==r)return;let i=Date.now();Le({...n,active:!1,leftAt:i}),Re(e.root,n,i)}}}function Qe(){let e=Je(),t=C(l),n=C(u);if(!e||!t||!_(t)||!n)return;let r=M(e,t);if(!(!r||r.teamId!==e.teamId||r.rootSessionId!==e.rootSessionId)&&!(r.tokenHash!==w(n)||!r.active))return{...e,memberId:t,token:n,role:r.role,...r.agent?{agent:r.agent}:{},...r.runId?{runId:r.runId}:{},...r.childIndex===void 0?{}:{childIndex:r.childIndex},...r.parentMemberId?{parentMemberId:r.parentMemberId}:{},...r.task?{task:r.task}:{}}}function $e(e,t){let n=M(e,e.memberId);if(!n||n.tokenHash!==w(e.token)||!N(e,n,t))throw Error(`This native team member is no longer active.`);return n}function et(e,t,n){let r=t?.trim();if(!r)throw p(`to is required for intercom send and ask.`,`Provide an explicit recipient.`);let i=P(e,n).filter(t=>t.memberId!==e.memberId),a=ve(r),o=i.find(e=>e.memberId===r||e.memberId===a);if(o)return o;let s=r.toLowerCase(),c=i.filter(e=>e.agent?.toLowerCase()===s||e.runId?.toLowerCase()===s||s===B&&e.role===`main`);if(c.length===1)return c[0];throw c.length>1?new f(`recipient_ambiguous`,`Multiple active intercom members match '${r}': ${c.map(e=>e.memberId).join(`, `)}.`,!1,`Retry with one exact member id.`):new f(`recipient_not_found`,`Active intercom member '${r}' was not found.`,!0,`Call intercom({"action":"members"}) and retry with an active member id.`)}function tt(e){let t=e?.trim();if(!t)throw p(`message is required for intercom communication.`,`Provide a nonblank message.`);if(!S(t,W))throw p(`Intercom message exceeds 64 KiB.`,`Shorten the message and retry.`);return t}function nt(e,t,n){let r=M(e,t);return!!(r&&r.tokenHash===n)}function rt(e,t,n){let r=D(e,e.memberId),i;try{i=h.readdirSync(r,{withFileTypes:!0})}catch{return{messages:[],foreignFiles:[]}}let a=[],o=[];for(let s of i){if(!s.isFile()||!s.name.endsWith(z)||n?.(s.name))continue;let i=g.join(r,s.name),c=je(A(i));if(!c){j(i);continue}if(c.teamId!==e.teamId||c.toMemberId!==e.memberId){o.push(s.name);continue}if(c.expiresAt<t||!nt(e,c.fromMemberId,c.senderTokenHash)){j(i);continue}a.push(c)}return{messages:it(a),foreignFiles:o}}function it(e){let t=new Map;for(let n of e){let e=t.get(n.fromMemberId);e?e.push(n):t.set(n.fromMemberId,[n])}let n=[];for(let e of t.values())e.sort((e,t)=>e.seq-t.seq),n.push(e);let r=[];for(;;){let e,t;for(let r of n){let n=r[0];n&&(!t||n.createdAt<t.createdAt||n.createdAt===t.createdAt&&n.fromMemberId<t.fromMemberId)&&(e=r,t=n)}if(!e||!t)break;e.shift(),r.push(t)}return r}function at(e){let t=e.role===`main`?B:e.agent??e.memberId,n=e.runId?` [${e.runId}]`:``,r=e.task?`, task ${e.task.id}: ${e.task.subject}`:``;return`- ${e.memberId}: ${t}${n}${r}`}function ot(e){return{name:e.memberId,role:e.role,...e.agent?{agent:e.agent}:{},...e.runId?{runId:e.runId}:{},...e.task?{task:e.task}:{}}}function st(e,t){return new Promise((n,r)=>{if(t?.aborted){r(Error(`Native team request cancelled.`));return}let i,a=()=>{i&&clearTimeout(i),t?.removeEventListener(`abort`,o)},o=()=>{a(),r(Error(`Native team request cancelled.`))};i=setTimeout(()=>{a(),n()},e),t?.addEventListener(`abort`,o,{once:!0})})}function ct(e,t){let n=M(e,t.fromMemberId),r=`${t.fromMemberId}${n?.agent?` (${n.agent})`:``}`,i=n?.task?`, task ${n.task.id}`:``,a=[`${t.kind===`ask`?`Question`:`Message`} from ${r}${i}.`];return a.push(``,t.message),t.kind===`ask`&&a.push(``,`Reply with ${F}({ action: "reply", requestId: "${t.id}", message: "..." }).`),a.join(`
2
+ `)}function lt(e,t){try{return e.getAllTools().some(e=>e.name===t)}catch{return!1}}var F,I,L,ut,dt,R,ft,pt,mt,ht,gt,z,B,_t,V,H,vt,yt,U,W,G,K,bt,xt,St,Ct,wt,Tt,Et,Dt,Ot,kt,At,jt,q,J,Y,X,Mt,Nt,Pt,Z,Ft,It,Lt,Rt,Q,zt,Bt,Vt,Ht,$,Ut=e((()=>{ee(),r(),ce(),n(),te(),oe(),ae(),o(),F=`intercom`,I=`subagent.team.message`,L=`subagent.team.reply`,ut=`intercom_message`,dt=`intercom_undeliverable`,R=`members`,ft=`heartbeats`,pt=`inboxes`,mt=`replies`,ht=`receipts`,gt=`team.json`,z=`.json`,B=`main`,_t=`main-agent`,V=`agent`,H=48,vt=`-`,yt=1,U=448,W=64*1024,G=256,K=4*1024,bt=1440*60*1e3,xt=600*1e3,St=5e3,Ct=250,wt=250,Tt=5,Et=1,Dt=1024,Ot=256,kt=32,At=6e4,jt=300*1e3,q=1,J=1,Y=1,X=2,Mt=[`members`,`send`,`ask`,`reply`,`pending`],Nt=/^[A-Za-z0-9._-]{1,256}$/,Pt=/[^a-z0-9._-]+/g,Z=/^[-.]+|[-.]+$/g,Ft=32,It=32,Lt=`sha256`,Rt=1,Q=`delivered`,zt=`failed`,Bt=`session-`,Vt={oneOf:[...[`members`,`pending`].map(e=>({type:`object`,properties:{action:{const:e}},required:[`action`],additionalProperties:!1})),{type:`object`,properties:{action:{const:`send`},to:{type:`string`},message:{type:`string`}},required:[`action`,`to`,`message`],additionalProperties:!1},{type:`object`,properties:{action:{const:`ask`},to:{type:`string`},message:{type:`string`},timeoutMs:{type:`integer`,minimum:1}},required:[`action`,`to`,`message`],additionalProperties:!1},{type:`object`,properties:{action:{const:`reply`},requestId:{type:`string`},message:{type:`string`}},required:[`action`,`requestId`,`message`],additionalProperties:!1}]},Ht=class{context;ownedMembershipDispose;poller;lastHeartbeatAt=0;lastGcAt=0;seenFiles=new se(Dt);deliveryAttempts=new t(Ot);undeliverableMessages=[];outboundSeq=0;constructor(e,t){if(this.pi=e,this.options=t,lt(e,`intercom`))throw Error(`[tool_conflict] A foreign '${F}' tool is already registered. Recovery: disable the competing extension and reload Doom Team.`);e.registerTool(this.buildTool())}current(){return this.context}undeliverable(){return this.undeliverableMessages}bindMainSession(e){let t=He(e);Ke(t);let n=Ze({root:t,role:`main`});return this.startBinding(n.context,n.dispose)}bindChildFromEnvironment(){let e=Qe();if(e)return this.context?.memberId===e.memberId&&this.context.token===e.token?this.context:this.startBinding(e)}dispose(){let e=this.context;this.stopBinding(),e?.role===`main`&&qe(e)}startBinding(e,t){return this.stopBinding(),this.context=e,this.ownedMembershipDispose=t,this.poll(),this.poller=setInterval(()=>{this.poll()},this.options.pollIntervalMs),this.poller.unref?.(),e}stopBinding(){this.poller&&clearInterval(this.poller),this.poller=void 0,this.ownedMembershipDispose?.(),this.ownedMembershipDispose=void 0,this.seenFiles.clear(),this.deliveryAttempts.clear(),this.lastHeartbeatAt=0,this.lastGcAt=0,this.outboundSeq=0,this.context=void 0}poll(){let e=this.context;if(!e)return;let t=this.options.now();this.heartbeat(e,t),this.collectGarbageIfDue(e,t);let n=rt(e,t,e=>this.seenFiles.has(e));for(let e of n.foreignFiles)this.seenFiles.add(e);for(let t of n.messages)this.deliverOnce(e,t)}deliverOnce(e,t){let n=Se(t.id);try{this.deliver(e,t)}catch(r){let i=(this.deliveryAttempts.get(n)??0)+Et;if(i<this.options.maxDeliveryAttempts){this.deliveryAttempts.set(n,i);return}this.deliveryAttempts.delete(n),this.seenFiles.add(n),this.reportUndeliverable(e,t,i,r);return}this.seenFiles.add(n),this.deliveryAttempts.delete(n),i(k(e,t.fromMemberId,t.id),{version:Rt,messageId:t.id,state:Q,deliveredAt:this.options.now()}),t.kind===`send`&&j(O(e,e.memberId,t.id))}deliver(e,t){let n=ct(e,t);if(e.role===`subagent`){this.pi.sendUserMessage(n,{deliverAs:`steer`});return}this.pi.sendMessage({customType:ut,content:n,display:!0,details:{id:t.id,kind:t.kind,from:t.fromMemberId,to:t.toMemberId,seq:t.seq}},{triggerTurn:!0,deliverAs:`steer`})}reportUndeliverable(e,t,n,r){let a={messageId:t.id,fromMemberId:t.fromMemberId,kind:t.kind,attempts:n,reason:he(r),at:this.options.now()};for(this.undeliverableMessages.push(a),i(k(e,t.fromMemberId,t.id),{version:Rt,messageId:t.id,state:zt,reason:a.reason,failedAt:a.at});this.undeliverableMessages.length>kt;)this.undeliverableMessages.shift();try{this.pi.sendMessage({customType:dt,content:`Native team message ${t.id} from ${t.fromMemberId} could not be delivered after ${n} attempts: ${a.reason}`,display:!0,details:{...a}},{triggerTurn:!0,deliverAs:`steer`})}catch{}}heartbeat(e,t){if(t-this.lastHeartbeatAt<this.options.heartbeatIntervalMs)return;let n=M(e,e.memberId);!n||n.tokenHash!==w(e.token)||!n.active||(this.lastHeartbeatAt=t,Re(e,n,t))}collectGarbageIfDue(e,t){if(!(t-this.lastGcAt<this.options.gcIntervalMs)){this.lastGcAt=t;try{Ve(e,e.memberId,t)}catch(n){for(this.undeliverableMessages.push({messageId:``,fromMemberId:e.memberId,kind:`send`,attempts:0,reason:`Native team directory sweep failed: ${he(n)}`,at:t});this.undeliverableMessages.length>kt;)this.undeliverableMessages.shift()}}}nextSeq(){return this.outboundSeq+=1,this.outboundSeq}queueMessage(e,t,n,r,a,o){if($e(e,a),!N(e,t,a))throw Error(`Native team member '${t.memberId}' is no longer active.`);let s={type:I,version:X,id:o,teamId:e.teamId,kind:n,fromMemberId:e.memberId,toMemberId:t.memberId,senderTokenHash:w(e.token),seq:this.nextSeq(),message:r,createdAt:a,expiresAt:a+bt};return h.mkdirSync(D(e,t.memberId),{recursive:!0,mode:U}),i(O(e,t.memberId,s.id),s),s}replyToRequest(e,t,n,r){if(!t||!_(t))throw Error(`requestId must be a valid intercom request id.`);$e(e,r);let a=O(e,e.memberId,t),o=je(A(a));if(!o||o.kind!==`ask`||o.teamId!==e.teamId||o.toMemberId!==e.memberId||!nt(e,o.fromMemberId,o.senderTokenHash))throw new f(`recipient_not_found`,`No pending intercom ask matches requestId '${t}'.`,!1,`Call intercom({"action":"pending"}) and retry with an exact requestId.`);let s={type:L,version:X,requestId:t,teamId:e.teamId,fromMemberId:e.memberId,toMemberId:o.fromMemberId,senderTokenHash:w(e.token),message:n,createdAt:r};return i(Ce(e,t),s),j(a),this.seenFiles.delete(Se(t)),s}async waitForReply(e,t,n,r,i){let a=Ce(e,n.id),o=this.options.now()+(i??this.options.askTimeoutMs);for(;this.options.now()<=o;){if(r?.aborted)throw Error(`Native team request cancelled.`);let i=Me(A(a));if(i&&i.teamId===e.teamId&&i.requestId===n.id&&i.fromMemberId===t.memberId&&i.toMemberId===e.memberId&&nt(e,i.fromMemberId,i.senderTokenHash))return j(a),i;let o=M(e,t.memberId);if(!o||!N(e,o,this.options.now()))throw new f(`communication_unavailable`,`Intercom member '${t.memberId}' became unreachable before replying.`,!0,`Call intercom({"action":"members"}) and decide whether to retry with an active member.`);await st(this.options.replyPollIntervalMs,r)}throw new f(`reply_timeout`,`Timed out waiting for intercom member '${t.memberId}' to reply.`,!0,`Check member status before deciding whether to ask again.`)}buildTool(){return{name:F,label:`Intercom`,description:`Communicate with active agents in this root session. Use members, send, ask, pending, or reply. The stable root identity is main.`,promptGuidelines:[`Send only new progress, blockers, or decisions. Do not repeat the task brief, sender task, or delegation instructions because the recipient already has them.`],parameters:Vt,execute:async(e,t,n,r)=>{let i=this.context;if(!i)throw new f(`communication_unavailable`,`Intercom is not active for this session.`,!0,`Wait for session startup or reload Doom Team.`);let a=Ne(t),o=this.options.now();if($e(i,o),a.action===`members`){let e=P(i,o);return{content:[{type:`text`,text:e.length?e.map(at).join(`
3
+ `):`No active members.`}],details:{members:e.map(ot)}}}if(a.action===`pending`){let e=rt(i,o).messages.filter(e=>e.kind===`ask`),t=e.map(e=>`- ${e.id}: from ${e.fromMemberId}. Reply with ${F}({ action: "reply", requestId: "${e.id}", message: "..." }).`);return{content:[{type:`text`,text:t.length?t.join(`
4
+ `):`No pending native team asks.`}],details:{pending:e.map(e=>({id:e.id,from:e.fromMemberId,message:e.message}))}}}let s=tt(a.message);if(a.action===`reply`){let e=this.replyToRequest(i,a.requestId,s,o);return{content:[{type:`text`,text:`Replied to native team request ${e.requestId}.`}],details:{requestId:e.requestId,to:e.toMemberId}}}let c=et(i,a.to,o);a.action===`ask`&&r?.({content:[{type:`text`,text:`Waiting for ${c.memberId} to reply...`}],details:{action:`ask`,to:c.memberId,partial:!0}});let l=we(i.memberId,e),u=A(k(i,i.memberId,l));if(u?.state===zt)throw new f(`delivery_unconfirmed`,`Intercom message ${l} failed: ${typeof u.reason==`string`?u.reason:`unknown error`}`,!1,`Call intercom({"action":"members"}) and do not resend automatically.`);if(a.action===`send`&&u?.state===Q)return{content:[{type:`text`,text:`Message ${l} delivered to ${c.memberId}.`}],details:{state:Q,delivered:!0,messageId:l,to:c.memberId}};let d=this.queueMessage(i,c,a.action,s,o,l);if(a.action===`send`)return{content:[{type:`text`,text:`Message ${d.id} queued for ${c.memberId}; delivery is not yet confirmed. Do not resend.`}],details:{state:`queued`,delivered:!1,messageId:d.id,to:c.memberId,seq:d.seq}};try{let e=await this.waitForReply(i,c,d,n,a.timeoutMs);return{content:[{type:`text`,text:`Reply from ${c.memberId}:\n${e.message}`}],details:{requestId:d.id,from:c.memberId,reply:e.message}}}finally{j(O(i,c.memberId,d.id))}}}}},$=class{runtimes=new WeakMap;pollIntervalMs=Ct;replyPollIntervalMs=wt;heartbeatIntervalMs=St;gcIntervalMs=At;askTimeoutMs=xt;maxDeliveryAttempts=Tt;now(){return Date.now()}createRuntime(e){let t=this.runtimes.get(e);if(t)return t;let n=new Ht(e,{pollIntervalMs:this.pollIntervalMs,replyPollIntervalMs:this.replyPollIntervalMs,heartbeatIntervalMs:this.heartbeatIntervalMs,gcIntervalMs:this.gcIntervalMs,askTimeoutMs:this.askTimeoutMs,maxDeliveryAttempts:this.maxDeliveryAttempts,now:()=>this.now()});return this.runtimes.set(e,n),e.on(`session_shutdown`,()=>{this.runtimes.get(e)?.dispose()}),n}registerClient(e){ie()&&Qe()&&this.createRuntime(e).bindChildFromEnvironment()}},$=a([le()],$)}));Ut();export{F as NATIVE_TEAM_TOOL_NAME,$ as NativeTeamChannelService,Ge as clearNativeTeamMemberEnvironment,Ut as init_nativeTeamChannel,We as nativeTeamMemberEnvironment,Ue as nativeTeamRootEnvironment,Be as readActiveNativeTeamSnapshot,Je as readNativeTeamRootFromEnvironment,Ze as registerNativeTeamMember};
5
+ //# sourceMappingURL=nativeTeamChannel.mjs.map