@askexenow/exe-os 0.9.409 → 0.9.411

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 (409) hide show
  1. package/deploy/stack-manifests/v0.9.json +408 -1
  2. package/dist/.dist-verified.json +3 -3
  3. package/dist/{active-agent-5AKPW2N7.js → active-agent-3YCLS7GB.js} +4 -4
  4. package/dist/{active-agent-2AMJC3SC.js → active-agent-MHWQDMML.js} +4 -4
  5. package/dist/agent-defs-generator-DNXMO34I.js +32 -0
  6. package/dist/{agentic-ontology-6RS7A7KP.js → agentic-ontology-RA6CMND6.js} +1 -1
  7. package/dist/{artifact-backup-6O4FNYPS.js → artifact-backup-EETHNFFP.js} +3 -3
  8. package/dist/{backfill-metadata-6YX6LGPJ.js → backfill-metadata-WYT257VG.js} +7 -7
  9. package/dist/backup-verify-AG54CYGR.js +62 -0
  10. package/dist/{behavior-injection-NRXTNROW.js → behavior-injection-G7GAUHGO.js} +10 -10
  11. package/dist/{behavior-promotion-MW7OQ72V.js → behavior-promotion-I2DIUFUR.js} +9 -9
  12. package/dist/{behaviors-7AOK44QK.js → behaviors-SKVKPCRW.js} +8 -8
  13. package/dist/bin/agentic-ontology-backfill.js +8 -8
  14. package/dist/bin/agentic-reflection-backfill.js +9 -9
  15. package/dist/bin/agentic-semantic-label.js +8 -8
  16. package/dist/bin/backfill-conversations.js +7 -7
  17. package/dist/bin/backfill-responses.js +7 -7
  18. package/dist/bin/backfill-vectors.js +7 -7
  19. package/dist/bin/bulk-sync-postgres.js +16 -16
  20. package/dist/bin/cc-doctor.js +8 -8
  21. package/dist/bin/cleanup-stale-review-tasks.js +13 -16
  22. package/dist/bin/cli.js +24 -24
  23. package/dist/bin/deferred-daemon-restart.js +97 -97
  24. package/dist/bin/exe-actions.js +1 -1
  25. package/dist/bin/exe-agent-config.js +3 -3
  26. package/dist/bin/exe-agent.js +12 -12
  27. package/dist/bin/exe-assign.js +8 -8
  28. package/dist/bin/exe-boot.js +35 -38
  29. package/dist/bin/exe-call.js +9 -9
  30. package/dist/bin/exe-cloud.js +26 -22
  31. package/dist/bin/exe-config-dump.js +3 -3
  32. package/dist/bin/exe-dispatch.js +14 -17
  33. package/dist/bin/exe-doctor.js +5 -5
  34. package/dist/bin/exe-export-behaviors.js +12 -12
  35. package/dist/bin/exe-forget.js +12 -12
  36. package/dist/bin/exe-gateway.js +9 -9
  37. package/dist/bin/exe-grant.js +6 -6
  38. package/dist/bin/exe-healthcheck.js +8 -8
  39. package/dist/bin/exe-heartbeat.js +19 -22
  40. package/dist/bin/exe-kill.js +18 -21
  41. package/dist/bin/exe-launch-agent.js +264 -110
  42. package/dist/bin/exe-mcp.js +5 -5
  43. package/dist/bin/exe-memory-reads.js +7 -7
  44. package/dist/bin/exe-new-employee.js +11 -11
  45. package/dist/bin/exe-os-mcp-proxy.js +5 -5
  46. package/dist/bin/exe-pending-messages.js +14 -17
  47. package/dist/bin/exe-pending-notifications.js +13 -16
  48. package/dist/bin/exe-pending-reviews.js +14 -17
  49. package/dist/bin/exe-rename.js +7 -7
  50. package/dist/bin/exe-review.js +17 -20
  51. package/dist/bin/exe-search.js +11 -11
  52. package/dist/bin/exe-session-cleanup.js +18 -21
  53. package/dist/bin/exe-settings.js +16 -16
  54. package/dist/bin/exe-start-codex.js +37 -19
  55. package/dist/bin/exe-start-opencode.js +35 -17
  56. package/dist/bin/exe-status.js +15 -18
  57. package/dist/bin/exe-support.js +3 -3
  58. package/dist/bin/exe-team.js +5 -5
  59. package/dist/bin/git-sweep.js +15 -17
  60. package/dist/bin/graph-backfill.js +8 -8
  61. package/dist/bin/graph-export.js +8 -8
  62. package/dist/bin/hooks-cli.js +1 -1
  63. package/dist/bin/import-history.js +11 -11
  64. package/dist/bin/install.js +99 -99
  65. package/dist/bin/intercom-check.js +5 -5
  66. package/dist/bin/mcp-sessions.js +2 -2
  67. package/dist/bin/orchestration-metrics.js +5 -5
  68. package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
  69. package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
  70. package/dist/bin/pre-publish.js +1 -1
  71. package/dist/bin/reconcile-backlog.js +2 -2
  72. package/dist/bin/registry-proxy.js +1 -1
  73. package/dist/bin/repair-document-chunks.js +7 -7
  74. package/dist/bin/scan-tasks.js +14 -17
  75. package/dist/bin/setup.js +2 -2
  76. package/dist/bin/shard-migrate.js +8 -8
  77. package/dist/bin/stack-update.js +4 -4
  78. package/dist/bin/vps-health-gate.js +1 -1
  79. package/dist/{boot-generation-HG6LLZLY.js → boot-generation-RPJVFAQJ.js} +4 -4
  80. package/dist/{boot-review-sections-STZ5EAIL.js → boot-review-sections-FOPPZTJI.js} +12 -15
  81. package/dist/{bug-landed-reconciler-EO72HUI2.js → bug-landed-reconciler-FN5KPBRK.js} +6 -6
  82. package/dist/build-info.json +3 -3
  83. package/dist/build-manifest.json +997 -987
  84. package/dist/{capability-cards-C3SMHB2E.js → capability-cards-YQWBEG7A.js} +3 -3
  85. package/dist/{capacity-monitor-UI553HRL.js → capacity-monitor-7SMEJHYG.js} +14 -17
  86. package/dist/{catchup-brief-VE2X4HML.js → catchup-brief-IBQ26LEB.js} +21 -23
  87. package/dist/{chunk-6ZW6BRI4.js → chunk-27NG2NTG.js} +2 -2
  88. package/dist/{chunk-EIM7OGTD.js → chunk-2BOLFLAU.js} +4 -2
  89. package/dist/{chunk-DM4VTXM6.js → chunk-2EYVXUGA.js} +4 -4
  90. package/dist/{chunk-LMF2YC5C.js → chunk-2YFMBXUU.js} +4 -4
  91. package/dist/{chunk-C426MZMD.js → chunk-2YGBJHC2.js} +3 -3
  92. package/dist/{chunk-6EY6OFBC.js → chunk-353XF4LU.js} +2 -2
  93. package/dist/{chunk-VMHZSZQJ.js → chunk-3ARSKDHC.js} +52 -0
  94. package/dist/{chunk-ZYOIH5NY.js → chunk-3DXAJVXE.js} +6 -6
  95. package/dist/{chunk-HFSFWMID.js → chunk-3GGMHSY2.js} +3 -3
  96. package/dist/{chunk-BM467PZN.js → chunk-3N24FV22.js} +1 -1
  97. package/dist/{chunk-SY53PYLU.js → chunk-47YGEM4N.js} +1 -1
  98. package/dist/{chunk-NVM3SKJ4.js → chunk-4CN3EE6U.js} +27 -21
  99. package/dist/{chunk-KIJRAZWR.js → chunk-4J77TCTX.js} +1 -1
  100. package/dist/{chunk-NHQWPKX7.js → chunk-54STF27U.js} +2 -2
  101. package/dist/{chunk-Q4GS5VW7.js → chunk-5BWDUUMH.js} +3 -3
  102. package/dist/{chunk-VYKXRSHU.js → chunk-5ZMNFSHV.js} +1 -1
  103. package/dist/{chunk-HNGAM3U4.js → chunk-657I6PUF.js} +3 -3
  104. package/dist/{chunk-OE7TAEOG.js → chunk-6777GNWI.js} +1 -1
  105. package/dist/{chunk-HYZV25LY.js → chunk-67IVG6CB.js} +1 -11
  106. package/dist/{chunk-5N34MMKS.js → chunk-6APOLYIZ.js} +43 -3
  107. package/dist/{chunk-TBYWOHTE.js → chunk-6BD6JYR2.js} +1 -1
  108. package/dist/{chunk-JJYAETCO.js → chunk-6DMURUBY.js} +4 -4
  109. package/dist/{chunk-W5XAB2SW.js → chunk-6HJF7IA3.js} +273 -206
  110. package/dist/{chunk-HRKN3DQE.js → chunk-6J2J3VJS.js} +11 -11
  111. package/dist/{chunk-XFGS22VE.js → chunk-6PXFF6IV.js} +1 -1
  112. package/dist/{chunk-RZ23QQCI.js → chunk-7HLAYQRG.js} +4 -4
  113. package/dist/{chunk-IUBCS6TA.js → chunk-7KPZQ65I.js} +3 -3
  114. package/dist/{chunk-SYUJCVJG.js → chunk-7PDZBPGW.js} +1 -1
  115. package/dist/{chunk-VLAENYCN.js → chunk-7SHU5MOD.js} +1 -1
  116. package/dist/{chunk-6RRPVE5O.js → chunk-A5I2GYVQ.js} +3 -3
  117. package/dist/{chunk-X4V5ZLNX.js → chunk-A75TAU2I.js} +628 -4
  118. package/dist/{chunk-SGR4ZQAV.js → chunk-BE3UETW6.js} +3 -3
  119. package/dist/{chunk-GG73NHZD.js → chunk-BG6RAOCJ.js} +63 -9
  120. package/dist/{chunk-DMYJVGQM.js → chunk-BIPTWAEO.js} +1 -1
  121. package/dist/{chunk-B3ISLIKE.js → chunk-BLTXAUP6.js} +2 -2
  122. package/dist/{chunk-G2M7WQ2M.js → chunk-CBC3JCIF.js} +1 -1
  123. package/dist/{chunk-FJKUFMNF.js → chunk-CFFSHBQF.js} +1 -1
  124. package/dist/{chunk-WYNIWJRN.js → chunk-CJ6CS2IH.js} +5 -5
  125. package/dist/{chunk-7LTAA55U.js → chunk-CRW63CDI.js} +1 -1
  126. package/dist/{chunk-BHDDDNC6.js → chunk-CWHTUNJX.js} +2 -2
  127. package/dist/{chunk-FZT4VQP7.js → chunk-D6NZNUVH.js} +1 -1
  128. package/dist/{chunk-GKPPLIMJ.js → chunk-DHLJZDWI.js} +4 -4
  129. package/dist/{chunk-JR3GTBV3.js → chunk-DRHTRVDT.js} +1 -1
  130. package/dist/{chunk-GTRB6DGI.js → chunk-DWRULKB3.js} +2 -2
  131. package/dist/{chunk-DIKLSAJE.js → chunk-EOWJXCYC.js} +25 -7
  132. package/dist/{chunk-4W7Y67B5.js → chunk-EWDBWOCX.js} +1 -1
  133. package/dist/{chunk-EHILXBVT.js → chunk-FPF2PJFK.js} +3 -3
  134. package/dist/{chunk-BPBEJD7U.js → chunk-FSXMKIDO.js} +1 -1
  135. package/dist/{chunk-E2Z3F26R.js → chunk-FUDXITKX.js} +1 -1
  136. package/dist/{chunk-SFGFNJBR.js → chunk-FYV2CTKP.js} +1 -1
  137. package/dist/{chunk-4M24XCTI.js → chunk-GATAYYAF.js} +53 -7
  138. package/dist/{chunk-L5CPS34O.js → chunk-GHYHNHDL.js} +1 -1
  139. package/dist/{chunk-OISOA6NX.js → chunk-GL5ZG72X.js} +1 -1
  140. package/dist/{chunk-XAGIZVYI.js → chunk-GM4UEZDE.js} +181 -1625
  141. package/dist/{chunk-4O7OUBEX.js → chunk-GZVFHFO3.js} +27 -140
  142. package/dist/{chunk-M4N7I2H5.js → chunk-HA6BIZ6L.js} +5 -5
  143. package/dist/chunk-HDQAVAV6.js +248 -0
  144. package/dist/{chunk-IPANAGA3.js → chunk-HDV2V25K.js} +1 -1
  145. package/dist/{chunk-XGPBHKU3.js → chunk-HTFM7ZDD.js} +2 -2
  146. package/dist/{chunk-KPLMY2GT.js → chunk-HUHR5CKJ.js} +4 -4
  147. package/dist/{chunk-IPBNHPTE.js → chunk-IC2AONBH.js} +9 -9
  148. package/dist/{chunk-23XUZHB7.js → chunk-IHAXXDBH.js} +245 -36
  149. package/dist/{chunk-4S6H2NWS.js → chunk-IPUDXR67.js} +1 -1
  150. package/dist/{chunk-UXJAW4IQ.js → chunk-J6U4ZR77.js} +2 -2
  151. package/dist/{chunk-7I6KVKFF.js → chunk-JAIZCE6W.js} +3 -3
  152. package/dist/{chunk-SA66WRBT.js → chunk-JGBYZTWH.js} +1 -1
  153. package/dist/{chunk-HRYWB4TO.js → chunk-JJZZXEAN.js} +3 -3
  154. package/dist/{chunk-IZ24HRDC.js → chunk-JNULO6I5.js} +3 -3
  155. package/dist/{chunk-YVS77JPW.js → chunk-JTJP4JK7.js} +3 -3
  156. package/dist/{chunk-BIV4IHED.js → chunk-JW5NUXPN.js} +15 -28
  157. package/dist/{chunk-NFNM64A7.js → chunk-K2HIXAIF.js} +22 -18
  158. package/dist/{chunk-F5ZRHLG5.js → chunk-KEDZRQI3.js} +2 -2
  159. package/dist/{chunk-QPMKVSHU.js → chunk-KN5GAVCG.js} +2 -2
  160. package/dist/{chunk-3MDUKF3N.js → chunk-L5JFVK5T.js} +5 -4
  161. package/dist/{chunk-FBZ32BD4.js → chunk-LBSCOP25.js} +1 -1
  162. package/dist/{chunk-K7DAE2HO.js → chunk-LLZUL7M2.js} +19 -6
  163. package/dist/{chunk-PCFYNK7V.js → chunk-LQGLGSBY.js} +2 -2
  164. package/dist/{chunk-APVU4Q5B.js → chunk-LSHUX7P4.js} +16 -16
  165. package/dist/{chunk-GRAMRMWS.js → chunk-M6AX64J2.js} +2 -2
  166. package/dist/{chunk-52Z435PH.js → chunk-M6SUJLNP.js} +15 -10
  167. package/dist/{chunk-GPWXUU3L.js → chunk-MZNLQC6W.js} +1 -1
  168. package/dist/{chunk-G3ZYXXO7.js → chunk-N7POJZJT.js} +10 -10
  169. package/dist/{chunk-DE2V7547.js → chunk-NCNT2C2P.js} +2 -2
  170. package/dist/{chunk-HK7HIDXP.js → chunk-O3BLL6MY.js} +1 -1
  171. package/dist/{chunk-YLWKWEJJ.js → chunk-O6KQAJCC.js} +3 -3
  172. package/dist/{chunk-QUK3UDZV.js → chunk-OHHZNNUD.js} +1 -1
  173. package/dist/{chunk-6JLVCMKH.js → chunk-PDQGR5LZ.js} +1 -1
  174. package/dist/{chunk-LE3DIA25.js → chunk-PTF5TB6O.js} +3 -3
  175. package/dist/{chunk-KBHK2WNO.js → chunk-PYXXL7N7.js} +1 -1
  176. package/dist/{chunk-QK3Z4TKQ.js → chunk-Q6KUBP6R.js} +5 -5
  177. package/dist/{chunk-NDCW4G55.js → chunk-QJWLQXR7.js} +1 -1
  178. package/dist/{chunk-ME733Y2F.js → chunk-QOFQY7BJ.js} +37 -9
  179. package/dist/{chunk-HFXBL7XE.js → chunk-QSW5DHMZ.js} +1 -1
  180. package/dist/{chunk-OFT5KSBM.js → chunk-QV26G2BF.js} +1 -1
  181. package/dist/{chunk-LVEMYNYH.js → chunk-RHHEYC6H.js} +3 -3
  182. package/dist/{chunk-QYIR64RR.js → chunk-RHJOTGEU.js} +1 -1
  183. package/dist/{chunk-HUMNRJZE.js → chunk-RJIH7JXM.js} +4 -4
  184. package/dist/{chunk-6TB7UXCA.js → chunk-RMC2A6EE.js} +1 -1
  185. package/dist/{chunk-XCPD7NGP.js → chunk-RYMXD2NT.js} +1 -1
  186. package/dist/{chunk-W2VDJKTB.js → chunk-RYYFFCJG.js} +1 -1
  187. package/dist/{chunk-YUAOQJVV.js → chunk-SINIRUYZ.js} +101 -9
  188. package/dist/{chunk-R7QZXQPU.js → chunk-SXUABANK.js} +216 -147
  189. package/dist/{backup-verify-QIAQ63VC.js → chunk-T3AM52YT.js} +411 -90
  190. package/dist/{chunk-NK4JHJNP.js → chunk-TCBWHLKH.js} +4 -4
  191. package/dist/{chunk-R6CKQLEA.js → chunk-TS4LSNRI.js} +2 -2
  192. package/dist/{chunk-4Q7H3TO7.js → chunk-TVWYMOZ4.js} +1 -1
  193. package/dist/{chunk-TCV3WA5I.js → chunk-VAHQOIQY.js} +1 -1
  194. package/dist/{chunk-ZEHBSA25.js → chunk-VQQPYI4X.js} +1 -1
  195. package/dist/{chunk-PZDAPIQL.js → chunk-VS7V5HNO.js} +1 -1
  196. package/dist/{chunk-7R7KDRKV.js → chunk-W7VKGB42.js} +1 -1
  197. package/dist/{chunk-M7774YLB.js → chunk-WC44PNZU.js} +1 -1
  198. package/dist/{chunk-3AL2LO3L.js → chunk-WHUQ44F2.js} +1 -1
  199. package/dist/{chunk-4RQ62XXK.js → chunk-X2ZHCNNB.js} +5 -5
  200. package/dist/{chunk-T2PAFWRK.js → chunk-X4FHT6ST.js} +5 -5
  201. package/dist/{chunk-N3JEYUDV.js → chunk-XC5OASHV.js} +1 -1
  202. package/dist/{agent-defs-generator-QN3J6FVJ.js → chunk-XDOCXKHW.js} +61 -21
  203. package/dist/{chunk-OEHZ46WQ.js → chunk-XEAZJXMZ.js} +2 -2
  204. package/dist/{chunk-DACRR362.js → chunk-XQ7BIVLI.js} +6 -6
  205. package/dist/{chunk-7P2TDFZL.js → chunk-Z3LGAFMG.js} +1 -1
  206. package/dist/{chunk-GEQQGN3J.js → chunk-ZJ6AMC4Y.js} +7 -7
  207. package/dist/{chunk-IURGBN5B.js → chunk-ZZR2WRNW.js} +4 -4
  208. package/dist/{cleanup-graph-garbage-NKAJSCWZ.js → cleanup-graph-garbage-SYGPMPUM.js} +8 -8
  209. package/dist/{cli-shutdown-F3DFDCB5.js → cli-shutdown-JI7CASE4.js} +1 -1
  210. package/dist/{cloud-sync-command-3YBLSMAL.js → cloud-sync-command-ZV3P5FP6.js} +2 -2
  211. package/dist/{cloud-sync-db-init-JWSPAFKY.js → cloud-sync-db-init-RQIHWKV4.js} +1 -1
  212. package/dist/{cloud-sync-shutdown-4R6RIO67.js → cloud-sync-shutdown-V2N7VLD3.js} +3 -3
  213. package/dist/{co-activation-2ZRANV3Q.js → co-activation-SRE6DIRX.js} +3 -3
  214. package/dist/{co-occurrence-6EELW2L2.js → co-occurrence-F5TMSEQZ.js} +6 -6
  215. package/dist/{consent-passphrase-TDR263MC.js → consent-passphrase-MWZRHJRC.js} +2 -2
  216. package/dist/content-extractor-GWF2T7FK.js +13 -0
  217. package/dist/{conversation-entity-extractor-KUJN3MOH.js → conversation-entity-extractor-XMOUHGMT.js} +3 -3
  218. package/dist/{crdt-sync-IX43KVQ3.js → crdt-sync-FXEKABM7.js} +4 -4
  219. package/dist/{crm-webhook-GSCIW6CE.js → crm-webhook-D6IJOPRQ.js} +2 -2
  220. package/dist/{cto-delegation-gate-ZWD4EFRR.js → cto-delegation-gate-BU3JRCYN.js} +12 -15
  221. package/dist/{daemon-orchestration-WL6V4QL4.js → daemon-orchestration-K4NKFYXO.js} +19 -21
  222. package/dist/{destructive-data-guard-JDUJ2ULM.js → destructive-data-guard-3TGAAE7K.js} +77 -23
  223. package/dist/{doc-graph-extractor-NJ7ZZC2C.js → doc-graph-extractor-TVK2NGAR.js} +6 -6
  224. package/dist/{documents-O7WYZFFE.js → documents-MDZ4VB5X.js} +8 -8
  225. package/dist/{dreaming-TUESPDT3.js → dreaming-L24PSS35.js} +17 -20
  226. package/dist/{employee-boot-brief-UCP6QLN4.js → employee-boot-brief-GQVL3FQC.js} +23 -25
  227. package/dist/{entity-boost-TK43XT24.js → entity-boost-OMFA5QCG.js} +2 -2
  228. package/dist/{exe-drift-QD6LUZT2.js → exe-drift-JDDG3OPT.js} +4 -4
  229. package/dist/{exe-export-QIUNHFSS.js → exe-export-EEGIE3JP.js} +10 -10
  230. package/dist/{exe-import-3UFOLHEW.js → exe-import-UJNC5Q2L.js} +10 -10
  231. package/dist/{exe-key-D5NDKGHT.js → exe-key-TYEY4W4E.js} +97 -97
  232. package/dist/{exe-org-UWDJBOCV.js → exe-org-B3ICTTEV.js} +32 -32
  233. package/dist/{exe-snapshot-P6SFODEN.js → exe-snapshot-VBFBONYN.js} +20 -23
  234. package/dist/{fast-db-init-SD7JZSEC.js → fast-db-init-TFRTK6EH.js} +1 -1
  235. package/dist/{founder-context-QIXDZIJX.js → founder-context-3X4QUWKD.js} +2 -2
  236. package/dist/{founder-monitor-envelope-TLOC4UYG.js → founder-monitor-envelope-54UNZNY4.js} +4 -4
  237. package/dist/gateway/index.js +11 -11
  238. package/dist/{gateway-client-CQTSYJLP.js → gateway-client-OUDO5GGV.js} +1 -1
  239. package/dist/{git-staleness-JSQTHB4Z.js → git-staleness-73YZ5PGU.js} +3 -3
  240. package/dist/{global-procedures-T3RKI4QX.js → global-procedures-PYNE2BQG.js} +20 -6
  241. package/dist/{graph-auto-extract-V75GSTNX.js → graph-auto-extract-PGUMEEQB.js} +6 -6
  242. package/dist/{graph-query-VAQN2RK3.js → graph-query-7YA3YNKL.js} +1 -1
  243. package/dist/{graph-rag-GBA5E3QC.js → graph-rag-UWOTK4AQ.js} +3 -3
  244. package/dist/{hook-integrity-II6QK6Y4.js → hook-integrity-6MNEPT6W.js} +1 -1
  245. package/dist/{hook-prefetch-5EHPOYY3.js → hook-prefetch-JOF6YZSR.js} +13 -16
  246. package/dist/hooks/bug-report-worker.js +17 -20
  247. package/dist/hooks/codex-stop-task-finalizer.js +19 -22
  248. package/dist/hooks/commit-complete.js +16 -19
  249. package/dist/hooks/error-recall.js +14 -14
  250. package/dist/hooks/exe-heartbeat-hook.js +5 -5
  251. package/dist/hooks/ingest-worker.js +18 -20
  252. package/dist/hooks/ingest.js +16 -16
  253. package/dist/hooks/instructions-loaded.js +7 -7
  254. package/dist/hooks/manifest.json +20 -20
  255. package/dist/hooks/notification.js +6 -6
  256. package/dist/hooks/post-compact.js +5 -5
  257. package/dist/hooks/post-tool-combined.js +13 -13
  258. package/dist/hooks/pre-compact.js +16 -19
  259. package/dist/hooks/pre-tool-use.js +2 -2
  260. package/dist/hooks/prompt-submit.js +40 -39
  261. package/dist/hooks/session-end.js +21 -24
  262. package/dist/hooks/session-start.js +18 -18
  263. package/dist/hooks/stop.js +19 -22
  264. package/dist/hooks/subagent-stop.js +18 -21
  265. package/dist/hooks/summary-worker.js +20 -23
  266. package/dist/index.js +25 -28
  267. package/dist/{installer-XEEZSF3V.js → installer-34XZ7JMW.js} +7 -8
  268. package/dist/{installer-MPVQ5L22.js → installer-356RMQ2K.js} +7 -8
  269. package/dist/{installer-ILYC4LI5.js → installer-7TN36Z7T.js} +113 -30
  270. package/dist/{intercom-queue-QGHAW2KO.js → intercom-queue-ZJ3MNULM.js} +12 -15
  271. package/dist/lib/backup-verify-worker.js +157 -0
  272. package/dist/lib/cloud-sync.js +16 -20
  273. package/dist/lib/consolidation.js +9 -9
  274. package/dist/lib/crypto.js +3 -3
  275. package/dist/lib/database.js +3 -3
  276. package/dist/lib/db-backup.js +7 -3
  277. package/dist/lib/db-write-worker.js +3 -3
  278. package/dist/lib/db.js +3 -3
  279. package/dist/lib/device-registry.js +1 -1
  280. package/dist/lib/employee-templates.js +7 -7
  281. package/dist/lib/employees.js +3 -3
  282. package/dist/lib/error-detector.js +2 -2
  283. package/dist/lib/exe-daemon.js +89 -87
  284. package/dist/lib/hybrid-search.js +11 -11
  285. package/dist/lib/identity.js +5 -3
  286. package/dist/lib/keychain.js +1 -1
  287. package/dist/lib/license.js +2 -2
  288. package/dist/lib/messaging.js +13 -16
  289. package/dist/lib/post-tool-memory.js +16 -18
  290. package/dist/lib/registry-proxy.js +1 -1
  291. package/dist/lib/reminders.js +4 -4
  292. package/dist/lib/schedules.js +8 -8
  293. package/dist/lib/session-registry.js +5 -5
  294. package/dist/lib/skill-learning.js +9 -9
  295. package/dist/lib/store.js +7 -7
  296. package/dist/lib/task-router.js +4 -4
  297. package/dist/lib/tasks.js +14 -17
  298. package/dist/lib/tmux-routing.js +14 -41
  299. package/dist/lib/token-spend.js +4 -4
  300. package/dist/lib/ws-client.js +1 -1
  301. package/dist/{license-gate-CARN6AB6.js → license-gate-4BXUTHLB.js} +3 -3
  302. package/dist/{license-recheck-7Z3LS6YS.js → license-recheck-QFPUKISQ.js} +1 -1
  303. package/dist/{license-sync-PUQV3HSZ.js → license-sync-FDEDT4AC.js} +2 -2
  304. package/dist/mcp/register-tools.js +96 -96
  305. package/dist/mcp/server.js +96 -96
  306. package/dist/mcp/tools/complete-reminder.js +5 -5
  307. package/dist/mcp/tools/create-reminder.js +5 -5
  308. package/dist/mcp/tools/create-task.js +16 -19
  309. package/dist/mcp/tools/deactivate-behavior.js +10 -10
  310. package/dist/mcp/tools/list-reminders.js +5 -5
  311. package/dist/mcp/tools/list-tasks.js +16 -19
  312. package/dist/mcp/tools/send-message.js +15 -18
  313. package/dist/mcp/tools/update-task.js +15 -18
  314. package/dist/{mcp-http-config-RJKTZPHZ.js → mcp-http-config-GKP5QGAO.js} +5 -5
  315. package/dist/{mcp-session-identity-HN444A3G.js → mcp-session-identity-JHAGRB7B.js} +12 -15
  316. package/dist/{memory-cards-AT3QCCWU.js → memory-cards-O377ETAM.js} +8 -8
  317. package/dist/{memory-graph-extractor-B43UWGV5.js → memory-graph-extractor-4KJCCUOP.js} +7 -7
  318. package/dist/{memory-maintenance-WDLL3ZX3.js → memory-maintenance-RR5UPRW3.js} +1 -1
  319. package/dist/{memory-poisoning-defense-TS4WNW4S.js → memory-poisoning-defense-Y5TTKGOP.js} +3 -3
  320. package/dist/{memory-pressure-watchdog-6YH7S6W7.js → memory-pressure-watchdog-NGXTI4HR.js} +13 -16
  321. package/dist/{memory-reflection-N6NSYW6S.js → memory-reflection-EXNHRZL7.js} +8 -8
  322. package/dist/{memory-write-repository-D35RDO62.js → memory-write-repository-S4TX7WQB.js} +1 -1
  323. package/dist/{monitor-grants-FH4PNYN5.js → monitor-grants-57Q4NL25.js} +3 -3
  324. package/dist/{monitor-identity-LK5ZCCND.js → monitor-identity-3FQ52SYU.js} +2 -2
  325. package/dist/{notification-ledger-3WJYJGGS.js → notification-ledger-O6KQYYGK.js} +13 -16
  326. package/dist/{notifications-T5C2CVB3.js → notifications-6FCQCJ4P.js} +12 -15
  327. package/dist/{orchestration-events-73VEJT7Q.js → orchestration-events-2Z2BMMA5.js} +4 -4
  328. package/dist/{orchestrator-3O657734.js → orchestrator-AGOSKPHD.js} +14 -17
  329. package/dist/{org-brief-session-EGB35QLM.js → org-brief-session-WJHZVXXJ.js} +15 -15
  330. package/dist/{org-consent-policy-MSVSRI53.js → org-consent-policy-X43UGTHI.js} +5 -5
  331. package/dist/{org-join-4BK2XJJI.js → org-join-M3UTBMHC.js} +9 -9
  332. package/dist/{org-key-admin-EUSSGXQ3.js → org-key-admin-AA2DRHB2.js} +11 -11
  333. package/dist/{org-key-epoch-NMEWDT5L.js → org-key-epoch-Z5UIVUHT.js} +5 -5
  334. package/dist/{org-key-pin-HUSXGINB.js → org-key-pin-FE6YHEZ3.js} +3 -3
  335. package/dist/{org-membership-B74IWEM5.js → org-membership-3J2MIGE4.js} +4 -4
  336. package/dist/{org-partner-config-5FJTJABN.js → org-partner-config-5HATZYG4.js} +8 -8
  337. package/dist/{org-partner-runtime-GN4GFWI2.js → org-partner-runtime-UI35IHUC.js} +15 -15
  338. package/dist/{org-row-visibility-PBZ2TSCR.js → org-row-visibility-TRJERVYP.js} +1 -1
  339. package/dist/{pipeline-router-2IELBSVJ.js → pipeline-router-EKQ6D7ZA.js} +4 -4
  340. package/dist/{plan-limits-4GXK5PFT.js → plan-limits-3BGHIHX6.js} +6 -6
  341. package/dist/{platform-procedures-QP3W2NLH.js → platform-procedures-RXW46WNY.js} +1 -1
  342. package/dist/{pre-tool-use-impl-CY73PRJP.js → pre-tool-use-impl-7BT5TJVM.js} +35 -33
  343. package/dist/{project-name-337ERIAX.js → project-name-PGJGUEJY.js} +4 -4
  344. package/dist/{projection-worker-W476IG6V.js → projection-worker-3GEVFPAI.js} +2 -2
  345. package/dist/{prospective-memory-5INB7NUL.js → prospective-memory-GEN7CN7H.js} +3 -3
  346. package/dist/{push-notifications-YVOP4KGN.js → push-notifications-QW4BWRC7.js} +13 -16
  347. package/dist/{reproject-worktree-memories-OGBR3CMO.js → reproject-worktree-memories-DIULBEBD.js} +12 -15
  348. package/dist/{reranker-W7WCJH6Y.js → reranker-LQ6OPJOI.js} +1 -1
  349. package/dist/{retrieval-health-R6MGXLTP.js → retrieval-health-XDFYFEOP.js} +1 -1
  350. package/dist/{review-polling-TKAWVY6G.js → review-polling-ED33YLFT.js} +13 -16
  351. package/dist/runtime/index.js +20 -23
  352. package/dist/{session-events-HUCZ7TOR.js → session-events-7IJGTBVH.js} +13 -16
  353. package/dist/{session-kill-telemetry-RWRWOW4C.js → session-kill-telemetry-RUTEARJ3.js} +13 -16
  354. package/dist/{session-scope-5CDRHV75.js → session-scope-SSYA64L3.js} +12 -15
  355. package/dist/{setup-wizard-RBTJAZOP.js → setup-wizard-XD7FZVLJ.js} +2 -2
  356. package/dist/{shard-manager-LRPAAQA4.js → shard-manager-FH5JZRSE.js} +2 -2
  357. package/dist/{skill-refinement-MDXKDCY6.js → skill-refinement-UHD4E6GV.js} +4 -4
  358. package/dist/{skill-retrieval-OWY6MTCX.js → skill-retrieval-F6PAJ3I5.js} +11 -11
  359. package/dist/{skill-usage-GNV737U5.js → skill-usage-2MBTF7Y4.js} +4 -4
  360. package/dist/{stack-generate-manifest-S4SBLKBY.js → stack-generate-manifest-SU6OFFY7.js} +4 -4
  361. package/dist/{stack-promote-U4EZNLOV.js → stack-promote-MJF436JD.js} +4 -4
  362. package/dist/{stack-release-4VBGOYGK.js → stack-release-S37R57XC.js} +5 -5
  363. package/dist/{stack-update-C5YKHE7A.js → stack-update-XXDRKGGR.js} +3 -3
  364. package/dist/{steward-gate-QFPXQBUZ.js → steward-gate-EWG2BHYQ.js} +4 -4
  365. package/dist/{subagent-brief-injection-GDXO5WNS.js → subagent-brief-injection-YZGSWUEY.js} +25 -27
  366. package/dist/{support-bug-actions-4XEKXIIO.js → support-bug-actions-RU6WZ3UV.js} +3 -3
  367. package/dist/{support-inbox-Y7AFCOGM.js → support-inbox-A3S52SPS.js} +12 -12
  368. package/dist/{task-enforcement-CN3Q4PEH.js → task-enforcement-LVAS55AR.js} +13 -16
  369. package/dist/{task-request-inbox-AY3C6DND.js → task-request-inbox-2TN4ZUH2.js} +5 -5
  370. package/dist/{task-scope-AMR3Z3DJ.js → task-scope-NLKUVCP5.js} +12 -15
  371. package/dist/{tasks-crud-2GHKIZOM.js → tasks-crud-NQDPLHNZ.js} +14 -15
  372. package/dist/{tasks-notify-Z53446KM.js → tasks-notify-BDM2NEHP.js} +13 -16
  373. package/dist/{tasks-review-APRNSHMQ.js → tasks-review-3G7CAW2O.js} +12 -15
  374. package/dist/{telemetry-upload-5XR42SQN.js → telemetry-upload-6DR6AL3V.js} +8 -8
  375. package/dist/{token-budget-TTNJXI7W.js → token-budget-KNC2WGR7.js} +4 -4
  376. package/dist/{tool-telemetry-36ST422N.js → tool-telemetry-I3SEU5M5.js} +1 -1
  377. package/dist/tui/App.js +23 -26
  378. package/dist/{tui-data-AP5TPUOQ.js → tui-data-KJDWP4CB.js} +16 -19
  379. package/dist/{update-support-SFTI2PUD.js → update-support-UYDYMHVR.js} +11 -11
  380. package/dist/{whatsapp-5CXE3JHG.js → whatsapp-5EMPZHF5.js} +2 -2
  381. package/dist/{wiki-acl-N754BC2W.js → wiki-acl-M7BTQJBZ.js} +1 -1
  382. package/dist/{work-claims-OAICQBWO.js → work-claims-5CFMZTML.js} +4 -4
  383. package/dist/{work-state-heartbeat-MTTUGMPU.js → work-state-heartbeat-7IA2DZ2E.js} +1 -1
  384. package/dist/{workflow-engine-RID3QL2U.js → workflow-engine-S5JOE2YR.js} +2 -2
  385. package/dist/{worktree-XWVNDBRD.js → worktree-7V4ZMF3D.js} +5 -5
  386. package/dist/{worktree-sweep-6VEHGH7U.js → worktree-sweep-34MXJ7S6.js} +6 -6
  387. package/package.json +2 -1
  388. package/release-notes.json +25 -7
  389. package/stack.release.json +3 -3
  390. package/dist/chunk-ESO5JDOT.js +0 -70
  391. package/dist/chunk-KCRSJ3VU.js +0 -113
  392. package/dist/content-extractor-OVD7PTSN.js +0 -9
  393. /package/dist/{chunk-OLMLA377.js → chunk-542FBM5U.js} +0 -0
  394. /package/dist/{chunk-LDHJX4TZ.js → chunk-6D2O5SAH.js} +0 -0
  395. /package/dist/{chunk-33PG3KNY.js → chunk-6NRZLVK3.js} +0 -0
  396. /package/dist/{chunk-CLV7ALXV.js → chunk-CFO47VW4.js} +0 -0
  397. /package/dist/{chunk-FLO24BNN.js → chunk-EULAP6L6.js} +0 -0
  398. /package/dist/{chunk-PKM456D2.js → chunk-FYSKQPTE.js} +0 -0
  399. /package/dist/{chunk-WIDOLS7T.js → chunk-J4B4M5PH.js} +0 -0
  400. /package/dist/{chunk-YBB43SXC.js → chunk-J635FA7T.js} +0 -0
  401. /package/dist/{chunk-64UAHPXA.js → chunk-MOBZTIJQ.js} +0 -0
  402. /package/dist/{chunk-EZQ4W3WW.js → chunk-N45FAI6D.js} +0 -0
  403. /package/dist/{chunk-OEEHLATI.js → chunk-QDSNEGJE.js} +0 -0
  404. /package/dist/{chunk-YG4DZZ6J.js → chunk-SKSXROKP.js} +0 -0
  405. /package/dist/{chunk-FUZHMV7K.js → chunk-YVWXI2HM.js} +0 -0
  406. /package/dist/{core-memory-WR7I7DIP.js → core-memory-PZEO3OWH.js} +0 -0
  407. /package/dist/{memory-isolation-4RQJ5RCK.js → memory-isolation-MFNT2ITE.js} +0 -0
  408. /package/dist/{oauth-server-VBDMZIEV.js → oauth-server-CBGEWD6H.js} +0 -0
  409. /package/dist/{project-boot-G7T5WHO6.js → project-boot-VESAYDIH.js} +0 -0
