@askexenow/exe-os 0.9.127 → 0.9.129

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 (373) hide show
  1. package/dist/active-agent-3FDJYREJ.js +22 -0
  2. package/dist/active-agent-WC7YK3L5.js +23 -0
  3. package/dist/agent-context-CDWUZEXY.js +11 -0
  4. package/dist/agent-loop-G4VUR5ME.js +10 -0
  5. package/dist/agentic-ontology-2VYNTMNO.js +25 -0
  6. package/dist/backfill-metadata-OJWOCLSZ.js +601 -0
  7. package/dist/background-jobs-LGRDXGXC.js +25 -0
  8. package/dist/bash-Y5PEW5UQ.js +8 -0
  9. package/dist/behaviors-CSB2YLDT.js +22 -0
  10. package/dist/bin/age-ontology-load.js +10 -258
  11. package/dist/bin/agentic-ontology-backfill.js +23 -5296
  12. package/dist/bin/agentic-reflection-backfill.js +19 -4739
  13. package/dist/bin/agentic-semantic-label.js +28 -4723
  14. package/dist/bin/backfill-conversations.js +42 -5543
  15. package/dist/bin/backfill-responses.js +41 -5542
  16. package/dist/bin/backfill-vectors.js +43 -4795
  17. package/dist/bin/bulk-sync-postgres.js +22 -5313
  18. package/dist/bin/cc-doctor.js +10 -602
  19. package/dist/bin/cleanup-stale-review-tasks.js +32 -6803
  20. package/dist/bin/cli.js +169 -38993
  21. package/dist/bin/exe-agent-config.js +21 -253
  22. package/dist/bin/exe-agent.js +63 -2429
  23. package/dist/bin/exe-assign.js +34 -5810
  24. package/dist/bin/exe-boot.js +180 -12726
  25. package/dist/bin/exe-call.js +48 -1409
  26. package/dist/bin/exe-cloud.js +64 -8516
  27. package/dist/bin/exe-dispatch.js +35 -10818
  28. package/dist/bin/exe-doctor.js +24 -7537
  29. package/dist/bin/exe-export-behaviors.js +18 -6122
  30. package/dist/bin/exe-forget.js +22 -6274
  31. package/dist/bin/exe-gateway.js +62 -15286
  32. package/dist/bin/exe-healthcheck.js +9 -602
  33. package/dist/bin/exe-heartbeat.js +51 -6898
  34. package/dist/bin/exe-kill.js +30 -5961
  35. package/dist/bin/exe-launch-agent.js +101 -6788
  36. package/dist/bin/exe-new-employee.js +42 -3774
  37. package/dist/bin/exe-pending-messages.js +28 -6833
  38. package/dist/bin/exe-pending-notifications.js +31 -6869
  39. package/dist/bin/exe-pending-reviews.js +38 -6910
  40. package/dist/bin/exe-rename.js +57 -5766
  41. package/dist/bin/exe-review.js +29 -5948
  42. package/dist/bin/exe-search.js +22 -7692
  43. package/dist/bin/exe-session-cleanup.js +52 -11147
  44. package/dist/bin/exe-settings.js +35 -524
  45. package/dist/bin/exe-start-codex.js +70 -6641
  46. package/dist/bin/exe-start-opencode.js +54 -6584
  47. package/dist/bin/exe-status.js +26 -7081
  48. package/dist/bin/exe-support.js +10 -546
  49. package/dist/bin/exe-team.js +18 -5942
  50. package/dist/bin/git-sweep.js +26 -10909
  51. package/dist/bin/graph-backfill.js +24 -5979
  52. package/dist/bin/graph-export.js +31 -6128
  53. package/dist/bin/graph-layer-benchmark.js +4 -8
  54. package/dist/bin/install.js +47 -2322
  55. package/dist/bin/intercom-check.js +25 -11501
  56. package/dist/bin/list-providers.js +4 -18
  57. package/dist/bin/postgres-agentic-reflection-backfill.js +14 -357
  58. package/dist/bin/postgres-agentic-semantic-backfill.js +14 -404
  59. package/dist/bin/pre-publish.js +4 -298
  60. package/dist/bin/registry-proxy.js +8 -172
  61. package/dist/bin/scan-tasks.js +47 -10881
  62. package/dist/bin/setup.js +6 -9492
  63. package/dist/bin/shard-migrate.js +30 -5149
  64. package/dist/bin/stack-update.js +75 -203
  65. package/dist/bin/update.js +20 -654
  66. package/dist/capacity-monitor-3GZIHLB4.js +46 -0
  67. package/dist/catchup-brief-67QDCINS.js +148 -0
  68. package/dist/chunk-2QD7KBJN.js +664 -0
  69. package/dist/chunk-2WGSIVI4.js +149 -0
  70. package/dist/chunk-35TVNLJI.js +57 -0
  71. package/dist/chunk-3SYV36U5.js +47 -0
  72. package/dist/chunk-46SQTBQW.js +207 -0
  73. package/dist/chunk-4CMVLKEI.js +171 -0
  74. package/dist/chunk-4FLUOZTR.js +116 -0
  75. package/dist/chunk-4NYQAS33.js +17 -0
  76. package/dist/chunk-4QNPADWL.js +902 -0
  77. package/dist/chunk-4Y6QZBEO.js +58 -0
  78. package/dist/chunk-557C2IGL.js +0 -0
  79. package/dist/chunk-55S56YDO.js +305 -0
  80. package/dist/chunk-5BS5ELMC.js +85 -0
  81. package/dist/chunk-5DHM77JE.js +256 -0
  82. package/dist/chunk-5QTWQKNF.js +137 -0
  83. package/dist/chunk-6A7P74QV.js +53 -0
  84. package/dist/chunk-6BFIFI5F.js +45 -0
  85. package/dist/chunk-6KFICEAT.js +20 -0
  86. package/dist/chunk-6LKDJ5WX.js +317 -0
  87. package/dist/chunk-6M5II4EV.js +148 -0
  88. package/dist/chunk-6QEFN3DV.js +302 -0
  89. package/dist/chunk-6WTMJAG3.js +171 -0
  90. package/dist/chunk-6Y4B3QF6.js +19 -0
  91. package/dist/chunk-7RK3AYJE.js +163 -0
  92. package/dist/chunk-7TCP2XTP.js +390 -0
  93. package/dist/chunk-A2NZP64U.js +2307 -0
  94. package/dist/chunk-AFYIYM2K.js +322 -0
  95. package/dist/chunk-AJWFPKQS.js +573 -0
  96. package/dist/chunk-AVE2B4DQ.js +140 -0
  97. package/dist/chunk-B4TT2QQA.js +87 -0
  98. package/dist/chunk-BCMOO4OQ.js +1066 -0
  99. package/dist/chunk-BU3ID2WT.js +432 -0
  100. package/dist/chunk-CFIM43JH.js +862 -0
  101. package/dist/chunk-CURJUF3W.js +66 -0
  102. package/dist/chunk-DC4ZD76Y.js +288 -0
  103. package/dist/chunk-DL52JPGF.js +706 -0
  104. package/dist/chunk-DRSC6ZRA.js +36 -0
  105. package/dist/chunk-E2Q4Y22A.js +86 -0
  106. package/dist/chunk-ECGTESAP.js +236 -0
  107. package/dist/chunk-EHOJUXYG.js +365 -0
  108. package/dist/chunk-EIT6J37V.js +119 -0
  109. package/dist/chunk-ELE2C7L4.js +31 -0
  110. package/dist/chunk-EQSQ4HBW.js +9 -0
  111. package/dist/chunk-FWFFZGSC.js +94 -0
  112. package/dist/chunk-GCNWCYJI.js +249 -0
  113. package/dist/chunk-GGTUUI7J.js +6 -0
  114. package/dist/chunk-GU56L7OY.js +223 -0
  115. package/dist/chunk-HF25XPZE.js +83 -0
  116. package/dist/chunk-HOKOOBDL.js +52 -0
  117. package/dist/chunk-HP43GLZ6.js +89 -0
  118. package/dist/chunk-HSRM6PNM.js +682 -0
  119. package/dist/chunk-HVRTW3OP.js +164 -0
  120. package/dist/chunk-IHDHL5ML.js +125 -0
  121. package/dist/chunk-IHF5RXJM.js +168 -0
  122. package/dist/chunk-IJ73YE73.js +409 -0
  123. package/dist/chunk-INO4ZD5Y.js +162 -0
  124. package/dist/chunk-IRQTM7DY.js +475 -0
  125. package/dist/chunk-JD4FAPYG.js +1208 -0
  126. package/dist/chunk-JN44LQ53.js +316 -0
  127. package/dist/chunk-JQ6TLNIV.js +133 -0
  128. package/dist/chunk-JT76KRZQ.js +35 -0
  129. package/dist/chunk-K6OEWZTB.js +262 -0
  130. package/dist/chunk-KCUYRZSX.js +72 -0
  131. package/dist/chunk-KFQGP6VL.js +33 -0
  132. package/dist/chunk-KRLOFIPI.js +83 -0
  133. package/dist/chunk-KVPG5UT6.js +305 -0
  134. package/dist/chunk-L3TB7CC3.js +170 -0
  135. package/dist/chunk-L4X5EUHR.js +283 -0
  136. package/dist/chunk-LAN26C3W.js +655 -0
  137. package/dist/chunk-LPGBKR4H.js +54 -0
  138. package/dist/chunk-LVNMOVGD.js +132 -0
  139. package/dist/chunk-LX5WEEZ7.js +157 -0
  140. package/dist/chunk-MBH42QNH.js +295 -0
  141. package/dist/chunk-MFO7MNSD.js +102 -0
  142. package/dist/chunk-MILTNDZH.js +736 -0
  143. package/dist/chunk-MJAE4NB7.js +1090 -0
  144. package/dist/chunk-MLCUPTP7.js +132 -0
  145. package/dist/chunk-MPURH6JI.js +445 -0
  146. package/dist/chunk-MVBWW2EO.js +89 -0
  147. package/dist/chunk-MZIGUUDQ.js +42 -0
  148. package/dist/chunk-N3DTSVKE.js +157 -0
  149. package/dist/chunk-N5RRQOAC.js +134 -0
  150. package/dist/chunk-N7L33TED.js +1664 -0
  151. package/dist/chunk-NDYSNVI5.js +122 -0
  152. package/dist/chunk-NEAHEC5G.js +155 -0
  153. package/dist/chunk-NGVOA6ZQ.js +84 -0
  154. package/dist/chunk-NHK5KW6Y.js +193 -0
  155. package/dist/chunk-NMQKGFEP.js +458 -0
  156. package/dist/chunk-NPT4EHZK.js +352 -0
  157. package/dist/chunk-NXFJHTED.js +55 -0
  158. package/dist/chunk-NZLCDI6Y.js +216 -0
  159. package/dist/chunk-O377P7GM.js +100 -0
  160. package/dist/chunk-O4VFZRA5.js +33 -0
  161. package/dist/chunk-O7YD7JYE.js +237 -0
  162. package/dist/chunk-OFK72LTZ.js +81 -0
  163. package/dist/chunk-ORCCI2VV.js +140 -0
  164. package/dist/chunk-OVQR4KMC.js +579 -0
  165. package/dist/chunk-P3CVUMEH.js +54 -0
  166. package/dist/chunk-P4HIF72O.js +30 -0
  167. package/dist/chunk-PEDLSJBL.js +1039 -0
  168. package/dist/chunk-PFICKZZ5.js +219 -0
  169. package/dist/chunk-PGW7TIV6.js +142 -0
  170. package/dist/chunk-PJHHFJAN.js +63 -0
  171. package/dist/chunk-PP4SNOJ5.js +471 -0
  172. package/dist/chunk-PRKVT4KN.js +90 -0
  173. package/dist/chunk-Q2O4VJHH.js +305 -0
  174. package/dist/chunk-Q36CMZIX.js +38 -0
  175. package/dist/chunk-Q3V7K4ME.js +149 -0
  176. package/dist/chunk-QGYPJGHB.js +81 -0
  177. package/dist/chunk-R23EMFJV.js +198 -0
  178. package/dist/chunk-R4M6XCMU.js +39 -0
  179. package/dist/chunk-R4WMF32C.js +81 -0
  180. package/dist/chunk-RJT7H2KR.js +349 -0
  181. package/dist/chunk-RJZMRZNV.js +280 -0
  182. package/dist/chunk-RMFDPCA2.js +72 -0
  183. package/dist/chunk-RUG3N6P4.js +292 -0
  184. package/dist/chunk-RWO327FJ.js +84 -0
  185. package/dist/chunk-SG7EFHQ7.js +108 -0
  186. package/dist/chunk-SH45SJQW.js +0 -0
  187. package/dist/chunk-SPKE5ANC.js +42 -0
  188. package/dist/chunk-SVMFVPBF.js +104 -0
  189. package/dist/chunk-SVXDCELZ.js +163 -0
  190. package/dist/chunk-TMEE7AT7.js +72 -0
  191. package/dist/chunk-TWYEE4FB.js +125 -0
  192. package/dist/chunk-TYLF4LSW.js +110 -0
  193. package/dist/chunk-V4TZI6EO.js +60 -0
  194. package/dist/chunk-VFZTXKQI.js +372 -0
  195. package/dist/chunk-VQ4K2MLM.js +199 -0
  196. package/dist/chunk-VU447UAO.js +173 -0
  197. package/dist/chunk-WMC3TXJF.js +50 -0
  198. package/dist/chunk-WPOA7XAE.js +84 -0
  199. package/dist/chunk-WZQ4CPRG.js +64 -0
  200. package/dist/chunk-X2IMCCM5.js +49 -0
  201. package/dist/chunk-X2Z5GT3V.js +118 -0
  202. package/dist/chunk-XEKO37NM.js +43 -0
  203. package/dist/chunk-XUHFQHGZ.js +505 -0
  204. package/dist/chunk-YGAAZN3E.js +47 -0
  205. package/dist/chunk-YKOW7KMK.js +558 -0
  206. package/dist/chunk-YOQKMB6N.js +145 -0
  207. package/dist/chunk-YZFZDJWZ.js +107 -0
  208. package/dist/chunk-ZBY4AUD4.js +10342 -0
  209. package/dist/chunk-ZOJYPNCM.js +127 -0
  210. package/dist/chunk-ZS7MGQSD.js +1494 -0
  211. package/dist/chunk-ZTZQ5A6B.js +191 -0
  212. package/dist/code-context-index-HXGC4IJL.js +28 -0
  213. package/dist/content-extractor-UVZXRIPC.js +8 -0
  214. package/dist/conversation-entity-extractor-HKSNDF4L.js +113 -0
  215. package/dist/conversation-wiki-populator-NKDAQEZ5.js +105 -0
  216. package/dist/crdt-sync-T7MHVQCS.js +33 -0
  217. package/dist/crm-bridge-Q5JBVJ6P.js +19 -0
  218. package/dist/crm-webhook-OAFTLJYA.js +10 -0
  219. package/dist/cto-delegation-gate-XWHZCUJH.js +208 -0
  220. package/dist/daemon-auth-GWUXTUYO.js +15 -0
  221. package/dist/daemon-orchestration-2C3TVOHO.js +91 -0
  222. package/dist/daemon-protocol-RLH2XM2K.js +19 -0
  223. package/dist/db-backup-CH2KG3JY.js +23 -0
  224. package/dist/devtools-PLJCAU53.js +8 -0
  225. package/dist/discord-G4BQJ2VX.js +7 -0
  226. package/dist/email-XMRNMFXR.js +137 -0
  227. package/dist/entity-boost-IOER4VRR.js +249 -0
  228. package/dist/exe-drift-2IJFQV43.js +68 -0
  229. package/dist/exe-export-Y2RFXGNB.js +71 -0
  230. package/dist/exe-import-LN6PE2YT.js +74 -0
  231. package/dist/exe-key-DHKBWLIT.js +571 -0
  232. package/dist/exe-org-F7LZRHFB.js +73 -0
  233. package/dist/factory-YTD23AW7.js +67 -0
  234. package/dist/fast-db-init-IIP6EGWT.js +7 -0
  235. package/dist/file-edit-FJVEO7XZ.js +8 -0
  236. package/dist/file-read-Q2NH3J35.js +8 -0
  237. package/dist/file-write-UNSFXNH4.js +8 -0
  238. package/dist/gateway/index.js +87 -16563
  239. package/dist/gateway-client-APTYJNCL.js +11 -0
  240. package/dist/git-staleness-I2BUEDE2.js +111 -0
  241. package/dist/git-task-sweep-UEOTXRW4.js +35 -0
  242. package/dist/glob-GRMXLDMB.js +7 -0
  243. package/dist/global-procedures-MFE5LGRF.js +19 -0
  244. package/dist/graph-query-657O5JYJ.js +25 -0
  245. package/dist/graph-rag-ZE5N7C65.js +28 -0
  246. package/dist/grep-NBV6SKYZ.js +7 -0
  247. package/dist/hooks/bug-report-worker.js +41 -10823
  248. package/dist/hooks/codex-stop-task-finalizer.js +38 -9055
  249. package/dist/hooks/commit-complete.js +32 -10914
  250. package/dist/hooks/error-recall.js +35 -7955
  251. package/dist/hooks/exe-heartbeat-hook.js +17 -327
  252. package/dist/hooks/ingest-worker.js +16 -565
  253. package/dist/hooks/ingest.js +98 -11436
  254. package/dist/hooks/instructions-loaded.js +25 -6209
  255. package/dist/hooks/notification.js +16 -6098
  256. package/dist/hooks/post-compact.js +34 -7041
  257. package/dist/hooks/post-tool-combined.js +27 -9751
  258. package/dist/hooks/pre-compact.js +38 -11130
  259. package/dist/hooks/pre-tool-use.js +61 -7233
  260. package/dist/hooks/prompt-submit.js +113 -13358
  261. package/dist/hooks/session-end.js +57 -11503
  262. package/dist/hooks/session-start.js +46 -9423
  263. package/dist/hooks/stop.js +70 -7210
  264. package/dist/hooks/subagent-stop.js +33 -6897
  265. package/dist/hooks/summary-worker.js +86 -8629
  266. package/dist/hooks-KD3N2D7P.js +9 -0
  267. package/dist/imessage-L7WKA2WD.js +7 -0
  268. package/dist/index.js +49 -19391
  269. package/dist/installer-5N24GXFB.js +32 -0
  270. package/dist/installer-QSD76YRY.js +291 -0
  271. package/dist/installer-ZPQUKHU5.js +331 -0
  272. package/dist/intercom-queue-PEEGAJ33.js +19 -0
  273. package/dist/key-backup-status-57UB74DU.js +41 -0
  274. package/dist/lib/agent-config.js +19 -224
  275. package/dist/lib/cloud-sync.js +44 -5398
  276. package/dist/lib/cloudflare-dns.js +7 -111
  277. package/dist/lib/config.js +18 -278
  278. package/dist/lib/consolidation.js +21 -1047
  279. package/dist/lib/crypto.js +7 -45
  280. package/dist/lib/database.js +20 -2932
  281. package/dist/lib/db-daemon-client.js +24 -460
  282. package/dist/lib/db.js +22 -2932
  283. package/dist/lib/device-registry.js +20 -2992
  284. package/dist/lib/embedder.js +14 -822
  285. package/dist/lib/employee-templates.js +21 -1102
  286. package/dist/lib/employees.js +30 -497
  287. package/dist/lib/error-detector.js +9 -149
  288. package/dist/lib/exe-daemon-client.js +16 -570
  289. package/dist/lib/exe-daemon.js +509 -18398
  290. package/dist/lib/file-grep.js +2 -0
  291. package/dist/lib/hybrid-search.js +18 -7674
  292. package/dist/lib/identity-templates.js +2 -0
  293. package/dist/lib/identity.js +13 -309
  294. package/dist/lib/keychain.js +9 -499
  295. package/dist/lib/license.js +21 -549
  296. package/dist/lib/messaging.js +35 -1631
  297. package/dist/lib/post-tool-memory.js +8 -370
  298. package/dist/lib/registry-proxy.js +8 -155
  299. package/dist/lib/reminders.js +11 -231
  300. package/dist/lib/runtime-table.js +7 -20
  301. package/dist/lib/schedules.js +16 -4614
  302. package/dist/lib/session-registry.js +9 -57
  303. package/dist/lib/session-wrappers.js +3 -127
  304. package/dist/lib/skill-learning.js +20 -2101
  305. package/dist/lib/status-brief.js +4 -368
  306. package/dist/lib/store.js +25 -5593
  307. package/dist/lib/task-router.js +12 -254
  308. package/dist/lib/tasks.js +44 -5801
  309. package/dist/lib/tmux-routing.js +45 -5804
  310. package/dist/lib/tmux-status.js +16 -248
  311. package/dist/lib/tmux-transport.js +6 -90
  312. package/dist/lib/token-spend.js +9 -337
  313. package/dist/lib/transport.js +8 -134
  314. package/dist/lib/ws-auth.js +6 -14
  315. package/dist/lib/ws-client.js +4 -22
  316. package/dist/license-gate-NXXDOOAQ.js +14 -0
  317. package/dist/mcp/register-tools.js +90 -32454
  318. package/dist/mcp/server.js +139 -32625
  319. package/dist/mcp/tools/complete-reminder.js +10 -237
  320. package/dist/mcp/tools/create-reminder.js +10 -222
  321. package/dist/mcp/tools/create-task.js +28 -6730
  322. package/dist/mcp/tools/deactivate-behavior.js +13 -476
  323. package/dist/mcp/tools/list-reminders.js +10 -232
  324. package/dist/mcp/tools/list-tasks.js +28 -1571
  325. package/dist/mcp/tools/send-message.js +25 -1672
  326. package/dist/mcp/tools/update-task.js +27 -6123
  327. package/dist/mcp-diagnostics-OOZ3TDPY.js +200 -0
  328. package/dist/memory-cards-RIL5BZHK.js +175 -0
  329. package/dist/memory-queue-JYIJ7TMQ.js +13 -0
  330. package/dist/memory-queue-client-PE7757HU.js +14 -0
  331. package/dist/notifications-CJFULBMN.js +42 -0
  332. package/dist/orchestration-phase-Y2TYNW5H.js +23 -0
  333. package/dist/orchestrator-RXIPT6PZ.js +29 -0
  334. package/dist/permission-presets-WI524OSE.js +25 -0
  335. package/dist/permissions-TYT6YMNZ.js +14 -0
  336. package/dist/pg-ssl-KFHNJPGO.js +7 -0
  337. package/dist/plan-limits-5WY5YK6X.js +27 -0
  338. package/dist/preferences-MW3BYTQ5.js +10 -0
  339. package/dist/project-name-PL2ZDWNU.js +11 -0
  340. package/dist/projection-worker-OY4WYZW6.js +661 -0
  341. package/dist/reranker-LFJ73RRS.js +19 -0
  342. package/dist/review-gate-E6K7QQE5.js +120 -0
  343. package/dist/runtime/index.js +82 -13408
  344. package/dist/self-query-router-IZANO632.js +83 -0
  345. package/dist/session-events-TQ6S5KQN.js +32 -0
  346. package/dist/session-kill-telemetry-46YIJWE2.js +30 -0
  347. package/dist/session-scope-3MYK3YRV.js +34 -0
  348. package/dist/setup-wizard-ZJ7UCRBP.js +12 -0
  349. package/dist/shard-manager-RCFZ6RXY.js +29 -0
  350. package/dist/signal-XN2C7PIG.js +7 -0
  351. package/dist/slack-Z77TFJCK.js +7 -0
  352. package/dist/task-enforcement-337DZI3I.js +252 -0
  353. package/dist/task-scanner-IMIR3T7T.js +11 -0
  354. package/dist/task-scope-MUU4KXE6.js +32 -0
  355. package/dist/tasks-crud-PMLK3MM4.js +53 -0
  356. package/dist/tasks-review-56LVKKNL.js +44 -0
  357. package/dist/telegram-CRPZO7JT.js +7 -0
  358. package/dist/telemetry-SPVGPKU7.js +9 -0
  359. package/dist/tool-capability-index-XNBSDCH3.js +10 -0
  360. package/dist/tool-gates-LGH6CSY4.js +14 -0
  361. package/dist/tool-gates-W7SZCYTX.js +13 -0
  362. package/dist/tool-registry-436LVVLY.js +11 -0
  363. package/dist/tool-telemetry-L77WNAYT.js +15 -0
  364. package/dist/tui/App.js +253 -14668
  365. package/dist/tui-data-SB45REYU.js +161 -0
  366. package/dist/update-check-LZGZISRJ.js +11 -0
  367. package/dist/webhook-VVP7KQVC.js +96 -0
  368. package/dist/whatsapp-J6QNDBGY.js +9 -0
  369. package/dist/whatsapp-accounts-RTJF3LM6.js +15 -0
  370. package/dist/wiki-client-EKCIKCVC.js +136 -0
  371. package/dist/worker-gate-UYNN62GJ.js +19 -0
  372. package/dist/worktree-4T4BPWPN.js +205 -0
  373. package/package.json +1 -1