@@ -1,20 +1,9 @@
1
1
  import {
2
- ensureAgentSymlink
3
- } from "./chunk-ESO5JDOT.js";
4
- import {
5
- ensureWorktree,
6
- ensureWorktreeAsync,
7
- getGitRoot,
8
- getMainRepoRoot,
9
- isInsideGitRepo,
10
- isWorktreeDirty
11
- } from "./chunk-VYKXRSHU.js";
2
+ resolveRowVisibility
3
+ } from "./chunk-PYXXL7N7.js";
12
4
  import {
13
5
  runBudgetedSweep
14
6
  } from "./chunk-ZKGWHT56.js";
15
- import {
16
- resolveRowVisibility
17
- } from "./chunk-KBHK2WNO.js";
18
7
  import {
19
8
  LEASE_MINUTES,
20
9
  isLeaseExpired,
@@ -35,9 +24,8 @@ import {
35
24
  writeMemoryViaDaemon
36
25
  } from "./chunk-QDMZ5DX2.js";
37
26
  import {
38
- listSessions,
39
- registerSession
40
- } from "./chunk-HFXBL7XE.js";
27
+ listSessions
28
+ } from "./chunk-QSW5DHMZ.js";
41
29
  import {
42
30
  getTransport
43
31
  } from "./chunk-VI4ATC6I.js";
@@ -46,7 +34,7 @@ import {
46
34
  } from "./chunk-6L4VIYLZ.js";
47
35
  import {
48
36
  recordOrchestrationEventBestEffort
49
- } from "./chunk-SA66WRBT.js";
37
+ } from "./chunk-JGBYZTWH.js";
50
38
  import {
51
39
  appendDispatchJournalEvent,
52
40
  releaseDispatchClaim,
@@ -55,30 +43,22 @@ import {
55
43
  } from "./chunk-T5SM4RXY.js";
56
44
  import {
57
45
  incrementSkillSuccess
58
- } from "./chunk-FJKUFMNF.js";
46
+ } from "./chunk-CFFSHBQF.js";
59
47
  import {
60
48
  assertRuntimeModelCompatible,
61
49
  getAgentRuntime,
62
- normalizeCcModelName,
63
50
  resolveSpawnRuntimeConfig
64
51
  } from "./chunk-IVXELUEQ.js";
65
52
  import {
66
53
  PlanLimitError,
67
54
  assertEmployeeLimitSync
68
- } from "./chunk-EIM7OGTD.js";
69
- import {
70
- AGENT_IDENTITY_TOKEN_ENV,
71
- getDaemonAgentIdentityBroker
72
- } from "./chunk-PCV52RYM.js";
55
+ } from "./chunk-2BOLFLAU.js";
73
56
  import {
74
57
  isValidSessionScope
75
58
  } from "./chunk-BTSWFMEH.js";
76
59
  import {
77
60
  getProjectName
78
- } from "./chunk-4Q7H3TO7.js";
79
- import {
80
- expandDualPrefixTools
81
- } from "./chunk-HYZV25LY.js";
61
+ } from "./chunk-TVWYMOZ4.js";
82
62
  import {
83
63
  getSessionKey
84
64
  } from "./chunk-CVYC6DUW.js";
@@ -99,176 +79,41 @@ import {
99
79
  getEmployee,
100
80
  isCoordinatorName,
101
81
  loadEmployees,
102
- loadEmployeesState,
103
82
  loadEmployeesSync,
104
83
  offloadReadIfMain,
105
84
  offloadReadQuery
106
- } from "./chunk-3MDUKF3N.js";
107
- import {
108
- RUNTIME_TABLE
109
- } from "./chunk-UWGQNJIE.js";
85
+ } from "./chunk-L5JFVK5T.js";
110
86
  import {
111
87
  loadDeviceId
112
- } from "./chunk-DIKLSAJE.js";
88
+ } from "./chunk-EOWJXCYC.js";
113
89
  import {
114
90
  EXE_AI_DIR
115
91
  } from "./chunk-MMS2HBRT.js";
116
92
  import {
117
- atomicWriteJsonSync,
118
- atomicWriteSync
93
+ atomicWriteJsonSync
119
94
  } from "./chunk-HSGBZSCA.js";
120
95
 
121
96
  // src/lib/tmux-routing.ts
122
- import { execFile as execFile2, execFileSync as execFileSync3 } from "child_process";
123
- import { promisify as promisify3 } from "util";
124
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, existsSync as existsSync9, appendFileSync as appendFileSync3, openSync as openSync2, closeSync as closeSync2, writeSync as writeSync2, renameSync as renameSync3, constants as constants2, statSync as statSync4, realpathSync as realpathSync2 } from "fs";
125
- import path8 from "path";
126
- import os6 from "os";
127
- import { fileURLToPath } from "url";
128
-
129
- // src/lib/cc-help-cache.ts
130
- import { execSync } from "child_process";
131
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
132
- import path from "path";
133
- import os from "os";
134
- var CACHE_DIR = path.join(os.homedir(), ".exe-os", "cache");
135
- var _cached = null;
136
- function getCcVersion() {
137
- try {
138
- const out = execSync("claude --version 2>/dev/null || echo unknown", {
139
- encoding: "utf8",
140
- timeout: 5e3
141
- }).trim();
142
- const m = out.match(/(\d+\.\d+\.\d+)/);
143
- return m ? m[1] : "unknown";
144
- } catch {
145
- return "unknown";
146
- }
147
- }
148
- function getCcHelpOutputCached() {
149
- if (_cached !== null) return _cached;
150
- const version = getCcVersion();
151
- const cacheFile = path.join(CACHE_DIR, `cc-help-${version}.txt`);
152
- if (existsSync(cacheFile)) {
153
- try {
154
- _cached = readFileSync(cacheFile, "utf8");
155
- return _cached;
156
- } catch {
157
- }
158
- }
159
- let helpText = "";
160
- try {
161
- const result = execSync("claude --help 2>&1", {
162
- encoding: "utf8",
163
- timeout: 5e3
164
- });
165
- helpText = typeof result === "string" ? result : "";
166
- } catch {
167
- helpText = "";
168
- }
169
- try {
170
- mkdirSync(CACHE_DIR, { recursive: true });
171
- writeFileSync(cacheFile, helpText, "utf8");
172
- } catch {
173
- }
174
- _cached = helpText;
175
- return _cached;
176
- }
177
- function _resetCcHelpCache() {
178
- _cached = null;
179
- }
180
-
181
- // src/lib/cc-agent-support.ts
182
- function _resetCcAgentSupportCache() {
183
- _resetCcHelpCache();
184
- }
185
- function claudeSupportsAgentFlag() {
186
- return /(^|\s)--agent(\b|=)/.test(getCcHelpOutputCached());
187
- }
188
-
189
- // src/lib/provider-table.ts
190
- var PROVIDER_TABLE = {
191
- opencode: {
192
- baseUrl: "https://opencode.ai/zen/go",
193
- apiKeyEnv: "OPENCODE_API_KEY",
194
- defaultModel: "kimi-k2.7-code"
195
- },
196
- glm: {
197
- baseUrl: "https://api.z.ai/api/anthropic",
198
- apiKeyEnv: "ZAI_API_KEY",
199
- defaultModel: "glm-5.3",
200
- authVar: "ANTHROPIC_AUTH_TOKEN",
201
- apiKeyFallbackFile: ".glm-mcp/config.json",
202
- contextByModel: {
203
- // glm-5.3 released 2026-08-14 (confirmed real via
204
- // api.z.ai/api/paas/v4/models — Z.ai's endpoint validates model ids and
205
- // this one isn't rejected). Z.ai's model-list/model-detail endpoints
206
- // don't expose context length via API, so this 1M figure is founder-
207
- // confirmed (2026-08-24), not independently API-verified — if that
208
- // ever turns out wrong, don't silently "fix" it back down, ask first.
209
- "glm-5.3": 1e6,
210
- "glm-5.2": 1e6,
211
- "glm-5": 2e5,
212
- "glm-5-turbo": 2e5,
213
- "glm-4.7": 2e5,
214
- "glm-4.7-flash": 2e5
215
- }
216
- },
217
- kimi: {
218
- // Kimi subscription via kimi-proxy (~/.kimi-code/kimi-proxy.mjs, launchd
219
- // com.exeai.kimi-proxy, port 8791). The subscription API
220
- // https://api.kimi.ai/coding/v1/messages speaks NATIVE Anthropic protocol
221
- // but authenticates with the Kimi CLI's OAuth token (15-min expiry,
222
- // refresh via auth.kimi.ai/v1/oauth/token — client_id 17e5f671-…,
223
- // anthropic-beta oauth-2025-04-20; extracted from @moonshot-ai/kimi-code
224
- // 2.0.2 dist/main.mjs). The proxy handles refresh + Cloudflare UA
225
- // fingerprinting (upstream 403s any non-kimi UA) and is a pure byte
226
- // passthrough, so Claude Code just points at 127.0.0.1:8791 and CC's
227
- // /v1/messages lands on /coding/v1/messages. Verified E2E 2026-09-22.
228
- //
229
- // Model ids are the Kimi Code registry's wire ids (NOT display names):
230
- // kimi-for-coding = "K2.8 Preview" (1M context, default per founder
231
- // 2026-09-22), kimi-for-coding-highspeed = "K2.7 Code Highspeed" (256k),
232
- // k3-256k. K3's 1M variant (wire id "k3") is deliberately NOT declared —
233
- // founder policy 2026-09-22: never use K3 1M, it burns 2x tokens; K3
234
- // work goes through k3-256k. The fallback api-key.json exists only to
235
- // satisfy the launcher's key check — the proxy owns real credentials.
236
- baseUrl: "http://127.0.0.1:8791",
237
- apiKeyEnv: "KIMI_API_KEY",
238
- defaultModel: "kimi-for-coding",
239
- authVar: "ANTHROPIC_AUTH_TOKEN",
240
- apiKeyFallbackFile: ".kimi-code/api-key.json",
241
- contextByModel: {
242
- "kimi-for-coding": 1e6,
243
- "kimi-for-coding-highspeed": 262144,
244
- "k3-256k": 262144
245
- }
246
- }
247
- };
248
- var DEFAULT_PROVIDER = "default";
249
- function detectActiveProvider(env = process.env) {
250
- const baseUrl = env.ANTHROPIC_BASE_URL;
251
- if (!baseUrl) return DEFAULT_PROVIDER;
252
- for (const [name, cfg] of Object.entries(PROVIDER_TABLE)) {
253
- if (cfg.baseUrl === baseUrl) return name;
254
- }
255
- return DEFAULT_PROVIDER;
256
- }
97
+ import { execFile } from "child_process";
98
+ import { promisify as promisify2 } from "util";
99
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, existsSync as existsSync7, appendFileSync as appendFileSync3, openSync as openSync2, closeSync as closeSync2, writeSync as writeSync2, renameSync as renameSync3, constants as constants2, statSync as statSync4 } from "fs";
100
+ import path6 from "path";
101
+ import os5 from "os";
257
102
 
258
103
  // src/lib/intercom-queue.ts
259
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, renameSync, existsSync as existsSync3, mkdirSync as mkdirSync2, appendFileSync, openSync, closeSync, writeSync, unlinkSync as unlinkSync2, constants, statSync } from "fs";
260
- import path3 from "path";
261
- import os3 from "os";
104
+ import { readFileSync as readFileSync2, writeFileSync, renameSync, existsSync as existsSync2, mkdirSync, appendFileSync, openSync, closeSync, writeSync, unlinkSync as unlinkSync2, constants, statSync } from "fs";
105
+ import path2 from "path";
106
+ import os2 from "os";
262
107
 
263
108
  // src/lib/notifications.ts
264
109
  import crypto from "crypto";
265
- import path2 from "path";
266
- import os2 from "os";
110
+ import path from "path";
111
+ import os from "os";
267
112
  import {
268
- readFileSync as readFileSync2,
113
+ readFileSync,
269
114
  readdirSync,
270
115
  unlinkSync,
271
- existsSync as existsSync2,
116
+ existsSync,
272
117
  rmdirSync
273
118
  } from "fs";
274
119
  var CLEANUP_DAYS = 7;
@@ -415,9 +260,9 @@ function formatNotifications(notifications) {
415
260
  return lines.join("\n");
416
261
  }