@@ -1,2311 +1,36 @@
1
1
  #!/usr/bin/env node
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __esm = (fn, res) => function __init() {
7
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
- };
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
- var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
19
- return to;
20
- };
21
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
-
23
- // src/lib/secure-files.ts
24
- import { chmodSync, existsSync, mkdirSync } from "fs";
25
- import { chmod, mkdir } from "fs/promises";
26
- function ensurePrivateDirSync(dirPath) {
27
- mkdirSync(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
28
- try {
29
- chmodSync(dirPath, PRIVATE_DIR_MODE);
30
- } catch {
31
- }
32
- }
33
- function enforcePrivateFileSync(filePath) {
34
- try {
35
- if (existsSync(filePath)) chmodSync(filePath, PRIVATE_FILE_MODE);
36
- } catch {
37
- }
38
- }
39
- var PRIVATE_DIR_MODE, PRIVATE_FILE_MODE;
40
- var init_secure_files = __esm({
41
- "src/lib/secure-files.ts"() {
42
- "use strict";
43
- PRIVATE_DIR_MODE = 448;
44
- PRIVATE_FILE_MODE = 384;
45
- }
46
- });
47
-
48
- // src/lib/config.ts
49
- import { readFile, writeFile } from "fs/promises";
50
- import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
51
- import path from "path";
52
- import os from "os";
53
- function resolveDataDir() {
54
- if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
55
- if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
56
- const newDir = path.join(os.homedir(), ".exe-os");
57
- const legacyDir = path.join(os.homedir(), ".exe-mem");
58
- if (!existsSync2(newDir) && existsSync2(legacyDir)) {
59
- try {
60
- renameSync(legacyDir, newDir);
61
- process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
62
- `);
63
- } catch {
64
- return legacyDir;
65
- }
66
- }
67
- return newDir;
68
- }
69
- var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG;
70
- var init_config = __esm({
71
- "src/lib/config.ts"() {
72
- "use strict";
73
- init_secure_files();
74
- EXE_AI_DIR = resolveDataDir();
75
- DB_PATH = path.join(EXE_AI_DIR, "memories.db");
76
- MODELS_DIR = path.join(EXE_AI_DIR, "models");
77
- CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
78
- LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
79
- CURRENT_CONFIG_VERSION = 1;
80
- DEFAULT_CONFIG = {
81
- config_version: CURRENT_CONFIG_VERSION,
82
- dbPath: DB_PATH,
83
- modelFile: "jina-embeddings-v5-small-q4_k_m.gguf",
84
- embeddingDim: 1024,
85
- batchSize: 20,
86
- flushIntervalMs: 1e4,
87
- autoIngestion: true,
88
- autoRetrieval: true,
89
- searchMode: "hybrid",
90
- hookSearchMode: "hybrid",
91
- fileGrepEnabled: true,
92
- splashEffect: true,
93
- consolidationEnabled: true,
94
- consolidationIntervalMs: 6 * 60 * 60 * 1e3,
95
- consolidationModel: "claude-haiku-4-5-20251001",
96
- consolidationMaxCallsPerRun: 20,
97
- selfQueryRouter: true,
98
- selfQueryModel: "claude-haiku-4-5-20251001",
99
- rerankerEnabled: true,
100
- scalingRoadmap: {
101
- rerankerAutoTrigger: {
102
- enabled: true,
103
- broadQueryMinCardinality: 5e4,
104
- fetchTopK: 150,
105
- returnTopK: 5
106
- }
107
- },
108
- graphRagEnabled: true,
109
- wikiEnabled: false,
110
- wikiUrl: "",
111
- wikiApiKey: "",
112
- wikiSyncIntervalMs: 30 * 60 * 1e3,
113
- wikiWorkspaceMapping: {},
114
- wikiAutoUpdate: true,
115
- wikiAutoUpdateThreshold: 0.5,
116
- wikiAutoUpdateCreateNew: true,
117
- skillLearning: true,
118
- skillThreshold: 3,
119
- skillModel: "claude-haiku-4-5-20251001",
120
- exeHeartbeat: {
121
- enabled: true,
122
- intervalSeconds: 60,
123
- staleInProgressThresholdHours: 2
124
- },
125
- sessionLifecycle: {
126
- idleKillEnabled: true,
127
- idleKillTicksRequired: 3,
128
- idleKillIntercomAckWindowMs: 1e4,
129
- maxAutoInstances: 10
130
- },
131
- autoUpdate: {
132
- checkOnBoot: true,
133
- autoInstall: false,
134
- checkIntervalMs: 24 * 60 * 60 * 1e3
135
- },
136
- support: {
137
- bugReportEndpoint: "https://askexe.com/v1/support/bug-reports"
138
- },
139
- orchestration: {
140
- phase: "phase_1_coo",
141
- phaseSetBy: "default"
142
- }
143
- };
144
- }
145
- });
146
-
147
- // src/lib/runtime-table.ts
148
- var RUNTIME_TABLE, DEFAULT_RUNTIME;
149
- var init_runtime_table = __esm({
150
- "src/lib/runtime-table.ts"() {
151
- "use strict";
152
- RUNTIME_TABLE = {
153
- codex: {
154
- binary: "codex",
155
- launchMode: "interactive",
156
- autoApproveFlag: "--dangerously-bypass-approvals-and-sandbox",
157
- inlineFlag: "--no-alt-screen",
158
- apiKeyEnv: "OPENAI_API_KEY",
159
- defaultModel: "gpt-5.5"
160
- },
161
- opencode: {
162
- binary: "opencode",
163
- launchMode: "exec",
164
- autoApproveFlag: "--dangerously-skip-permissions",
165
- inlineFlag: "",
166
- apiKeyEnv: "ANTHROPIC_API_KEY",
167
- defaultModel: "anthropic/claude-sonnet-4-6"
168
- }
169
- };
170
- DEFAULT_RUNTIME = "claude";
171
- }
172
- });
173
-
174
- // src/lib/agent-config.ts
175
- var agent_config_exports = {};
176
- __export(agent_config_exports, {
177
- AGENT_CONFIG_PATH: () => AGENT_CONFIG_PATH,
178
- DEFAULT_MODELS: () => DEFAULT_MODELS,
179
- KNOWN_RUNTIMES: () => KNOWN_RUNTIMES,
180
- RUNTIME_LABELS: () => RUNTIME_LABELS,
181
- clearAgentRuntime: () => clearAgentRuntime,
182
- getAgentRuntime: () => getAgentRuntime,
183
- loadAgentConfig: () => loadAgentConfig,
184
- normalizeCcModelName: () => normalizeCcModelName,
185
- saveAgentConfig: () => saveAgentConfig,
186
- setAgentMcps: () => setAgentMcps,
187
- setAgentRuntime: () => setAgentRuntime
188
- });
189
- import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3 } from "fs";
190
- import path2 from "path";
191
- function loadAgentConfig() {
192
- if (!existsSync3(AGENT_CONFIG_PATH)) return {};
193
- try {
194
- return JSON.parse(readFileSync2(AGENT_CONFIG_PATH, "utf-8"));
195
- } catch {
196
- return {};
197
- }
198
- }
199
- function saveAgentConfig(config) {
200
- const dir = path2.dirname(AGENT_CONFIG_PATH);
201
- ensurePrivateDirSync(dir);
202
- writeFileSync(AGENT_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
203
- enforcePrivateFileSync(AGENT_CONFIG_PATH);
204
- }
205
- function getAgentRuntime(agentId) {
206
- const config = loadAgentConfig();
207
- const entry = config[agentId];
208
- if (entry) return entry;
209
- const orgDefault = config["default"];
210
- if (orgDefault) return orgDefault;
211
- return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
212
- }
213
- function normalizeCcModelName(model) {
214
- let ccModel = model.replace(/(\d+)\.(\d+)/g, "$1-$2");
215
- if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
216
- ccModel += "[1m]";
217
- }
218
- return ccModel;
219
- }
220
- function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
221
- const knownModels = KNOWN_RUNTIMES[runtime];
222
- if (!knownModels) {
223
- return {
224
- ok: false,
225
- error: `Unknown runtime "${runtime}". Valid: ${Object.keys(KNOWN_RUNTIMES).join(", ")}`
226
- };
227
- }
228
- if (!knownModels.includes(model)) {
229
- return {
230
- ok: false,
231
- error: `Unknown model "${model}" for runtime "${runtime}". Valid: ${knownModels.join(", ")}`
232
- };
233
- }
234
- const config = loadAgentConfig();
235
- const existing = config[agentId];
236
- const entry = { runtime, model };
237
- if (reasoning_effort) entry.reasoning_effort = reasoning_effort;
238
- if (mcps !== void 0) {
239
- entry.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
240
- } else if (existing?.mcps) {
241
- entry.mcps = existing.mcps;
242
- }
243
- config[agentId] = entry;
244
- saveAgentConfig(config);
245
- return { ok: true };
246
- }
247
- function setAgentMcps(agentId, mcps) {
248
- const config = loadAgentConfig();
249
- const existing = config[agentId] ?? getAgentRuntime(agentId);
250
- existing.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
251
- config[agentId] = existing;
252
- saveAgentConfig(config);
253
- return { ok: true };
254
- }
255
- function clearAgentRuntime(agentId) {
256
- const config = loadAgentConfig();
257
- delete config[agentId];
258
- saveAgentConfig(config);
259
- }
260
- var AGENT_CONFIG_PATH, KNOWN_RUNTIMES, RUNTIME_LABELS, DEFAULT_MODELS;
261
- var init_agent_config = __esm({
262
- "src/lib/agent-config.ts"() {
263
- "use strict";
264
- init_config();
265
- init_runtime_table();
266
- init_secure_files();
267
- AGENT_CONFIG_PATH = path2.join(EXE_AI_DIR, "agent-config.json");
268
- KNOWN_RUNTIMES = {
269
- claude: ["claude-opus-4.6", "claude-opus-4", "claude-sonnet-4.6", "claude-sonnet-4", "claude-haiku-4.5"],
270
- codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
271
- opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
272
- };
273
- RUNTIME_LABELS = {
274
- claude: "Claude Code (Anthropic)",
275
- codex: "Codex (OpenAI)",
276
- opencode: "OpenCode (open source)"
277
- };
278
- DEFAULT_MODELS = {
279
- claude: "claude-opus-4.6",
280
- codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
281
- opencode: RUNTIME_TABLE.opencode?.defaultModel ?? "anthropic/claude-sonnet-4-6"
282
- };
283
- }
284
- });
285
-
286
- // src/lib/employees.ts
287
- var employees_exports = {};
288
- __export(employees_exports, {
289
- COORDINATOR_ROLE: () => COORDINATOR_ROLE,
290
- DEFAULT_COORDINATOR_TEMPLATE_NAME: () => DEFAULT_COORDINATOR_TEMPLATE_NAME,
291
- EMPLOYEES_PATH: () => EMPLOYEES_PATH,
292
- addEmployee: () => addEmployee,
293
- baseAgentName: () => baseAgentName,
294
- canCoordinate: () => canCoordinate,
295
- getCoordinatorEmployee: () => getCoordinatorEmployee,
296
- getCoordinatorName: () => getCoordinatorName,
297
- getEmployee: () => getEmployee,
298
- getEmployeeByRole: () => getEmployeeByRole,
299
- getEmployeeNamesByRole: () => getEmployeeNamesByRole,
300
- hasRole: () => hasRole,
301
- hireEmployee: () => hireEmployee,
302
- isCoordinatorName: () => isCoordinatorName,
303
- isCoordinatorRole: () => isCoordinatorRole,
304
- isMultiInstance: () => isMultiInstance,
305
- loadEmployees: () => loadEmployees,
306
- loadEmployeesSync: () => loadEmployeesSync,
307
- normalizeRole: () => normalizeRole,
308
- normalizeRosterCase: () => normalizeRosterCase,
309
- registerBinSymlinks: () => registerBinSymlinks,
310
- saveEmployees: () => saveEmployees,
311
- validateEmployeeName: () => validateEmployeeName
312
- });
313
- import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
314
- import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync3, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
315
- import { execSync } from "child_process";
316
- import path3 from "path";
317
- import os2 from "os";
318
- function normalizeRole(role) {
319
- return (role ?? "").trim().toLowerCase();
320
- }
321
- function isCoordinatorRole(role) {
322
- return normalizeRole(role) === normalizeRole(COORDINATOR_ROLE);
323
- }
324
- function getCoordinatorEmployee(employees) {
325
- return employees.find((e) => isCoordinatorRole(e.role));
326
- }
327
- function getCoordinatorName(employees = loadEmployeesSync()) {
328
- return getCoordinatorEmployee(employees)?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
329
- }
330
- function isCoordinatorName(agentName, employees = loadEmployeesSync()) {
331
- if (!agentName) return false;
332
- return agentName.toLowerCase() === getCoordinatorName(employees).toLowerCase();
333
- }
334
- function canCoordinate(agentName, agentRole, employees = loadEmployeesSync()) {
335
- return agentName === "default" || isCoordinatorRole(agentRole) || isCoordinatorName(agentName, employees);
336
- }
337
- function validateEmployeeName(name) {
338
- if (!name) {
339
- return { valid: false, error: "Name is required" };
340
- }
341
- if (name.length > 32) {
342
- return { valid: false, error: "Name must be 32 characters or fewer" };
343
- }
344
- if (!/^[a-z][a-z0-9]*$/.test(name)) {
345
- return {
346
- valid: false,
347
- error: "Name must start with a letter and contain only lowercase alphanumeric characters"
348
- };
349
- }
350
- return { valid: true };
351
- }
352
- async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
353
- if (!existsSync4(employeesPath)) {
354
- return [];
355
- }
356
- const raw = await readFile2(employeesPath, "utf-8");
357
- try {
358
- return JSON.parse(raw);
359
- } catch {
360
- return [];
361
- }
362
- }
363
- async function saveEmployees(employees, employeesPath = EMPLOYEES_PATH) {
364
- await mkdir2(path3.dirname(employeesPath), { recursive: true });
365
- await writeFile2(employeesPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
366
- }
367
- function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
368
- if (!existsSync4(employeesPath)) return [];
369
- try {
370
- return JSON.parse(readFileSync3(employeesPath, "utf-8"));
371
- } catch {
372
- return [];
373
- }
374
- }
375
- function getEmployee(employees, name) {
376
- return employees.find((e) => e.name.toLowerCase() === name.toLowerCase());
377
- }
378
- function getEmployeeByRole(employees, role) {
379
- const lower = role.toLowerCase();
380
- return employees.find((e) => e.role.toLowerCase() === lower);
381
- }
382
- function getEmployeeNamesByRole(employees, role) {
383
- const lower = role.toLowerCase();
384
- return employees.filter((e) => e.role.toLowerCase() === lower).map((e) => e.name);
385
- }
386
- function hasRole(agentName, role) {
387
- const employees = loadEmployeesSync();
388
- const emp = getEmployee(employees, agentName);
389
- return emp ? emp.role.toLowerCase() === role.toLowerCase() : false;
390
- }
391
- function baseAgentName(name, employees) {
392
- const match = name.match(/^([a-zA-Z]+)\d+$/);
393
- if (!match) return name;
394
- const base = match[1];
395
- const roster = employees ?? loadEmployeesSync();
396
- if (getEmployee(roster, base)) return base;
397
- return name;
398
- }
399
- function isMultiInstance(agentName, employees) {
400
- const roster = employees ?? loadEmployeesSync();
401
- const emp = getEmployee(roster, agentName);
402
- if (!emp) return false;
403
- return MULTI_INSTANCE_ROLES.has(emp.role.toLowerCase());
404
- }
405
- function addEmployee(employees, employee) {
406
- const { systemPrompt: _legacyPrompt, ...rest } = employee;
407
- const normalized = { ...rest, name: employee.name.toLowerCase() };
408
- if (employees.some((e) => e.name.toLowerCase() === normalized.name)) {
409
- throw new Error(`Employee '${normalized.name}' already exists`);
410
- }
411
- return [...employees, normalized];
412
- }
413
- function appendToCoordinatorTeam(employee) {
414
- const coordinator = getCoordinatorEmployee(loadEmployeesSync());
415
- if (!coordinator) return;
416
- const idPath = path3.join(IDENTITY_DIR, `${coordinator.name}.md`);
417
- if (!existsSync4(idPath)) return;
418
- const content = readFileSync3(idPath, "utf-8");
419
- if (content.includes(`**${capitalize(employee.name)}`)) return;
420
- const teamMatch = content.match(TEAM_SECTION_RE);
421
- if (!teamMatch || teamMatch.index === void 0) return;
422
- const afterTeam = content.slice(teamMatch.index + teamMatch[0].length);
423
- const nextHeading = afterTeam.match(/\n## /);
424
- const entry = `
425
- **${capitalize(employee.name)} (${employee.role}):** Newly hired. Update this description as the role develops.
426
- `;
427
- let updated;
428
- if (nextHeading && nextHeading.index !== void 0) {
429
- const insertAt = teamMatch.index + teamMatch[0].length + nextHeading.index;
430
- updated = content.slice(0, insertAt) + entry + content.slice(insertAt);
431
- } else {
432
- updated = content.trimEnd() + "\n" + entry;
433
- }
434
- writeFileSync2(idPath, updated, "utf-8");
435
- }
436
- function capitalize(s) {
437
- return s.charAt(0).toUpperCase() + s.slice(1);
438
- }
439
- async function hireEmployee(employee) {
440
- const employees = await loadEmployees();
441
- const updated = addEmployee(employees, employee);
442
- await saveEmployees(updated);
443
- try {
444
- appendToCoordinatorTeam(employee);
445
- } catch {
446
- }
447
- try {
448
- const { loadAgentConfig: loadAgentConfig2, saveAgentConfig: saveAgentConfig2 } = await Promise.resolve().then(() => (init_agent_config(), agent_config_exports));
449
- const config = loadAgentConfig2();
450
- const name = employee.name.toLowerCase();
451
- if (!config[name] && config["default"]) {
452
- config[name] = { ...config["default"] };
453
- saveAgentConfig2(config);
454
- }
455
- } catch {
456
- }
457
- return updated;
458
- }
459
- async function normalizeRosterCase(rosterPath) {
460
- const employees = await loadEmployees(rosterPath);
461
- let changed = false;
462
- for (const emp of employees) {
463
- if (emp.name !== emp.name.toLowerCase()) {
464
- const oldName = emp.name;
465
- emp.name = emp.name.toLowerCase();
466
- changed = true;
467
- try {
468
- const identityDir = path3.join(os2.homedir(), ".exe-os", "identity");
469
- const oldPath = path3.join(identityDir, `${oldName}.md`);
470
- const newPath = path3.join(identityDir, `${emp.name}.md`);
471
- if (existsSync4(oldPath) && !existsSync4(newPath)) {
472
- renameSync2(oldPath, newPath);
473
- } else if (existsSync4(oldPath) && oldPath !== newPath) {
474
- const content = readFileSync3(oldPath, "utf-8");
475
- writeFileSync2(newPath, content, "utf-8");
476
- if (oldPath.toLowerCase() !== newPath.toLowerCase()) {
477
- unlinkSync(oldPath);
478
- }
479
- }
480
- } catch {
481
- }
482
- }
483
- }
484
- if (changed) {
485
- await saveEmployees(employees, rosterPath);
486
- }
487
- return changed;
488
- }
489
- function findExeBin() {
490
- try {
491
- return execSync(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
492
- } catch {
493
- return null;
494
- }
495
- }
496
- function registerBinSymlinks(name) {
497
- const created = [];
498
- const skipped = [];
499
- const errors = [];
500
- const exeBinPath = findExeBin();
501
- if (!exeBinPath) {
502
- errors.push("Could not find 'exe-os' in PATH");
503
- return { created, skipped, errors };
504
- }
505
- const binDir = path3.dirname(exeBinPath);
506
- let target;
507
- try {
508
- target = readlinkSync(exeBinPath);
509
- } catch {
510
- errors.push("Could not read 'exe' symlink");
511
- return { created, skipped, errors };
512
- }
513
- for (const suffix of ["", "-opencode"]) {
514
- const linkName = `${name}${suffix}`;
515
- const linkPath = path3.join(binDir, linkName);
516
- if (existsSync4(linkPath)) {
517
- skipped.push(linkName);
518
- continue;
519
- }
520
- try {
521
- symlinkSync(target, linkPath);
522
- created.push(linkName);
523
- } catch (err) {
524
- errors.push(`${linkName}: ${err instanceof Error ? err.message : String(err)}`);
525
- }
526
- }
527
- return { created, skipped, errors };
528
- }
529
- var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, MULTI_INSTANCE_ROLES, IDENTITY_DIR, TEAM_SECTION_RE;
530
- var init_employees = __esm({
531
- "src/lib/employees.ts"() {
532
- "use strict";
533
- init_config();
534
- EMPLOYEES_PATH = path3.join(EXE_AI_DIR, "exe-employees.json");
535
- DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
536
- COORDINATOR_ROLE = "COO";
537
- MULTI_INSTANCE_ROLES = /* @__PURE__ */ new Set(["principal engineer", "content production specialist", "staff code reviewer"]);
538
- IDENTITY_DIR = path3.join(EXE_AI_DIR, "identity");
539
- TEAM_SECTION_RE = /^## Team\b.*$/m;
540
- }
541
- });
542
-
543
- // src/lib/agent-symlinks.ts
544
- import os3 from "os";
545
- import path4 from "path";
546
2
  import {
547
- existsSync as existsSync5,
548
- lstatSync,
549
- mkdirSync as mkdirSync2,
550
- readlinkSync as readlinkSync2,
551
- symlinkSync as symlinkSync2
552
- } from "fs";
553
- function claudeAgentsDir(homeDir) {
554
- return path4.join(homeDir, ".claude", "agents");
555
- }
556
- function identitySourcePath(homeDir, agentId) {
557
- return path4.join(homeDir, ".exe-os", "identity", `${agentId}.md`);
558
- }
559
- function claudeAgentLinkPath(homeDir, agentId) {
560
- return path4.join(claudeAgentsDir(homeDir), `${agentId}.md`);
561
- }
562
- function ensureAgentSymlink(agentId, homeDir = os3.homedir()) {
563
- const target = identitySourcePath(homeDir, agentId);
564
- const link = claudeAgentLinkPath(homeDir, agentId);
565
- mkdirSync2(claudeAgentsDir(homeDir), { recursive: true });
566
- if (existsSync5(link)) {
567
- let stat;
568
- try {
569
- stat = lstatSync(link);
570
- } catch {
571
- return { agentId, action: "conflict", target, link, conflict: "stat_failed" };
572
- }
573
- if (!stat.isSymbolicLink()) {
574
- return { agentId, action: "conflict", target, link, conflict: "regular_file" };
575
- }
576
- let currentTarget;
577
- try {
578
- currentTarget = readlinkSync2(link);
579
- } catch {
580
- return { agentId, action: "conflict", target, link, conflict: "readlink_failed" };
581
- }
582
- if (currentTarget === target) {
583
- return { agentId, action: "already_correct", target, link };
584
- }
585
- return { agentId, action: "conflict", target, link, conflict: `points_to:${currentTarget}` };
586
- }
587
- try {
588
- symlinkSync2(target, link);
589
- } catch (err) {
590
- return {
591
- agentId,
592
- action: "conflict",
593
- target,
594
- link,
595
- conflict: err instanceof Error ? err.message : String(err)
596
- };
597
- }
598
- return { agentId, action: "created", target, link };
599
- }
600
- async function ensureAllAgentSymlinks(homeDir = os3.homedir()) {
601
- const employees = await loadEmployees();
602
- return employees.map((emp) => ensureAgentSymlink(emp.name, homeDir));
603
- }
604
- var init_agent_symlinks = __esm({
605
- "src/lib/agent-symlinks.ts"() {
606
- "use strict";
607
- init_employees();
608
- }
609
- });
610
-
611
- // src/lib/mcp-prefix.ts
612
- var MCP_PRIMARY_KEY, MCP_LEGACY_KEY, MCP_TOOL_PREFIXES;
613
- var init_mcp_prefix = __esm({
614
- "src/lib/mcp-prefix.ts"() {
615
- "use strict";
616
- MCP_PRIMARY_KEY = "exe-os";
617
- MCP_LEGACY_KEY = "exe-mem";
618
- MCP_TOOL_PREFIXES = [
619
- `mcp__${MCP_PRIMARY_KEY}__`,
620
- `mcp__${MCP_LEGACY_KEY}__`
621
- ];
622
- }
623
- });
624
-
625
- // src/lib/preferences.ts
626
- import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
627
- import path5 from "path";
628
- import os4 from "os";
629
- function loadPreferences(homeDir = os4.homedir()) {
630
- const configPath = path5.join(homeDir, ".exe-os", "config.json");
631
- if (!existsSync6(configPath)) return {};
632
- try {
633
- const config = JSON.parse(readFileSync4(configPath, "utf-8"));
634
- return config.preferences ?? {};
635
- } catch {
636
- return {};
637
- }
638
- }
639
- var init_preferences = __esm({
640
- "src/lib/preferences.ts"() {
641
- "use strict";
642
- init_secure_files();
643
- }
644
- });
645
-
646
- // src/adapters/mcp-http-config.ts
647
- import { chmodSync as chmodSync2, existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
648
- import { randomBytes } from "crypto";
649
- import path6 from "path";
650
- import os5 from "os";
651
- function resolveDefaultAgentId() {
652
- if (process.env.AGENT_ID && process.env.AGENT_ID !== "default") return process.env.AGENT_ID;
653
- try {
654
- const { loadEmployeesSync: loadEmployeesSync2 } = (init_employees(), __toCommonJS(employees_exports));
655
- const coo = loadEmployeesSync2().find((e) => e.role === "COO");
656
- if (coo) return coo.name;
657
- } catch {
658
- }
659
- return "exe";
660
- }
661
- function mcpHttpPort() {
662
- return process.env.EXE_MCP_PORT || DEFAULT_MCP_HTTP_PORT;
663
- }
664
- function mcpHttpUrl() {
665
- return `http://127.0.0.1:${mcpHttpPort()}/mcp`;
666
- }
667
- function readOrCreateDaemonToken(homeDir = os5.homedir()) {
668
- const exeDir = path6.join(homeDir, ".exe-os");
669
- const tokenPath = path6.join(exeDir, "exed.token");
670
- if (existsSync7(tokenPath)) {
671
- try {
672
- const token2 = readFileSync5(tokenPath, "utf-8").trim();
673
- if (/^[a-f0-9]{64}$/i.test(token2)) return token2;
674
- } catch {
675
- }
676
- }
677
- const token = randomBytes(32).toString("hex");
678
- mkdirSync3(exeDir, { recursive: true });
679
- writeFileSync4(tokenPath, `${token}
680
- `, "utf-8");
681
- try {
682
- chmodSync2(tokenPath, 384);
683
- } catch {
684
- }
685
- return token;
686
- }
687
- function buildMcpHttpHeaders(homeDir = os5.homedir(), opts = {}) {
688
- const agentId = opts.useShellPlaceholders ? "${AGENT_ID:-exe}" : opts.agentId ?? DEFAULT_MCP_HTTP_AGENT_ID;
689
- const agentRole = opts.useShellPlaceholders ? "${AGENT_ROLE:-COO}" : opts.agentRole ?? DEFAULT_MCP_HTTP_AGENT_ROLE;
690
- const sessionName = opts.useShellPlaceholders ? "" : process.env.EXE_SESSION_NAME ?? "";
691
- const headers = {
692
- Authorization: `Bearer ${readOrCreateDaemonToken(homeDir)}`,
693
- "X-Agent-Id": agentId,
694
- "X-Agent-Role": agentRole
695
- };
696
- if (sessionName) headers["X-Exe-Session"] = sessionName;
697
- return headers;
698
- }
699
- function buildClaudeHttpMcpEntry(homeDir = os5.homedir()) {
700
- return {
701
- type: "http",
702
- url: mcpHttpUrl(),
703
- headers: buildMcpHttpHeaders(homeDir, { useShellPlaceholders: true })
704
- };
705
- }
706
- var DEFAULT_MCP_HTTP_PORT, DEFAULT_MCP_HTTP_AGENT_ID, DEFAULT_MCP_HTTP_AGENT_ROLE;
707
- var init_mcp_http_config = __esm({
708
- "src/adapters/mcp-http-config.ts"() {
709
- "use strict";
710
- DEFAULT_MCP_HTTP_PORT = "48739";
711
- DEFAULT_MCP_HTTP_AGENT_ID = resolveDefaultAgentId();
712
- DEFAULT_MCP_HTTP_AGENT_ROLE = "COO";
713
- }
714
- });
715
-
716
- // src/adapters/runtime-hook-manifest.ts
717
- function isLegacyHomeDirHookCommand(command) {
718
- return LEGACY_HOME_DIR_HOOK_PATTERNS.some((pattern) => command.includes(pattern));
719
- }
720
- function commandHasAnyMarker(command, markers) {
721
- return markers.some((marker) => command.includes(marker));
722
- }
723
- function isLegacySplitPostToolCommand(command) {
724
- return commandHasAnyMarker(command, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS);
725
- }
726
- var EXE_HOOKS, EXE_HOOK_MANIFEST, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS, LEGACY_HOME_DIR_HOOK_PATTERNS;
727
- var init_runtime_hook_manifest = __esm({
728
- "src/adapters/runtime-hook-manifest.ts"() {
729
- "use strict";
730
- EXE_HOOKS = {
731
- postToolCombined: "dist/hooks/post-tool-combined.js",
732
- sessionStart: "dist/hooks/session-start.js",
733
- promptSubmit: "dist/hooks/prompt-submit.js",
734
- heartbeat: "dist/hooks/exe-heartbeat-hook.js",
735
- stop: "dist/hooks/stop.js",
736
- preToolUse: "dist/hooks/pre-tool-use.js",
737
- subagentStop: "dist/hooks/subagent-stop.js",
738
- preCompact: "dist/hooks/pre-compact.js",
739
- postCompact: "dist/hooks/post-compact.js",
740
- sessionEnd: "dist/hooks/session-end.js",
741
- notification: "dist/hooks/notification.js",
742
- instructionsLoaded: "dist/hooks/instructions-loaded.js"
743
- };
744
- EXE_HOOK_MANIFEST = [
745
- {
746
- key: "postToolCombined",
747
- event: "PostToolUse",
748
- commandMarker: EXE_HOOKS.postToolCombined,
749
- owner: "exe-os",
750
- purpose: "Single PostToolUse entrypoint for ingestion, error recall, summaries, and bug detection.",
751
- runtimes: ["claude", "codex", "opencode"],
752
- checkpointRole: "none"
753
- },
754
- {
755
- key: "sessionStart",
756
- event: "SessionStart",
757
- commandMarker: EXE_HOOKS.sessionStart,
758
- owner: "exe-os",
759
- purpose: "Loads agent identity, procedures, and boot context.",
760
- runtimes: ["claude", "codex", "opencode"],
761
- checkpointRole: "none"
762
- },
763
- {
764
- key: "promptSubmit",
765
- event: "UserPromptSubmit",
766
- commandMarker: EXE_HOOKS.promptSubmit,
767
- owner: "exe-os",
768
- purpose: "Injects current tasks, pending reviews, and local context before each prompt.",
769
- runtimes: ["claude", "codex", "opencode"],
770
- checkpointRole: "none"
771
- },
772
- {
773
- key: "heartbeat",
774
- event: "UserPromptSubmit",
775
- commandMarker: EXE_HOOKS.heartbeat,
776
- owner: "exe-os",
777
- purpose: "Lightweight heartbeat/status sidecar for Claude Code sessions.",
778
- runtimes: ["claude"],
779
- checkpointRole: "none"
780
- },
781
- {
782
- key: "stop",
783
- event: "Stop",
784
- commandMarker: EXE_HOOKS.stop,
785
- owner: "exe-os",
786
- purpose: "Finalizes task state, capacity signals, and emergency checkpointing.",
787
- runtimes: ["claude", "codex", "opencode"],
788
- checkpointRole: "capacity_checkpoint"
789
- },
790
- {
791
- key: "preToolUse",
792
- event: "PreToolUse",
793
- commandMarker: EXE_HOOKS.preToolUse,
794
- owner: "exe-os",
795
- purpose: "Preflight guardrails before shell/tool execution.",
796
- runtimes: ["claude", "codex", "opencode"],
797
- checkpointRole: "none"
798
- },
799
- {
800
- key: "subagentStop",
801
- event: "SubagentStop",
802
- commandMarker: EXE_HOOKS.subagentStop,
803
- owner: "exe-os",
804
- purpose: "Captures subagent completion context.",
805
- runtimes: ["claude"],
806
- checkpointRole: "none"
807
- },
808
- {
809
- key: "preCompact",
810
- event: "PreCompact",
811
- commandMarker: EXE_HOOKS.preCompact,
812
- owner: "exe-os",
813
- purpose: "Writes active-task snapshot and compaction recovery context.",
814
- runtimes: ["claude"],
815
- checkpointRole: "recovery_context"
816
- },
817
- {
818
- key: "postCompact",
819
- event: "PostCompact",
820
- commandMarker: EXE_HOOKS.postCompact,
821
- owner: "exe-os",
822
- purpose: "Rehydrates recovery context after compaction.",
823
- runtimes: ["claude"],
824
- checkpointRole: "recovery_context"
825
- },
826
- {
827
- key: "sessionEnd",
828
- event: "SessionEnd",
829
- commandMarker: EXE_HOOKS.sessionEnd,
830
- owner: "exe-os",
831
- purpose: "Stores session-end checkpoint and triages orphaned in-progress tasks.",
832
- runtimes: ["claude"],
833
- checkpointRole: "session_summary"
834
- },
835
- {
836
- key: "notification",
837
- event: "Notification",
838
- commandMarker: EXE_HOOKS.notification,
839
- owner: "exe-os",
840
- purpose: "Captures runtime notifications and nudges.",
841
- runtimes: ["claude"],
842
- checkpointRole: "none"
843
- },
844
- {
845
- key: "instructionsLoaded",
846
- event: "InstructionsLoaded",
847
- commandMarker: EXE_HOOKS.instructionsLoaded,
848
- owner: "exe-os",
849
- purpose: "Applies runtime instruction post-processing.",
850
- runtimes: ["claude"],
851
- checkpointRole: "none"
852
- }
853
- ];
854
- LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS = [
855
- "dist/hooks/ingest.js",
856
- "dist/hooks/error-recall.js",
857
- "dist/hooks/ingest-worker.js"
858
- ];
859
- LEGACY_HOME_DIR_HOOK_PATTERNS = [
860
- ".exe-os/hooks/",
861
- // Old hook storage path (pre-npm-package era)
862
- "log-prefix.js",
863
- // Removed hook from early versions
864
- "approval-bridge.log"
865
- // Removed log redirect from early versions
866
- ];
867
- }
868
- });
869
-
870
- // src/adapters/claude/installer.ts
871
- import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir, rm } from "fs/promises";
872
- import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync5, copyFileSync, mkdirSync as mkdirSync4 } from "fs";
873
- import { createHash } from "crypto";
874
- import path7 from "path";
875
- import os6 from "os";
876
- import { execSync as execSync2 } from "child_process";
877
- import { fileURLToPath } from "url";
878
- function resolvePackageRoot() {
879
- const thisFile = fileURLToPath(import.meta.url);
880
- let dir = path7.dirname(thisFile);
881
- const root = path7.parse(dir).root;
882
- while (dir !== root) {
883
- const pkgPath = path7.join(dir, "package.json");
884
- if (existsSync8(pkgPath)) {
885
- try {
886
- const pkg = JSON.parse(readFileSync6(pkgPath, "utf-8"));
887
- if (pkg.name === "@askexenow/exe-os" || pkg.name === "exe-os") return dir;
888
- } catch {
889
- }
890
- }
891
- dir = path7.dirname(dir);
892
- }
893
- return path7.resolve(path7.dirname(thisFile), "..", "..", "..");
894
- }
895
- async function copySlashCommands(packageRoot, homeDir = os6.homedir()) {
896
- let copied = 0;
897
- let skipped = 0;
898
- const skillsBase = path7.join(homeDir, ".claude", "skills");
899
- const deprecatedExeLink = path7.join(skillsBase, "exe-link");
900
- if (existsSync8(deprecatedExeLink)) {
901
- await rm(deprecatedExeLink, { recursive: true, force: true });
902
- }
903
- const exeDir = path7.join(packageRoot, "src", "commands", "exe");
904
- if (existsSync8(exeDir)) {
905
- const entries = await readdir(exeDir);
906
- const mdFiles = entries.filter((f) => f.endsWith(".md"));
907
- for (const file of mdFiles) {
908
- const name = file.replace(".md", "");
909
- const destDir = path7.join(skillsBase, `exe-${name}`);
910
- await mkdir3(destDir, { recursive: true });
911
- const srcPath = path7.join(exeDir, file);
912
- const destPath = path7.join(destDir, "SKILL.md");
913
- const result = await copyAsSkill(srcPath, destPath, `exe-${name}`);
914
- if (result) copied++;
915
- else skipped++;
916
- }
917
- }
918
- const topLevelSrc = path7.join(packageRoot, "src", "commands", "exe.md");
919
- if (existsSync8(topLevelSrc)) {
920
- const destDir = path7.join(skillsBase, "exe");
921
- await mkdir3(destDir, { recursive: true });
922
- const destPath = path7.join(destDir, "SKILL.md");
923
- const result = await copyAsSkill(topLevelSrc, destPath, "exe");
924
- if (result) copied++;
925
- else skipped++;
926
- }
927
- return { copied, skipped };
928
- }
929
- async function copyAsSkill(srcPath, destPath, skillName) {
930
- let content = await readFile3(srcPath, "utf-8");
931
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
932
- if (fmMatch?.[1]) {
933
- const fm = fmMatch[1];
934
- if (fm.includes("name:")) {
935
- content = content.replace(
936
- /^(---\n[\s\S]*?)name:\s*[^\n]+/,
937
- `$1name: ${skillName}`
938
- );
939
- } else {
940
- content = content.replace(/^---\n/, `---
941
- name: ${skillName}
942
- `);
943
- }
944
- }
945
- if (existsSync8(destPath)) {
946
- const existing = await readFile3(destPath, "utf-8");
947
- if (existing === content) return false;
948
- }
949
- await writeFile3(destPath, content);
950
- return true;
951
- }
952
- function readJsonFile(filePath) {
953
- try {
954
- return JSON.parse(readFileSync6(filePath, "utf-8"));
955
- } catch {
956
- return null;
957
- }
958
- }
959
- function findAncestorMcpJsons(startDir, homeDir) {
960
- const files = [];
961
- let dir = path7.resolve(startDir);
962
- const root = path7.parse(dir).root;
963
- const stop = path7.resolve(homeDir);
964
- while (dir !== root) {
965
- const candidate = path7.join(dir, ".mcp.json");
966
- if (existsSync8(candidate)) files.push(candidate);
967
- if (dir === stop) break;
968
- dir = path7.dirname(dir);
969
- }
970
- return files;
971
- }
972
- function pathApplies(projectPath, cwd) {
973
- const project = path7.resolve(projectPath);
974
- const current = path7.resolve(cwd);
975
- return current === project || current.startsWith(project + path7.sep);
976
- }
977
- function detectMcpNameCollisions(homeDir = os6.homedir(), cwd = process.cwd()) {
978
- const claudeJsonPath = path7.join(homeDir, ".claude.json");
979
- if (!existsSync8(claudeJsonPath)) return [];
980
- const claudeJson = readJsonFile(claudeJsonPath);
981
- if (!claudeJson?.projects) return [];
982
- const collisions = [];
983
- const mcpJsons = findAncestorMcpJsons(cwd, homeDir);
984
- if (mcpJsons.length === 0) return [];
985
- for (const [projectPath, projectConfig] of Object.entries(claudeJson.projects)) {
986
- if (!pathApplies(projectPath, cwd)) continue;
987
- const projectServerNames = new Set(Object.keys(projectConfig.mcpServers ?? {}));
988
- if (projectServerNames.size === 0) continue;
989
- const enabled = new Set(projectConfig.enabledMcpjsonServers ?? []);
990
- for (const mcpJsonPath of mcpJsons) {
991
- const mcpJson = readJsonFile(mcpJsonPath);
992
- const mcpServerNames = Object.keys(mcpJson?.mcpServers ?? {});
993
- for (const serverName of mcpServerNames) {
994
- if (!projectServerNames.has(serverName)) continue;
995
- collisions.push({
996
- mcpJsonPath,
997
- projectPath,
998
- serverName,
999
- disabledInMcpJson: !enabled.has(serverName)
1000
- });
1001
- }
1002
- }
1003
- }
1004
- return collisions;
1005
- }
1006
- function buildStdioMcpEntry(packageRoot) {
1007
- return {
1008
- type: "stdio",
1009
- command: "node",
1010
- args: [path7.join(packageRoot, "dist", "mcp", "server.js")],
1011
- env: {}
1012
- };
1013
- }
1014
- function mcpTransportMode() {
1015
- const value = process.env.EXE_OS_MCP_TRANSPORT?.trim().toLowerCase();
1016
- if (value === "stdio") return "stdio";
1017
- if (value === "http") return "http";
1018
- const totalGB = os6.totalmem() / (1024 * 1024 * 1024);
1019
- if (totalGB <= 8) return "stdio";
1020
- return "http";
1021
- }
1022
- async function registerMcpServer(packageRoot, homeDir = os6.homedir()) {
1023
- const claudeJsonPath = path7.join(homeDir, ".claude.json");
1024
- let claudeJson = {};
1025
- if (existsSync8(claudeJsonPath)) {
1026
- try {
1027
- claudeJson = JSON.parse(await readFile3(claudeJsonPath, "utf-8"));
1028
- } catch {
1029
- claudeJson = {};
1030
- }
1031
- }
1032
- if (!claudeJson.mcpServers) {
1033
- claudeJson.mcpServers = {};
1034
- }
1035
- const newEntry = mcpTransportMode() === "stdio" ? buildStdioMcpEntry(packageRoot) : buildClaudeHttpMcpEntry(homeDir);
1036
- if (claudeJson.mcpServers[MCP_LEGACY_KEY]) {
1037
- delete claudeJson.mcpServers[MCP_LEGACY_KEY];
1038
- process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
1039
- }
1040
- if (claudeJson.projects) {
1041
- for (const [projectPath, projectConfig] of Object.entries(claudeJson.projects)) {
1042
- if (projectConfig.mcpServers?.[MCP_LEGACY_KEY]) {
1043
- delete projectConfig.mcpServers[MCP_LEGACY_KEY];
1044
- process.stderr.write(`exe-os: removed stale project-level exe-mem from ${projectPath}
1045
- `);
1046
- }
1047
- }
1048
- }
1049
- const currentOs = claudeJson.mcpServers[MCP_PRIMARY_KEY];
1050
- const osMatches = currentOs && JSON.stringify(currentOs) === JSON.stringify(newEntry);
1051
- if (osMatches) {
1052
- await cleanSettingsJsonMcp(path7.join(homeDir, ".claude", "settings.json"));
1053
- await migratePermissionsToExeOs(path7.join(homeDir, ".claude", "settings.json"));
1054
- const collisions2 = detectMcpNameCollisions(homeDir, packageRoot).filter((c) => c.serverName === MCP_PRIMARY_KEY || c.serverName === MCP_LEGACY_KEY);
1055
- for (const c of collisions2) {
1056
- process.stderr.write(
1057
- `exe-os: WARNING Claude Code MCP name collision: ${c.serverName} exists in ${c.mcpJsonPath} and ~/.claude.json project ${c.projectPath}. Remove or rename the .mcp.json entry if tools do not surface.
1058
- `
1059
- );
1060
- }
1061
- await registerExeRustMcpConfig(packageRoot, homeDir);
1062
- return false;
1063
- }
1064
- claudeJson.mcpServers[MCP_PRIMARY_KEY] = newEntry;
1065
- await writeFile3(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
1066
- await cleanSettingsJsonMcp(path7.join(homeDir, ".claude", "settings.json"));
1067
- await migratePermissionsToExeOs(path7.join(homeDir, ".claude", "settings.json"));
1068
- const collisions = detectMcpNameCollisions(homeDir, packageRoot).filter((c) => c.serverName === MCP_PRIMARY_KEY || c.serverName === MCP_LEGACY_KEY);
1069
- for (const c of collisions) {
1070
- process.stderr.write(
1071
- `exe-os: WARNING Claude Code MCP name collision: ${c.serverName} exists in ${c.mcpJsonPath} and ~/.claude.json project ${c.projectPath}. Remove or rename the .mcp.json entry if tools do not surface.
1072
- `
1073
- );
1074
- }
1075
- await registerExeRustMcpConfig(packageRoot, homeDir);
1076
- return true;
1077
- }
1078
- async function registerExeRustMcpConfig(packageRoot, homeDir) {
1079
- const exeDir = path7.join(homeDir, ".exe");
1080
- const exeMcpPath = path7.join(exeDir, "mcp.json");
1081
- await mkdir3(exeDir, { recursive: true });
1082
- let config = { servers: {} };
1083
- if (existsSync8(exeMcpPath)) {
1084
- try {
1085
- config = JSON.parse(await readFile3(exeMcpPath, "utf-8"));
1086
- if (!config.servers) config.servers = {};
1087
- } catch {
1088
- config = { servers: {} };
1089
- }
1090
- }
1091
- const stdioEntry = {
1092
- command: "node",
1093
- args: [path7.join(packageRoot, "dist", "mcp", "server.js")],
1094
- env: {},
1095
- shared: true
1096
- };
1097
- const existing = config.servers[MCP_PRIMARY_KEY];
1098
- if (existing && JSON.stringify(existing) === JSON.stringify(stdioEntry)) {
1099
- return;
1100
- }
1101
- if (config.servers[MCP_LEGACY_KEY]) {
1102
- delete config.servers[MCP_LEGACY_KEY];
1103
- }
1104
- config.servers[MCP_PRIMARY_KEY] = stdioEntry;
1105
- await writeFile3(exeMcpPath, JSON.stringify(config, null, 2) + "\n");
1106
- process.stderr.write("exe-os: registered MCP server in ~/.exe/mcp.json (Rust runtime)\n");
1107
- }
1108
- async function cleanSettingsJsonMcp(settingsPath) {
1109
- if (!existsSync8(settingsPath)) return;
1110
- try {
1111
- const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1112
- const servers = settings.mcpServers;
1113
- if (!servers) return;
1114
- let changed = false;
1115
- if (servers[MCP_PRIMARY_KEY]) {
1116
- delete servers[MCP_PRIMARY_KEY];
1117
- changed = true;
1118
- }
1119
- if (servers[MCP_LEGACY_KEY]) {
1120
- delete servers[MCP_LEGACY_KEY];
1121
- changed = true;
1122
- }
1123
- if (changed) {
1124
- await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1125
- }
1126
- } catch {
1127
- }
1128
- }
1129
- async function migratePermissionsToExeOs(settingsPath) {
1130
- if (!existsSync8(settingsPath)) return;
1131
- try {
1132
- const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1133
- const permissions = settings.permissions;
1134
- if (!permissions || !Array.isArray(permissions.allow)) return;
1135
- const allow = permissions.allow;
1136
- let migrated = 0;
1137
- for (let i = 0; i < allow.length; i++) {
1138
- if (allow[i].startsWith("mcp__exe-mem__")) {
1139
- const newName = allow[i].replace("mcp__exe-mem__", "mcp__exe-os__");
1140
- if (!allow.includes(newName)) {
1141
- allow[i] = newName;
1142
- } else {
1143
- allow[i] = "__REMOVE__";
1144
- }
1145
- migrated++;
1146
- }
1147
- }
1148
- if (migrated > 0) {
1149
- permissions.allow = allow.filter((e) => e !== "__REMOVE__");
1150
- permissions.allow = [...new Set(permissions.allow)];
1151
- await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1152
- process.stderr.write(`exe-os: migrated ${migrated} permission(s) from exe-mem \u2192 exe-os
1153
- `);
1154
- }
1155
- } catch {
1156
- }
1157
- }
1158
- async function mergeHooks(packageRoot, homeDir = os6.homedir()) {
1159
- const settingsPath = path7.join(homeDir, ".claude", "settings.json");
1160
- const logsDir = path7.join(homeDir, ".exe-os", "logs");
1161
- const hookLogPath = path7.join(logsDir, "hooks.log");
1162
- const logSuffix = ` 2>> "${hookLogPath}"`;
1163
- await mkdir3(logsDir, { recursive: true });
1164
- let settings = {};
1165
- if (existsSync8(settingsPath)) {
1166
- try {
1167
- settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1168
- } catch {
1169
- settings = {};
1170
- }
1171
- }
1172
- if (!settings.hooks) {
1173
- settings.hooks = {};
1174
- }
1175
- if (settings.hooks && typeof settings.hooks !== "object") {
1176
- console.warn("[exe-os] Unexpected hooks schema in settings.json \u2014 skipping hook installation");
1177
- return { added: 0, skipped: 0 };
1178
- }
1179
- const hooksToRegister = [
1180
- {
1181
- event: "PostToolUse",
1182
- group: {
1183
- matcher: "Bash|Edit|Write|Read|Glob|Grep|Agent|mcp__.*",
1184
- hooks: [
1185
- {
1186
- type: "command",
1187
- command: `node "${path7.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
1188
- }
1189
- ]
1190
- },
1191
- marker: EXE_HOOKS.postToolCombined
1192
- },
1193
- {
1194
- event: "SessionStart",
1195
- group: {
1196
- hooks: [
1197
- {
1198
- type: "command",
1199
- command: `node "${path7.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
1200
- timeout: 1e4
1201
- }
1202
- ]
1203
- },
1204
- marker: EXE_HOOKS.sessionStart
1205
- },
1206
- {
1207
- event: "UserPromptSubmit",
1208
- group: {
1209
- hooks: [
1210
- {
1211
- type: "command",
1212
- command: `node "${path7.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
1213
- }
1214
- ]
1215
- },
1216
- marker: EXE_HOOKS.promptSubmit
1217
- },
1218
- {
1219
- event: "UserPromptSubmit",
1220
- group: {
1221
- hooks: [
1222
- {
1223
- type: "command",
1224
- command: `node "${path7.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
1225
- timeout: 5e3
1226
- }
1227
- ]
1228
- },
1229
- marker: EXE_HOOKS.heartbeat
1230
- },
1231
- {
1232
- event: "Stop",
1233
- group: {
1234
- hooks: [
1235
- {
1236
- type: "command",
1237
- command: `node "${path7.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1238
- }
1239
- ]
1240
- },
1241
- marker: EXE_HOOKS.stop
1242
- },
1243
- {
1244
- event: "PreToolUse",
1245
- group: {
1246
- matcher: "Write|Edit|Read|Bash",
1247
- hooks: [
1248
- {
1249
- type: "command",
1250
- command: `node "${path7.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
1251
- }
1252
- ]
1253
- },
1254
- marker: EXE_HOOKS.preToolUse
1255
- },
1256
- {
1257
- event: "SubagentStop",
1258
- group: {
1259
- hooks: [
1260
- {
1261
- type: "command",
1262
- command: `node "${path7.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
1263
- }
1264
- ]
1265
- },
1266
- marker: EXE_HOOKS.subagentStop
1267
- },
1268
- {
1269
- event: "PreCompact",
1270
- group: {
1271
- hooks: [
1272
- {
1273
- type: "command",
1274
- command: `node "${path7.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
1275
- timeout: 1e4
1276
- }
1277
- ]
1278
- },
1279
- marker: EXE_HOOKS.preCompact
1280
- },
1281
- {
1282
- event: "SessionEnd",
1283
- group: {
1284
- hooks: [
1285
- {
1286
- type: "command",
1287
- command: `node "${path7.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
1288
- }
1289
- ]
1290
- },
1291
- marker: EXE_HOOKS.sessionEnd
1292
- },
1293
- {
1294
- event: "Notification",
1295
- group: {
1296
- hooks: [
1297
- {
1298
- type: "command",
1299
- command: `node "${path7.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
1300
- }
1301
- ]
1302
- },
1303
- marker: EXE_HOOKS.notification
1304
- },
1305
- {
1306
- event: "PostCompact",
1307
- group: {
1308
- hooks: [
1309
- {
1310
- type: "command",
1311
- command: `node "${path7.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
1312
- timeout: 1e4
1313
- }
1314
- ]
1315
- },
1316
- marker: EXE_HOOKS.postCompact
1317
- },
1318
- {
1319
- event: "InstructionsLoaded",
1320
- group: {
1321
- hooks: [
1322
- {
1323
- type: "command",
1324
- command: `node "${path7.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
1325
- }
1326
- ]
1327
- },
1328
- marker: EXE_HOOKS.instructionsLoaded
1329
- }
1330
- ];
1331
- let added = 0;
1332
- let skipped = 0;
1333
- for (const eventKey of Object.keys(settings.hooks)) {
1334
- const groups = settings.hooks[eventKey];
1335
- if (!Array.isArray(groups)) continue;
1336
- settings.hooks[eventKey] = groups.map((g) => ({
1337
- ...g,
1338
- hooks: g.hooks.filter((h) => !isLegacyHomeDirHookCommand(h.command))
1339
- })).filter((g) => g.hooks.length > 0);
1340
- }
1341
- const postToolGroups = settings.hooks["PostToolUse"];
1342
- if (Array.isArray(postToolGroups)) {
1343
- settings.hooks["PostToolUse"] = postToolGroups.map((g) => ({
1344
- ...g,
1345
- hooks: g.hooks.filter((h) => !isLegacySplitPostToolCommand(h.command))
1346
- })).filter((g) => g.hooks.length > 0);
1347
- }
1348
- for (const { event, group, marker } of hooksToRegister) {
1349
- if (!settings.hooks[event]) {
1350
- settings.hooks[event] = [];
1351
- }
1352
- if (!Array.isArray(settings.hooks[event])) {
1353
- console.warn(`[exe-os] Hook event "${event}" has unexpected structure \u2014 skipping`);
1354
- skipped++;
1355
- continue;
1356
- }
1357
- const existing = settings.hooks[event];
1358
- const correctCommand = group.hooks[0]?.command ?? "";
1359
- const alreadyCorrect = existing.some(
1360
- (g) => g.hooks.some((h) => h.command === correctCommand)
1361
- );
1362
- if (alreadyCorrect) {
1363
- skipped++;
1364
- } else {
1365
- settings.hooks[event] = existing.filter(
1366
- (g) => !g.hooks.some((h) => h.command.includes(marker))
1367
- );
1368
- settings.hooks[event].push(group);
1369
- added++;
1370
- }
1371
- }
1372
- const perms = settings.permissions;
1373
- if (!perms) {
1374
- settings.permissions = {};
1375
- }
1376
- const permissions = settings.permissions;
1377
- if (!Array.isArray(permissions.allow)) {
1378
- permissions.allow = [];
1379
- }
1380
- const toolNames = [
1381
- // Core memory
1382
- "store_memory",
1383
- "recall_my_memory",
1384
- "commit_to_long_term_memory",
1385
- "consolidate_memories",
1386
- "ask_team_memory",
1387
- "get_session_context",
1388
- // Tasks
1389
- "create_task",
1390
- "list_tasks",
1391
- "get_task",
1392
- "update_task",
1393
- "close_task",
1394
- "checkpoint_task",
1395
- // Behaviors
1396
- "store_behavior",
1397
- "deactivate_behavior",
1398
- "list_behaviors",
1399
- // Identity
1400
- "get_identity",
1401
- "update_identity",
1402
- // Messaging
1403
- "send_message",
1404
- "acknowledge_messages",
1405
- "send_whatsapp",
1406
- "query_conversations",
1407
- // Reminders + triggers
1408
- "create_reminder",
1409
- "complete_reminder",
1410
- "list_reminders",
1411
- "create_trigger",
1412
- "list_triggers",
1413
- // GraphRAG
1414
- "query_relationships",
1415
- "merge_entities",
1416
- // Documents + wiki
1417
- "ingest_document",
1418
- "list_documents",
1419
- "purge_document",
1420
- "rerank_documents",
1421
- "set_document_importance",
1422
- "get_wiki_page",
1423
- "list_wiki_pages",
1424
- // System
1425
- "load_skill",
1426
- "apply_starter_pack",
1427
- "resume_employee",
1428
- "deploy_client"
1429
- ];
1430
- const allowList = permissions.allow;
1431
- for (const name of toolNames) {
1432
- const fullName = `mcp__${MCP_PRIMARY_KEY}__${name}`;
1433
- if (!allowList.includes(fullName)) {
1434
- allowList.push(fullName);
1435
- }
1436
- }
1437
- await mkdir3(path7.dirname(settingsPath), { recursive: true });
1438
- await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1439
- return { added, skipped };
1440
- }
1441
- async function cleanOldShellFunctions(homeDir = os6.homedir()) {
1442
- const rosterPath = path7.join(homeDir, ".exe-os", "exe-employees.json");
1443
- if (!existsSync8(rosterPath)) return 0;
1444
- let employees;
1445
- try {
1446
- employees = JSON.parse(await readFile3(rosterPath, "utf-8"));
1447
- } catch {
1448
- return 0;
1449
- }
1450
- if (employees.length === 0) return 0;
1451
- const names = employees.map((e) => e.name);
1452
- const funcPatterns = names.map((n) => {
1453
- const funcDef = new RegExp(`^\\s*(function\\s+)?${escapeRegExp(n)}\\d+\\s*\\(\\)`, "m");
1454
- const forLoop = new RegExp(`${escapeRegExp(n)}\\$\\{?[a-zA-Z_][a-zA-Z0-9_]*\\}?`, "m");
1455
- return { name: n, funcDef, forLoop };
1456
- });
1457
- const rcFiles = [
1458
- path7.join(homeDir, ".zshrc"),
1459
- path7.join(homeDir, ".bashrc")
1460
- ];
1461
- const REMOVED_MARKER = "# Removed by exe-os \u2014 wrappers now at ~/.exe-os/bin/";
1462
- let totalRemoved = 0;
1463
- for (const rcPath of rcFiles) {
1464
- if (!existsSync8(rcPath)) continue;
1465
- let content;
1466
- try {
1467
- content = await readFile3(rcPath, "utf-8");
1468
- } catch {
1469
- continue;
1470
- }
1471
- if (content.includes(REMOVED_MARKER)) continue;
1472
- const lines = content.split("\n");
1473
- let changed = false;
1474
- let inForLoop = false;
1475
- let forLoopMatchesEmployee = false;
1476
- for (let i = 0; i < lines.length; i++) {
1477
- const line = lines[i];
1478
- const trimmed = line.trim();
1479
- if (trimmed.startsWith("#")) continue;
1480
- if (/^\s*for\s+/.test(trimmed)) {
1481
- inForLoop = true;
1482
- forLoopMatchesEmployee = false;
1483
- for (const { forLoop } of funcPatterns) {
1484
- if (forLoop.test(trimmed)) {
1485
- forLoopMatchesEmployee = true;
1486
- break;
1487
- }
1488
- }
1489
- if (forLoopMatchesEmployee) {
1490
- lines[i] = `${REMOVED_MARKER}
1491
- # ${line}`;
1492
- changed = true;
1493
- totalRemoved++;
1494
- continue;
1495
- }
1496
- }
1497
- if (inForLoop) {
1498
- if (!forLoopMatchesEmployee) {
1499
- for (const { forLoop } of funcPatterns) {
1500
- if (forLoop.test(trimmed)) {
1501
- forLoopMatchesEmployee = true;
1502
- for (let j = i - 1; j >= 0; j--) {
1503
- if (/^\s*for\s+/.test(lines[j].replace(/^#\s*/, ""))) {
1504
- if (!lines[j].startsWith("#")) {
1505
- lines[j] = `${REMOVED_MARKER}
1506
- # ${lines[j]}`;
1507
- totalRemoved++;
1508
- }
1509
- break;
1510
- }
1511
- }
1512
- break;
1513
- }
1514
- }
1515
- }
1516
- if (forLoopMatchesEmployee && !trimmed.startsWith("#")) {
1517
- lines[i] = `# ${line}`;
1518
- changed = true;
1519
- totalRemoved++;
1520
- }
1521
- if (trimmed === "done" || trimmed.startsWith("done;") || trimmed.startsWith("done ")) {
1522
- inForLoop = false;
1523
- forLoopMatchesEmployee = false;
1524
- }
1525
- continue;
1526
- }
1527
- for (const { funcDef } of funcPatterns) {
1528
- if (funcDef.test(trimmed)) {
1529
- lines[i] = `${REMOVED_MARKER}
1530
- # ${line}`;
1531
- changed = true;
1532
- totalRemoved++;
1533
- let braceDepth = 0;
1534
- const hasBrace = trimmed.includes("{");
1535
- if (hasBrace) braceDepth = 1;
1536
- for (let j = i + 1; j < lines.length; j++) {
1537
- const bodyLine = lines[j].trim();
1538
- if (!hasBrace && braceDepth === 0) {
1539
- if (bodyLine === "{") {
1540
- braceDepth = 1;
1541
- lines[j] = `# ${lines[j]}`;
1542
- totalRemoved++;
1543
- continue;
1544
- }
1545
- }
1546
- if (braceDepth > 0) {
1547
- braceDepth += (bodyLine.match(/{/g) ?? []).length;
1548
- braceDepth -= (bodyLine.match(/}/g) ?? []).length;
1549
- lines[j] = `# ${lines[j]}`;
1550
- totalRemoved++;
1551
- if (braceDepth <= 0) break;
1552
- }
1553
- }
1554
- break;
1555
- }
1556
- }
1557
- }
1558
- if (changed) {
1559
- await writeFile3(rcPath, lines.join("\n"));
1560
- }
1561
- }
1562
- return totalRemoved;
1563
- }
1564
- function escapeRegExp(s) {
1565
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1566
- }
1567
- async function injectOrchestrationRules(homeDir) {
1568
- const claudeDir = path7.join(homeDir, ".claude");
1569
- const claudeMdPath = path7.join(claudeDir, "CLAUDE.md");
1570
- await mkdir3(claudeDir, { recursive: true });
1571
- let existing = "";
1572
- try {
1573
- existing = await readFile3(claudeMdPath, "utf-8");
1574
- } catch {
1575
- }
1576
- const startIdx = existing.indexOf(EXE_SECTION_START);
1577
- const endIdx = existing.indexOf(EXE_SECTION_END);
1578
- if (startIdx !== -1 && endIdx !== -1) {
1579
- const currentSection = existing.slice(startIdx, endIdx + EXE_SECTION_END.length);
1580
- if (currentSection === ORCHESTRATION_RULES) {
1581
- return "unchanged";
1582
- }
1583
- const updated = existing.slice(0, startIdx) + ORCHESTRATION_RULES + existing.slice(endIdx + EXE_SECTION_END.length);
1584
- await writeFile3(claudeMdPath, updated, "utf-8");
1585
- return "updated";
1586
- }
1587
- const separator = existing.length > 0 && !existing.endsWith("\n\n") ? "\n\n" : "";
1588
- await writeFile3(claudeMdPath, existing + separator + ORCHESTRATION_RULES + "\n", "utf-8");
1589
- return "injected";
1590
- }
1591
- async function installStatusLine(packageRoot, homeDir = os6.homedir()) {
1592
- const prefs = loadPreferences(homeDir);
1593
- if (prefs.ccStatusLine === false) return "opted-out";
1594
- const claudeDir = path7.join(homeDir, ".claude");
1595
- await mkdir3(claudeDir, { recursive: true });
1596
- const assetPath = path7.join(packageRoot, "dist", "assets", "statusline-command.sh");
1597
- if (!existsSync8(assetPath)) return "asset-missing";
1598
- const destScript = path7.join(claudeDir, "statusline-command.sh");
1599
- const assetContent = await readFile3(assetPath, "utf-8");
1600
- await writeFile3(destScript, assetContent, { mode: 493 });
1601
- const settingsPath = path7.join(claudeDir, "settings.json");
1602
- let settings = {};
1603
- if (existsSync8(settingsPath)) {
1604
- try {
1605
- settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1606
- } catch {
1607
- settings = {};
1608
- }
1609
- }
1610
- if (settings.statusLine) return "already-configured";
1611
- settings.statusLine = {
1612
- type: "command",
1613
- command: `bash ${destScript}`
1614
- };
1615
- await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1616
- return "installed";
1617
- }
1618
- async function runInstaller(homeDir) {
1619
- const packageRoot = resolvePackageRoot();
1620
- process.stderr.write(`exe-os installer v1.3.0
1621
- `);
1622
- process.stderr.write(`Package root: ${packageRoot}
1623
-
1624
- `);
1625
- const cmdResult = await copySlashCommands(packageRoot, homeDir);
1626
- process.stderr.write(
1627
- `Slash commands: ${cmdResult.copied} copied, ${cmdResult.skipped} unchanged
1628
- `
1629
- );
1630
- const mcpChanged = await registerMcpServer(packageRoot, homeDir);
1631
- process.stderr.write(
1632
- `MCP server: ${mcpChanged ? "registered" : "already registered"}
1633
- `
1634
- );
1635
- const hookResult = await mergeHooks(packageRoot, homeDir);
1636
- process.stderr.write(
1637
- `Hooks: ${hookResult.added} added, ${hookResult.skipped} unchanged
1638
- `
1639
- );
1640
- const resolvedHome = homeDir ?? os6.homedir();
1641
- const exeWorkspace = path7.join(resolvedHome, "exe");
1642
- if (!existsSync8(exeWorkspace)) {
1643
- try {
1644
- await mkdir3(path7.join(exeWorkspace, "content"), { recursive: true });
1645
- await mkdir3(path7.join(exeWorkspace, "operations"), { recursive: true });
1646
- await mkdir3(path7.join(exeWorkspace, "output"), { recursive: true });
1647
- process.stderr.write(
1648
- `Created ~/exe/ \u2014 your automation workspace for non-code projects
1649
- `
1650
- );
1651
- } catch {
1652
- }
1653
- }
1654
- const claudeMdResult = await injectOrchestrationRules(resolvedHome);
1655
- process.stderr.write(
1656
- `CLAUDE.md orchestration: ${claudeMdResult}
1657
- `
1658
- );
1659
- const symlinkResults = await ensureAllAgentSymlinks(resolvedHome);
1660
- process.stderr.write(
1661
- `Agent symlinks: ${summarizeSymlinkResults(symlinkResults)}
1662
- `
1663
- );
1664
- const statusLineResult = await installStatusLine(packageRoot, resolvedHome);
1665
- process.stderr.write(
1666
- `Status line: ${statusLineResult}
1667
- `
1668
- );
1669
- const shellFuncsCleaned = await cleanOldShellFunctions(resolvedHome);
1670
- if (shellFuncsCleaned > 0) {
1671
- process.stderr.write(
1672
- `Shell cleanup: removed ${shellFuncsCleaned} old shell function(s) that were shadowing exe-os wrappers
1673
- `
1674
- );
1675
- }
1676
- process.stderr.write(`
1677
- exe-os installed successfully.
1678
- `);
1679
- }
1680
- function setupTmux(home) {
1681
- const homeDir = home ?? os6.homedir();
1682
- const exeDir = path7.join(homeDir, ".exe-os");
1683
- const exeTmuxConf = path7.join(exeDir, "tmux.conf");
1684
- const userTmuxConf = path7.join(homeDir, ".tmux.conf");
1685
- const backupPath = path7.join(homeDir, ".tmux.conf.backup");
1686
- const sourceLine = "source-file ~/.exe-os/tmux.conf";
1687
- const pkgRoot = resolvePackageRoot();
1688
- const assetPath = path7.join(pkgRoot, "dist", "assets", "tmux.conf");
1689
- if (!existsSync8(assetPath)) {
1690
- process.stderr.write(`exe-os: tmux.conf asset not found at ${assetPath} \u2014 skipping tmux setup
1691
- `);
1692
- return;
1693
- }
1694
- mkdirSync4(exeDir, { recursive: true });
1695
- if (existsSync8(exeTmuxConf)) {
1696
- const currentContent = readFileSync6(exeTmuxConf, "utf8");
1697
- const newContent = readFileSync6(assetPath, "utf8");
1698
- const currentHash = createHash("sha256").update(currentContent).digest("hex");
1699
- const newHash = createHash("sha256").update(newContent).digest("hex");
1700
- if (currentHash !== newHash) {
1701
- const shippedPath = path7.join(exeDir, ".tmux.conf.shipped-hash");
1702
- const lastShippedHash = existsSync8(shippedPath) ? readFileSync6(shippedPath, "utf8").trim() : "";
1703
- if (lastShippedHash && currentHash !== lastShippedHash) {
1704
- process.stderr.write("exe-os: tmux config has user customizations \u2014 skipping overwrite\n");
1705
- } else {
1706
- copyFileSync(assetPath, exeTmuxConf);
1707
- process.stderr.write("exe-os: tmux config updated\n");
1708
- }
1709
- writeFileSync5(shippedPath, newHash, "utf8");
1710
- } else {
1711
- process.stderr.write("exe-os: tmux config already up to date\n");
1712
- }
1713
- } else {
1714
- copyFileSync(assetPath, exeTmuxConf);
1715
- const newContent = readFileSync6(assetPath, "utf8");
1716
- const newHash = createHash("sha256").update(newContent).digest("hex");
1717
- writeFileSync5(path7.join(exeDir, ".tmux.conf.shipped-hash"), newHash, "utf8");
1718
- }
1719
- if (existsSync8(userTmuxConf)) {
1720
- const existing = readFileSync6(userTmuxConf, "utf8");
1721
- if (!existing.includes(sourceLine)) {
1722
- if (!existsSync8(backupPath)) {
1723
- copyFileSync(userTmuxConf, backupPath);
1724
- process.stderr.write(`exe-os: backed up existing tmux config to ${backupPath}
1725
- `);
1726
- }
1727
- writeFileSync5(userTmuxConf, `${sourceLine}
1728
- ${existing}`);
1729
- }
1730
- } else {
1731
- writeFileSync5(userTmuxConf, `# Exe OS tmux defaults \u2014 remove this line to use your own config
1732
- ${sourceLine}
1733
- `);
1734
- }
1735
- try {
1736
- execSync2(`tmux source-file ${exeTmuxConf} 2>/dev/null`);
1737
- } catch {
1738
- }
1739
- process.stderr.write("exe-os: tmux config installed\n");
1740
- }
1741
- function setupGhostty(home) {
1742
- const homeDir = home ?? os6.homedir();
1743
- const xdgConfig = path7.join(homeDir, ".config", "ghostty");
1744
- const macConfig = path7.join(homeDir, "Library", "Application Support", "com.mitchellh.ghostty");
1745
- const ghosttyInstalled = existsSync8(xdgConfig) || existsSync8(macConfig) || (() => {
1746
- try {
1747
- execSync2("which ghostty 2>/dev/null");
1748
- return true;
1749
- } catch {
1750
- return false;
1751
- }
1752
- })();
1753
- if (!ghosttyInstalled) {
1754
- return;
1755
- }
1756
- const pkgRoot = resolvePackageRoot();
1757
- const assetPath = path7.join(pkgRoot, "dist", "assets", "ghostty.conf");
1758
- if (!existsSync8(assetPath)) {
1759
- process.stderr.write("exe-os: ghostty.conf asset not found \u2014 skipping Ghostty setup\n");
1760
- return;
1761
- }
1762
- const configDir = xdgConfig;
1763
- const configPath = path7.join(configDir, "config");
1764
- const backupPath = path7.join(configDir, "config.backup");
1765
- mkdirSync4(configDir, { recursive: true });
1766
- const START_MARKER = "# \u2500\u2500 exe-os:ghostty-start \u2500\u2500";
1767
- const END_MARKER = "# \u2500\u2500 exe-os:ghostty-end \u2500\u2500";
1768
- const assetContent = readFileSync6(assetPath, "utf8").trim();
1769
- const markedSection = `${START_MARKER}
1770
- ${assetContent}
1771
- ${END_MARKER}`;
1772
- if (existsSync8(configPath)) {
1773
- const existing = readFileSync6(configPath, "utf8");
1774
- if (existing.includes(START_MARKER) && existing.includes(END_MARKER)) {
1775
- process.stderr.write("exe-os: Ghostty config already installed \u2014 preserving local settings\n");
1776
- return;
1777
- } else if (existing.includes("Exe OS")) {
1778
- if (!existsSync8(backupPath)) {
1779
- copyFileSync(configPath, backupPath);
1780
- process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
1781
- `);
1782
- }
1783
- writeFileSync5(configPath, `${START_MARKER}
1784
- ${existing.trim()}
1785
- ${END_MARKER}
1786
- `);
1787
- } else {
1788
- if (!existsSync8(backupPath)) {
1789
- copyFileSync(configPath, backupPath);
1790
- process.stderr.write(`exe-os: backed up existing Ghostty config to ${backupPath}
1791
- `);
1792
- }
1793
- writeFileSync5(configPath, `${markedSection}
1794
-
1795
- ${existing}`);
1796
- }
1797
- } else {
1798
- writeFileSync5(configPath, `${markedSection}
1799
- `);
1800
- }
1801
- process.stderr.write("exe-os: Ghostty config installed\n");
1802
- }
1803
- function summarizeSymlinkResults(results) {
1804
- if (results.length === 0) return "no employees in roster";
1805
- const created = results.filter((r) => r.action === "created").length;
1806
- const already = results.filter((r) => r.action === "already_correct").length;
1807
- const conflicts = results.filter((r) => r.action === "conflict");
1808
- let summary = `${created} created, ${already} already linked`;
1809
- if (conflicts.length > 0) {
1810
- const details = conflicts.map((r) => `${r.agentId} (${r.conflict ?? "unknown"})`).join(", ");
1811
- summary += `, ${conflicts.length} conflict(s): ${details}`;
1812
- }
1813
- return summary;
1814
- }
1815
- var EXE_SECTION_START, EXE_SECTION_END, ORCHESTRATION_RULES;
1816
- var init_installer = __esm({
1817
- "src/adapters/claude/installer.ts"() {
1818
- "use strict";
1819
- init_agent_symlinks();
1820
- init_mcp_prefix();
1821
- init_preferences();
1822
- init_mcp_http_config();
1823
- init_runtime_hook_manifest();
1824
- EXE_SECTION_START = "<!-- exe-os:orchestration-start -->";
1825
- EXE_SECTION_END = "<!-- exe-os:orchestration-end -->";
1826
- ORCHESTRATION_RULES = `${EXE_SECTION_START}
1827
- ## exe-os Multi-Agent Orchestration (auto-managed \u2014 do not edit)
1828
-
1829
- These rules are injected by exe-os and override default behavior for multi-agent coordination.
1830
-
1831
- - **Session routing is deterministic.** When working in a coordinator session, ALL employee sessions use that same coordinator-session suffix. NEVER reference, consider, or dispatch to employee sessions from other project sessions. This is not a choice \u2014 it is a hard constraint.
1832
- - **Always use create_task to assign work.** Never use messages, tmux send-keys, or ad-hoc instructions as a substitute for tasks.
1833
- - **Never modify another agent's in-progress task.** Create a new task instead. Modifying active tasks causes race conditions.
1834
- - **Chain of command:** founder -> coordinator/executive agent (internal routing slot may be "COO") -> managers -> specialists. The coordinator does not bypass managers for specialist work. Internal role labels are plumbing, not user-facing titles.
1835
- - **Verify dispatch.** After every create_task, confirm the employee received and started the task via tmux capture-pane.
1836
- ${EXE_SECTION_END}`;
1837
- }
1838
- });
1839
-
1840
- // src/adapters/codex/installer.ts
1841
- var installer_exports = {};
1842
- __export(installer_exports, {
1843
- ensureCodexHooksFeature: () => ensureCodexHooksFeature,
1844
- installCodexStatusLine: () => installCodexStatusLine,
1845
- mergeCodexHooks: () => mergeCodexHooks,
1846
- registerCodexMcpServer: () => registerCodexMcpServer,
1847
- runCodexInstaller: () => runCodexInstaller,
1848
- verifyCodexHooks: () => verifyCodexHooks
1849
- });
1850
- import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
1851
- import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
1852
- import path9 from "path";
1853
- import os7 from "os";
1854
- async function mergeCodexHooks(packageRoot, homeDir = os7.homedir()) {
1855
- const codexDir = path9.join(homeDir, ".codex");
1856
- const hooksPath = path9.join(codexDir, "hooks.json");
1857
- const logsDir = path9.join(homeDir, ".exe-os", "logs");
1858
- const hookLogPath = path9.join(logsDir, "hooks.log");
1859
- const logSuffix = ` 2>> "${hookLogPath}"`;
1860
- await mkdir4(codexDir, { recursive: true });
1861
- await mkdir4(logsDir, { recursive: true });
1862
- let hooksJson = {};
1863
- if (existsSync10(hooksPath)) {
1864
- try {
1865
- hooksJson = JSON.parse(await readFile4(hooksPath, "utf-8"));
1866
- } catch {
1867
- hooksJson = {};
1868
- }
1869
- }
1870
- if (!hooksJson.hooks) {
1871
- hooksJson.hooks = {};
1872
- }
1873
- const hooksToRegister = [
1874
- {
1875
- event: "PostToolUse",
1876
- group: {
1877
- matcher: "Bash|apply_patch|Edit|Write|Read|Glob|Grep|mcp__.*",
1878
- hooks: [
1879
- {
1880
- // Combined hook: runs ingest + error-recall in one Node process.
1881
- // Eliminates a cold-start cycle per tool call (~3-6s savings on Codex).
1882
- type: "command",
1883
- command: `node "${path9.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
1884
- }
1885
- ]
1886
- },
1887
- marker: EXE_HOOKS.postToolCombined
1888
- },
1889
- {
1890
- event: "UserPromptSubmit",
1891
- group: {
1892
- hooks: [
1893
- {
1894
- // Single hook: prompt-submit handles memory retrieval + entity boost.
1895
- // exe-heartbeat-hook is CC-specific (intercom) — omitted on Codex.
1896
- type: "command",
1897
- command: `node "${path9.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
1898
- }
1899
- ]
1900
- },
1901
- marker: EXE_HOOKS.promptSubmit
1902
- },
1903
- {
1904
- event: "Stop",
1905
- group: {
1906
- hooks: [
1907
- {
1908
- type: "command",
1909
- command: `node "${path9.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
1910
- }
1911
- ]
1912
- },
1913
- marker: EXE_HOOKS.stop
1914
- },
1915
- {
1916
- event: "PreToolUse",
1917
- group: {
1918
- matcher: "Bash|apply_patch",
1919
- hooks: [
1920
- {
1921
- type: "command",
1922
- command: `node "${path9.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
1923
- }
1924
- ]
1925
- },
1926
- marker: EXE_HOOKS.preToolUse
1927
- }
1928
- ];
1929
- let added = 0;
1930
- let skipped = 0;
1931
- const sessionStartGroups = hooksJson.hooks["SessionStart"];
1932
- if (Array.isArray(sessionStartGroups)) {
1933
- hooksJson.hooks["SessionStart"] = sessionStartGroups.map((g) => ({
1934
- ...g,
1935
- hooks: g.hooks.filter((h) => !h.command.includes(EXE_HOOKS.sessionStart))
1936
- })).filter((g) => g.hooks.length > 0);
1937
- if (hooksJson.hooks["SessionStart"].length === 0) {
1938
- delete hooksJson.hooks["SessionStart"];
1939
- }
1940
- }
1941
- const postToolGroups = hooksJson.hooks["PostToolUse"];
1942
- if (Array.isArray(postToolGroups)) {
1943
- hooksJson.hooks["PostToolUse"] = postToolGroups.map((g) => ({
1944
- ...g,
1945
- hooks: g.hooks.filter((h) => !isLegacySplitPostToolCommand(h.command))
1946
- })).filter((g) => g.hooks.length > 0);
1947
- }
1948
- for (const { event, group, marker } of hooksToRegister) {
1949
- if (!hooksJson.hooks[event]) {
1950
- hooksJson.hooks[event] = [];
1951
- }
1952
- const existing = hooksJson.hooks[event];
1953
- const correctCommand = group.hooks[0]?.command ?? "";
1954
- const alreadyCorrect = existing.some(
1955
- (g) => g.hooks.some((h) => h.command === correctCommand)
1956
- );
1957
- if (alreadyCorrect) {
1958
- skipped++;
1959
- } else {
1960
- hooksJson.hooks[event] = existing.filter(
1961
- (g) => !g.hooks.some((h) => h.command.includes(marker))
1962
- );
1963
- hooksJson.hooks[event].push(group);
1964
- added++;
1965
- }
1966
- }
1967
- await writeFile4(hooksPath, JSON.stringify(hooksJson, null, 2) + "\n");
1968
- return { added, skipped };
1969
- }
1970
- function verifyCodexHooks(homeDir = os7.homedir()) {
1971
- const hooksPath = path9.join(homeDir, ".codex", "hooks.json");
1972
- if (!existsSync10(hooksPath)) return false;
1973
- try {
1974
- const hooksJson = JSON.parse(readFileSync8(hooksPath, "utf-8"));
1975
- if (!hooksJson.hooks) return false;
1976
- const required = ["PostToolUse", "UserPromptSubmit", "Stop", "PreToolUse"];
1977
- for (const event of required) {
1978
- const groups = hooksJson.hooks[event];
1979
- if (!groups || !groups.some(
1980
- (g) => g.hooks.some((h) => h.command.includes("dist/hooks/"))
1981
- )) {
1982
- return false;
1983
- }
1984
- }
1985
- const postToolCommands = (hooksJson.hooks.PostToolUse ?? []).flatMap((g) => g.hooks.map((h) => h.command));
1986
- if (!postToolCommands.some((cmd) => cmd.includes(EXE_HOOKS.postToolCombined))) {
1987
- return false;
1988
- }
1989
- if (postToolCommands.some(
1990
- (cmd) => isLegacySplitPostToolCommand(cmd)
1991
- )) {
1992
- return false;
1993
- }
1994
- const sessionStartCommands = (hooksJson.hooks.SessionStart ?? []).flatMap((g) => g.hooks.map((h) => h.command));
1995
- if (sessionStartCommands.some((cmd) => cmd.includes(EXE_HOOKS.sessionStart))) {
1996
- return false;
1997
- }
1998
- return true;
1999
- } catch {
2000
- return false;
2001
- }
2002
- }
2003
- async function installCodexStatusLine(homeDir = os7.homedir()) {
2004
- const prefs = loadPreferences(homeDir);
2005
- if (prefs.codexStatusLine === false) return "opted-out";
2006
- const codexDir = path9.join(homeDir, ".codex");
2007
- const configPath = path9.join(codexDir, "config.toml");
2008
- await mkdir4(codexDir, { recursive: true });
2009
- let content = "";
2010
- if (existsSync10(configPath)) {
2011
- content = await readFile4(configPath, "utf-8");
2012
- if (/\[tui\][\s\S]*?status_line\s*=/.test(content)) {
2013
- return "already-configured";
2014
- }
2015
- }
2016
- const statusLineToml = `[tui]
2017
- status_line = [${DEFAULT_CODEX_STATUS_LINE.map((s) => `"${s}"`).join(", ")}]`;
2018
- if (content.includes("[tui]")) {
2019
- content = content.replace(/\[tui\]/, `${statusLineToml}`);
2020
- } else {
2021
- const separator = content.length > 0 && !content.endsWith("\n") ? "\n\n" : content.length > 0 ? "\n" : "";
2022
- content = content + separator + statusLineToml + "\n";
2023
- }
2024
- await writeFile4(configPath, content);
2025
- return "installed";
2026
- }
2027
- function tomlString(value) {
2028
- return JSON.stringify(value);
2029
- }
2030
- function codexHttpHeadersToml(homeDir) {
2031
- const headers = buildMcpHttpHeaders(homeDir);
2032
- return `{ ${Object.entries(headers).map(([key, value]) => `${tomlString(key)} = ${tomlString(value)}`).join(", ")} }`;
2033
- }
2034
- function desiredCodexMcpSection(homeDir) {
2035
- return [
2036
- "[mcp_servers.exe-os]",
2037
- `url = ${tomlString(mcpHttpUrl())}`,
2038
- `http_headers = ${codexHttpHeadersToml(homeDir)}`,
2039
- `startup_timeout_sec = ${CODEX_EXE_MCP_STARTUP_TIMEOUT_SEC}`,
2040
- `tool_timeout_sec = ${CODEX_EXE_MCP_TOOL_TIMEOUT_SEC}`,
2041
- ""
2042
- ].join("\n");
2043
- }
2044
- function reconcileCodexMcpSection(sectionContent, homeDir) {
2045
- const desiredLines = {
2046
- url: `url = ${tomlString(mcpHttpUrl())}`,
2047
- headers: `http_headers = ${codexHttpHeadersToml(homeDir)}`,
2048
- startup: `startup_timeout_sec = ${CODEX_EXE_MCP_STARTUP_TIMEOUT_SEC}`,
2049
- tool: `tool_timeout_sec = ${CODEX_EXE_MCP_TOOL_TIMEOUT_SEC}`
2050
- };
2051
- let next = sectionContent;
2052
- next = next.split("\n").filter((line) => !/^(command|args|env|type|url|http_headers|startup_timeout_sec|tool_timeout_sec)\s*=/.test(line.trim())).join("\n").replace(/\n{3,}/g, "\n\n");
2053
- for (const line of [desiredLines.url, desiredLines.headers, desiredLines.startup, desiredLines.tool]) {
2054
- next = next.endsWith("\n") ? `${next}${line}
2055
- ` : `${next}
2056
- ${line}
2057
- `;
2058
- }
2059
- return { content: next, changed: next !== sectionContent };
2060
- }
2061
- async function registerCodexMcpServer(packageRoot, homeDir = os7.homedir()) {
2062
- const codexDir = path9.join(homeDir, ".codex");
2063
- const configPath = path9.join(codexDir, "config.toml");
2064
- void packageRoot;
2065
- await mkdir4(codexDir, { recursive: true });
2066
- let content = "";
2067
- if (existsSync10(configPath)) {
2068
- content = await readFile4(configPath, "utf-8");
2069
- }
2070
- const sectionHeader = "[mcp_servers.exe-os]";
2071
- const headerIndex = content.indexOf(sectionHeader);
2072
- if (headerIndex !== -1) {
2073
- const afterHeader = content.slice(headerIndex + sectionHeader.length);
2074
- const nextSectionMatch = afterHeader.match(/\n\[(?!mcp_servers\.exe-os)/);
2075
- const sectionEnd = nextSectionMatch ? headerIndex + sectionHeader.length + nextSectionMatch.index : content.length;
2076
- const sectionContent = content.slice(headerIndex, sectionEnd);
2077
- const reconciled = reconcileCodexMcpSection(sectionContent, homeDir);
2078
- if (!reconciled.changed) {
2079
- return "already-registered";
2080
- }
2081
- content = content.slice(0, headerIndex) + reconciled.content + content.slice(sectionEnd);
2082
- await writeFile4(configPath, content);
2083
- return "updated";
2084
- }
2085
- const newSection = desiredCodexMcpSection(homeDir);
2086
- const separator = content.length > 0 && !content.endsWith("\n") ? "\n\n" : content.length > 0 ? "\n" : "";
2087
- content = content + separator + newSection;
2088
- await writeFile4(configPath, content);
2089
- return "registered";
2090
- }
2091
- async function ensureCodexHooksFeature(homeDir = os7.homedir()) {
2092
- const configPath = path9.join(homeDir, ".codex", "config.toml");
2093
- await mkdir4(path9.join(homeDir, ".codex"), { recursive: true });
2094
- let content = "";
2095
- if (existsSync10(configPath)) {
2096
- content = await readFile4(configPath, "utf-8");
2097
- }
2098
- if (/\[features\][\s\S]*?codex_hooks\s*=\s*true/.test(content)) {
2099
- return "already-enabled";
2100
- }
2101
- if (content.includes("[features]")) {
2102
- if (/codex_hooks\s*=\s*false/.test(content)) {
2103
- content = content.replace(/codex_hooks\s*=\s*false/, "codex_hooks = true");
2104
- } else {
2105
- content = content.replace(/\[features\]/, "[features]\ncodex_hooks = true");
2106
- }
2107
- } else {
2108
- const firstSectionMatch = content.match(/\n\[(?!features\])/);
2109
- if (firstSectionMatch && firstSectionMatch.index != null) {
2110
- const insertAt = firstSectionMatch.index;
2111
- content = content.slice(0, insertAt) + "\n\n[features]\ncodex_hooks = true" + content.slice(insertAt);
2112
- } else {
2113
- const separator = content.length > 0 && !content.endsWith("\n") ? "\n\n" : "\n";
2114
- content = content + separator + "[features]\ncodex_hooks = true\n";
2115
- }
2116
- }
2117
- await writeFile4(configPath, content);
2118
- return "enabled";
2119
- }
2120
- async function runCodexInstaller(homeDir) {
2121
- const packageRoot = resolvePackageRoot();
2122
- const result = await mergeCodexHooks(packageRoot, homeDir);
2123
- process.stderr.write(
2124
- `[exe-os] Codex hooks: ${result.added} added, ${result.skipped} unchanged
2125
- `
2126
- );
2127
- const featureResult = await ensureCodexHooksFeature(homeDir);
2128
- process.stderr.write(
2129
- `[exe-os] Codex hooks feature: ${featureResult}
2130
- `
2131
- );
2132
- const mcpResult = await registerCodexMcpServer(packageRoot, homeDir);
2133
- process.stderr.write(
2134
- `[exe-os] Codex MCP server: ${mcpResult}
2135
- `
2136
- );
2137
- const statusResult = await installCodexStatusLine(homeDir);
2138
- process.stderr.write(
2139
- `[exe-os] Codex status line: ${statusResult}
2140
- `
2141
- );
2142
- }
2143
- var DEFAULT_CODEX_STATUS_LINE, CODEX_EXE_MCP_STARTUP_TIMEOUT_SEC, CODEX_EXE_MCP_TOOL_TIMEOUT_SEC;
2144
- var init_installer2 = __esm({
2145
- "src/adapters/codex/installer.ts"() {
2146
- "use strict";
2147
- init_installer();
2148
- init_preferences();
2149
- init_runtime_hook_manifest();
2150
- init_mcp_http_config();
2151
- DEFAULT_CODEX_STATUS_LINE = [
2152
- "model-with-reasoning",
2153
- "current-dir",
2154
- "project-name",
2155
- "git-branch",
2156
- "run-state",
2157
- "context-used"
2158
- ];
2159
- CODEX_EXE_MCP_STARTUP_TIMEOUT_SEC = 30;
2160
- CODEX_EXE_MCP_TOOL_TIMEOUT_SEC = 120;
2161
- }
2162
- });
2163
-
2164
- // src/bin/install.ts
2165
- init_installer();
2166
- import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3, readdirSync as readdirSync2, openSync, closeSync } from "fs";
2167
- import { spawn, execSync as execSync4 } from "child_process";
2168
- import path10 from "path";
2169
- import os8 from "os";
2170
-
2171
- // src/lib/session-wrappers.ts
3
+ copySlashCommands,
4
+ resolvePackageRoot,
5
+ runInstaller,
6
+ setupGhostty,
7
+ setupTmux
8
+ } from "../chunk-BCMOO4OQ.js";
9
+ import "../chunk-SPKE5ANC.js";
2172
10
  import {
2173
- existsSync as existsSync9,
2174
- readFileSync as readFileSync7,
2175
- writeFileSync as writeFileSync6,
2176
- mkdirSync as mkdirSync5,
2177
- chmodSync as chmodSync3,
2178
- readdirSync,
2179
- unlinkSync as unlinkSync2
2180
- } from "fs";
2181
- import { execSync as execSync3 } from "child_process";
2182
- import path8 from "path";
2183
- import { homedir } from "os";
2184
- var MAX_N = 9;
2185
- function generateSessionWrappers(packageRoot, homeDir) {
2186
- const home = homeDir ?? homedir();
2187
- const binDir = path8.join(home, ".exe-os", "bin");
2188
- const rosterPath = path8.join(home, ".exe-os", "exe-employees.json");
2189
- const shouldMirrorToGlobalBin = homeDir === void 0;
2190
- mkdirSync5(binDir, { recursive: true });
2191
- const exeStartDst = path8.join(binDir, "exe-start");
2192
- const candidates = [
2193
- path8.join(packageRoot, "dist", "bin", "exe-start.sh"),
2194
- path8.join(packageRoot, "src", "bin", "exe-start.sh")
2195
- ];
2196
- for (const src of candidates) {
2197
- if (existsSync9(src)) {
2198
- writeFileSync6(exeStartDst, readFileSync7(src));
2199
- chmodSync3(exeStartDst, 493);
2200
- break;
2201
- }
2202
- }
2203
- let employees = [];
2204
- try {
2205
- employees = JSON.parse(readFileSync7(rosterPath, "utf8"));
2206
- } catch {
2207
- return { created: 0, pathConfigured: false };
2208
- }
2209
- if (employees.length === 0) {
2210
- return { created: 0, pathConfigured: false };
2211
- }
2212
- try {
2213
- for (const f of readdirSync(binDir)) {
2214
- if (f === "exe-start") continue;
2215
- const fPath = path8.join(binDir, f);
2216
- try {
2217
- const content = readFileSync7(fPath, "utf8");
2218
- if (content.includes("exe-start")) {
2219
- unlinkSync2(fPath);
2220
- }
2221
- } catch {
2222
- }
2223
- }
2224
- } catch {
2225
- }
2226
- let created = 0;
2227
- const wrapperContent = `#!/bin/bash
2228
- exec "${exeStartDst}" "$0" "$@"
2229
- `;
2230
- const globalBinDir = shouldMirrorToGlobalBin ? resolveGlobalBinDir() : null;
2231
- for (const emp of employees) {
2232
- for (let n = 1; n <= MAX_N; n++) {
2233
- writeWrapper(path8.join(binDir, `${emp.name}${n}`), wrapperContent);
2234
- if (globalBinDir) {
2235
- writeWrapper(path8.join(globalBinDir, `${emp.name}${n}`), wrapperContent);
2236
- }
2237
- created++;
2238
- }
2239
- }
2240
- const pathConfigured = ensurePath(home, binDir);
2241
- return { created, pathConfigured };
2242
- }
2243
- function writeWrapper(wrapperPath, content) {
2244
- try {
2245
- writeFileSync6(wrapperPath, content);
2246
- chmodSync3(wrapperPath, 493);
2247
- } catch {
2248
- }
2249
- }
2250
- function resolveGlobalBinDir() {
2251
- try {
2252
- const exeOsPath = execSync3("command -v exe-os", { encoding: "utf8", timeout: 3e3 }).trim().split("\n")[0];
2253
- if (exeOsPath) return path8.dirname(exeOsPath);
2254
- } catch {
2255
- }
2256
- try {
2257
- const prefix = execSync3("npm prefix -g", { encoding: "utf8", timeout: 3e3 }).trim();
2258
- if (prefix) return path8.join(prefix, "bin");
2259
- } catch {
2260
- }
2261
- return null;
2262
- }
2263
- function ensurePath(home, binDir) {
2264
- if (process.env.PATH?.split(":").includes(binDir)) {
2265
- return false;
2266
- }
2267
- const exportLine = `
2268
- # exe-os session commands
2269
- export PATH="${binDir}:$PATH"
2270
- `;
2271
- const shell = process.env.SHELL ?? "/bin/bash";
2272
- const profilePaths = [];
2273
- if (shell.includes("zsh")) {
2274
- profilePaths.push(path8.join(home, ".zshrc"));
2275
- } else if (shell.includes("bash")) {
2276
- profilePaths.push(path8.join(home, ".bashrc"));
2277
- profilePaths.push(path8.join(home, ".bash_profile"));
2278
- } else {
2279
- profilePaths.push(path8.join(home, ".profile"));
2280
- }
2281
- for (const profilePath of profilePaths) {
2282
- try {
2283
- let content = "";
2284
- try {
2285
- content = readFileSync7(profilePath, "utf8");
2286
- } catch {
2287
- }
2288
- if (content.includes(".exe-os/bin")) {
2289
- return false;
2290
- }
2291
- writeFileSync6(profilePath, content + exportLine);
2292
- return true;
2293
- } catch {
2294
- continue;
2295
- }
2296
- }
2297
- return false;
2298
- }
11
+ generateSessionWrappers
12
+ } from "../chunk-MLCUPTP7.js";
13
+ import "../chunk-L3TB7CC3.js";
14
+ import "../chunk-OFK72LTZ.js";
15
+ import "../chunk-6BFIFI5F.js";
16
+ import "../chunk-RUG3N6P4.js";
17
+ import "../chunk-KVPG5UT6.js";
18
+ import "../chunk-X2IMCCM5.js";
19
+ import "../chunk-KFQGP6VL.js";
2299
20
 
2300
21
  // src/bin/install.ts
2301
- var homedir2 = os8.homedir;
2302
- var EXE_DIR = path10.join(homedir2(), ".exe-os");
22
+ import { existsSync, readFileSync, writeFileSync, unlinkSync, readdirSync, openSync, closeSync } from "fs";
23
+ import { spawn, execSync } from "child_process";
24
+ import path from "path";
25
+ import os from "os";
26
+ var homedir = os.homedir;
27
+ var EXE_DIR = path.join(homedir(), ".exe-os");
2303
28
  function restartDaemon() {
2304
- const pidPath = path10.join(EXE_DIR, "exed.pid");
2305
- const sockPath = path10.join(EXE_DIR, "exed.sock");
29
+ const pidPath = path.join(EXE_DIR, "exed.pid");
30
+ const sockPath = path.join(EXE_DIR, "exed.sock");
2306
31
  try {
2307
- if (existsSync11(pidPath)) {
2308
- const pid = parseInt(readFileSync9(pidPath, "utf8").trim(), 10);
32
+ if (existsSync(pidPath)) {
33
+ const pid = parseInt(readFileSync(pidPath, "utf8").trim(), 10);
2309
34
  if (!isNaN(pid) && pid > 0) {
2310
35
  try {
2311
36
  process.kill(pid, "SIGKILL");
@@ -2313,16 +38,16 @@ function restartDaemon() {
2313
38
  }
2314
39
  }
2315
40
  try {
2316
- unlinkSync3(pidPath);
41
+ unlinkSync(pidPath);
2317
42
  } catch {
2318
43
  }
2319
44
  try {
2320
- unlinkSync3(pidPath + ".lock");
45
+ unlinkSync(pidPath + ".lock");
2321
46
  } catch {
2322
47
  }
2323
48
  }
2324
49
  try {
2325
- const pids = execSync4("pgrep -f 'exe-daemon.js' 2>/dev/null || true", { encoding: "utf8" }).trim().split("\n").filter(Boolean).map(Number).filter((n) => !isNaN(n) && n !== process.pid);
50
+ const pids = execSync("pgrep -f 'exe-daemon.js' 2>/dev/null || true", { encoding: "utf8" }).trim().split("\n").filter(Boolean).map(Number).filter((n) => !isNaN(n) && n !== process.pid);
2326
51
  for (const pid of pids) {
2327
52
  try {
2328
53
  process.kill(pid, "SIGKILL");
@@ -2336,7 +61,7 @@ function restartDaemon() {
2336
61
  } catch {
2337
62
  }
2338
63
  try {
2339
- const pids = execSync4("pgrep -f 'backfill-vectors.js' 2>/dev/null || true", { encoding: "utf8" }).trim().split("\n").filter(Boolean).map(Number).filter((n) => !isNaN(n) && n !== process.pid);
64
+ const pids = execSync("pgrep -f 'backfill-vectors.js' 2>/dev/null || true", { encoding: "utf8" }).trim().split("\n").filter(Boolean).map(Number).filter((n) => !isNaN(n) && n !== process.pid);
2340
65
  for (const pid of pids) {
2341
66
  try {
2342
67
  process.kill(pid, "SIGKILL");
@@ -2350,18 +75,18 @@ function restartDaemon() {
2350
75
  } catch {
2351
76
  }
2352
77
  try {
2353
- const versionPath = path10.join(EXE_DIR, "mcp-version");
2354
- writeFileSync7(versionPath, `deploy-${Date.now()}`);
78
+ const versionPath = path.join(EXE_DIR, "mcp-version");
79
+ writeFileSync(versionPath, `deploy-${Date.now()}`);
2355
80
  process.stderr.write(`exe-os: MCP version marker updated \u2014 servers will hot-reload within 10s
2356
81
  `);
2357
82
  } catch {
2358
83
  }
2359
84
  try {
2360
- const wpDir = path10.join(EXE_DIR, "worker-pids");
2361
- if (existsSync11(wpDir)) {
2362
- for (const f of readdirSync2(wpDir)) {
85
+ const wpDir = path.join(EXE_DIR, "worker-pids");
86
+ if (existsSync(wpDir)) {
87
+ for (const f of readdirSync(wpDir)) {
2363
88
  try {
2364
- unlinkSync3(path10.join(wpDir, f));
89
+ unlinkSync(path.join(wpDir, f));
2365
90
  } catch {
2366
91
  }
2367
92
  }
@@ -2369,16 +94,16 @@ function restartDaemon() {
2369
94
  } catch {
2370
95
  }
2371
96
  try {
2372
- unlinkSync3(sockPath);
97
+ unlinkSync(sockPath);
2373
98
  } catch {
2374
99
  }
2375
100
  try {
2376
- execSync4("sleep 0.5");
101
+ execSync("sleep 0.5");
2377
102
  } catch {
2378
103
  }
2379
104
  } catch {
2380
105
  }
2381
- const totalGB = os8.totalmem() / (1024 * 1024 * 1024);
106
+ const totalGB = os.totalmem() / (1024 * 1024 * 1024);
2382
107
  if (totalGB <= 8) {
2383
108
  process.stderr.write(
2384
109
  `exe-os: ${totalGB.toFixed(0)}GB system \u2014 skipping daemon spawn (keyword search mode)
@@ -2388,13 +113,13 @@ function restartDaemon() {
2388
113
  }
2389
114
  try {
2390
115
  const pkgRoot = resolvePackageRoot();
2391
- const daemonPath = path10.join(pkgRoot, "dist", "lib", "exe-daemon.js");
2392
- if (!existsSync11(daemonPath)) {
116
+ const daemonPath = path.join(pkgRoot, "dist", "lib", "exe-daemon.js");
117
+ if (!existsSync(daemonPath)) {
2393
118
  process.stderr.write(`exe-os: daemon not found at ${daemonPath} \u2014 skipping respawn
2394
119
  `);
2395
120
  return;
2396
121
  }
2397
- const logPath = path10.join(EXE_DIR, "exed.log");
122
+ const logPath = path.join(EXE_DIR, "exed.log");
2398
123
  let stderrFd = "ignore";
2399
124
  try {
2400
125
  stderrFd = openSync(logPath, "a");
@@ -2444,8 +169,8 @@ if (args.includes("--commands-only")) {
2444
169
  setupTmux();
2445
170
  setupGhostty();
2446
171
  try {
2447
- const { normalizeRosterCase: normalizeRosterCase2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
2448
- const changed = await normalizeRosterCase2();
172
+ const { normalizeRosterCase } = await import("../lib/employees.js");
173
+ const changed = await normalizeRosterCase();
2449
174
  if (changed) {
2450
175
  process.stderr.write("exe-os: normalized employee names to lowercase\n");
2451
176
  }
@@ -2467,9 +192,9 @@ if (args.includes("--commands-only")) {
2467
192
  `);
2468
193
  }
2469
194
  try {
2470
- execSync4("which codex", { encoding: "utf8", timeout: 5e3 });
2471
- const { runCodexInstaller: runCodexInstaller2 } = await Promise.resolve().then(() => (init_installer2(), installer_exports));
2472
- await runCodexInstaller2();
195
+ execSync("which codex", { encoding: "utf8", timeout: 5e3 });
196
+ const { runCodexInstaller } = await import("../installer-ZPQUKHU5.js");
197
+ await runCodexInstaller();
2473
198
  } catch {
2474
199
  }
2475
200
  restartDaemon();