417
262
  async function migrateJsonNotifications() {
418
- const base = process.env.EXE_OS_DIR || process.env.EXE_MEM_DIR || path2.join(os2.homedir(), ".exe-os");
419
- const notifDir = path2.join(base, "notifications");
420
- if (!existsSync2(notifDir)) return 0;
263
+ const base = process.env.EXE_OS_DIR || process.env.EXE_MEM_DIR || path.join(os.homedir(), ".exe-os");
264
+ const notifDir = path.join(base, "notifications");
265
+ if (!existsSync(notifDir)) return 0;
421
266
  let migrated = 0;
422
267
  try {
423
268
  const files = readdirSync(notifDir).filter((f) => f.endsWith(".json"));
@@ -425,8 +270,8 @@ async function migrateJsonNotifications() {
425
270
  const client = getClient();
426
271
  for (const file of files) {
427
272
  try {
428
- const filePath = path2.join(notifDir, file);
429
- const data = JSON.parse(readFileSync2(filePath, "utf8"));
273
+ const filePath = path.join(notifDir, file);
274
+ const data = JSON.parse(readFileSync(filePath, "utf8"));
430
275
  await client.execute({
431
276
  sql: `INSERT OR IGNORE INTO notifications (id, agent_id, agent_role, event, project, summary, task_file, session_scope, read, created_at)
432
277
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
@@ -495,14 +340,14 @@ function formatTimeAgo(timestamp) {
495
340
  }
496
341
 
497
342
  // src/lib/intercom-queue.ts
498
- var QUEUE_PATH = path3.join(os3.homedir(), ".exe-os", "intercom-queue.json");
343
+ var QUEUE_PATH = path2.join(os2.homedir(), ".exe-os", "intercom-queue.json");
499
344
  var QUEUE_LOCK_PATH = `${QUEUE_PATH}.lock`;
500
345
  var MAX_RETRIES = 10;
501
346
  var TTL_MS = 60 * 60 * 1e3;
502
347
  var HARD_TTL_MS = 2 * TTL_MS;
503
348
  function ensureDir() {
504
- const dir = path3.dirname(QUEUE_PATH);
505
- if (!existsSync3(dir)) mkdirSync2(dir, { recursive: true });
349
+ const dir = path2.dirname(QUEUE_PATH);
350
+ if (!existsSync2(dir)) mkdirSync(dir, { recursive: true });
506
351
  }
507
352
  function acquireQueueLock() {
508
353
  ensureDir();
@@ -517,7 +362,7 @@ function acquireQueueLock() {
517
362
  } catch (err) {
518
363
  if (err.code !== "EEXIST") return false;
519
364
  try {
520
- const lock = JSON.parse(readFileSync3(QUEUE_LOCK_PATH, "utf8"));
365
+ const lock = JSON.parse(readFileSync2(QUEUE_LOCK_PATH, "utf8"));
521
366
  if (Date.now() - Number(lock.timestamp ?? 0) > 3e4) unlinkSync2(QUEUE_LOCK_PATH);
522
367
  } catch {
523
368
  try {
@@ -538,8 +383,8 @@ function releaseQueueLock() {
538
383
  }
539
384
  function readQueue() {
540
385
  try {
541
- if (!existsSync3(QUEUE_PATH)) return [];
542
- return JSON.parse(readFileSync3(QUEUE_PATH, "utf8"));
386
+ if (!existsSync2(QUEUE_PATH)) return [];
387
+ return JSON.parse(readFileSync2(QUEUE_PATH, "utf8"));
543
388
  } catch {
544
389
  return [];
545
390
  }
@@ -547,7 +392,7 @@ function readQueue() {
547
392
  function writeQueue(queue) {
548
393
  ensureDir();
549
394
  const tmp = `${QUEUE_PATH}.tmp`;
550
- writeFileSync2(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
395
+ writeFileSync(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
551
396
  renameSync(tmp, QUEUE_PATH);
552
397
  }
553
398
  function queueIntercom(targetSession, reason, intercomReason = "nudge") {
@@ -783,7 +628,7 @@ function clearQueueForAgent(agentName) {
783
628
  function _resetDrainGuard() {
784
629
  _draining = false;
785
630
  }
786
- var INTERCOM_LOG = path3.join(os3.homedir(), ".exe-os", "intercom.log");
631
+ var INTERCOM_LOG = path2.join(os2.homedir(), ".exe-os", "intercom.log");
787
632
  var INTERCOM_LOG_MAX_BYTES = 1024 * 1024;
788
633
  function logQueue(msg) {
789
634
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
@@ -791,7 +636,7 @@ function logQueue(msg) {
791
636
  process.stderr.write(`[intercom-queue] ${msg}
792
637
  `);
793
638
  try {
794
- if (existsSync3(INTERCOM_LOG) && statSync(INTERCOM_LOG).size > INTERCOM_LOG_MAX_BYTES) {
639
+ if (existsSync2(INTERCOM_LOG) && statSync(INTERCOM_LOG).size > INTERCOM_LOG_MAX_BYTES) {
795
640
  renameSync(INTERCOM_LOG, `${INTERCOM_LOG}.1`);
796
641
  }
797
642
  appendFileSync(INTERCOM_LOG, line);
@@ -803,16 +648,16 @@ function logQueue(msg) {
803
648
  import { unlinkSync as unlinkSync4 } from "fs";
804
649
 
805
650
  // src/lib/routing-log.ts
806
- import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, existsSync as existsSync4, statSync as statSync2, renameSync as renameSync2 } from "fs";
807
- import path4 from "path";
808
- import os4 from "os";
809
- var LOG_DIR = path4.join(os4.homedir(), ".exe-os", "logs");
810
- var LOG_FILE = path4.join(LOG_DIR, "routing.log");
651
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync3, statSync as statSync2, renameSync as renameSync2 } from "fs";
652
+ import path3 from "path";
653
+ import os3 from "os";
654
+ var LOG_DIR = path3.join(os3.homedir(), ".exe-os", "logs");
655
+ var LOG_FILE = path3.join(LOG_DIR, "routing.log");
811
656
  var dirChecked = false;
812
657
  var MAX_LOG_BYTES = 5 * 1024 * 1024;
813
658
  function ensureDir2() {
814
659
  if (dirChecked) return;
815
- if (!existsSync4(LOG_DIR)) mkdirSync3(LOG_DIR, { recursive: true });
660
+ if (!existsSync3(LOG_DIR)) mkdirSync2(LOG_DIR, { recursive: true });
816
661
  dirChecked = true;
817
662
  }
818
663
  function rotateIfNeeded() {
@@ -910,21 +755,21 @@ function logTaskDispatch(opts) {
910
755
  }
911
756
 
912
757
  // src/lib/tasks-review.ts
913
- import path6 from "path";
914
- import { existsSync as existsSync7, readdirSync as readdirSync2, statSync as statSync3, unlinkSync as unlinkSync3 } from "fs";
758
+ import path5 from "path";
759
+ import { existsSync as existsSync6, readdirSync as readdirSync2, statSync as statSync3, unlinkSync as unlinkSync3 } from "fs";
915
760
  import { homedir as homedir2 } from "os";
916
761
 
917
762
  // src/lib/tasks-crud.ts
918
763
  import crypto2 from "crypto";
919
- import path5 from "path";
920
- import os5 from "os";
921
- import { execSync as execSync2, execFile as execFileCb, execFileSync } from "child_process";
764
+ import path4 from "path";
765
+ import os4 from "os";
766
+ import { execSync, execFile as execFileCb, execFileSync } from "child_process";
922
767
  import { promisify } from "util";
923
768
  import { mkdir, writeFile, appendFile, readdir, unlink, stat } from "fs/promises";
924
- import { existsSync as existsSync6, readFileSync as readFileSync5, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
769
+ import { existsSync as existsSync5, readFileSync as readFileSync4, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3 } from "fs";
925
770
 
926
771
  // src/lib/completion-nudge-dedup.ts
927
- import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4 } from "fs";
772
+ import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "fs";
928
773
  import { join, dirname } from "path";
929
774
  import { homedir } from "os";
930
775
  var COMPLETION_NUDGE_COOLDOWN_MS = Number(process.env.EXE_COMPLETION_NUDGE_COOLDOWN_MS) || 6 * 60 * 60 * 1e3;
@@ -943,8 +788,8 @@ function load(ledger) {
943
788
  if (ledger.state) return ledger.state;
944
789
  ledger.state = {};
945
790
  try {
946
- if (existsSync5(ledger.path)) {
947
- const raw = JSON.parse(readFileSync4(ledger.path, "utf8"));
791
+ if (existsSync4(ledger.path)) {
792
+ const raw = JSON.parse(readFileSync3(ledger.path, "utf8"));
948
793
  if (raw && typeof raw === "object" && !Array.isArray(raw)) {
949
794
  for (const [k, v] of Object.entries(raw)) {
950
795
  if (typeof v === "number") ledger.state[k] = v;
@@ -957,8 +802,8 @@ function load(ledger) {
957
802
  }
958
803
  function persist(ledger, state) {
959
804
  try {
960
- mkdirSync4(dirname(ledger.path), { recursive: true });
961
- writeFileSync3(ledger.path, JSON.stringify(state), "utf8");
805
+ mkdirSync3(dirname(ledger.path), { recursive: true });
806
+ writeFileSync2(ledger.path, JSON.stringify(state), "utf8");
962
807
  } catch {
963
808
  }
964
809
  }
@@ -1011,6 +856,7 @@ function clearStaleReviewEscalation(taskId) {
1011
856
  // src/lib/tasks-crud.ts
1012
857
  var execFileAsync = promisify(execFileCb);
1013
858
  var DEFAULT_TASK_PRIORITY = "p1";
859
+ var DEFAULT_NEW_TASK_EXECUTION_MODE = "checklist";
1014
860
  function normalizeTaskPriority(value) {
1015
861
  const v = typeof value === "string" ? value.trim().toLowerCase() : "";
1016
862
  if (v === "p0" || v === "p1" || v === "p2") return v;
@@ -1531,8 +1377,8 @@ ${f.context}
1531
1377
  `;
1532
1378
  }
1533
1379
  async function writeTaskMarkdownAtomic(finalPath, content) {
1534
- const dir = path5.dirname(finalPath);
1535
- if (!existsSync6(dir)) await mkdir(dir, { recursive: true });
1380
+ const dir = path4.dirname(finalPath);
1381
+ if (!existsSync5(dir)) await mkdir(dir, { recursive: true });
1536
1382
  const tmpPath = `${finalPath}.${crypto2.randomBytes(6).toString("hex")}.tmp`;
1537
1383
  try {
1538
1384
  await writeFile(tmpPath, content, "utf-8");
@@ -1610,7 +1456,7 @@ async function createTaskCore(input, deps = {}) {
1610
1456
  if (isCoordinatorSession) {
1611
1457
  earlySessionScope = resolved;
1612
1458
  } else {
1613
- const { getSessionProject } = await import("./session-scope-5CDRHV75.js");
1459
+ const { getSessionProject } = await import("./session-scope-SSYA64L3.js");
1614
1460
  const sessionProject = getSessionProject(resolved);
1615
1461
  if (sessionProject && sessionProject !== input.projectName) {
1616
1462
  scopeMismatchWarning = `session/project mismatch: session "${resolved}" owns "${sessionProject}" but task targets "${input.projectName}". Routed to default scope.`;
@@ -1681,8 +1527,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
1681
1527
  }
1682
1528
  if (input.baseDir) {
1683
1529
  try {
1684
- await mkdir(path5.join(input.baseDir, "exe", "output"), { recursive: true });
1685
- await mkdir(path5.join(input.baseDir, "exe", "research"), { recursive: true });
1530
+ await mkdir(path4.join(input.baseDir, "exe", "output"), { recursive: true });
1531
+ await mkdir(path4.join(input.baseDir, "exe", "research"), { recursive: true });
1686
1532
  await ensureArchitectureDoc(input.baseDir, input.projectName);
1687
1533
  await ensureGitignoreExe(input.baseDir);
1688
1534
  } catch {
@@ -1712,7 +1558,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
1712
1558
  }
1713
1559
  const groupId = input.groupId ?? null;
1714
1560
  if (groupId) {
1715
- const requestedExecutionMode = input.executionMode ?? "durable_tmux";
1561
+ const requestedExecutionMode = input.executionMode ?? DEFAULT_NEW_TASK_EXECUTION_MODE;
1716
1562
  const groupCheck = await client.execute({
1717
1563
  sql: `SELECT id, execution_mode FROM task_groups WHERE id = ? AND session_scope IS ?`,
1718
1564
  args: [groupId, sessionScope]
@@ -1757,7 +1603,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
1757
1603
  sessionScope,
1758
1604
  input.spawnRuntime ?? null,
1759
1605
  input.spawnModel ?? null,
1760
- input.executionMode ?? "durable_tmux",
1606
+ input.executionMode ?? DEFAULT_NEW_TASK_EXECUTION_MODE,
1761
1607
  groupId,
1762
1608
  loadDeviceId(),
1763
1609
  input.founderId ?? null,
@@ -1781,7 +1627,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
1781
1627
  if (existing.rows.length > 0) {
1782
1628
  const r = existing.rows[0];
1783
1629
  const persistedMode = r.execution_mode === "checklist" ? "checklist" : "durable_tmux";
1784
- const requestedMode = input.executionMode ?? "durable_tmux";
1630
+ const requestedMode = input.executionMode ?? DEFAULT_NEW_TASK_EXECUTION_MODE;
1785
1631
  if (persistedMode !== requestedMode) {
1786
1632
  throw new Error(
1787
1633
  `Idempotency execution_mode mismatch: existing task is ${persistedMode}, requested ${requestedMode}`
@@ -1862,8 +1708,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
1862
1708
  });
1863
1709
  if (input.baseDir) {
1864
1710
  try {
1865
- const EXE_OS_DIR = path5.join(os5.homedir(), ".exe-os");
1866
- const mdPath = path5.join(EXE_OS_DIR, taskFile);
1711
+ const EXE_OS_DIR = path4.join(os4.homedir(), ".exe-os");
1712
+ const mdPath = path4.join(EXE_OS_DIR, taskFile);
1867
1713
  const reviewer = input.reviewer ?? input.assignedBy;
1868
1714
  const mdContent = renderTaskMarkdown({
1869
1715
  id,
@@ -1880,7 +1726,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
1880
1726
  });
1881
1727
  await writeTaskMarkdownAtomic(mdPath, mdContent);
1882
1728
  try {
1883
- const { injectBehaviors } = await import("./behavior-injection-NRXTNROW.js");
1729
+ const { injectBehaviors } = await import("./behavior-injection-G7GAUHGO.js");
1884
1730
  await injectBehaviors({
1885
1731
  taskFile: mdPath,
1886
1732
  title: input.title,
@@ -1921,7 +1767,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
1921
1767
  tokensWarnedAt: null,
1922
1768
  spawnRuntime: input.spawnRuntime ?? null,
1923
1769
  spawnModel: input.spawnModel ?? null,
1924
- executionMode: input.executionMode ?? "durable_tmux",
1770
+ executionMode: input.executionMode ?? DEFAULT_NEW_TASK_EXECUTION_MODE,
1925
1771
  sessionScope
1926
1772
  };
1927
1773
  }
@@ -1975,7 +1821,7 @@ async function buildTaskRowsStatement(opts) {
1975
1821
  }
1976
1822
  if (opts.founderId !== null) {
1977
1823
  try {
1978
- const { founderScopeFilter } = await import("./founder-context-QIXDZIJX.js");
1824
+ const { founderScopeFilter } = await import("./founder-context-3X4QUWKD.js");
1979
1825
  const founderFilter = founderScopeFilter(opts.founderId);
1980
1826
  const cleaned = founderFilter.sql.replace(/^\s*AND\s+/, "");
1981
1827
  conditions.push(cleaned);
@@ -2191,7 +2037,7 @@ function refreshTmuxAliveCacheSync() {
2191
2037
  _tmuxAliveSessions = /* @__PURE__ */ new Set();
2192
2038
  _tmuxAlivePanes = /* @__PURE__ */ new Set();
2193
2039
  try {
2194
- const output = execSync2(tmuxCmd("list-panes -a -F '#{session_name} #{pane_id} #{pane_dead}'"), {
2040
+ const output = execSync(tmuxCmd("list-panes -a -F '#{session_name} #{pane_id} #{pane_dead}'"), {
2195
2041
  timeout: 2e3,
2196
2042
  encoding: "utf8",
2197
2043
  stdio: ["pipe", "pipe", "pipe"]
@@ -2465,12 +2311,12 @@ function checkStaleCompletion(taskContext, taskCreatedAt) {
2465
2311
  if (!DELEGATION_KEYWORDS.test(taskContext)) return null;
2466
2312
  try {
2467
2313
  const since = new Date(taskCreatedAt).toISOString();
2468
- const branch = execSync2(
2314
+ const branch = execSync(
2469
2315
  "git rev-parse --abbrev-ref HEAD 2>/dev/null",
2470
2316
  { encoding: "utf8", timeout: 3e3 }
2471
2317
  ).trim();
2472
2318
  const branchArg = branch && branch !== "HEAD" ? branch : "";
2473
- const commitCount = execSync2(
2319
+ const commitCount = execSync(
2474
2320
  `git log --oneline --since="${since}" ${branchArg} 2>/dev/null | wc -l`,
2475
2321
  { encoding: "utf8", timeout: 5e3 }
2476
2322
  ).trim();
@@ -3377,8 +3223,8 @@ ${input.result ?? ""}`;
3377
3223
  try {
3378
3224
  const scope = row.session_scope ? String(row.session_scope) : "default";
3379
3225
  const dir = taskSignalDir(scope);
3380
- mkdirSync5(dir, { recursive: true });
3381
- writeFileSync4(
3226
+ mkdirSync4(dir, { recursive: true });
3227
+ writeFileSync3(
3382
3228
  reviewSignalPath(scope, reviewer, taskId),
3383
3229
  JSON.stringify({
3384
3230
  task_id: taskId,
@@ -3663,9 +3509,9 @@ async function deleteTaskCore(taskId, _baseDir) {
3663
3509
  return { taskFile, assignedTo, assignedBy, taskSlug };
3664
3510
  }
3665
3511
  async function ensureArchitectureDoc(baseDir, projectName) {
3666
- const archPath = path5.join(baseDir, "exe", "ARCHITECTURE.md");
3512
+ const archPath = path4.join(baseDir, "exe", "ARCHITECTURE.md");
3667
3513
  try {
3668
- if (existsSync6(archPath)) return;
3514
+ if (existsSync5(archPath)) return;
3669
3515
  const template = [
3670
3516
  `# ${projectName} \u2014 System Architecture`,
3671
3517
  "",
@@ -3699,10 +3545,10 @@ async function ensureArchitectureDoc(baseDir, projectName) {
3699
3545
  }
3700
3546
  var GITIGNORE_EXE_BLOCK = "# Employee task assignments (private)\n# exe/output/ stays tracked \u2014 it is the sanctioned deliverable handoff\n# location (bug 4c8d4c4b). Never collapse this back to a blanket /exe/.\n/exe/*\n!/exe/output/\n";
3701
3547
  async function ensureGitignoreExe(baseDir) {
3702
- const gitignorePath = path5.join(baseDir, ".gitignore");
3548
+ const gitignorePath = path4.join(baseDir, ".gitignore");
3703
3549
  try {
3704
- if (existsSync6(gitignorePath)) {
3705
- const content = readFileSync5(gitignorePath, "utf-8");
3550
+ if (existsSync5(gitignorePath)) {
3551
+ const content = readFileSync4(gitignorePath, "utf-8");
3706
3552
  if (/^\/?exe\/\*$/m.test(content) && /^!\/?exe\/output\/?$/m.test(content)) return;
3707
3553
  if (/^\/?exe\/?$/m.test(content)) {
3708
3554
  const narrowed = content.replace(/^\/?exe\/?$/m, "/exe/*\n!/exe/output/");
@@ -3727,7 +3573,7 @@ async function collectTaskMarkdownPaths(root) {
3727
3573
  return;
3728
3574
  }
3729
3575
  for (const entry of entries) {
3730
- const fullPath = path5.join(dir, entry.name);
3576
+ const fullPath = path4.join(dir, entry.name);
3731
3577
  if (entry.isDirectory()) {
3732
3578
  await walkDir(fullPath);
3733
3579
  } else if (entry.name.endsWith(".md")) {
@@ -3740,14 +3586,14 @@ async function collectTaskMarkdownPaths(root) {
3740
3586
  }
3741
3587
  var TASK_FILE_CONFLICT_MARKER_SUFFIX = ".conflict";
3742
3588
  async function cleanOrphanedTaskFiles() {
3743
- const EXE_TASKS_DIR = path5.join(os5.homedir(), ".exe-os", "tasks");
3744
- if (!existsSync6(EXE_TASKS_DIR)) return 0;
3589
+ const EXE_TASKS_DIR = path4.join(os4.homedir(), ".exe-os", "tasks");
3590
+ if (!existsSync5(EXE_TASKS_DIR)) return 0;
3745
3591
  let cleaned = 0;
3746
3592
  const paths = await collectTaskMarkdownPaths(EXE_TASKS_DIR);
3747
3593
  await runBudgetedSweep(paths, async (fullPath) => {
3748
- const entryName = path5.basename(fullPath);
3749
- if (existsSync6(`${fullPath}${TASK_FILE_CONFLICT_MARKER_SUFFIX}`)) return;
3750
- const relativePath = path5.relative(path5.join(os5.homedir(), ".exe-os"), fullPath);
3594
+ const entryName = path4.basename(fullPath);
3595
+ if (existsSync5(`${fullPath}${TASK_FILE_CONFLICT_MARKER_SUFFIX}`)) return;
3596
+ const relativePath = path4.relative(path4.join(os4.homedir(), ".exe-os"), fullPath);
3751
3597
  try {
3752
3598
  const result = await offloadReadQuery("SELECT id FROM tasks WHERE task_file = ? LIMIT 1", [relativePath]);
3753
3599
  if (result.rows.length === 0) {
@@ -3830,7 +3676,7 @@ async function createTaskGroup(input) {
3830
3676
  input.projectName ?? null,
3831
3677
  input.timeoutMinutes ?? 120,
3832
3678
  input.onPartialFailure ?? "notify",
3833
- input.executionMode ?? "durable_tmux",
3679
+ input.executionMode ?? DEFAULT_NEW_TASK_EXECUTION_MODE,
3834
3680
  now,
3835
3681
  now
3836
3682
  ]
@@ -3851,7 +3697,7 @@ async function createTaskGroup(input) {
3851
3697
  projectName: input.projectName ?? null,
3852
3698
  timeoutMinutes: input.timeoutMinutes ?? 120,
3853
3699
  onPartialFailure: input.onPartialFailure ?? "notify",
3854
- executionMode: input.executionMode ?? "durable_tmux",
3700
+ executionMode: input.executionMode ?? DEFAULT_NEW_TASK_EXECUTION_MODE,
3855
3701
  barrierFired: false,
3856
3702
  barrierFiredAt: null,
3857
3703
  aggregatedResult: null,
@@ -4114,8 +3960,8 @@ async function checkTaskFileConsistency() {
4114
3960
  for (const row of result.rows) {
4115
3961
  const taskFile = String(row.task_file ?? "");
4116
3962
  if (!taskFile) continue;
4117
- const fullPath = taskFile.startsWith("/") ? taskFile : path5.join(os5.homedir(), ".exe-os", taskFile);
4118
- if (existsSync6(fullPath)) continue;
3963
+ const fullPath = taskFile.startsWith("/") ? taskFile : path4.join(os4.homedir(), ".exe-os", taskFile);
3964
+ if (existsSync5(fullPath)) continue;
4119
3965
  let repaired = false;
4120
3966
  try {
4121
3967
  const mdContent = renderTaskMarkdown({
@@ -4269,10 +4115,10 @@ async function invalidateReviewArtifacts(row) {
4269
4115
  }
4270
4116
  try {
4271
4117
  const dir = taskSignalDir(row.session_scope || "default");
4272
- if (existsSync7(dir)) {
4118
+ if (existsSync6(dir)) {
4273
4119
  for (const f of readdirSync2(dir)) {
4274
4120
  if (f.endsWith(`.review-${row.id}.pending`)) {
4275
- unlinkSync3(path6.join(dir, f));
4121
+ unlinkSync3(path5.join(dir, f));
4276
4122
  }
4277
4123
  }
4278
4124
  }
@@ -4322,10 +4168,10 @@ async function closeReviewRows(client, rows, status, now) {
4322
4168
  function sweepExpiredSignalFiles(now = Date.now()) {
4323
4169
  let deleted = 0;
4324
4170
  try {
4325
- const base = path6.join(homedir2(), ".exe-os", "task-signals");
4326
- if (!existsSync7(base)) return 0;
4171
+ const base = path5.join(homedir2(), ".exe-os", "task-signals");
4172
+ if (!existsSync6(base)) return 0;
4327
4173
  for (const scopeName of readdirSync2(base)) {
4328
- const scopeDir = path6.join(base, scopeName);
4174
+ const scopeDir = path5.join(base, scopeName);
4329
4175
  let entries;
4330
4176
  try {
4331
4177
  entries = readdirSync2(scopeDir);
@@ -4334,7 +4180,7 @@ function sweepExpiredSignalFiles(now = Date.now()) {
4334
4180
  }
4335
4181
  for (const f of entries) {
4336
4182
  if (!f.endsWith(".pending")) continue;
4337
- const filePath = path6.join(scopeDir, f);
4183
+ const filePath = path5.join(scopeDir, f);
4338
4184
  try {
4339
4185
  if (now - statSync3(filePath).mtimeMs > SIGNAL_FILE_TTL_MS) {
4340
4186
  unlinkSync3(filePath);
@@ -4648,11 +4494,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
4648
4494
  );
4649
4495
  }
4650
4496
  try {
4651
- const cacheDir = path6.join(EXE_AI_DIR, "session-cache");
4652
- if (existsSync7(cacheDir)) {
4497
+ const cacheDir = path5.join(EXE_AI_DIR, "session-cache");
4498
+ if (existsSync6(cacheDir)) {
4653
4499
  for (const f of readdirSync2(cacheDir)) {
4654
4500
  if (f.startsWith("review-notified-")) {
4655
- unlinkSync3(path6.join(cacheDir, f));
4501
+ unlinkSync3(path5.join(cacheDir, f));
4656
4502
  }
4657
4503
  }
4658
4504
  }
@@ -4660,193 +4506,6 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
4660
4506
  }
4661
4507
  }
4662
4508
 
4663
- // src/lib/worktree-guard.ts
4664
- import { execFile, execFileSync as execFileSync2 } from "child_process";
4665
- import { promisify as promisify2 } from "util";
4666
- import { existsSync as existsSync8, realpathSync } from "fs";
4667
- import path7 from "path";
4668
- var GIT_TIMEOUT_MS = 1e4;
4669
- var execFileAsync2 = promisify2(execFile);
4670
- function realpath(p) {
4671
- try {
4672
- return realpathSync(p);
4673
- } catch {
4674
- return p;
4675
- }
4676
- }
4677
- var defaultGitExecutor = async (args, cwd) => {
4678
- const { stdout } = await execFileAsync2("git", args, {
4679
- cwd,
4680
- encoding: "utf8",
4681
- timeout: GIT_TIMEOUT_MS
4682
- });
4683
- return String(stdout ?? "");
4684
- };
4685
- function listWorktreesPorcelain(repoRoot) {
4686
- try {
4687
- const output = execFileSync2("git", ["worktree", "list", "--porcelain"], {
4688
- cwd: repoRoot,
4689
- encoding: "utf8",
4690
- timeout: GIT_TIMEOUT_MS,
4691
- stdio: ["pipe", "pipe", "pipe"]
4692
- });
4693
- const worktrees = [];
4694
- let currentPath = "";
4695
- for (const line of output.split("\n")) {
4696
- if (line.startsWith("worktree ")) {
4697
- currentPath = line.slice("worktree ".length);
4698
- } else if (line.startsWith("branch ") && currentPath) {
4699
- const branch = line.slice("branch refs/heads/".length);
4700
- worktrees.push({ path: currentPath, branch });
4701
- currentPath = "";
4702
- }
4703
- }
4704
- return worktrees;
4705
- } catch {
4706
- return [];
4707
- }
4708
- }
4709
- function inferSessionOwner(wtPath, branch) {
4710
- const dirName = path7.basename(wtPath);
4711
- if (dirName && dirName !== ".worktrees") {
4712
- return dirName;
4713
- }
4714
- const dashIdx = branch.indexOf("-");
4715
- if (dashIdx > 0) {
4716
- return branch.slice(0, dashIdx);
4717
- }
4718
- return null;
4719
- }
4720
- function hasUnpushedCommits(wtPath, branch) {
4721
- for (const mainRef of ["main", "master"]) {
4722
- try {
4723
- const ahead = execFileSync2(
4724
- "git",
4725
- ["-C", wtPath, "rev-list", `${mainRef}..${branch}`, "--count"],
4726
- { encoding: "utf-8", timeout: GIT_TIMEOUT_MS, stdio: ["pipe", "pipe", "ignore"] }
4727
- ).trim();
4728
- return parseInt(ahead, 10) > 0;
4729
- } catch {
4730
- }
4731
- }
4732
- return true;
4733
- }
4734
- function checkWorktreeCollisions(repoPath) {
4735
- const repoRoot = getGitRoot(repoPath);
4736
- if (!repoRoot) return [];
4737
- const warnings = [];
4738
- const worktrees = listWorktreesPorcelain(repoRoot);
4739
- for (const wt of worktrees) {
4740
- if (!wt.path.includes("/.worktrees/")) continue;
4741
- if (!existsSync8(wt.path)) continue;
4742
- const owner = inferSessionOwner(wt.path, wt.branch);
4743
- const dirty = isWorktreeDirty(wt.path);
4744
- const hasCommits = hasUnpushedCommits(wt.path, wt.branch);
4745
- if (dirty) {
4746
- warnings.push({
4747
- worktreePath: wt.path,
4748
- branch: wt.branch,
4749
- sessionOwner: owner,
4750
- dirty: true,
4751
- reason: `Worktree has uncommitted changes (agent: ${owner ?? "unknown"}, branch: ${wt.branch})`
4752
- });
4753
- } else if (hasCommits) {
4754
- warnings.push({
4755
- worktreePath: wt.path,
4756
- branch: wt.branch,
4757
- sessionOwner: owner,
4758
- dirty: false,
4759
- reason: `Worktree has unpushed commits on branch ${wt.branch} (agent: ${owner ?? "unknown"})`
4760
- });
4761
- }
4762
- }
4763
- return warnings;
4764
- }
4765
- async function getGitRootAsync(dir, git) {
4766
- try {
4767
- const root = (await git(["rev-parse", "--show-toplevel"], dir)).trim();
4768
- return root ? realpath(root) : null;
4769
- } catch {
4770
- return null;
4771
- }
4772
- }
4773
- async function listWorktreesPorcelainAsync(repoRoot, git) {
4774
- try {
4775
- const output = await git(["worktree", "list", "--porcelain"], repoRoot);
4776
- const worktrees = [];
4777
- let currentPath = "";
4778
- for (const line of output.split("\n")) {
4779
- if (line.startsWith("worktree ")) {
4780
- currentPath = line.slice("worktree ".length);
4781
- } else if (line.startsWith("branch ") && currentPath) {
4782
- const branch = line.slice("branch refs/heads/".length);
4783
- worktrees.push({ path: currentPath, branch });
4784
- currentPath = "";
4785
- }
4786
- }
4787
- return worktrees;
4788
- } catch {
4789
- return [];
4790
- }
4791
- }
4792
- async function isWorktreeDirtyAsync(wtPath, git) {
4793
- try {
4794
- return (await git(["status", "--porcelain"], wtPath)).trim().length > 0;
4795
- } catch {
4796
- return true;
4797
- }
4798
- }
4799
- async function hasUnpushedCommitsAsync(wtPath, branch, git) {
4800
- for (const mainRef of ["main", "master"]) {
4801
- try {
4802
- const ahead = (await git(["-C", wtPath, "rev-list", `${mainRef}..${branch}`, "--count"], wtPath)).trim();
4803
- return parseInt(ahead, 10) > 0;
4804
- } catch {
4805
- }
4806
- }
4807
- return true;
4808
- }
4809
- async function checkWorktreeCollisionsAsync(repoPath, git = defaultGitExecutor) {
4810
- const worktreeListCache = /* @__PURE__ */ new Map();
4811
- const listWorktreesOnce = (root) => {
4812
- let cached = worktreeListCache.get(root);
4813
- if (!cached) {
4814
- cached = listWorktreesPorcelainAsync(root, git);
4815
- worktreeListCache.set(root, cached);
4816
- }
4817
- return cached;
4818
- };
4819
- const repoRoot = await getGitRootAsync(repoPath, git);
4820
- if (!repoRoot) return [];
4821
- const warnings = [];
4822
- const worktrees = await listWorktreesOnce(repoRoot);
4823
- for (const wt of worktrees) {
4824
- if (!wt.path.includes("/.worktrees/")) continue;
4825
- if (!existsSync8(wt.path)) continue;
4826
- const owner = inferSessionOwner(wt.path, wt.branch);
4827
- const dirty = await isWorktreeDirtyAsync(wt.path, git);
4828
- const hasCommits = await hasUnpushedCommitsAsync(wt.path, wt.branch, git);
4829
- if (dirty) {
4830
- warnings.push({
4831
- worktreePath: wt.path,
4832
- branch: wt.branch,
4833
- sessionOwner: owner,
4834
- dirty: true,
4835
- reason: `Worktree has uncommitted changes (agent: ${owner ?? "unknown"}, branch: ${wt.branch})`
4836
- });
4837
- } else if (hasCommits) {
4838
- warnings.push({
4839
- worktreePath: wt.path,
4840
- branch: wt.branch,
4841
- sessionOwner: owner,
4842
- dirty: false,
4843
- reason: `Worktree has unpushed commits on branch ${wt.branch} (agent: ${owner ?? "unknown"})`
4844
- });
4845
- }
4846
- }
4847
- return warnings;
4848
- }
4849
-
4850
4509
  // src/lib/intercom-prompts.ts
4851
4510
  function formatIntercomPrompt(reason = "nudge") {
4852
4511
  switch (reason) {
@@ -4863,6 +4522,15 @@ function formatIntercomPrompt(reason = "nudge") {
4863
4522
  }
4864
4523
  }
4865
4524
 
4525
+ // src/lib/tmux-dispatch-gate.ts
4526
+ var TMUX_DISPATCH_RETIRED_MESSAGE = "tmux dispatch is retired; dispatch a named subagent: Agent(subagent_type='<name>') \u2014 worktree isolation for code, brief it with a file fence and the guardrails, and persist its result into the task checklist row + memory before you finish. task(action='create') stays a durable checklist row for tracking and never launches compute.";
4527
+ function tmuxDispatchRefusal(toolName) {
4528
+ return `${toolName}: ${TMUX_DISPATCH_RETIRED_MESSAGE} Nothing was created or dispatched.`;
4529
+ }
4530
+ function spawnOverrideNoopNotice(fields) {
4531
+ return `Ignored ${fields.join(", ")} \u2014 ${TMUX_DISPATCH_RETIRED_MESSAGE} Set a subagent's model per employee with set_agent_config, or per dispatch with the Agent tool's own model argument.`;
4532
+ }
4533
+
4866
4534
  // src/lib/session-busy-pattern.ts
4867
4535
  var BUSY_PATTERN = /[✻✽✶✳].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt|Waiting for \d+ background agents?/i;
4868
4536
 
@@ -4870,13 +4538,13 @@ var BUSY_PATTERN = /[✻✽✶✳].*…|Running…|• Working|• Ran |• Expl
4870
4538
  var _cachedExeBinDir;
4871
4539
  function resolveExeBinDir() {
4872
4540
  if (_cachedExeBinDir !== void 0) return _cachedExeBinDir;
4873
- const nodeBinDir = path8.dirname(process.execPath);
4874
- if (existsSync9(path8.join(nodeBinDir, "exe-launch-agent"))) {
4541
+ const nodeBinDir = path6.dirname(process.execPath);
4542
+ if (existsSync7(path6.join(nodeBinDir, "exe-launch-agent"))) {
4875
4543
  _cachedExeBinDir = nodeBinDir;
4876
4544
  return _cachedExeBinDir;
4877
4545
  }
4878
- const localBin = path8.join(os6.homedir(), ".local", "bin");
4879
- if (existsSync9(path8.join(localBin, "exe-launch-agent"))) {
4546
+ const localBin = path6.join(os5.homedir(), ".local", "bin");
4547
+ if (existsSync7(path6.join(localBin, "exe-launch-agent"))) {
4880
4548
  _cachedExeBinDir = localBin;
4881
4549
  return _cachedExeBinDir;
4882
4550
  }
@@ -4887,9 +4555,9 @@ function _resetExeBinDirCache() {
4887
4555
  _cachedExeBinDir = void 0;
4888
4556
  }
4889
4557
  function buildSpawnPath(inheritedPath = process.env.PATH, execPath = process.execPath) {
4890
- const sep = path8.delimiter;
4891
- const nodeBinDir = path8.dirname(execPath);
4892
- const localBin = path8.join(os6.homedir(), ".local", "bin");
4558
+ const sep = path6.delimiter;
4559
+ const nodeBinDir = path6.dirname(execPath);
4560
+ const localBin = path6.join(os5.homedir(), ".local", "bin");
4893
4561
  const exeBinDir = resolveExeBinDir();
4894
4562
  const prefixDirs = [nodeBinDir, exeBinDir, localBin].filter(
4895
4563
  (d) => Boolean(d)
@@ -4907,17 +4575,17 @@ function buildSpawnPath(inheritedPath = process.env.PATH, execPath = process.exe
4907
4575
  return ordered.join(sep);
4908
4576
  }
4909
4577
  function spawnLockDir() {
4910
- return process.env.EXE_SPAWN_LOCK_DIR || path8.join(os6.homedir(), ".exe-os", "spawn-locks");
4578
+ return process.env.EXE_SPAWN_LOCK_DIR || path6.join(os5.homedir(), ".exe-os", "spawn-locks");
4911
4579
  }
4912
4580
  function spawnLockPath(sessionName) {
4913
- return path8.join(spawnLockDir(), `${sessionName}.lock`);
4581
+ return path6.join(spawnLockDir(), `${sessionName}.lock`);
4914
4582
  }
4915
4583
  function sanitizeLockKey(value) {
4916
4584
  return value.replace(/[^a-zA-Z0-9_.-]/g, "_");
4917
4585
  }
4918
4586
  function spawnMutexPath(employeeName, exeSession) {
4919
4587
  const key = `${sanitizeLockKey(baseAgentName(employeeName).toLowerCase())}--${sanitizeLockKey(exeSession)}`;
4920
- return path8.join(spawnLockDir(), `${key}.spawn-mutex.lock`);
4588
+ return path6.join(spawnLockDir(), `${key}.spawn-mutex.lock`);
4921
4589
  }
4922
4590
  function isProcessAlive(pid) {
4923
4591
  try {
@@ -4929,8 +4597,8 @@ function isProcessAlive(pid) {
4929
4597
  }
4930
4598
  function acquireSpawnLock(sessionName) {
4931
4599
  const lockDir = spawnLockDir();
4932
- if (!existsSync9(lockDir)) {
4933
- mkdirSync6(lockDir, { recursive: true });
4600
+ if (!existsSync7(lockDir)) {
4601
+ mkdirSync5(lockDir, { recursive: true });
4934
4602
  }
4935
4603
  const lockFile = spawnLockPath(sessionName);
4936
4604
  const lockData = JSON.stringify({ pid: process.pid, timestamp: Date.now() });
@@ -4945,7 +4613,7 @@ function acquireSpawnLock(sessionName) {
4945
4613
  }
4946
4614
  }
4947
4615
  try {
4948
- const lock = JSON.parse(readFileSync6(lockFile, "utf8"));
4616
+ const lock = JSON.parse(readFileSync5(lockFile, "utf8"));
4949
4617
  const age = Date.now() - lock.timestamp;
4950
4618
  if (isProcessAlive(lock.pid) && age < 6e4) {
4951
4619
  return false;
@@ -4957,7 +4625,7 @@ function acquireSpawnLock(sessionName) {
4957
4625
  unlinkSync4(tmpName);
4958
4626
  } catch {
4959
4627
  }
4960
- writeFileSync5(lockFile, lockData);
4628
+ writeFileSync4(lockFile, lockData);
4961
4629
  return true;
4962
4630
  } catch {
4963
4631
  return false;
@@ -4970,7 +4638,7 @@ function acquireSpawnLock(sessionName) {
4970
4638
  unlinkSync4(tmpName);
4971
4639
  } catch {
4972
4640
  }
4973
- writeFileSync5(lockFile, lockData);
4641
+ writeFileSync4(lockFile, lockData);
4974
4642
  return true;
4975
4643
  } catch {
4976
4644
  return false;
@@ -4985,7 +4653,7 @@ function releaseSpawnLock(sessionName) {
4985
4653
  }
4986
4654
  function acquireAgentSpawnMutex(employeeName, exeSession) {
4987
4655
  const lockDir = spawnLockDir();
4988
- if (!existsSync9(lockDir)) mkdirSync6(lockDir, { recursive: true });
4656
+ if (!existsSync7(lockDir)) mkdirSync5(lockDir, { recursive: true });
4989
4657
  const lockFile = spawnMutexPath(employeeName, exeSession);
4990
4658
  const lockData = JSON.stringify({ pid: process.pid, timestamp: Date.now() });
4991
4659
  try {
@@ -4997,7 +4665,7 @@ function acquireAgentSpawnMutex(employeeName, exeSession) {
4997
4665
  if (err?.code !== "EEXIST") return true;
4998
4666
  }
4999
4667
  try {
5000
- const lock = JSON.parse(readFileSync6(lockFile, "utf8"));
4668
+ const lock = JSON.parse(readFileSync5(lockFile, "utf8"));
5001
4669
  const age = Date.now() - lock.timestamp;
5002
4670
  if (isProcessAlive(lock.pid) && age < 6e4) return false;
5003
4671
  } catch {
@@ -5009,7 +4677,7 @@ function acquireAgentSpawnMutex(employeeName, exeSession) {
5009
4677
  unlinkSync4(tmpName);
5010
4678
  } catch {
5011
4679
  }
5012
- writeFileSync5(lockFile, lockData);
4680
+ writeFileSync4(lockFile, lockData);
5013
4681
  return true;
5014
4682
  } catch {
5015
4683
  return false;
@@ -5041,59 +4709,7 @@ function reconcileStaleSpawnLock(sessionName, isAlive = isEmployeeAlive) {
5041
4709
  });
5042
4710
  return { skip: false, brokeStaleLock: true };
5043
4711
  }
5044
- var SESSION_CACHE = path8.join(os6.homedir(), ".exe-os", "session-cache");
5045
- var BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
5046
- function resolveBehaviorsExporterScript() {
5047
- try {
5048
- const thisFile = fileURLToPath(import.meta.url);
5049
- const scriptPath = path8.join(
5050
- path8.dirname(thisFile),
5051
- "..",
5052
- "bin",
5053
- "exe-export-behaviors.js"
5054
- );
5055
- return existsSync9(scriptPath) ? scriptPath : null;
5056
- } catch {
5057
- return null;
5058
- }
5059
- }
5060
- function exportBehaviorsSync(agentId, projectName, sessionKey) {
5061
- const script = resolveBehaviorsExporterScript();
5062
- if (!script) return null;
5063
- try {
5064
- const output = execFileSync3(
5065
- process.execPath,
5066
- [script, agentId, projectName, sessionKey],
5067
- { encoding: "utf-8", timeout: BEHAVIORS_EXPORT_TIMEOUT_MS }
5068
- ).trim();
5069
- return output.length > 0 ? output : null;
5070
- } catch (err) {
5071
- process.stderr.write(
5072
- `[tmux-routing] behaviors export failed for ${agentId}: ${err instanceof Error ? err.message : String(err)}
5073
- `
5074
- );
5075
- return null;
5076
- }
5077
- }
5078
- async function exportBehaviorsAsync(agentId, projectName, sessionKey) {
5079
- const script = resolveBehaviorsExporterScript();
5080
- if (!script) return null;
5081
- try {
5082
- const { stdout } = await execFileAsync3(
5083
- process.execPath,
5084
- [script, agentId, projectName, sessionKey],
5085
- { encoding: "utf-8", timeout: BEHAVIORS_EXPORT_TIMEOUT_MS }
5086
- );
5087
- const output = stdout.trim();
5088
- return output.length > 0 ? output : null;
5089
- } catch (err) {
5090
- process.stderr.write(
5091
- `[tmux-routing] behaviors export failed for ${agentId}: ${err instanceof Error ? err.message : String(err)}
5092
- `
5093
- );
5094
- return null;
5095
- }
5096
- }
4712
+ var SESSION_CACHE = path6.join(os5.homedir(), ".exe-os", "session-cache");
5097
4713
  function getMySession() {
5098
4714
  return getTransport().getMySession();
5099
4715
  }
@@ -5156,8 +4772,8 @@ function extractRootExe(name) {
5156
4772
  return tail.length > 0 ? tail : null;
5157
4773
  }
5158
4774
  function registerParentExe(sessionKey, parentExe, dispatchedBy) {
5159
- if (!existsSync9(SESSION_CACHE)) {
5160
- mkdirSync6(SESSION_CACHE, { recursive: true });
4775
+ if (!existsSync7(SESSION_CACHE)) {
4776
+ mkdirSync5(SESSION_CACHE, { recursive: true });
5161
4777
  }
5162
4778
  const rootExe = extractRootExe(parentExe) ?? parentExe;
5163
4779
  if (!isValidSessionScope(rootExe)) {
@@ -5167,7 +4783,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
5167
4783
  );
5168
4784
  return;
5169
4785
  }
5170
- const filePath = path8.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
4786
+ const filePath = path6.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
5171
4787
  atomicWriteJsonSync(filePath, {
5172
4788
  parentExe: rootExe,
5173
4789
  dispatchedBy: dispatchedBy || rootExe,
@@ -5177,7 +4793,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
5177
4793
  var PARENT_EXE_CACHE_TTL_MS = 4 * 60 * 60 * 1e3;
5178
4794
  function getParentExe(sessionKey) {
5179
4795
  try {
5180
- const data = JSON.parse(readFileSync6(path8.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
4796
+ const data = JSON.parse(readFileSync5(path6.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
5181
4797
  if (data.registeredAt) {
5182
4798
  const age = Date.now() - new Date(data.registeredAt).getTime();
5183
4799
  if (age > PARENT_EXE_CACHE_TTL_MS) return null;
@@ -5189,8 +4805,8 @@ function getParentExe(sessionKey) {
5189
4805
  }
5190
4806
  function getDispatchedBy(sessionKey) {
5191
4807
  try {
5192
- const data = JSON.parse(readFileSync6(
5193
- path8.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
4808
+ const data = JSON.parse(readFileSync5(
4809
+ path6.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
5194
4810
  "utf8"
5195
4811
  ));
5196
4812
  return data.dispatchedBy ?? data.parentExe ?? null;
@@ -5465,40 +5081,6 @@ function liveAgentSessionsForScope(employeeName, exeSession, listSessions2 = ()
5465
5081
  function firstLiveAgentSessionForScope(employeeName, exeSession) {
5466
5082
  return liveAgentSessionsForScope(employeeName, exeSession)[0] ?? null;
5467
5083
  }
5468
- function realpathForCompare(pathname) {
5469
- try {
5470
- return realpathSync2(pathname);
5471
- } catch {
5472
- return path8.resolve(pathname);
5473
- }
5474
- }
5475
- function sameRealPath(a, b) {
5476
- try {
5477
- return path8.resolve(a) === path8.resolve(b);
5478
- } catch {
5479
- return a === b;
5480
- }
5481
- }
5482
- function detectCoordinatorCheckoutCwd(cwd) {
5483
- if (cwd.includes("/.worktrees/") || cwd.includes("/.claude/worktrees/")) return null;
5484
- const cwdRepoRoot = getMainRepoRoot(cwd);
5485
- if (!cwdRepoRoot) return null;
5486
- const cwdResolved = realpathForCompare(cwd);
5487
- if (!sameRealPath(cwdRepoRoot, cwdResolved)) return null;
5488
- try {
5489
- for (const session of listSessions()) {
5490
- if (!isRootSession(session.windowName)) continue;
5491
- if (!session.projectDir || !existsSync9(session.projectDir)) continue;
5492
- const coordinatorRepoRoot = getMainRepoRoot(session.projectDir);
5493
- if (coordinatorRepoRoot && sameRealPath(coordinatorRepoRoot, cwdRepoRoot)) {
5494
- return { coordinatorSession: session.windowName, repoRoot: cwdRepoRoot };
5495
- }
5496
- }
5497
- } catch {
5498
- return null;
5499
- }
5500
- return null;
5501
- }
5502
5084
  var VERIFY_PANE_LINES = 200;
5503
5085
  async function verifyPaneAtCapacity(sessionName) {
5504
5086
  const transport = getTransport();
@@ -5514,7 +5096,7 @@ async function verifyPaneAtCapacity(sessionName) {
5514
5096
  reason: `capture-pane failed: ${err instanceof Error ? err.message : String(err)}`
5515
5097
  };
5516
5098
  }
5517
- const { isAtCapacity } = await import("./capacity-monitor-UI553HRL.js");
5099
+ const { isAtCapacity } = await import("./capacity-monitor-7SMEJHYG.js");
5518
5100
  if (!isAtCapacity(pane)) {
5519
5101
  return {
5520
5102
  atCapacity: false,
@@ -5528,15 +5110,15 @@ async function verifyPaneAtCapacity(sessionName) {
5528
5110
  }
5529
5111
  var INTERCOM_DEBOUNCE_MS = 3e5;
5530
5112
  var CODEX_DEBOUNCE_MS = 3e5;
5531
- var INTERCOM_LOG2 = path8.join(os6.homedir(), ".exe-os", "intercom.log");
5113
+ var INTERCOM_LOG2 = path6.join(os5.homedir(), ".exe-os", "intercom.log");
5532
5114
  var INTERCOM_LOG_MAX_BYTES2 = 1024 * 1024;
5533
- var execFileAsync3 = promisify3(execFile2);
5534
- var DEBOUNCE_FILE = path8.join(SESSION_CACHE, "intercom-debounce.json");
5115
+ var execFileAsync2 = promisify2(execFile);
5116
+ var DEBOUNCE_FILE = path6.join(SESSION_CACHE, "intercom-debounce.json");
5535
5117
  var DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
5536
5118
  function readDebounceState() {
5537
5119
  try {
5538
- if (!existsSync9(DEBOUNCE_FILE)) return {};
5539
- const raw = JSON.parse(readFileSync6(DEBOUNCE_FILE, "utf8"));
5120
+ if (!existsSync7(DEBOUNCE_FILE)) return {};
5121
+ const raw = JSON.parse(readFileSync5(DEBOUNCE_FILE, "utf8"));
5540
5122
  const state = {};
5541
5123
  for (const [key, val] of Object.entries(raw)) {
5542
5124
  if (typeof val === "number") {
@@ -5552,7 +5134,7 @@ function readDebounceState() {
5552
5134
  }
5553
5135
  function writeDebounceState(state) {
5554
5136
  try {
5555
- if (!existsSync9(SESSION_CACHE)) mkdirSync6(SESSION_CACHE, { recursive: true });
5137
+ if (!existsSync7(SESSION_CACHE)) mkdirSync5(SESSION_CACHE, { recursive: true });
5556
5138
  atomicWriteJsonSync(DEBOUNCE_FILE, state);
5557
5139
  } catch {
5558
5140
  }
@@ -5560,9 +5142,9 @@ function writeDebounceState(state) {
5560
5142
  function resolveSessionRuntime(targetSession) {
5561
5143
  const agentName = baseAgentName(targetSession.split("-")[0] ?? "");
5562
5144
  try {
5563
- const diPath = path8.join(SESSION_CACHE, `dispatch-info-${targetSession}.json`);
5564
- if (existsSync9(diPath)) {
5565
- const di = JSON.parse(readFileSync6(diPath, "utf-8"));
5145
+ const diPath = path6.join(SESSION_CACHE, `dispatch-info-${targetSession}.json`);
5146
+ if (existsSync7(diPath)) {
5147
+ const di = JSON.parse(readFileSync5(diPath, "utf-8"));
5566
5148
  if (di.runtime) return di.runtime;
5567
5149
  }
5568
5150
  return getAgentRuntime(agentName).runtime;
@@ -5602,7 +5184,7 @@ function logIntercom(msg, meta) {
5602
5184
  process.stderr.write(`[intercom] ${msg}${metaStr}
5603
5185
  `);
5604
5186
  try {
5605
- if (existsSync9(INTERCOM_LOG2) && statSync4(INTERCOM_LOG2).size > INTERCOM_LOG_MAX_BYTES2) {
5187
+ if (existsSync7(INTERCOM_LOG2) && statSync4(INTERCOM_LOG2).size > INTERCOM_LOG_MAX_BYTES2) {
5606
5188
  renameSync3(INTERCOM_LOG2, `${INTERCOM_LOG2}.1`);
5607
5189
  }
5608
5190
  appendFileSync3(INTERCOM_LOG2, line);
@@ -5629,7 +5211,7 @@ function getSessionState(sessionName) {
5629
5211
  }
5630
5212
  }
5631
5213
  async function captureSessionPaneAsync(sessionName, lines) {
5632
- const { stdout } = await execFileAsync3(
5214
+ const { stdout } = await execFileAsync2(
5633
5215
  "tmux",
5634
5216
  ["capture-pane", "-t", sessionName, "-p", "-S", `-${lines}`],
5635
5217
  { encoding: "utf8", timeout: 3e3 }
@@ -5678,7 +5260,7 @@ async function confirmNudgeSubmittedAsync(targetSession, runtime) {
5678
5260
  if (verdict.state === "confirmed") return true;
5679
5261
  if (!isSubmitRepairable(verdict.reason)) return false;
5680
5262
  try {
5681
- await execFileAsync3("tmux", ["send-keys", "-t", targetSession, isCodex ? "C-m" : "Enter"], { timeout: 1e3 });
5263
+ await execFileAsync2("tmux", ["send-keys", "-t", targetSession, isCodex ? "C-m" : "Enter"], { timeout: 1e3 });
5682
5264
  } catch {
5683
5265
  }
5684
5266
  await new Promise((r) => setTimeout(r, SUBMIT_CONFIRM_DELAY_MS));
@@ -5821,7 +5403,7 @@ async function countScopedPendingReviews(targetSession, reviewer) {
5821
5403
  }
5822
5404
  async function countScopedOpenTasks(targetSession, agentId) {
5823
5405
  try {
5824
- const { fastDbInit } = await import("./fast-db-init-SD7JZSEC.js");
5406
+ const { fastDbInit } = await import("./fast-db-init-TFRTK6EH.js");
5825
5407
  const client = await fastDbInit();
5826
5408
  const scope = extractRootExe(targetSession);
5827
5409
  if (!scope) return 0;
@@ -5878,7 +5460,7 @@ function buildScopedInProgressTaskQuery(targetSession) {
5878
5460
  async function findScopedInProgressTaskId(targetSession) {
5879
5461
  const q = buildScopedInProgressTaskQuery(targetSession);
5880
5462
  if (!q) return null;
5881
- const { fastDbInit } = await import("./fast-db-init-SD7JZSEC.js");
5463
+ const { fastDbInit } = await import("./fast-db-init-TFRTK6EH.js");
5882
5464
  const client = await fastDbInit();
5883
5465
  const result = await client.execute(q);
5884
5466
  const id = result.rows[0]?.id;
@@ -5999,7 +5581,7 @@ function sendIntercom(targetSession, opts) {
5999
5581
  const ledgerEnv = (process.env.EXE_NOTIFICATION_LEDGER ?? "").trim().toLowerCase();
6000
5582
  if (ledgerEnv === "shadow") {
6001
5583
  const ledgerScope = opts && "callerSessionScope" in opts ? opts.callerSessionScope : void 0;
6002
- void import("./notification-ledger-3WJYJGGS.js").then((m) => m.recordShadowNudge(targetSession, reason, ledgerScope, { force: opts?.force })).catch(() => {
5584
+ void import("./notification-ledger-O6KQYYGK.js").then((m) => m.recordShadowNudge(targetSession, reason, ledgerScope, { force: opts?.force })).catch(() => {
6003
5585
  });
6004
5586
  }
6005
5587
  if (!opts?.force && isDebounced(targetSession)) {
@@ -6040,8 +5622,8 @@ function sendIntercom(targetSession, opts) {
6040
5622
  try {
6041
5623
  const rawAgent2 = targetSession.split("-")[0] ?? targetSession;
6042
5624
  const agent = baseAgentName(rawAgent2);
6043
- const markerPath = path8.join(SESSION_CACHE, `current-task-${agent}.json`);
6044
- if (existsSync9(markerPath)) {
5625
+ const markerPath = path6.join(SESSION_CACHE, `current-task-${agent}.json`);
5626
+ if (existsSync7(markerPath)) {
6045
5627
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
6046
5628
  recordResult("debounced", "in_progress_marker");
6047
5629
  return "debounced";
@@ -6101,89 +5683,22 @@ function sendIntercom(targetSession, opts) {
6101
5683
  return "failed";
6102
5684
  }
6103
5685
  }
6104
- var DEFERRED_SPAWN_NUDGE_ATTEMPTS = 3;
6105
- var DEFERRED_SPAWN_NUDGE_RETRY_MS = Number(process.env.EXE_DEFERRED_SPAWN_NUDGE_RETRY_MS || 5e3);
6106
- function scheduleDeferredSpawnNudge(input) {
6107
- const attemptSend = (attempt) => {
6108
- setTimeout(() => {
6109
- void (async () => {
6110
- try {
6111
- if (!input.transport.isAlive(input.sessionName)) {
6112
- throw new Error("session not alive at deferred nudge time");
6113
- }
6114
- input.transport.sendKeysLiteral(input.sessionName, input.message, input.runtime);
6115
- const verdict = await verifyNudgeDeliveredAsync(input.sessionName, input.runtime, true);
6116
- if (verdict.state !== "confirmed") {
6117
- throw new Error(`nudge unconfirmed at target pane (${verdict.reason})`);
6118
- }
6119
- process.stderr.write(
6120
- `[tmux-routing] deferred spawn nudge delivered to ${input.sessionName} (attempt ${attempt}/${DEFERRED_SPAWN_NUDGE_ATTEMPTS})
6121
- `
6122
- );
6123
- recordOrchestrationEventBestEffort({
6124
- eventType: "dispatch.spawn_nudge.delivered",
6125
- source: "tmux-routing.scheduleDeferredSpawnNudge",
6126
- agentId: input.employeeName,
6127
- sessionScope: input.exeSession,
6128
- tmuxSession: input.sessionName,
6129
- runtime: input.runtime,
6130
- result: "delivered",
6131
- payload: { attempt }
6132
- });
6133
- } catch (err) {
6134
- const msg = err instanceof Error ? err.message : String(err);
6135
- process.stderr.write(
6136
- `[tmux-routing] deferred spawn nudge failed for ${input.sessionName} (attempt ${attempt}/${DEFERRED_SPAWN_NUDGE_ATTEMPTS}): ${msg}
6137
- `
6138
- );
6139
- recordOrchestrationEventBestEffort({
6140
- eventType: "dispatch.spawn_nudge.failed",
6141
- source: "tmux-routing.scheduleDeferredSpawnNudge",
6142
- severity: "warn",
6143
- agentId: input.employeeName,
6144
- sessionScope: input.exeSession,
6145
- tmuxSession: input.sessionName,
6146
- runtime: input.runtime,
6147
- result: "failed",
6148
- errorCode: "deferred_nudge_failed",
6149
- payload: { attempt, error: msg }
6150
- });
6151
- if (attempt < DEFERRED_SPAWN_NUDGE_ATTEMPTS) {
6152
- attemptSend(attempt + 1);
6153
- return;
6154
- }
6155
- queueIntercom(input.sessionName, `spawn nudge failed after ${attempt} attempts: ${msg}`, "signal");
6156
- void import("./notifications-T5C2CVB3.js").then(({ writeNotification: writeNotification2 }) => writeNotification2({
6157
- agentId: getCoordinatorName(),
6158
- agentRole: "COO",
6159
- event: "error_spike",
6160
- project: "",
6161
- summary: `Spawned ${input.sessionName}, but the initial task nudge failed after ${attempt} attempts (${msg}). Worker may be idle with open task; check session and re-dispatch if needed.`,
6162
- sessionScope: input.exeSession
6163
- })).catch(() => {
6164
- });
6165
- }
6166
- })();
6167
- }, attempt === 1 ? 1e4 : DEFERRED_SPAWN_NUDGE_RETRY_MS);
6168
- };
6169
- attemptSend(1);
6170
- }
6171
5686
  var CODEX_SUBMIT_DELAY_MS = Number(process.env.EXE_CODEX_SUBMIT_DELAY_MS || 250);
6172
5687
  var SUBMIT_DELAY_MS = Number(process.env.EXE_SUBMIT_DELAY_MS || 60);
6173
5688
  async function sendKeysLiteralAsync(targetSession, text, runtime) {
6174
5689
  const isCodex = runtime === "codex";
6175
5690
  const submit = async () => {
6176
5691
  await new Promise((r) => setTimeout(r, isCodex ? CODEX_SUBMIT_DELAY_MS : SUBMIT_DELAY_MS));
6177
- await execFileAsync3("tmux", ["send-keys", "-t", targetSession, isCodex ? "C-m" : "Enter"], { timeout: 1e3 });
5692
+ await execFileAsync2("tmux", ["send-keys", "-t", targetSession, isCodex ? "C-m" : "Enter"], { timeout: 1e3 });
6178
5693
  };
6179
5694
  if (text.length >= 500) {
6180
- const tmpDir = path8.join(os6.tmpdir(), "exe-os-intercom");
6181
- mkdirSync6(tmpDir, { recursive: true });
6182
- const tmpFile = path8.join(tmpDir, `msg-${process.pid}-${Date.now()}.txt`);
5695
+ const tmpDir = path6.join(os5.tmpdir(), "exe-os-intercom");
5696
+ mkdirSync5(tmpDir, { recursive: true });
5697
+ const tmpFile = path6.join(tmpDir, `msg-${process.pid}-${Date.now()}.txt`);
6183
5698
  try {
6184
- writeFileSync5(tmpFile, text, "utf-8");
6185
- await execFileAsync3("tmux", ["load-buffer", tmpFile], { timeout: 3e3 });
6186
- await execFileAsync3("tmux", ["paste-buffer", "-p", "-t", targetSession], { timeout: 3e3 });
5699
+ writeFileSync4(tmpFile, text, "utf-8");
5700
+ await execFileAsync2("tmux", ["load-buffer", tmpFile], { timeout: 3e3 });
5701
+ await execFileAsync2("tmux", ["paste-buffer", "-p", "-t", targetSession], { timeout: 3e3 });
6187
5702
  await submit();
6188
5703
  } finally {
6189
5704
  try {
@@ -6193,7 +5708,7 @@ async function sendKeysLiteralAsync(targetSession, text, runtime) {
6193
5708
  }
6194
5709
  return;
6195
5710
  }
6196
- await execFileAsync3("tmux", ["send-keys", "-t", targetSession, "-l", text], { timeout: 3e3 });
5711
+ await execFileAsync2("tmux", ["send-keys", "-t", targetSession, "-l", text], { timeout: 3e3 });
6197
5712
  await submit();
6198
5713
  }
6199
5714
  async function sendIntercomAsync(targetSession, opts) {
@@ -6248,7 +5763,7 @@ async function sendIntercomAsync(targetSession, opts) {
6248
5763
  let ledgerClaim = null;
6249
5764
  if (authoritativeLedger) {
6250
5765
  try {
6251
- const { claimAuthoritativeNudge } = await import("./notification-ledger-3WJYJGGS.js");
5766
+ const { claimAuthoritativeNudge } = await import("./notification-ledger-O6KQYYGK.js");
6252
5767
  const claim2 = await claimAuthoritativeNudge(
6253
5768
  targetSession,
6254
5769
  reason,
@@ -6271,7 +5786,7 @@ async function sendIntercomAsync(targetSession, opts) {
6271
5786
  const markLedgerDelivered = async () => {
6272
5787
  if (!ledgerClaim) return;
6273
5788
  try {
6274
- const { markNudgeDelivered } = await import("./notification-ledger-3WJYJGGS.js");
5789
+ const { markNudgeDelivered } = await import("./notification-ledger-O6KQYYGK.js");
6275
5790
  await markNudgeDelivered(ledgerClaim.id, ledgerClaim.sessionScope);
6276
5791
  } catch {
6277
5792
  }
@@ -6279,7 +5794,7 @@ async function sendIntercomAsync(targetSession, opts) {
6279
5794
  const markLedgerFailed = async (error) => {
6280
5795
  if (!ledgerClaim) return;
6281
5796
  try {
6282
- const { markNudgeDeliveryFailed } = await import("./notification-ledger-3WJYJGGS.js");
5797
+ const { markNudgeDeliveryFailed } = await import("./notification-ledger-O6KQYYGK.js");
6283
5798
  await markNudgeDeliveryFailed(ledgerClaim.id, error, ledgerClaim.sessionScope);
6284
5799
  } catch {
6285
5800
  }
@@ -6290,7 +5805,7 @@ async function sendIntercomAsync(targetSession, opts) {
6290
5805
  return "debounced";
6291
5806
  }
6292
5807
  try {
6293
- const { stdout } = await execFileAsync3("tmux", ["list-sessions", "-F", "#{session_name}"], { encoding: "utf8", timeout: 3e3 });
5808
+ const { stdout } = await execFileAsync2("tmux", ["list-sessions", "-F", "#{session_name}"], { encoding: "utf8", timeout: 3e3 });
6294
5809
  const sessions = stdout.trim().split("\n").filter(Boolean);
6295
5810
  if (!sessions.includes(targetSession)) {
6296
5811
  logIntercom(`SKIP \u2192 ${targetSession} (session not found)`);
@@ -6321,10 +5836,10 @@ async function sendIntercomAsync(targetSession, opts) {
6321
5836
  return "queued";
6322
5837
  }
6323
5838
  try {
6324
- const mode = await execFileAsync3("tmux", ["display-message", "-p", "-t", targetSession, "#{pane_in_mode}"], { encoding: "utf8", timeout: 1e3 });
5839
+ const mode = await execFileAsync2("tmux", ["display-message", "-p", "-t", targetSession, "#{pane_in_mode}"], { encoding: "utf8", timeout: 1e3 });
6325
5840
  if (mode.stdout.trim() === "1") {
6326
5841
  logIntercom(`COPY_MODE \u2192 ${targetSession} (exiting copy mode first)`);
6327
- await execFileAsync3("tmux", ["send-keys", "-t", targetSession, "q"], { timeout: 1e3 });
5842
+ await execFileAsync2("tmux", ["send-keys", "-t", targetSession, "q"], { timeout: 1e3 });
6328
5843
  }
6329
5844
  } catch {
6330
5845
  }
@@ -6428,23 +5943,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
6428
5943
  return false;
6429
5944
  }
6430
5945
  }
6431
- function emitOptOutBypassWarning(employeeName, projectDir) {
6432
- process.stderr.write(
6433
- `[tmux-routing] WORKTREE ISOLATION BYPASSED by explicit spawn_worktree=false for code-role ${employeeName} in real repo ${projectDir} \u2014 commits can land on main. This is a deliberate operator opt-out.
6434
- `
6435
- );
6436
- }
6437
- function worktreeIsolationGate(employeeName, projectDir, opts) {
6438
- const nonGit = !isInsideGitRepo(projectDir);
6439
- if (opts?.spawnWorktree === false) {
6440
- if (!nonGit) emitOptOutBypassWarning(employeeName, projectDir);
6441
- return { allow: true, nonGit };
6442
- }
6443
- if (nonGit) return { allow: true, nonGit: true };
6444
- const message = `Worktree isolation required for code-role ${employeeName}; refusing to spawn in ${projectDir}. ${projectDir} is a git repo but the worktree could not be created (git error/timeout) \u2014 spawning here would let commits land on main. To dispatch a code-role agent here anyway, pass spawn_worktree=false (create_task) or opts.spawnWorktree=false.`;
6445
- return { allow: false, message };
6446
- }
6447
- function ensureEmployee(employeeName, exeSession, projectDir, opts) {
5946
+ function ensureEmployee(employeeName, exeSession, _projectDir, opts) {
6448
5947
  employeeName = employeeName.toLowerCase();
6449
5948
  if (isCoordinatorName(employeeName)) {
6450
5949
  return { status: "failed", sessionName: "", error: "The coordinator is not a dispatchable employee" };
@@ -6542,12 +6041,12 @@ function ensureEmployee(employeeName, exeSession, projectDir, opts) {
6542
6041
  } else {
6543
6042
  const liveSession = firstLiveAgentSessionForScope(employeeName, exeSession);
6544
6043
  if (liveSession) {
6545
- const result2 = sendIntercom(liveSession, {
6044
+ const result = sendIntercom(liveSession, {
6546
6045
  force: true,
6547
6046
  reason: "signal",
6548
6047
  callerSessionScope: exeSession
6549
6048
  });
6550
- const status = classifyIntercomHandoff(result2);
6049
+ const status = classifyIntercomHandoff(result);
6551
6050
  if (status === "failed") {
6552
6051
  return { status, sessionName: liveSession, error: "intercom delivery failed during spawn mutex handoff" };
6553
6052
  }
@@ -6633,114 +6132,19 @@ function ensureEmployee(employeeName, exeSession, projectDir, opts) {
6633
6132
  if (isEmployeeAlive(sessionName)) {
6634
6133
  releaseIfOwned();
6635
6134
  releaseSpawnMutexIfOwned();
6636
- const result2 = sendIntercom(sessionName, { force: true, reason: "signal", callerSessionScope: exeSession });
6637
- const status = classifyIntercomHandoff(result2);
6135
+ const result = sendIntercom(sessionName, { force: true, reason: "signal", callerSessionScope: exeSession });
6136
+ const status = classifyIntercomHandoff(result);
6638
6137
  if (status === "failed") {
6639
6138
  return { status, sessionName, error: "intercom delivery failed" };
6640
6139
  }
6641
6140
  return { status, sessionName };
6642
6141
  }
6643
- const spawnOpts = { ...opts, instance: effectiveInstance };
6644
- if (!spawnOpts.cwd) {
6645
- const COORDINATOR_ROLES = /* @__PURE__ */ new Set(["COO", "CTO", "CMO"]);
6646
- try {
6647
- const roster = loadEmployeesSync();
6648
- const emp = roster.find((e) => baseAgentName(e.name) === baseAgentName(employeeName));
6649
- if (emp && !COORDINATOR_ROLES.has(emp.role)) {
6650
- try {
6651
- const collisions = spawnOpts.collisionGuardHandled ? [] : checkWorktreeCollisions(projectDir);
6652
- if (collisions.length > 0) {
6653
- for (const c of collisions) {
6654
- process.stderr.write(
6655
- `[worktree-guard] WARNING: ${c.reason} (path: ${c.worktreePath})
6656
- `
6657
- );
6658
- }
6659
- recordOrchestrationEventBestEffort({
6660
- eventType: "worktree.collision_warning",
6661
- source: "tmux-routing.ensureEmployee",
6662
- agentId: employeeName,
6663
- sessionScope: exeSession,
6664
- instanceId: effectiveInstance != null ? String(effectiveInstance) : null,
6665
- payload: { collisionCount: collisions.length, collisions: collisions.map((c) => ({ branch: c.branch, owner: c.sessionOwner, dirty: c.dirty })) }
6666
- });
6667
- }
6668
- } catch {
6669
- }
6670
- const wtPath = ensureWorktree(projectDir, employeeName, effectiveInstance);
6671
- if (wtPath) {
6672
- spawnOpts.cwd = wtPath;
6673
- process.stderr.write(`[tmux-routing] worktree isolation: ${employeeName} \u2192 ${wtPath}
6674
- `);
6675
- } else {
6676
- const gate = worktreeIsolationGate(employeeName, projectDir, opts);
6677
- if (gate.allow) {
6678
- spawnOpts.cwd = projectDir;
6679
- spawnOpts.spawnWorktree = false;
6680
- const reason = gate.nonGit ? "non_git_project" : "opt_out_override";
6681
- process.stderr.write(
6682
- `[tmux-routing] WORKTREE BYPASSED: code-role ${employeeName} spawning in ${projectDir} (reason=${reason}) \u2014 no git worktree isolation
6683
- `
6684
- );
6685
- recordOrchestrationEventBestEffort({
6686
- eventType: "worktree.bypassed",
6687
- source: "tmux-routing.ensureEmployee",
6688
- severity: "warn",
6689
- agentId: employeeName,
6690
- sessionScope: exeSession,
6691
- instanceId: effectiveInstance != null ? String(effectiveInstance) : null,
6692
- tmuxSession: sessionName,
6693
- payload: {
6694
- agent: employeeName,
6695
- cwd: projectDir,
6696
- reason,
6697
- risk: "code-role agent runs in project root without git worktree isolation"
6698
- }
6699
- });
6700
- } else {
6701
- releaseIfOwned();
6702
- releaseSpawnMutexIfOwned();
6703
- process.stderr.write(`[tmux-routing] ${gate.message}
6704
- `);
6705
- return { status: "failed", sessionName, error: gate.message };
6706
- }
6707
- }
6708
- }
6709
- } catch (e) {
6710
- process.stderr.write(`[tmux-routing] worktree setup failed for ${employeeName}: ${e instanceof Error ? e.message : String(e)}
6711
- `);
6712
- }
6713
- }
6714
- let result;
6715
- try {
6716
- result = spawnEmployee(employeeName, exeSession, projectDir, spawnOpts);
6717
- } catch (err) {
6718
- releaseSpawnLock(sessionName);
6719
- releaseSpawnMutexIfOwned();
6720
- const msg = err instanceof Error ? err.message : String(err);
6721
- process.stderr.write(
6722
- `[ensureEmployee] spawnEmployee THREW for ${sessionName}: ${msg} \u2014 released spawn lock to prevent permanent dispatch block
6723
- `
6724
- );
6725
- recordOrchestrationEventBestEffort({
6726
- eventType: "tmux.spawn.completed",
6727
- source: "tmux-routing.ensureEmployee",
6728
- severity: "warn",
6729
- agentId: employeeName,
6730
- sessionScope: exeSession,
6731
- tmuxSession: sessionName,
6732
- result: "failed",
6733
- errorCode: "spawn_threw",
6734
- payload: { error: msg }
6735
- });
6736
- return { status: "failed", sessionName, error: `spawn threw: ${msg}` };
6737
- }
6738
- if (result.error) {
6739
- releaseSpawnMutexIfOwned();
6740
- return { status: "failed", sessionName, error: result.error };
6741
- }
6142
+ releaseIfOwned();
6742
6143
  releaseSpawnMutexIfOwned();
6743
- return { status: "spawned", sessionName };
6144
+ const refusal = tmuxDispatchRefusal(`ensureEmployee(${employeeName})`);
6145
+ process.stderr.write(`[ensureEmployee] ${refusal}
6146
+ `);
6147
+ return { status: "failed", sessionName, error: refusal };
6744
6148
  }
6745
6149
  async function ensureEmployeeAsync(employeeName, exeSession, projectDir, opts) {
6746
6150
  let asyncOpts = { ...opts, behaviorsExported: true };
@@ -6825,87 +6229,6 @@ async function ensureEmployeeAsync(employeeName, exeSession, projectDir, opts) {
6825
6229
  spawnMutexHeld: true
6826
6230
  };
6827
6231
  }
6828
- if (!asyncOpts.cwd) {
6829
- const COORDINATOR_ROLES = /* @__PURE__ */ new Set(["COO", "CTO", "CMO"]);
6830
- try {
6831
- const roster = loadEmployeesSync();
6832
- const emp = roster.find((e) => baseAgentName(e.name) === baseAgentName(employeeName));
6833
- if (emp && !COORDINATOR_ROLES.has(emp.role)) {
6834
- try {
6835
- const collisions = await checkWorktreeCollisionsAsync(projectDir);
6836
- if (collisions.length > 0) {
6837
- for (const c of collisions) {
6838
- process.stderr.write(
6839
- `[worktree-guard] WARNING: ${c.reason} (path: ${c.worktreePath})
6840
- `
6841
- );
6842
- }
6843
- recordOrchestrationEventBestEffort({
6844
- eventType: "worktree.collision_warning",
6845
- source: "tmux-routing.ensureEmployeeAsync",
6846
- agentId: employeeName,
6847
- sessionScope: exeSession,
6848
- instanceId: asyncOpts.instance != null ? String(asyncOpts.instance) : null,
6849
- payload: { collisionCount: collisions.length, collisions: collisions.map((c) => ({ branch: c.branch, owner: c.sessionOwner, dirty: c.dirty })) }
6850
- });
6851
- }
6852
- } catch {
6853
- }
6854
- const wtPath = await ensureWorktreeAsync(projectDir, employeeName, asyncOpts.instance);
6855
- if (wtPath) {
6856
- asyncOpts.cwd = wtPath;
6857
- } else {
6858
- const sessionName = employeeSessionName(employeeName, exeSession, asyncOpts.instance);
6859
- const gate = worktreeIsolationGate(employeeName, projectDir, asyncOpts);
6860
- if (gate.allow) {
6861
- asyncOpts.cwd = projectDir;
6862
- asyncOpts.spawnWorktree = false;
6863
- const reason = gate.nonGit ? "non_git_project" : "opt_out_override";
6864
- process.stderr.write(
6865
- `[ensureEmployeeAsync] WORKTREE BYPASSED: code-role ${employeeName} spawning in ${projectDir} (reason=${reason}) \u2014 no git worktree isolation
6866
- `
6867
- );
6868
- recordOrchestrationEventBestEffort({
6869
- eventType: "worktree.bypassed",
6870
- source: "tmux-routing.ensureEmployeeAsync",
6871
- severity: "warn",
6872
- agentId: employeeName,
6873
- sessionScope: exeSession,
6874
- instanceId: asyncOpts.instance != null ? String(asyncOpts.instance) : null,
6875
- tmuxSession: sessionName,
6876
- payload: {
6877
- agent: employeeName,
6878
- cwd: projectDir,
6879
- reason,
6880
- risk: "code-role agent runs in project root without git worktree isolation"
6881
- }
6882
- });
6883
- } else {
6884
- process.stderr.write(`[ensureEmployeeAsync] ${gate.message}
6885
- `);
6886
- if (asyncOpts.spawnLockHeld) releaseSpawnLock(sessionName);
6887
- releaseSpawnMutexIfOwned();
6888
- return { status: "failed", sessionName, error: gate.message };
6889
- }
6890
- }
6891
- }
6892
- } catch (err) {
6893
- process.stderr.write(
6894
- `[ensureEmployeeAsync] worktree setup failed for ${employeeName}: ${err instanceof Error ? err.message : String(err)}
6895
- `
6896
- );
6897
- }
6898
- }
6899
- try {
6900
- const sessionName = employeeSessionName(employeeName, exeSession, asyncOpts.instance);
6901
- await exportBehaviorsAsync(employeeName, path8.basename(asyncOpts.cwd ?? projectDir), sessionName);
6902
- } catch (err) {
6903
- process.stderr.write(
6904
- `[ensureEmployeeAsync] behavior export failed for ${employeeName}: ${err instanceof Error ? err.message : String(err)}
6905
- `
6906
- );
6907
- }
6908
- asyncOpts = { ...asyncOpts, collisionGuardHandled: true };
6909
6232
  const result = ensureEmployee(employeeName, exeSession, projectDir, asyncOpts);
6910
6233
  if (asyncOpts.spawnLockHeld && result.sessionName) {
6911
6234
  releaseSpawnLock(result.sessionName);
@@ -6913,764 +6236,12 @@ async function ensureEmployeeAsync(employeeName, exeSession, projectDir, opts) {
6913
6236
  releaseSpawnMutexIfOwned();
6914
6237
  return result;
6915
6238
  }
6916
- function decideSpawnWorktreeDiscipline(input) {
6917
- if (input.inWorktree) return "ok";
6918
- if (input.roleKnown) {
6919
- if (!input.isCodeRole) return "ok";
6920
- if (input.optOut) return "bypass";
6921
- return input.spawnCwdIsGitRepo ? "refuse" : "bypass";
6922
- }
6923
- if (input.optOut) return "bypass";
6924
- return input.spawnCwdIsGitRepo ? "refuse" : "bypass";
6925
- }
6926
- function resolveSpawnCwd(requestedCwd, projectDir, dirExists = existsSync9) {
6927
- if (dirExists(requestedCwd)) return { cwd: requestedCwd, fellBack: false, requestedCwd };
6928
- if (dirExists(projectDir)) return { cwd: projectDir, fellBack: true, requestedCwd };
6929
- return { cwd: null, fellBack: false, requestedCwd };
6930
- }
6931
- function spawnExitMarkerPath(sessionName) {
6932
- const safe = sessionName.replace(/[^A-Za-z0-9._-]/g, "_");
6933
- return path8.join(SESSION_CACHE, `spawn-exit-${safe}`);
6934
- }
6935
- function buildSpawnCommand(launchCommand, exitMarkerPath, cleanupSuffix) {
6936
- const list = `${launchCommand}; printf '%s' "$?" > "${exitMarkerPath}"${cleanupSuffix}`;
6937
- return `/bin/sh -c '${list.replace(/'/g, `'\\''`)}'`;
6938
- }
6939
- function readSpawnExitMarker(markerPath, read = (p) => readFileSync6(p, "utf8")) {
6940
- let raw;
6941
- try {
6942
- raw = read(markerPath);
6943
- } catch {
6944
- return null;
6945
- }
6946
- const trimmed = raw.trim();
6947
- if (!/^\d+$/.test(trimmed)) return null;
6948
- return Number(trimmed);
6949
- }
6950
- function paneShowsRuntimeBanner(pane, runtime) {
6951
- if (runtime === "exe-agent") return pane.includes("[exe-agent]") || pane.includes("online");
6952
- if (runtime === "codex") {
6953
- return pane.includes("codex") || pane.includes("Codex") || pane.includes("exe-start-codex");
6954
- }
6955
- if (runtime === "opencode") {
6956
- return pane.includes("opencode") || pane.includes("OpenCode") || pane.includes("exe-start-opencode");
6957
- }
6958
- return pane.includes("Claude Code") || pane.includes("\u276F");
6959
- }
6960
- function classifySpawnFailurePane(pane) {
6961
- const paneLc = pane.toLowerCase();
6962
- if (paneLc.includes("command not found") || paneLc.includes(": not found")) {
6963
- return "path_not_found";
6964
- }
6965
- if (paneLc.includes("exit 127") || paneLc.includes("claude") && paneLc.includes("not found") || paneLc.includes("not support") || // existing "unsupported launch flag" hint
6966
- paneLc.includes("unknown option") || paneLc.includes("enoent")) {
6967
- return "claude_launch_failed";
6968
- }
6969
- return "timeout";
6970
- }
6971
- function resolveStartupWatchCapMs(input) {
6972
- const explicit = Number(input.override) || Number(input.legacyOverride);
6973
- if (explicit > 0) return explicit;
6974
- if (input.useCodex) return 2500;
6975
- return input.callerIsDaemon ? 2e3 : 3e3;
6976
- }
6977
- function watchSpawnStartup(probes, opts) {
6978
- const interval = Math.max(1, opts.intervalMs);
6979
- const iterations = Math.max(0, Math.ceil(Math.max(0, opts.capMs) / interval));
6980
- const capture = () => {
6981
- try {
6982
- return probes.capturePane();
6983
- } catch {
6984
- return "";
6985
- }
6986
- };
6987
- let polls = 0;
6988
- for (let i = 0; i <= iterations; i++) {
6989
- polls++;
6990
- const exitCode = probes.readLauncherExit();
6991
- if (exitCode !== null) return { outcome: "exited", exitCode, pane: capture(), polls };
6992
- if (!probes.isAlive()) {
6993
- return { outcome: "exited", exitCode: probes.readLauncherExit(), pane: capture(), polls };
6994
- }
6995
- if (i < iterations) probes.sleep(interval);
6996
- }
6997
- return { outcome: "running", polls };
6998
- }
6999
- function spawnEmployee(employeeName, exeSession, projectDir, opts) {
7000
- const transport = getTransport();
7001
- const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
7002
- const spawnStartedAt = Date.now();
7003
- const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
7004
- const logDir = path8.join(os6.homedir(), ".exe-os", "session-logs");
7005
- const logFile = path8.join(logDir, `${instanceLabel}-${Date.now()}.log`);
7006
- {
7007
- const earlyRt = resolveSpawnRuntimeConfig(
7008
- employeeName,
7009
- opts?.runtimeOverride,
7010
- opts?.modelOverride
7011
- );
7012
- const compat = assertRuntimeModelCompatible(earlyRt.runtime, earlyRt.model);
7013
- if (!compat.ok) {
7014
- process.stderr.write(`[spawnEmployee] ${compat.error}
6239
+ function spawnEmployee(employeeName, _exeSession, _projectDir, opts) {
6240
+ const sessionName = employeeSessionName(employeeName, _exeSession, opts?.instance);
6241
+ const message = tmuxDispatchRefusal(`spawnEmployee(${employeeName})`);
6242
+ process.stderr.write(`[spawnEmployee] ${message}
7015
6243
  `);
7016
- recordOrchestrationEventBestEffort({
7017
- eventType: "tmux.spawn.completed",
7018
- source: "tmux-routing.spawnEmployee",
7019
- severity: "error",
7020
- agentId: employeeName,
7021
- sessionScope: exeSession,
7022
- tmuxSession: sessionName,
7023
- runtime: earlyRt.runtime,
7024
- result: "failed",
7025
- errorCode: "runtime_model_mismatch",
7026
- payload: { runtime: earlyRt.runtime, model: earlyRt.model }
7027
- });
7028
- return { sessionName, error: compat.error };
7029
- }
7030
- }
7031
- recordOrchestrationEventBestEffort({
7032
- eventType: "tmux.spawn.attempted",
7033
- source: "tmux-routing.spawnEmployee",
7034
- agentId: employeeName,
7035
- sessionScope: exeSession,
7036
- instanceId: opts?.instance != null ? String(opts.instance) : null,
7037
- tmuxSession: sessionName,
7038
- runtime: opts?.runtimeOverride ?? null,
7039
- payload: { hasCwdOverride: Boolean(opts?.cwd), autoInstance: Boolean(opts?.autoInstance) }
7040
- });
7041
- if (!existsSync9(logDir)) {
7042
- mkdirSync6(logDir, { recursive: true });
7043
- }
7044
- const cwdResolution = resolveSpawnCwd(opts?.cwd ?? projectDir, projectDir);
7045
- if (cwdResolution.cwd === null) {
7046
- process.stderr.write(
7047
- `[tmux-routing] spawn cwd does not exist: ${cwdResolution.requestedCwd} \u2014 and project root ${projectDir} is also missing; refusing spawn
7048
- `
7049
- );
7050
- recordOrchestrationEventBestEffort({
7051
- eventType: "worktree.stale_cwd_fallback",
7052
- source: "tmux-routing.spawnEmployee",
7053
- severity: "error",
7054
- agentId: employeeName,
7055
- sessionScope: exeSession,
7056
- instanceId: opts?.instance != null ? String(opts.instance) : null,
7057
- tmuxSession: sessionName,
7058
- result: "failed",
7059
- errorCode: "spawn_cwd_missing",
7060
- payload: { requestedCwd: cwdResolution.requestedCwd, fallbackCwd: null, projectDir }
7061
- });
7062
- releaseSpawnLock(sessionName);
7063
- return { sessionName, error: `spawn cwd missing: ${cwdResolution.requestedCwd} (project root ${projectDir} also missing)` };
7064
- }
7065
- if (cwdResolution.fellBack) {
7066
- process.stderr.write(
7067
- `[tmux-routing] spawn cwd does not exist: ${cwdResolution.requestedCwd} \u2014 falling back to project root ${cwdResolution.cwd} (never spawning into a stale/deleted worktree)
7068
- `
7069
- );
7070
- recordOrchestrationEventBestEffort({
7071
- eventType: "worktree.stale_cwd_fallback",
7072
- source: "tmux-routing.spawnEmployee",
7073
- severity: "warn",
7074
- agentId: employeeName,
7075
- sessionScope: exeSession,
7076
- instanceId: opts?.instance != null ? String(opts.instance) : null,
7077
- tmuxSession: sessionName,
7078
- payload: { requestedCwd: cwdResolution.requestedCwd, fallbackCwd: cwdResolution.cwd, projectDir }
7079
- });
7080
- }
7081
- const spawnCwd = cwdResolution.cwd;
7082
- const optedOutOfWorktree = opts?.spawnWorktree === false;
7083
- const coordinatorCheckout = !isCoordinatorName(employeeName) && optedOutOfWorktree ? detectCoordinatorCheckoutCwd(spawnCwd) : null;
7084
- if (coordinatorCheckout) {
7085
- const message = `Coordinator checkout refusal: refusing to spawn employee ${employeeName} in registered coordinator repo root ${coordinatorCheckout.repoRoot} (coordinator session ${coordinatorCheckout.coordinatorSession}). Spawned implementation agents must run from an isolated worktree; launching here would let commits land on the coordinator's checked-out branch.`;
7086
- process.stderr.write(`[tmux-routing] ${message}
7087
- `);
7088
- releaseSpawnLock(sessionName);
7089
- recordOrchestrationEventBestEffort({
7090
- eventType: "worktree.refused",
7091
- source: "tmux-routing.spawnEmployee",
7092
- severity: "error",
7093
- agentId: employeeName,
7094
- sessionScope: exeSession,
7095
- instanceId: opts?.instance != null ? String(opts.instance) : null,
7096
- tmuxSession: sessionName,
7097
- result: "failed",
7098
- errorCode: "coordinator_checkout_cwd",
7099
- payload: {
7100
- cwd: spawnCwd,
7101
- coordinatorSession: coordinatorCheckout.coordinatorSession,
7102
- repoRoot: coordinatorCheckout.repoRoot
7103
- }
7104
- });
7105
- return { sessionName, error: message };
7106
- }
7107
- transport.kill(sessionName, exeSession);
7108
- let cleanupSuffix = "";
7109
- try {
7110
- const thisFile = fileURLToPath(import.meta.url);
7111
- const cleanupScript = path8.join(path8.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
7112
- if (existsSync9(cleanupScript)) {
7113
- cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
7114
- }
7115
- } catch {
7116
- }
7117
- try {
7118
- const claudeJsonPath = path8.join(os6.homedir(), ".claude.json");
7119
- let claudeJson = {};
7120
- try {
7121
- claudeJson = JSON.parse(readFileSync6(claudeJsonPath, "utf8"));
7122
- } catch {
7123
- }
7124
- if (!claudeJson.projects) claudeJson.projects = {};
7125
- const projects = claudeJson.projects;
7126
- const trustDir = opts?.cwd ?? projectDir;
7127
- if (!projects[trustDir]) projects[trustDir] = {};
7128
- projects[trustDir].hasTrustDialogAccepted = true;
7129
- atomicWriteSync(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
7130
- } catch {
7131
- }
7132
- try {
7133
- const settingsDir = path8.join(os6.homedir(), ".claude", "projects");
7134
- const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
7135
- const projSettingsDir = path8.join(settingsDir, normalizedKey);
7136
- const settingsPath = path8.join(projSettingsDir, "settings.json");
7137
- let settings = {};
7138
- try {
7139
- settings = JSON.parse(readFileSync6(settingsPath, "utf8"));
7140
- } catch {
7141
- }
7142
- const perms = settings.permissions ?? {};
7143
- const allow = perms.allow ?? [];
7144
- const toolNames = [
7145
- "recall_my_memory",
7146
- "store_memory",
7147
- "create_task",
7148
- "update_task",
7149
- "list_tasks",
7150
- "get_task",
7151
- // Work claims: spawned agents must be able to claim/release without a
7152
- // permission prompt, or the dispatch gate becomes advisory in practice.
7153
- "claim",
7154
- "ask_team_memory",
7155
- "store_behavior",
7156
- "get_identity",
7157
- "send_message"
7158
- ];
7159
- const requiredTools = expandDualPrefixTools(toolNames);
7160
- let changed = false;
7161
- for (const tool of requiredTools) {
7162
- if (!allow.includes(tool)) {
7163
- allow.push(tool);
7164
- changed = true;
7165
- }
7166
- }
7167
- if (changed) {
7168
- perms.allow = allow;
7169
- settings.permissions = perms;
7170
- mkdirSync6(projSettingsDir, { recursive: true });
7171
- atomicWriteSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
7172
- }
7173
- } catch {
7174
- }
7175
- let disciplineRefusal = null;
7176
- try {
7177
- const inWorktree = spawnCwd.includes("/.worktrees/") || spawnCwd.includes("/.claude/worktrees/");
7178
- const COORDINATOR_ROLES = /* @__PURE__ */ new Set(["COO", "CTO", "CMO"]);
7179
- const rosterResult = loadEmployeesState();
7180
- const emp = rosterResult.employees.find(
7181
- (e) => baseAgentName(e.name) === baseAgentName(employeeName)
7182
- );
7183
- const roleKnown = emp != null;
7184
- const isCodeRole = emp != null && !COORDINATOR_ROLES.has(emp.role);
7185
- const optOut = opts?.spawnWorktree === false;
7186
- const spawnCwdIsGitRepo = isInsideGitRepo(spawnCwd);
7187
- const decision = decideSpawnWorktreeDiscipline({
7188
- inWorktree,
7189
- roleKnown,
7190
- isCodeRole,
7191
- spawnCwdIsGitRepo,
7192
- optOut
7193
- });
7194
- if (decision !== "ok") {
7195
- const reason = rosterResult.status === "error" && !roleKnown ? "roster_load_error" : opts?.cwd != null ? "preset_cwd" : !roleKnown ? "roster_miss" : "git_timeout";
7196
- const role = emp?.role ?? "unknown";
7197
- if (decision === "refuse") {
7198
- const rosterNote = reason === "roster_load_error" ? ` The roster failed to load (unreadable/corrupt/truncated), so ${employeeName}'s role could not be verified and is treated as code-role.` : reason === "roster_miss" ? ` ${employeeName} is not in the roster, so its role could not be verified and is treated as code-role.` : "";
7199
- disciplineRefusal = `Worktree isolation required for ${roleKnown ? `code-role ${employeeName} (role=${role})` : employeeName}; refusing to spawn in MAIN checkout ${spawnCwd} (reason=${reason}) \u2014 commits would land on main.${rosterNote} Pass spawn_worktree=false (create_task) or opts.spawnWorktree=false to dispatch here anyway (e.g. a non-git automation project).`;
7200
- process.stderr.write(`[tmux-routing] ${disciplineRefusal}
7201
- `);
7202
- recordOrchestrationEventBestEffort({
7203
- eventType: "worktree.refused",
7204
- source: "tmux-routing.spawnEmployee",
7205
- severity: "warn",
7206
- agentId: employeeName,
7207
- sessionScope: exeSession,
7208
- instanceId: opts?.instance != null ? String(opts.instance) : null,
7209
- tmuxSession: sessionName,
7210
- payload: { agent: employeeName, role, cwd: spawnCwd, reason, rosterStatus: rosterResult.status }
7211
- });
7212
- } else {
7213
- const viaOptOut = optOut;
7214
- process.stderr.write(
7215
- `[tmux-routing] WORKTREE BYPASSED: ${role} ${employeeName} spawning in MAIN checkout ${spawnCwd} (reason=${reason}${viaOptOut ? ", opt-out" : ""}) \u2014 commits will land on main
7216
- `
7217
- );
7218
- if (viaOptOut && spawnCwdIsGitRepo) emitOptOutBypassWarning(employeeName, spawnCwd);
7219
- recordOrchestrationEventBestEffort({
7220
- eventType: "worktree.bypassed",
7221
- source: "tmux-routing.spawnEmployee",
7222
- severity: "warn",
7223
- agentId: employeeName,
7224
- sessionScope: exeSession,
7225
- instanceId: opts?.instance != null ? String(opts.instance) : null,
7226
- tmuxSession: sessionName,
7227
- payload: { agent: employeeName, role, cwd: spawnCwd, reason, optOut: viaOptOut, rosterStatus: rosterResult.status }
7228
- });
7229
- }
7230
- }
7231
- } catch {
7232
- }
7233
- if (disciplineRefusal) {
7234
- releaseSpawnLock(sessionName);
7235
- return { sessionName, error: disciplineRefusal };
7236
- }
7237
- const useExeAgent = !!(opts?.model && opts?.provider);
7238
- const agentRtConfig = resolveSpawnRuntimeConfig(
7239
- employeeName,
7240
- opts?.runtimeOverride,
7241
- opts?.modelOverride
7242
- );
7243
- const useCodex = !useExeAgent && agentRtConfig.runtime === "codex";
7244
- const useOpencode = !useExeAgent && !useCodex && agentRtConfig.runtime === "opencode";
7245
- const ccProvider = useExeAgent || useCodex || useOpencode ? DEFAULT_PROVIDER : detectActiveProvider();
7246
- const useBinSymlink = ccProvider !== DEFAULT_PROVIDER;
7247
- let legacyFallbackWarned = false;
7248
- if (!useExeAgent && !useBinSymlink) {
7249
- const identityPath = path8.join(
7250
- os6.homedir(),
7251
- ".exe-os",
7252
- "identity",
7253
- `${employeeName}.md`
7254
- );
7255
- _resetCcAgentSupportCache();
7256
- const hasAgentFlag = claudeSupportsAgentFlag();
7257
- if (hasAgentFlag) {
7258
- const symlink = ensureAgentSymlink(employeeName);
7259
- if (symlink.action === "conflict") {
7260
- process.stderr.write(
7261
- `[tmux-routing] WARN: respecting customer-owned ~/.claude/agents/${employeeName}.md (${symlink.conflict}); not overwriting or bypassing it.
7262
- `
7263
- );
7264
- }
7265
- } else if (existsSync9(identityPath)) {
7266
- legacyFallbackWarned = true;
7267
- }
7268
- if (!opts?.behaviorsExported) {
7269
- const behaviorsFile = exportBehaviorsSync(
7270
- employeeName,
7271
- path8.basename(spawnCwd),
7272
- sessionName
7273
- );
7274
- void behaviorsFile;
7275
- }
7276
- }
7277
- if (legacyFallbackWarned) {
7278
- process.stderr.write(
7279
- `[tmux-routing] claude --agent not supported by installed CC. Falling back to --append-system-prompt-file for ${employeeName}. Upgrade Claude Code to enable native --agent launch.
7280
- `
7281
- );
7282
- }
7283
- try {
7284
- const ctxDir = path8.join(os6.homedir(), ".exe-os", "session-cache");
7285
- mkdirSync6(ctxDir, { recursive: true });
7286
- const ctxFile = path8.join(ctxDir, `session-context-${sessionName}.md`);
7287
- const ctxContent = [
7288
- `## Session Context`,
7289
- `You are running in tmux session: ${sessionName}.`,
7290
- `Your parent coordinator session is ${exeSession}.`,
7291
- `Your employees (if any) use the -${exeSession} suffix.`
7292
- ].join("\n");
7293
- atomicWriteSync(ctxFile, ctxContent);
7294
- void ctxFile;
7295
- } catch {
7296
- }
7297
- const launchEnv = {
7298
- AGENT_ID: employeeName,
7299
- EXE_SESSION: exeSession,
7300
- EXE_SESSION_NAME: sessionName,
7301
- EXE_SESSION_START_ISO: (/* @__PURE__ */ new Date()).toISOString(),
7302
- EXE_OS_ENABLE_LEAN_MCP: "1",
7303
- // Bug 1ed715ec: dispatcher-reply path — spawned agents need to know which
7304
- // coordinator session dispatched them so they can address replies to the
7305
- // exact originator. exeSession is the coordinator's session name (e.g.
7306
- // "exe1", "exe2") that spawned this agent.
7307
- EXE_DISPATCHER_SESSION: exeSession,
7308
- // Bug bbf7824c: tmux inherits a minimal PATH from the launchd-spawned
7309
- // daemon, which omits the nvm/.local bin dir where exe-launch-agent,
7310
- // exe-agent, and claude live — so the spawn command is unresolvable and
7311
- // every auto-dispatch fails. Carry an explicit, PATH that includes the
7312
- // running node's bin dir and preserves the inherited PATH.
7313
- PATH: buildSpawnPath()
7314
- };
7315
- if (process.env.EXE_IS_DAEMON === "1") {
7316
- try {
7317
- let identityRole = "employee";
7318
- try {
7319
- const emp = loadEmployeesState().employees.find(
7320
- (e) => baseAgentName(e.name) === baseAgentName(employeeName)
7321
- );
7322
- if (emp?.role) identityRole = emp.role;
7323
- } catch {
7324
- }
7325
- const { token } = getDaemonAgentIdentityBroker().issue({
7326
- agentId: employeeName,
7327
- role: identityRole,
7328
- sessionId: sessionName
7329
- });
7330
- launchEnv[AGENT_IDENTITY_TOKEN_ENV] = token;
7331
- } catch (e) {
7332
- process.stderr.write(
7333
- `[tmux-routing] WARN: could not mint agent identity credential for ${sessionName}: ${e instanceof Error ? e.message : String(e)}
7334
- `
7335
- );
7336
- }
7337
- }
7338
- if (ccProvider !== DEFAULT_PROVIDER) {
7339
- const cfg = PROVIDER_TABLE[ccProvider];
7340
- if (cfg?.apiKeyEnv) {
7341
- const keyVal = process.env[cfg.apiKeyEnv];
7342
- if (keyVal) {
7343
- launchEnv[cfg.apiKeyEnv] = keyVal;
7344
- }
7345
- }
7346
- }
7347
- if (useCodex) {
7348
- const codexCfg = RUNTIME_TABLE.codex;
7349
- if (codexCfg?.apiKeyEnv) {
7350
- const keyVal = process.env[codexCfg.apiKeyEnv];
7351
- if (keyVal) {
7352
- launchEnv[codexCfg.apiKeyEnv] = keyVal;
7353
- }
7354
- }
7355
- if (agentRtConfig.model) launchEnv.EXE_AGENT_MODEL = agentRtConfig.model;
7356
- if (agentRtConfig.reasoning_effort) {
7357
- launchEnv.EXE_AGENT_REASONING_EFFORT = agentRtConfig.reasoning_effort;
7358
- }
7359
- }
7360
- if (useOpencode) {
7361
- const ocCfg = PROVIDER_TABLE.opencode;
7362
- if (ocCfg?.apiKeyEnv) {
7363
- const keyVal = process.env[ocCfg.apiKeyEnv];
7364
- if (keyVal) {
7365
- launchEnv[ocCfg.apiKeyEnv] = keyVal;
7366
- }
7367
- }
7368
- if (agentRtConfig.model) launchEnv.ANTHROPIC_MODEL = agentRtConfig.model;
7369
- }
7370
- if (!useExeAgent && !useCodex && !useOpencode && !useBinSymlink) {
7371
- if (agentRtConfig.runtime === "claude" && agentRtConfig.model) {
7372
- const ccModel = normalizeCcModelName(agentRtConfig.model);
7373
- launchEnv.ANTHROPIC_MODEL = ccModel;
7374
- if (opts?.modelOverride) {
7375
- launchEnv.EXE_AGENT_MODEL = ccModel;
7376
- }
7377
- }
7378
- }
7379
- let launchCommand;
7380
- if (useExeAgent) {
7381
- launchCommand = `exe-agent --employee ${employeeName} --model ${opts.model} --provider ${opts.provider}`;
7382
- } else if (useCodex) {
7383
- process.stderr.write(
7384
- `[tmux-routing] agent-config: ${employeeName} \u2192 codex (${agentRtConfig.model})
7385
- `
7386
- );
7387
- launchCommand = `exe-start-codex --agent ${employeeName} --session ${sessionName}`;
7388
- } else if (useOpencode) {
7389
- const binName = `${employeeName}-opencode`;
7390
- process.stderr.write(
7391
- `[tmux-routing] agent-config: ${employeeName} \u2192 opencode (${agentRtConfig.model})
7392
- `
7393
- );
7394
- launchCommand = binName;
7395
- } else if (useBinSymlink) {
7396
- const binName = `${employeeName}-${ccProvider}`;
7397
- process.stderr.write(
7398
- `[tmux-routing] provider cascade: ${ccProvider} \u2192 spawning ${binName}
7399
- `
7400
- );
7401
- launchCommand = binName;
7402
- } else {
7403
- let launcherAbs = "";
7404
- try {
7405
- const launcherJs = path8.join(path8.dirname(fileURLToPath(import.meta.url)), "..", "bin", "exe-launch-agent.js");
7406
- if (existsSync9(launcherJs)) launcherAbs = launcherJs;
7407
- } catch {
7408
- }
7409
- launchCommand = launcherAbs ? `"${process.execPath}" "${launcherAbs}" --agent ${employeeName}` : `exe-launch-agent --agent ${employeeName}`;
7410
- }
7411
- const exitMarkerPath = spawnExitMarkerPath(sessionName);
7412
- try {
7413
- mkdirSync6(SESSION_CACHE, { recursive: true });
7414
- } catch {
7415
- }
7416
- try {
7417
- unlinkSync4(exitMarkerPath);
7418
- } catch {
7419
- }
7420
- const spawnCommand = buildSpawnCommand(launchCommand, exitMarkerPath, cleanupSuffix);
7421
- const tmuxEnvArgs = Object.entries(launchEnv).flatMap(([key, val]) => ["-e", `${key}=${val}`]);
7422
- let spawnResult;
7423
- try {
7424
- execFileSync3("tmux", [
7425
- "new-session",
7426
- "-d",
7427
- ...tmuxEnvArgs,
7428
- "-s",
7429
- sessionName,
7430
- "-x",
7431
- "200",
7432
- "-y",
7433
- "50",
7434
- "-c",
7435
- spawnCwd,
7436
- spawnCommand
7437
- ], { timeout: 1e4 });
7438
- spawnResult = { sessionName };
7439
- } catch (e) {
7440
- spawnResult = { sessionName, error: `spawn failed: ${e instanceof Error ? e.message : String(e)}` };
7441
- }
7442
- if (spawnResult.error) {
7443
- releaseSpawnLock(sessionName);
7444
- recordOrchestrationEventBestEffort({
7445
- eventType: "tmux.spawn.completed",
7446
- source: "tmux-routing.spawnEmployee",
7447
- severity: "warn",
7448
- agentId: employeeName,
7449
- sessionScope: exeSession,
7450
- instanceId: opts?.instance != null ? String(opts.instance) : null,
7451
- tmuxSession: sessionName,
7452
- runtime: useCodex ? "codex" : useOpencode ? "opencode" : useExeAgent ? "exe-agent" : "claude",
7453
- durationMs: Date.now() - spawnStartedAt,
7454
- result: "failed",
7455
- errorCode: "tmux_new_session_failed"
7456
- });
7457
- return { sessionName, error: `tmux new-session failed: ${spawnResult.error}` };
7458
- }
7459
- transport.pipeLog(sessionName, logFile);
7460
- try {
7461
- const mySession = getMySession();
7462
- const dispatchInfo = path8.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
7463
- atomicWriteJsonSync(dispatchInfo, {
7464
- dispatchedBy: mySession,
7465
- rootExe: exeSession,
7466
- provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : useCodex ? "openai" : useOpencode ? "opencode" : "anthropic",
7467
- runtime: useCodex ? "codex" : useOpencode ? "opencode" : useExeAgent ? "exe-agent" : "claude",
7468
- model: useCodex ? agentRtConfig.model : useOpencode ? agentRtConfig.model : void 0,
7469
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
7470
- });
7471
- } catch {
7472
- }
7473
- const callerIsDaemon = process.env.EXE_IS_DAEMON === "1";
7474
- const POLL_INTERVAL_MS = 500;
7475
- const runtimeLabel = useExeAgent ? "exe-agent" : useCodex ? "codex" : useOpencode ? "opencode" : "claude";
7476
- const LIVENESS_CAP_MS = Number(process.env.EXE_SPAWN_LIVENESS_CAP_MS) || (callerIsDaemon ? 6e3 : 8e3);
7477
- const livenessIterations = Math.max(1, Math.ceil(LIVENESS_CAP_MS / POLL_INTERVAL_MS));
7478
- let sessionLive = false;
7479
- for (let i = 0; i < livenessIterations; i++) {
7480
- if (transport.isAlive(sessionName)) {
7481
- sessionLive = true;
7482
- break;
7483
- }
7484
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, POLL_INTERVAL_MS);
7485
- }
7486
- if (!sessionLive) sessionLive = transport.isAlive(sessionName);
7487
- if (!sessionLive) {
7488
- releaseSpawnLock(sessionName);
7489
- let lastPane = "";
7490
- try {
7491
- lastPane = transport.capturePane(sessionName, 50);
7492
- } catch {
7493
- }
7494
- const spawnFailureCause = classifySpawnFailurePane(lastPane);
7495
- const errMsg2 = `spawn did not start: tmux session "${sessionName}" never came alive within ${LIVENESS_CAP_MS / 1e3}s (${runtimeLabel} process failed to launch or exited immediately; cause=${spawnFailureCause}). Check ~/.exe-os/session-logs/${instanceLabel}-*.log \u2014 common cause: installed Claude Code does not support a launch flag, or the daemon PATH excludes the node/launcher bin dir (cause=path_not_found).`;
7496
- process.stderr.write(`[tmux-routing] SPAWN FAILED ${sessionName} (${spawnFailureCause}): ${errMsg2}
7497
- `);
7498
- recordOrchestrationEventBestEffort({
7499
- eventType: "tmux.spawn.completed",
7500
- source: "tmux-routing.spawnEmployee",
7501
- severity: "warn",
7502
- agentId: employeeName,
7503
- sessionScope: exeSession,
7504
- instanceId: opts?.instance != null ? String(opts.instance) : null,
7505
- tmuxSession: sessionName,
7506
- runtime: useCodex ? "codex" : useOpencode ? "opencode" : useExeAgent ? "exe-agent" : "claude",
7507
- durationMs: Date.now() - spawnStartedAt,
7508
- result: "failed",
7509
- // Refined, classified errorCode drives the spawnFailureByCause breakdown
7510
- // in orchestration-events. Keep the generic detail in payload for context.
7511
- errorCode: spawnFailureCause,
7512
- payload: { spawnFailureCause, detail: "spawn_session_not_live", spawnCommand }
7513
- });
7514
- return { sessionName, error: errMsg2 };
7515
- }
7516
- const STARTUP_WATCH_MS = resolveStartupWatchCapMs({
7517
- useCodex,
7518
- callerIsDaemon,
7519
- override: process.env.EXE_SPAWN_STARTUP_WATCH_MS,
7520
- legacyOverride: process.env.EXE_SPAWN_STABILITY_MS
7521
- });
7522
- const STARTUP_WATCH_INTERVAL_MS = 250;
7523
- const startupWatch = watchSpawnStartup(
7524
- {
7525
- readLauncherExit: () => readSpawnExitMarker(exitMarkerPath),
7526
- isAlive: () => transport.isAlive(sessionName),
7527
- capturePane: () => transport.capturePane(sessionName, 50),
7528
- sleep: (ms) => {
7529
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
7530
- }
7531
- },
7532
- { capMs: STARTUP_WATCH_MS, intervalMs: STARTUP_WATCH_INTERVAL_MS }
7533
- );
7534
- if (startupWatch.outcome === "exited") {
7535
- try {
7536
- execFileSync3("tmux", ["kill-session", "-t", sessionName], { timeout: 3e3 });
7537
- } catch {
7538
- }
7539
- releaseSpawnLock(sessionName);
7540
- const { exitCode } = startupWatch;
7541
- const refused = exitCode === 78;
7542
- const errorCode = refused ? "launch_refused" : "startup_exit";
7543
- const paneCause = classifySpawnFailurePane(startupWatch.pane);
7544
- const errMsg2 = refused ? `spawn refused: ${runtimeLabel} launcher for "${sessionName}" exited 78 (refusal) within ${STARTUP_WATCH_MS / 1e3}s \u2014 it declined to start the agent. Most common cause: running as root (uid 0), where Claude Code rejects --dangerously-skip-permissions / bypassPermissions. Run the daemon as a non-root user. Check ~/.exe-os/session-logs/${instanceLabel}-*.log. Pane tail: ${startupWatch.pane.trim().slice(-500) || "(empty)"}` : `spawn died during startup: ${runtimeLabel} launcher for "${sessionName}" ` + (exitCode === null ? `disappeared within ${STARTUP_WATCH_MS / 1e3}s of launch` : `exited ${exitCode} within ${STARTUP_WATCH_MS / 1e3}s of launch`) + ` (cause=${paneCause}). Check ~/.exe-os/session-logs/${instanceLabel}-*.log. Pane tail: ${startupWatch.pane.trim().slice(-500) || "(empty)"}`;
7545
- process.stderr.write(`[tmux-routing] SPAWN FAILED ${sessionName} (${errorCode}): ${errMsg2}
7546
- `);
7547
- recordOrchestrationEventBestEffort({
7548
- eventType: "tmux.spawn.completed",
7549
- source: "tmux-routing.spawnEmployee",
7550
- severity: "warn",
7551
- agentId: employeeName,
7552
- sessionScope: exeSession,
7553
- instanceId: opts?.instance != null ? String(opts.instance) : null,
7554
- tmuxSession: sessionName,
7555
- runtime: runtimeLabel,
7556
- durationMs: Date.now() - spawnStartedAt,
7557
- result: "failed",
7558
- errorCode,
7559
- payload: {
7560
- detail: "spawn_exited_during_startup",
7561
- exitCode,
7562
- spawnFailureCause: paneCause,
7563
- watchCapMs: STARTUP_WATCH_MS,
7564
- polls: startupWatch.polls,
7565
- spawnCommand
7566
- }
7567
- });
7568
- return { sessionName, error: errMsg2 };
7569
- }
7570
- if (useCodex) {
7571
- let pane = "";
7572
- try {
7573
- pane = transport.capturePane(sessionName, 80);
7574
- } catch {
7575
- }
7576
- if (isBlockedCodexPrompt(pane)) {
7577
- try {
7578
- execFileSync3("tmux", ["kill-session", "-t", sessionName], { timeout: 3e3 });
7579
- } catch {
7580
- }
7581
- releaseSpawnLock(sessionName);
7582
- const errMsg2 = `codex spawn blocked by an interactive model prompt in ${sessionName}; killed session so it can respawn non-interactively`;
7583
- process.stderr.write(`[tmux-routing] SPAWN FAILED ${sessionName} (codex_blocked_prompt): ${errMsg2}
7584
- `);
7585
- recordOrchestrationEventBestEffort({
7586
- eventType: "tmux.spawn.completed",
7587
- source: "tmux-routing.spawnEmployee",
7588
- severity: "warn",
7589
- agentId: employeeName,
7590
- sessionScope: exeSession,
7591
- instanceId: opts?.instance != null ? String(opts.instance) : null,
7592
- tmuxSession: sessionName,
7593
- runtime: "codex",
7594
- durationMs: Date.now() - spawnStartedAt,
7595
- result: "failed",
7596
- errorCode: "codex_blocked_prompt",
7597
- payload: { detail: "interactive_model_prompt" }
7598
- });
7599
- return { sessionName, error: errMsg2 };
7600
- }
7601
- }
7602
- const POLL_CAP_MS = callerIsDaemon ? 0 : 45e3;
7603
- const pollIterations = Math.ceil(POLL_CAP_MS / POLL_INTERVAL_MS);
7604
- let booted = false;
7605
- for (let i = 0; i < pollIterations; i++) {
7606
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, POLL_INTERVAL_MS);
7607
- try {
7608
- if (paneShowsRuntimeBanner(transport.capturePane(sessionName), runtimeLabel)) {
7609
- booted = true;
7610
- break;
7611
- }
7612
- } catch {
7613
- }
7614
- }
7615
- if (!booted && !callerIsDaemon) {
7616
- process.stderr.write(
7617
- `[tmux-routing] ${runtimeLabel} boot banner poll capped at ${POLL_CAP_MS / 1e3}s for ${sessionName} (session is live) \u2014 sending task nudge anyway
7618
- `
7619
- );
7620
- }
7621
- if (!useExeAgent && !useCodex) {
7622
- if (callerIsDaemon) {
7623
- try {
7624
- const empRoster = loadEmployeesSync();
7625
- const bootCache = {
7626
- agentId: employeeName,
7627
- agentRole: empRoster.find((e) => baseAgentName(e.name) === baseAgentName(employeeName))?.role ?? "employee",
7628
- sessionName,
7629
- exeSession,
7630
- dispatchedAt: (/* @__PURE__ */ new Date()).toISOString()
7631
- };
7632
- const cachePath = path8.join(os6.homedir(), ".exe-os", "session-cache", `boot-cache-${sessionName}.json`);
7633
- writeFileSync5(cachePath, JSON.stringify(bootCache));
7634
- } catch {
7635
- }
7636
- scheduleDeferredSpawnNudge({
7637
- sessionName,
7638
- employeeName,
7639
- exeSession,
7640
- runtime: useOpencode ? "opencode" : "claude",
7641
- transport,
7642
- message: `You have pending tasks. Run list_tasks and start your highest priority task immediately.`
7643
- });
7644
- } else {
7645
- try {
7646
- transport.sendKeysLiteral(sessionName, `You have pending tasks. Run list_tasks and start immediately.`);
7647
- } catch (e) {
7648
- process.stderr.write(`[tmux-routing] CLI nudge ${employeeName}: ${e instanceof Error ? e.message : String(e)}
7649
- `);
7650
- }
7651
- }
7652
- }
7653
- registerSession({
7654
- windowName: sessionName,
7655
- agentId: employeeName,
7656
- projectDir: spawnCwd,
7657
- parentExe: exeSession,
7658
- pid: 0,
7659
- registeredAt: (/* @__PURE__ */ new Date()).toISOString()
7660
- });
7661
- releaseSpawnLock(sessionName);
7662
- recordOrchestrationEventBestEffort({
7663
- eventType: "tmux.spawn.completed",
7664
- source: "tmux-routing.spawnEmployee",
7665
- agentId: employeeName,
7666
- sessionScope: exeSession,
7667
- instanceId: opts?.instance != null ? String(opts.instance) : null,
7668
- tmuxSession: sessionName,
7669
- runtime: useCodex ? "codex" : useOpencode ? "opencode" : useExeAgent ? "exe-agent" : "claude",
7670
- durationMs: Date.now() - spawnStartedAt,
7671
- result: booted ? "spawned_booted" : "spawned_unverified"
7672
- });
7673
- return { sessionName };
6244
+ return { sessionName, error: message };
7674
6245
  }
7675
6246
 
7676
6247
  // src/lib/task-scope.ts
@@ -7909,12 +6480,6 @@ function canonicalTaskFilePath(oldTaskFile, assignedTo, newSessionScope) {
7909
6480
  }
7910
6481
 
7911
6482
  export {
7912
- getCcHelpOutputCached,
7913
- _resetCcHelpCache,
7914
- _resetCcAgentSupportCache,
7915
- claudeSupportsAgentFlag,
7916
- PROVIDER_TABLE,
7917
- DEFAULT_PROVIDER,
7918
6483
  isAmbiguousMultiCoordinatorContext,
7919
6484
  hasLiveCoordinatorLanes,
7920
6485
  isMultiCoordinatorSharedProject,
@@ -7945,6 +6510,7 @@ export {
7945
6510
  _resetDrainGuard,
7946
6511
  logTaskDispatch,
7947
6512
  DEFAULT_TASK_PRIORITY,
6513
+ DEFAULT_NEW_TASK_EXECUTION_MODE,
7948
6514
  normalizeTaskPriority,
7949
6515
  isStructuredTaskCompletionReport,
7950
6516
  resolveCompletionChangedFiles,
@@ -8007,6 +6573,8 @@ export {
8007
6573
  getReviewChecklist,
8008
6574
  createReviewForCompletedTask,
8009
6575
  cleanupReviewFile,
6576
+ tmuxDispatchRefusal,
6577
+ spawnOverrideNoopNotice,
8010
6578
  BUSY_PATTERN,
8011
6579
  _resetExeBinDirCache,
8012
6580
  buildSpawnPath,
@@ -8025,7 +6593,6 @@ export {
8025
6593
  resolveExeSession,
8026
6594
  isEmployeeAlive,
8027
6595
  findFreeInstance,
8028
- detectCoordinatorCheckoutCwd,
8029
6596
  verifyPaneAtCapacity,
8030
6597
  resolveSessionRuntime,
8031
6598
  classifyPaneSessionState,
@@ -8058,18 +6625,7 @@ export {
8058
6625
  sendIntercomAsync,
8059
6626
  notifyParentExe,
8060
6627
  notifyCoordinatorTaskCompletion,
8061
- emitOptOutBypassWarning,
8062
- worktreeIsolationGate,
8063
6628
  ensureEmployee,
8064
6629
  ensureEmployeeAsync,
8065
- decideSpawnWorktreeDiscipline,
8066
- resolveSpawnCwd,
8067
- spawnExitMarkerPath,
8068
- buildSpawnCommand,
8069
- readSpawnExitMarker,
8070
- paneShowsRuntimeBanner,
8071
- classifySpawnFailurePane,
8072
- resolveStartupWatchCapMs,
8073
- watchSpawnStartup,
8074
6630
  spawnEmployee
8075
6631
  };