@askexenow/exe-os 0.9.382 → 0.9.384

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 (493) hide show
  1. package/delivery/catalog.json +1254 -0
  2. package/deploy/compose/.env.customer.example +5 -5
  3. package/deploy/compose/.env.example +3 -3
  4. package/deploy/compose/docker-compose.yml +1 -1
  5. package/deploy/compose/generate-env.ts +65 -9
  6. package/deploy/compose/setup.sh +205 -7
  7. package/deploy/compose/sso-edge/default.conf.template +45 -0
  8. package/deploy/compose/sso-edge/sso-redirect.conf +11 -2
  9. package/deploy/stack-manifests/v0.9.30-apps.json +1 -1
  10. package/deploy/stack-manifests/v0.9.json +254 -2
  11. package/dist/.dist-verified.json +3 -3
  12. package/dist/{active-agent-GFUUCFLD.js → active-agent-F5V4E4UL.js} +7 -7
  13. package/dist/{active-agent-LE6FE6SO.js → active-agent-YTBB4ZQM.js} +7 -7
  14. package/dist/{agent-defs-generator-EIUA3SH5.js → agent-defs-generator-7TFISIJQ.js} +6 -6
  15. package/dist/{agent-loop-7ZRH56EX.js → agent-loop-EZ7LDAGD.js} +1 -1
  16. package/dist/{agentic-ontology-67JGSP7G.js → agentic-ontology-XVTUVV7W.js} +1 -1
  17. package/dist/{artifact-backup-NYXAYASJ.js → artifact-backup-TF6YWQT2.js} +5 -5
  18. package/dist/{backfill-gate-KWJQ35YX.js → backfill-gate-FWYLCGNJ.js} +3 -3
  19. package/dist/{backfill-metadata-RQYG2WUJ.js → backfill-metadata-J6MXIDCW.js} +10 -10
  20. package/dist/{background-jobs-6VMD55PK.js → background-jobs-V3DZRFKU.js} +3 -3
  21. package/dist/{backup-verify-HC4YDSGN.js → backup-verify-6DVBQMDP.js} +67 -18
  22. package/dist/{behavior-injection-6HSXP43Q.js → behavior-injection-XDA7ZCYN.js} +21 -20
  23. package/dist/{behavior-promotion-SJDQ2Y3U.js → behavior-promotion-4VLQ7LXK.js} +20 -19
  24. package/dist/{behaviors-6ITLA2CK.js → behaviors-SCCZP7RZ.js} +19 -18
  25. package/dist/bin/age-ontology-load.js +3 -3
  26. package/dist/bin/agentic-ontology-backfill.js +12 -12
  27. package/dist/bin/agentic-reflection-backfill.js +13 -13
  28. package/dist/bin/agentic-semantic-label.js +12 -12
  29. package/dist/bin/backfill-conversations.js +17 -16
  30. package/dist/bin/backfill-responses.js +17 -16
  31. package/dist/bin/backfill-vectors.js +23 -22
  32. package/dist/bin/bulk-sync-postgres.js +28 -27
  33. package/dist/bin/cc-doctor.js +17 -16
  34. package/dist/bin/cleanup-stale-review-tasks.js +29 -28
  35. package/dist/bin/cli.js +35 -26
  36. package/dist/bin/deferred-daemon-restart.js +124 -123
  37. package/dist/bin/exe-actions.js +1 -1
  38. package/dist/bin/exe-agent-config.js +6 -6
  39. package/dist/bin/exe-agent.js +22 -22
  40. package/dist/bin/exe-assign.js +19 -18
  41. package/dist/bin/exe-boot.js +57 -56
  42. package/dist/bin/exe-call.js +7 -7
  43. package/dist/bin/exe-cicd.js +38 -8
  44. package/dist/bin/exe-cloud.js +30 -29
  45. package/dist/bin/exe-config-dump.js +6 -6
  46. package/dist/bin/exe-dispatch.js +30 -29
  47. package/dist/bin/exe-doctor.js +11 -11
  48. package/dist/bin/exe-export-behaviors.js +23 -22
  49. package/dist/bin/exe-forget.js +13 -13
  50. package/dist/bin/exe-gateway.js +47 -14
  51. package/dist/bin/exe-grant.js +6 -6
  52. package/dist/bin/exe-healthcheck.js +17 -16
  53. package/dist/bin/exe-heartbeat.js +41 -35
  54. package/dist/bin/exe-kill.js +35 -34
  55. package/dist/bin/exe-launch-agent.js +43 -42
  56. package/dist/bin/exe-mcp.js +9 -9
  57. package/dist/bin/exe-memory-reads.js +10 -10
  58. package/dist/bin/exe-new-employee.js +11 -11
  59. package/dist/bin/exe-os-mcp-proxy.js +9 -9
  60. package/dist/bin/exe-pending-messages.js +30 -29
  61. package/dist/bin/exe-pending-notifications.js +29 -28
  62. package/dist/bin/exe-pending-reviews.js +30 -29
  63. package/dist/bin/exe-preflight.js +1 -1
  64. package/dist/bin/exe-rename.js +9 -9
  65. package/dist/bin/exe-review.js +34 -33
  66. package/dist/bin/exe-search.js +12 -12
  67. package/dist/bin/exe-session-cleanup.js +35 -34
  68. package/dist/bin/exe-settings.js +29 -28
  69. package/dist/bin/exe-start-codex.js +30 -29
  70. package/dist/bin/exe-start-opencode.js +27 -26
  71. package/dist/bin/exe-status.js +31 -30
  72. package/dist/bin/exe-support.js +5 -5
  73. package/dist/bin/exe-team.js +7 -7
  74. package/dist/bin/exe-verify-running-images.js +1 -1
  75. package/dist/bin/exe-watchdog.js +8 -8
  76. package/dist/bin/generate-hook-manifest.js +7 -1
  77. package/dist/bin/git-sweep.js +30 -29
  78. package/dist/bin/graph-backfill.js +12 -12
  79. package/dist/bin/graph-export.js +11 -11
  80. package/dist/bin/hooks-cli.js +1 -1
  81. package/dist/bin/import-history.js +15 -15
  82. package/dist/bin/install.js +130 -129
  83. package/dist/bin/intercom-check.js +11 -7
  84. package/dist/bin/mcp-sessions.js +2 -2
  85. package/dist/bin/orchestration-metrics.js +7 -7
  86. package/dist/bin/postgres-agentic-reflection-backfill.js +5 -5
  87. package/dist/bin/postgres-agentic-semantic-backfill.js +4 -4
  88. package/dist/bin/reconcile-backlog.js +2 -2
  89. package/dist/bin/registry-proxy.js +1 -1
  90. package/dist/bin/repair-document-chunks.js +161 -0
  91. package/dist/bin/scan-tasks.js +30 -29
  92. package/dist/bin/setup.js +5 -5
  93. package/dist/bin/shard-migrate.js +11 -11
  94. package/dist/bin/stack-update.js +625 -33
  95. package/dist/bin/update.js +96 -22
  96. package/dist/bin/verify-stack.js +2 -2
  97. package/dist/bin/vps-health-gate.js +1 -1
  98. package/dist/{boot-generation-L55QANCX.js → boot-generation-Q7LGQ3AO.js} +6 -6
  99. package/dist/{boot-review-sections-AON5ZCR2.js → boot-review-sections-G5774FR5.js} +28 -27
  100. package/dist/{branch-hygiene-QLD77IMJ.js → branch-hygiene-44WLSOZR.js} +2 -2
  101. package/dist/{branding-I6KIMB7F.js → branding-KMWCY5HZ.js} +3 -3
  102. package/dist/build-manifest.json +1259 -1219
  103. package/dist/{capability-cards-WTOXY7O6.js → capability-cards-I3RHCF4F.js} +5 -5
  104. package/dist/{capacity-monitor-ZLG7FSWM.js → capacity-monitor-7I7GDONU.js} +30 -29
  105. package/dist/{catchup-brief-QHY7D7N2.js → catchup-brief-3T5PARIR.js} +39 -36
  106. package/dist/check-image-pullability-2AIVB4BX.js +338 -0
  107. package/dist/{chunk-CTCCYKOV.js → chunk-2FKU4ZEO.js} +55 -29
  108. package/dist/{chunk-M7O7TGGU.js → chunk-2NW4LRDU.js} +1 -1
  109. package/dist/{chunk-XTFM4KMW.js → chunk-2PZTMSMG.js} +6 -6
  110. package/dist/{chunk-UWX6MMCX.js → chunk-3B6FLNLV.js} +1 -1
  111. package/dist/{chunk-GPJIBLP4.js → chunk-3DAEZILW.js} +1 -1
  112. package/dist/{chunk-NY6SBR4O.js → chunk-3FGBBJYM.js} +15 -3
  113. package/dist/{chunk-C4OZVVSG.js → chunk-3OX34OC3.js} +50 -18
  114. package/dist/{chunk-TXTXC3QG.js → chunk-3RGTLZNO.js} +12 -12
  115. package/dist/{chunk-PYRO25A5.js → chunk-3SUPEE6H.js} +10 -11
  116. package/dist/{chunk-PPMGQFLJ.js → chunk-3XY57PKT.js} +2 -2
  117. package/dist/{chunk-CRHI5QTZ.js → chunk-46VSBDUW.js} +2 -2
  118. package/dist/{chunk-VZT66WWP.js → chunk-4AAMFWJT.js} +2 -2
  119. package/dist/{chunk-4GZTBLJG.js → chunk-4AR5XKCH.js} +1 -1
  120. package/dist/{chunk-IHXW4VUI.js → chunk-5IADGFGR.js} +1 -1
  121. package/dist/{chunk-GLQEJOXE.js → chunk-5MVKTNZP.js} +57 -0
  122. package/dist/{chunk-AVMLC2MR.js → chunk-5U2IJBFV.js} +290 -41
  123. package/dist/{chunk-JUKDL5MF.js → chunk-6BJCDWSM.js} +1 -1
  124. package/dist/{chunk-6WWNK7UX.js → chunk-6FIC57PH.js} +1 -1
  125. package/dist/{chunk-ASUICGPX.js → chunk-6YDY6ZTD.js} +4 -4
  126. package/dist/{chunk-FU5O2REK.js → chunk-72V3S44T.js} +108 -29
  127. package/dist/{chunk-LTIIZHNA.js → chunk-7J2ZQ4XN.js} +1 -1
  128. package/dist/{chunk-7RI2CNXJ.js → chunk-7OTR2OET.js} +1 -1
  129. package/dist/{chunk-ZVBVPX4W.js → chunk-7UHZBVP3.js} +82 -51
  130. package/dist/{chunk-PTY2N23C.js → chunk-AGC2V7JS.js} +26 -13
  131. package/dist/{chunk-44VR3PFW.js → chunk-AHESD3KW.js} +1 -1
  132. package/dist/{chunk-NPGV4MZ3.js → chunk-ALRHGEAJ.js} +1 -1
  133. package/dist/{chunk-WJC6AAJN.js → chunk-ANVHWV2X.js} +2 -2
  134. package/dist/{chunk-AGZSGAEN.js → chunk-APL7HUE3.js} +105 -32
  135. package/dist/{chunk-7UH2JWBF.js → chunk-AZSTIAVL.js} +176 -11
  136. package/dist/chunk-AZXMR25O.js +545 -0
  137. package/dist/{chunk-WPWEBZ37.js → chunk-B7AMNZTC.js} +2 -2
  138. package/dist/{chunk-4CF5KUWH.js → chunk-BPVFZ6Q4.js} +3 -3
  139. package/dist/{chunk-XTQ7R2PA.js → chunk-BV2IET6B.js} +73 -17
  140. package/dist/{chunk-4F5CNI65.js → chunk-C5ISP5FO.js} +2 -2
  141. package/dist/{chunk-NPWNXJ3U.js → chunk-CH7BUBP3.js} +7 -7
  142. package/dist/{chunk-X5Q66EOG.js → chunk-CHIUS5QB.js} +16 -16
  143. package/dist/{chunk-ZG62LIK3.js → chunk-CIPDQRFO.js} +1 -1
  144. package/dist/{chunk-4PYIRIU6.js → chunk-CM7N5MBY.js} +5 -5
  145. package/dist/{chunk-L5YDAFUH.js → chunk-CYCIX7AW.js} +5 -5
  146. package/dist/{chunk-76YRJKKF.js → chunk-D3LXVAIQ.js} +28 -16
  147. package/dist/{chunk-2GNAHBRD.js → chunk-DMUOTCDN.js} +1 -1
  148. package/dist/{chunk-QMUFSRQX.js → chunk-DN3ZR3UE.js} +1 -1
  149. package/dist/{chunk-V3WLC5TJ.js → chunk-DRTJCG6B.js} +1 -1
  150. package/dist/{chunk-275WHBEN.js → chunk-DYVLEMKS.js} +1 -1
  151. package/dist/{chunk-O34F5EP5.js → chunk-DZN7SDY2.js} +1 -1
  152. package/dist/{chunk-ZDIXMHY7.js → chunk-E3ZM32LF.js} +8 -8
  153. package/dist/{chunk-N2HXR5MB.js → chunk-E7C2WNR5.js} +4 -4
  154. package/dist/{chunk-VVGXWVZU.js → chunk-EGOEB42T.js} +3 -3
  155. package/dist/{chunk-QV5CQLQH.js → chunk-EIOGV75A.js} +2 -2
  156. package/dist/{chunk-ZY4IGUOS.js → chunk-ELCRJGCH.js} +3 -3
  157. package/dist/{chunk-5QCIWWFA.js → chunk-ELEGH4DX.js} +130 -14
  158. package/dist/{chunk-S7CTCPSW.js → chunk-EOTZSAQL.js} +1 -1
  159. package/dist/{chunk-PPLQ4ECD.js → chunk-EUGEFBGV.js} +3 -3
  160. package/dist/{chunk-UFNCL6MS.js → chunk-EYMFVITZ.js} +1 -1
  161. package/dist/{chunk-F6H7GP2O.js → chunk-F4BBMIPG.js} +3 -3
  162. package/dist/{chunk-FNEZ4BWT.js → chunk-FEU6QEEL.js} +1 -1
  163. package/dist/{chunk-JKOC2L6P.js → chunk-FHIFTSPL.js} +1 -1
  164. package/dist/{chunk-4RTKETV3.js → chunk-FMIYFHLE.js} +3 -3
  165. package/dist/{chunk-TK544DEW.js → chunk-FVLNNNH6.js} +3 -3
  166. package/dist/{chunk-AY2U4NZ5.js → chunk-GL47M7NY.js} +85 -17
  167. package/dist/{chunk-DN24VTS5.js → chunk-GSLFH4AI.js} +25 -13
  168. package/dist/{chunk-CHO5SNWR.js → chunk-HA63SH5W.js} +1 -1
  169. package/dist/{chunk-4IK2K3B3.js → chunk-HME6ITKV.js} +1 -1
  170. package/dist/{chunk-H2T6TFJZ.js → chunk-HU3VD4MQ.js} +2 -2
  171. package/dist/{chunk-ZW32RI66.js → chunk-I5XIW2BP.js} +49 -11
  172. package/dist/{chunk-3CL2I3RG.js → chunk-IGJMS7C5.js} +2 -2
  173. package/dist/{chunk-BRPO6GOH.js → chunk-JA3Y5TV6.js} +2 -2
  174. package/dist/{chunk-SFFXAPYK.js → chunk-JDDM6C57.js} +1 -1
  175. package/dist/{chunk-W4EGAQXW.js → chunk-JFJP6ATJ.js} +2 -2
  176. package/dist/{chunk-ENCUOZXX.js → chunk-JFTUAV4J.js} +1 -1
  177. package/dist/{chunk-3UOQH2DJ.js → chunk-JJTPPAZY.js} +2568 -345
  178. package/dist/{chunk-A6QBAUJH.js → chunk-KILR4FBR.js} +4 -4
  179. package/dist/{chunk-CGFGNHSP.js → chunk-KTKIFXIP.js} +1 -1
  180. package/dist/{chunk-NCJBPXGM.js → chunk-KXYKSLW4.js} +108 -24
  181. package/dist/{chunk-3MUARHPO.js → chunk-L3VUW5M4.js} +1 -1
  182. package/dist/{chunk-GZOG2MAX.js → chunk-L5EPGGDP.js} +1 -1
  183. package/dist/{chunk-T7VSKWES.js → chunk-L63V25HS.js} +6 -5
  184. package/dist/{chunk-R4VNGRKU.js → chunk-LFBLQE2P.js} +1 -1
  185. package/dist/{chunk-W5MCOZTW.js → chunk-LFUBEHFW.js} +12 -2
  186. package/dist/{chunk-AIBIEP4R.js → chunk-LKTN22L6.js} +61 -25
  187. package/dist/{chunk-3KFQCFQB.js → chunk-LR5O2XWZ.js} +5 -5
  188. package/dist/{chunk-VUOAPKPI.js → chunk-LSNBTGW4.js} +1 -1
  189. package/dist/{chunk-P5U3GAWU.js → chunk-MB47DRF5.js} +2 -2
  190. package/dist/{chunk-HZESME3B.js → chunk-MC4IM2CC.js} +16 -13
  191. package/dist/{chunk-ZKJ5S23O.js → chunk-MFAOAIUE.js} +12 -9
  192. package/dist/{chunk-62J64CHO.js → chunk-MKM6D7JM.js} +26 -7
  193. package/dist/{chunk-ZIG7VPJV.js → chunk-MMS2HBRT.js} +15 -3
  194. package/dist/{chunk-FHSV4BSW.js → chunk-MOANZQXF.js} +12 -4
  195. package/dist/{chunk-RTZZBWQC.js → chunk-MPZ2AVNS.js} +16 -5
  196. package/dist/{chunk-AZ6KLVDX.js → chunk-MROSARM5.js} +2 -2
  197. package/dist/{chunk-RV2FFCDS.js → chunk-MUAWCFW6.js} +6 -2
  198. package/dist/{chunk-K4ESASPL.js → chunk-MUCNYSJP.js} +1 -1
  199. package/dist/{chunk-5QGKMP6T.js → chunk-NF5FOSLD.js} +1 -1
  200. package/dist/{chunk-CKOJP7JI.js → chunk-NKEFYE4R.js} +2 -2
  201. package/dist/{chunk-3SXHEQ7X.js → chunk-NPXIS2RY.js} +1 -1
  202. package/dist/{chunk-A5USSF66.js → chunk-NVFNADTX.js} +12 -8
  203. package/dist/{chunk-VVUO3RJS.js → chunk-NYLJQ2M2.js} +4 -4
  204. package/dist/{chunk-HIVOLPLD.js → chunk-OAFENIHN.js} +1 -1
  205. package/dist/{chunk-PMZHZQ6K.js → chunk-OBBO6EJR.js} +1 -1
  206. package/dist/{chunk-SS6EMDLL.js → chunk-P2UY34XE.js} +6 -6
  207. package/dist/{chunk-Y4T5IUEP.js → chunk-P3QQ52QK.js} +2 -2
  208. package/dist/{chunk-GGEKMY6G.js → chunk-P3UX5EH4.js} +4 -4
  209. package/dist/{chunk-F7IRZU5G.js → chunk-P4PIZOL2.js} +3 -3
  210. package/dist/{chunk-GEPFKUUR.js → chunk-P4XLIPB7.js} +1 -1
  211. package/dist/{chunk-GPUOUUHA.js → chunk-PCV52RYM.js} +1 -1
  212. package/dist/{chunk-XR3773KZ.js → chunk-PL4CFSQ7.js} +1 -1
  213. package/dist/{chunk-LLZNPOGB.js → chunk-PLII76NJ.js} +58 -0
  214. package/dist/{chunk-FT5PPV2C.js → chunk-PRDDPQLC.js} +5 -5
  215. package/dist/{chunk-BZ546I4Q.js → chunk-PUBA5B4M.js} +24 -0
  216. package/dist/{chunk-2TGJ5XCV.js → chunk-PWC3C5ME.js} +4 -4
  217. package/dist/{chunk-A4YCLD3L.js → chunk-QFAFKEB5.js} +40 -4
  218. package/dist/{chunk-CL4J4757.js → chunk-QH5ZQ5SJ.js} +26 -0
  219. package/dist/{chunk-UJWZYK46.js → chunk-QNZ4562V.js} +1 -1
  220. package/dist/{chunk-IPHLUZ37.js → chunk-QPTSA4PP.js} +2 -2
  221. package/dist/{chunk-O3YJTHWI.js → chunk-R5E7WNAC.js} +3 -3
  222. package/dist/{chunk-V3M4LJRA.js → chunk-RB3J2WYQ.js} +1 -1
  223. package/dist/{chunk-IUCWOI4Y.js → chunk-RDWIKDMY.js} +237 -11
  224. package/dist/{chunk-ENN6DY4T.js → chunk-RVO5O5SR.js} +46 -21
  225. package/dist/{chunk-LY4AXCYJ.js → chunk-RZN2LEAK.js} +6 -6
  226. package/dist/{chunk-2YIB75UQ.js → chunk-S26CV7BE.js} +57 -13
  227. package/dist/{chunk-XC36HYP6.js → chunk-SDYWZRPN.js} +1 -1
  228. package/dist/{chunk-PHBU4LGO.js → chunk-SNHYZYGZ.js} +1 -1
  229. package/dist/{chunk-4KTTBKWQ.js → chunk-T5FEAQES.js} +1 -1
  230. package/dist/{chunk-XU57KFD6.js → chunk-T5SM4RXY.js} +5 -1
  231. package/dist/{chunk-KUV5VBAO.js → chunk-TKAU7IJ2.js} +1 -1
  232. package/dist/{chunk-KBR5LIWD.js → chunk-TKS5GMYA.js} +1 -1
  233. package/dist/{chunk-5DFE2NAF.js → chunk-TNS63ATU.js} +96 -22
  234. package/dist/{chunk-RFPMXR6B.js → chunk-U4GMOT4M.js} +1 -1
  235. package/dist/{chunk-CO5ZVE3D.js → chunk-UOPCVFVR.js} +17 -17
  236. package/dist/{chunk-22LNFCDF.js → chunk-UX2EO653.js} +1 -1
  237. package/dist/{chunk-LGC6TBA3.js → chunk-UXN4BICC.js} +2 -2
  238. package/dist/{chunk-7J5X4AK7.js → chunk-VF2KRROX.js} +1 -1
  239. package/dist/{chunk-7THUQU44.js → chunk-VF3BZOZK.js} +5 -2
  240. package/dist/{chunk-M2B35MUK.js → chunk-VHHX4UCP.js} +1 -1
  241. package/dist/{chunk-AZBJXATK.js → chunk-VJEJ7JNB.js} +1 -1
  242. package/dist/{chunk-4TRVALTR.js → chunk-VLBHZ6TF.js} +2 -2
  243. package/dist/{chunk-7BMSBACY.js → chunk-VOVFUKEB.js} +5 -5
  244. package/dist/{chunk-MDPGZS6C.js → chunk-VROK4X2L.js} +1 -1
  245. package/dist/{chunk-J6ABJDZ4.js → chunk-W3KPQE7H.js} +4 -4
  246. package/dist/{chunk-3Q7NEDHB.js → chunk-W6BZ4UGA.js} +48 -9
  247. package/dist/{chunk-IZ3IFLL2.js → chunk-XEBKIWI7.js} +14 -14
  248. package/dist/{chunk-UZDF6FLJ.js → chunk-XHU3KOKJ.js} +1 -1
  249. package/dist/{chunk-PA37MXV5.js → chunk-XSUALA32.js} +2 -2
  250. package/dist/{chunk-GR5WJPKF.js → chunk-XUZK23V7.js} +11 -6
  251. package/dist/{chunk-IDB3EZLW.js → chunk-YLB365YX.js} +148 -5
  252. package/dist/{chunk-JDQ7JU3A.js → chunk-YLFCH3VA.js} +24 -16
  253. package/dist/{chunk-ZJJL2Z23.js → chunk-YRQ26MNP.js} +4 -4
  254. package/dist/chunk-YRUZK2QA.js +35 -0
  255. package/dist/{chunk-7HLJ4BSF.js → chunk-ZAEUEDTN.js} +2 -2
  256. package/dist/{chunk-NY74W3S4.js → chunk-ZBPZDADW.js} +313 -43
  257. package/dist/{chunk-ZLPS3GR7.js → chunk-ZJQ56DZZ.js} +42 -1
  258. package/dist/{chunk-VMZZTFXT.js → chunk-ZOTTYCP5.js} +4 -4
  259. package/dist/{chunk-MP4ST7RO.js → chunk-ZPP63JSQ.js} +51 -11
  260. package/dist/{chunk-N4J5WHO2.js → chunk-ZT4LFTUJ.js} +1 -1
  261. package/dist/{cleanup-graph-garbage-GE2DYOTB.js → cleanup-graph-garbage-VQAJ2RBT.js} +11 -11
  262. package/dist/{cloud-sync-command-T6KF3ARK.js → cloud-sync-command-J7NEFUY7.js} +2 -2
  263. package/dist/{cloud-sync-db-init-RSHCCY74.js → cloud-sync-db-init-KWEMNMGA.js} +1 -1
  264. package/dist/{cloud-sync-shutdown-6IVCSLM5.js → cloud-sync-shutdown-P63AUTUI.js} +5 -5
  265. package/dist/{co-activation-AF7RCJPX.js → co-activation-7IHRPBZN.js} +5 -5
  266. package/dist/{co-occurrence-DMOOGBVV.js → co-occurrence-R5AG4OAU.js} +9 -9
  267. package/dist/{code-context-index-LIDOFKOR.js → code-context-index-WFLLZBVB.js} +10 -9
  268. package/dist/{code-context-watcher-4F7K2N3U.js → code-context-watcher-3QAPHO7N.js} +10 -9
  269. package/dist/{codex-consolidation-SH4UKFBQ.js → codex-consolidation-ONZ2AQFX.js} +2 -2
  270. package/dist/{consent-passphrase-WV7MZPMO.js → consent-passphrase-5ZBDJ5G7.js} +2 -2
  271. package/dist/{content-extractor-DJM5EUDA.js → content-extractor-ZLXC6GNR.js} +2 -2
  272. package/dist/{conversation-entity-extractor-4UG7BKWL.js → conversation-entity-extractor-7FRKLLBD.js} +4 -4
  273. package/dist/{conversation-wiki-populator-OS4C6W54.js → conversation-wiki-populator-YAOVCUGO.js} +1 -1
  274. package/dist/{crdt-sync-VL4KXZB7.js → crdt-sync-IFRZOEIS.js} +4 -4
  275. package/dist/{crm-webhook-IDBJ7X5Y.js → crm-webhook-L2S63ASV.js} +2 -2
  276. package/dist/{cto-delegation-gate-4FLSHSLO.js → cto-delegation-gate-3WU7OHX7.js} +29 -28
  277. package/dist/{daemon-auth-PNKHERLV.js → daemon-auth-OWLFYEFR.js} +3 -3
  278. package/dist/{daemon-orchestration-HFCB6OK4.js → daemon-orchestration-3VQYKLOR.js} +33 -32
  279. package/dist/{daemon-ready-BN6EZLTQ.js → daemon-ready-VZ6ZHA2C.js} +1 -1
  280. package/dist/{db-integrity-events-GYGANKZV.js → db-integrity-events-7NKWS5MT.js} +3 -3
  281. package/dist/{db-restore-events-G6NOQOVE.js → db-restore-events-XYL6CGPC.js} +2 -2
  282. package/dist/{destructive-data-guard-HHWUBIGS.js → destructive-data-guard-JDUJ2ULM.js} +58 -2
  283. package/dist/{dispatch-ack-X4DXUSKP.js → dispatch-ack-UYEAKON5.js} +2 -1
  284. package/dist/{doc-graph-extractor-E36PQUCS.js → doc-graph-extractor-YIR5E7OF.js} +9 -9
  285. package/dist/{documents-SCKKHDR7.js → documents-QEHPTYIY.js} +19 -18
  286. package/dist/{dreaming-Q26JBH56.js → dreaming-LNFE7DTN.js} +34 -33
  287. package/dist/{employee-boot-brief-XU6EI2EO.js → employee-boot-brief-ZTXDYNWM.js} +39 -38
  288. package/dist/{entity-boost-VNQLLR3Q.js → entity-boost-R5N6JWXD.js} +1 -1
  289. package/dist/{exe-drift-YZ6OIUAY.js → exe-drift-WYSJVZFO.js} +6 -6
  290. package/dist/{exe-export-HHRQMLSS.js → exe-export-GOLNAEAV.js} +20 -19
  291. package/dist/{exe-import-5XR4NQAB.js → exe-import-U4BSI6OH.js} +20 -19
  292. package/dist/{exe-key-5XOFVP3I.js → exe-key-V42G3NGO.js} +152 -130
  293. package/dist/{exe-org-TPAX4AAK.js → exe-org-U4GLQ6OP.js} +27 -27
  294. package/dist/{exe-snapshot-GIRP3XCJ.js → exe-snapshot-U7ONBYNY.js} +38 -37
  295. package/dist/{fast-db-init-MGY6VCLG.js → fast-db-init-W3NGKAEU.js} +1 -1
  296. package/dist/{founder-context-WD72OL2P.js → founder-context-ZSIBRVDM.js} +4 -4
  297. package/dist/{founder-monitor-envelope-XGYMHT4W.js → founder-monitor-envelope-L3IWZLFY.js} +7 -7
  298. package/dist/{fts-integrity-PLAL6NMG.js → fts-integrity-PHCKKOBC.js} +3 -3
  299. package/dist/gateway/index.js +23 -22
  300. package/dist/{gateway-client-VO3BRLV5.js → gateway-client-DJFCVIPT.js} +1 -1
  301. package/dist/{git-staleness-KGZABPP3.js → git-staleness-OF24QXFZ.js} +5 -5
  302. package/dist/{global-procedures-KOU6A5E5.js → global-procedures-WSIOWO43.js} +6 -6
  303. package/dist/{graph-auto-extract-OZNRDAHE.js → graph-auto-extract-IEVVN3L3.js} +9 -9
  304. package/dist/{graph-query-36K6VXFF.js → graph-query-JDZWAVCU.js} +1 -1
  305. package/dist/{graph-rag-TZLH3CTQ.js → graph-rag-BKAD2XQA.js} +4 -4
  306. package/dist/{hook-integrity-BWFFISJV.js → hook-integrity-TPWDGX2M.js} +3 -1
  307. package/dist/{hook-prefetch-MFUJRAIM.js → hook-prefetch-FD6VGJJA.js} +29 -28
  308. package/dist/hooks/bug-report-worker.js +34 -33
  309. package/dist/hooks/codex-stop-task-finalizer.js +36 -35
  310. package/dist/hooks/commit-complete.js +40 -36
  311. package/dist/hooks/error-recall.js +15 -15
  312. package/dist/hooks/exe-heartbeat-hook.js +8 -8
  313. package/dist/hooks/ingest-worker.js +21 -20
  314. package/dist/hooks/ingest.js +23 -23
  315. package/dist/hooks/instructions-loaded.js +10 -10
  316. package/dist/hooks/manifest.json +20 -20
  317. package/dist/hooks/notification.js +9 -9
  318. package/dist/hooks/post-compact.js +8 -8
  319. package/dist/hooks/post-tool-combined.js +15 -15
  320. package/dist/hooks/pre-compact.js +33 -32
  321. package/dist/hooks/pre-tool-use.js +2 -2
  322. package/dist/hooks/prompt-submit.js +52 -51
  323. package/dist/hooks/session-end.js +38 -37
  324. package/dist/hooks/session-start.js +25 -22
  325. package/dist/hooks/stop.js +40 -39
  326. package/dist/hooks/subagent-stop.js +36 -35
  327. package/dist/hooks/summary-worker.js +41 -40
  328. package/dist/index.js +43 -42
  329. package/dist/{inrun-inbox-DRKVDPLY.js → inrun-inbox-RGNFFGMU.js} +5 -0
  330. package/dist/{installer-RM4ASY7U.js → installer-NMOBSEZ2.js} +11 -11
  331. package/dist/{installer-IESPHXVH.js → installer-OTI5SA43.js} +11 -11
  332. package/dist/{installer-SQZRVD36.js → installer-SRJGE4GU.js} +11 -11
  333. package/dist/{intercom-queue-DGLAC224.js → intercom-queue-4FFXCBHO.js} +28 -27
  334. package/dist/{key-backup-status-LQPINQ3W.js → key-backup-status-6U7D5GOD.js} +2 -2
  335. package/dist/lib/agent-config.js +3 -3
  336. package/dist/lib/cloud-sync.js +28 -27
  337. package/dist/lib/config.js +4 -2
  338. package/dist/lib/consolidation.js +14 -12
  339. package/dist/lib/crypto.js +5 -3
  340. package/dist/lib/database.js +5 -5
  341. package/dist/lib/db-backup.js +11 -3
  342. package/dist/lib/db-daemon-client.js +11 -10
  343. package/dist/lib/db-write-worker.js +4 -4
  344. package/dist/lib/db.js +5 -5
  345. package/dist/lib/delivery-catalog.js +431 -0
  346. package/dist/lib/delivery-schemas.js +62 -0
  347. package/dist/lib/delivery-truth.js +1 -1
  348. package/dist/lib/device-registry.js +3 -3
  349. package/dist/lib/embed-worker.js +2 -2
  350. package/dist/lib/embedder.js +10 -9
  351. package/dist/lib/employee-templates.js +7 -7
  352. package/dist/lib/employees.js +5 -5
  353. package/dist/lib/exe-daemon-client.js +9 -8
  354. package/dist/lib/exe-daemon.js +186 -117
  355. package/dist/lib/hybrid-search.js +12 -12
  356. package/dist/lib/identity.js +5 -5
  357. package/dist/lib/keychain.js +13 -1
  358. package/dist/lib/license.js +8 -4
  359. package/dist/lib/messaging.js +39 -30
  360. package/dist/lib/post-tool-memory.js +9 -9
  361. package/dist/lib/registry-proxy.js +9 -1
  362. package/dist/lib/reminders.js +6 -6
  363. package/dist/lib/schedules.js +11 -11
  364. package/dist/lib/session-registry.js +7 -7
  365. package/dist/lib/skill-learning.js +20 -19
  366. package/dist/lib/status-brief.js +5 -4
  367. package/dist/lib/store.js +10 -10
  368. package/dist/lib/task-router.js +6 -6
  369. package/dist/lib/tasks.js +30 -29
  370. package/dist/lib/tmux-routing.js +28 -27
  371. package/dist/lib/tmux-status.js +3 -1
  372. package/dist/lib/token-spend.js +6 -6
  373. package/dist/lib/ws-client.js +1 -1
  374. package/dist/{license-gate-E6GTRYBA.js → license-gate-R4JWTWM4.js} +5 -5
  375. package/dist/{license-recheck-RBAO6Z2H.js → license-recheck-3MBJ4IJX.js} +1 -1
  376. package/dist/{license-sync-ZCZ2LIHK.js → license-sync-BVSG3WMW.js} +4 -4
  377. package/dist/local-secret-inventory-JWNBHZZ4.js +20 -0
  378. package/dist/mailbox-inbox-MTAT4MXX.js +13 -0
  379. package/dist/{mailbox-outbox-DNDDP2HW.js → mailbox-outbox-OY4IU6S4.js} +2 -1
  380. package/dist/mcp/register-tools.js +121 -120
  381. package/dist/mcp/server.js +123 -122
  382. package/dist/mcp/tools/complete-reminder.js +7 -7
  383. package/dist/mcp/tools/create-reminder.js +7 -7
  384. package/dist/mcp/tools/create-task.js +35 -32
  385. package/dist/mcp/tools/deactivate-behavior.js +22 -21
  386. package/dist/mcp/tools/list-reminders.js +7 -7
  387. package/dist/mcp/tools/list-tasks.js +33 -32
  388. package/dist/mcp/tools/send-message.js +32 -31
  389. package/dist/mcp/tools/update-task.js +31 -30
  390. package/dist/{mcp-child-registry-DVHYAHPW.js → mcp-child-registry-TIZERM7O.js} +5 -5
  391. package/dist/{mcp-health-B5EKRCZG.js → mcp-health-4ZHU67LM.js} +9 -3
  392. package/dist/{mcp-http-config-ME67QDOF.js → mcp-http-config-VUMSFWFH.js} +12 -12
  393. package/dist/{mcp-session-identity-DNG4ULAE.js → mcp-session-identity-DZHWEJRV.js} +28 -27
  394. package/dist/{memory-cards-WCISXY62.js → memory-cards-JVXTMSAT.js} +10 -10
  395. package/dist/{memory-graph-extractor-GXIK4QUF.js → memory-graph-extractor-PPBJMYFJ.js} +10 -10
  396. package/dist/{memory-poisoning-defense-25LZ5FJI.js → memory-poisoning-defense-K5Q74XQ4.js} +5 -5
  397. package/dist/{memory-pressure-watchdog-XGXI7WGE.js → memory-pressure-watchdog-YMJH5CSA.js} +29 -28
  398. package/dist/{memory-queue-YF7IDSFY.js → memory-queue-2MA67TAA.js} +3 -3
  399. package/dist/{memory-queue-client-QC2OTMJB.js → memory-queue-client-4G7HVRSX.js} +11 -10
  400. package/dist/{memory-reflection-GFGT44NT.js → memory-reflection-7BZWIHRE.js} +10 -10
  401. package/dist/{monitor-grants-Z2SEFE6E.js → monitor-grants-Q7X3MYQP.js} +6 -6
  402. package/dist/{monitor-identity-AEMHCVHV.js → monitor-identity-ZQB4IXEE.js} +2 -2
  403. package/dist/{notification-ledger-ETQBGRP7.js → notification-ledger-XRAXL5OI.js} +32 -29
  404. package/dist/{notifications-LPRCFJYY.js → notifications-JE3PX55X.js} +28 -27
  405. package/dist/{orchestration-events-T2GXV2NG.js → orchestration-events-JCQ5F5IJ.js} +6 -6
  406. package/dist/{orchestration-phase-T2WD45UA.js → orchestration-phase-QKTGQ2YT.js} +3 -3
  407. package/dist/{orchestrator-HY2IB3NA.js → orchestrator-X65INDTR.js} +30 -29
  408. package/dist/{org-brief-session-UWFCFEEB.js → org-brief-session-3PQ22UIX.js} +19 -18
  409. package/dist/{org-consent-policy-XXMST37J.js → org-consent-policy-VGELJ7K7.js} +7 -6
  410. package/dist/{org-join-72QKM7JR.js → org-join-6TO5ZYUZ.js} +12 -12
  411. package/dist/{org-key-admin-YCIAYP7V.js → org-key-admin-XHYVRRAZ.js} +12 -12
  412. package/dist/{org-key-pin-F7BQPI5P.js → org-key-pin-TTTYGTQL.js} +6 -6
  413. package/dist/{org-membership-JQSU4Z5P.js → org-membership-Y7T2BS57.js} +7 -7
  414. package/dist/{org-partner-config-PVJ45SLC.js → org-partner-config-OP4NEUNF.js} +10 -10
  415. package/dist/{org-partner-runtime-U4CTLWLC.js → org-partner-runtime-YNVUNT2R.js} +20 -19
  416. package/dist/{org-row-visibility-WUX4N3FX.js → org-row-visibility-JBBXNYXD.js} +1 -1
  417. package/dist/{pipeline-router-2RMBCBRM.js → pipeline-router-EIBB7QNG.js} +6 -6
  418. package/dist/{plan-limits-Z47XYEJR.js → plan-limits-MEWXYLEN.js} +8 -8
  419. package/dist/{postinstall-failure-O6TSSNJB.js → postinstall-failure-VETYYWEZ.js} +3 -3
  420. package/dist/{pre-tool-use-impl-JPE6XMRJ.js → pre-tool-use-impl-C6KJY22W.js} +60 -49
  421. package/dist/{project-boot-UFQDAFU5.js → project-boot-VEYFCCSL.js} +2 -2
  422. package/dist/{project-name-V4IREGHO.js → project-name-UYORSNGE.js} +6 -6
  423. package/dist/{projection-worker-HAD6H3VJ.js → projection-worker-WYFDWS57.js} +5 -5
  424. package/dist/{prospective-memory-KIF4JLFF.js → prospective-memory-E6XBQFJA.js} +5 -5
  425. package/dist/{push-notifications-GDKRTYXH.js → push-notifications-M7YU63FY.js} +29 -28
  426. package/dist/{reproject-worktree-memories-SG4BZJ3Z.js → reproject-worktree-memories-B5XMGJSD.js} +28 -27
  427. package/dist/{reranker-G2AZ67JP.js → reranker-SRA4BR7N.js} +3 -3
  428. package/dist/{retrieval-health-GBJRXTBZ.js → retrieval-health-P2JPZUPV.js} +4 -4
  429. package/dist/{review-polling-VUZPAAGT.js → review-polling-KQPN7IQE.js} +29 -28
  430. package/dist/runtime/index.js +37 -36
  431. package/dist/{session-events-BI6NIFIR.js → session-events-6LDDKKY3.js} +29 -28
  432. package/dist/{session-kill-telemetry-HPBDOPHT.js → session-kill-telemetry-5DSRGWCL.js} +29 -28
  433. package/dist/{session-mcp-config-WFZAH6R5.js → session-mcp-config-F7RCERUG.js} +3 -3
  434. package/dist/{session-scope-UB3HA5E7.js → session-scope-XG5R3P3D.js} +28 -27
  435. package/dist/{setup-wizard-6XULOT3L.js → setup-wizard-7QFLZIKT.js} +5 -5
  436. package/dist/{shard-manager-DYEJ6ETD.js → shard-manager-HHHHV2KZ.js} +3 -3
  437. package/dist/{skill-refinement-MKBQIWZ6.js → skill-refinement-I5RMAHSC.js} +6 -6
  438. package/dist/{stack-generate-manifest-7ODQ6W2O.js → stack-generate-manifest-AKMZ3AUX.js} +246 -13
  439. package/dist/stack-init-5VKL5PL5.js +136 -0
  440. package/dist/{stack-promote-3UKJBJSP.js → stack-promote-34CE2HHF.js} +7 -6
  441. package/dist/{stack-release-5CVXMJM5.js → stack-release-5PGWV5D4.js} +123 -12
  442. package/dist/{stack-update-Z53KG2P5.js → stack-update-ZQQ5YYPJ.js} +20 -5
  443. package/dist/{steward-gate-OKUYYIX6.js → steward-gate-AQJ6KT2C.js} +6 -6
  444. package/dist/{subagent-brief-injection-T2CVQLAS.js → subagent-brief-injection-3GU7YAWY.js} +50 -42
  445. package/dist/{subagent-spawn-ledger-E6U3OY6Z.js → subagent-spawn-ledger-52I66CLW.js} +3 -3
  446. package/dist/{supervisor-handoff-SGLEPOCY.js → supervisor-handoff-BWJW6CKZ.js} +4 -4
  447. package/dist/{support-inbox-WJIDCKJC.js → support-inbox-NY5TB3FN.js} +12 -12
  448. package/dist/{support-outbox-G2NG2U5K.js → support-outbox-KNI3FR3G.js} +3 -2
  449. package/dist/{task-enforcement-JL5ADPS6.js → task-enforcement-CAA6D2MH.js} +29 -28
  450. package/dist/{task-request-inbox-54BRRFHZ.js → task-request-inbox-QBZVU66E.js} +9 -6
  451. package/dist/{task-scope-OBPZBID5.js → task-scope-NHXB4ZRN.js} +32 -27
  452. package/dist/{tasks-crud-YBCPT7TY.js → tasks-crud-JHSWL5NM.js} +28 -27
  453. package/dist/{tasks-notify-CEEQSDJF.js → tasks-notify-7PBE4U7T.js} +29 -28
  454. package/dist/{tasks-review-JIEI656P.js → tasks-review-PPPVEE62.js} +28 -27
  455. package/dist/{telemetry-upload-ZZSEZR2U.js → telemetry-upload-YU2VRNHX.js} +10 -10
  456. package/dist/{token-budget-AUFMEMQ2.js → token-budget-QCMWKG3K.js} +6 -6
  457. package/dist/{tool-capability-index-6HLZU437.js → tool-capability-index-7AWQAJRP.js} +1 -1
  458. package/dist/{tool-gates-VXITVRFQ.js → tool-gates-5Q3RSQEG.js} +1 -1
  459. package/dist/{tool-gates-JWVSAYTW.js → tool-gates-QD26D2NE.js} +1 -1
  460. package/dist/{tool-telemetry-RHSEK2TO.js → tool-telemetry-LTOIC64I.js} +1 -1
  461. package/dist/tui/App.js +43 -42
  462. package/dist/{tui-data-PBZNN5YB.js → tui-data-NDBXD6U7.js} +32 -31
  463. package/dist/{update-support-V3ZCJR6L.js → update-support-BMJM4NG7.js} +27 -26
  464. package/dist/{whatsapp-NAM2CRVQ.js → whatsapp-QQLDAHUX.js} +2 -2
  465. package/dist/{wiki-acl-NUBAPLCD.js → wiki-acl-W6WDCVCP.js} +1 -1
  466. package/dist/{work-claims-Q2NU6JON.js → work-claims-6DM32MGO.js} +6 -6
  467. package/dist/{work-state-heartbeat-HAQRV3RK.js → work-state-heartbeat-HG7D4AWJ.js} +1 -1
  468. package/dist/{worker-gate-NUUSQMBT.js → worker-gate-FTMW7GBB.js} +3 -3
  469. package/dist/{workflow-engine-GEWPU5YR.js → workflow-engine-ZWC6CCXE.js} +2 -2
  470. package/dist/{worktree-C7LFMRKW.js → worktree-EMQCPGFE.js} +7 -7
  471. package/dist/{worktree-ownership-guard-4LKMW6PW.js → worktree-ownership-guard-O6JQF2CL.js} +2 -2
  472. package/dist/{worktree-sweep-SYF62ANH.js → worktree-sweep-XVUJZBXV.js} +8 -8
  473. package/package.json +23 -7
  474. package/release-notes.json +39 -12
  475. package/stack.release.json +4 -4
  476. package/dist/mailbox-inbox-XE72D3AX.js +0 -10
  477. /package/dist/{chunk-QIEYJ4KZ.js → chunk-2KY7WZZF.js} +0 -0
  478. /package/dist/{chunk-T3667X2B.js → chunk-2Q2CD6CD.js} +0 -0
  479. /package/dist/{chunk-JZJZYKMW.js → chunk-AJK2PVQW.js} +0 -0
  480. /package/dist/{chunk-ZEGEFBZV.js → chunk-AWWDKF22.js} +0 -0
  481. /package/dist/{chunk-QNTKRGJ6.js → chunk-GIRD7O5X.js} +0 -0
  482. /package/dist/{chunk-FWA4MYTA.js → chunk-JRIH6I7D.js} +0 -0
  483. /package/dist/{chunk-C7H2D7LX.js → chunk-M4XY4JRK.js} +0 -0
  484. /package/dist/{chunk-Q3DN5J6F.js → chunk-P2VVMGMI.js} +0 -0
  485. /package/dist/{chunk-BRAIWGMF.js → chunk-Q46NYJ77.js} +0 -0
  486. /package/dist/{chunk-3LQ2N4H7.js → chunk-U2D6PJ5T.js} +0 -0
  487. /package/dist/{chunk-3O6OGZL3.js → chunk-XDVOGDBC.js} +0 -0
  488. /package/dist/{core-memory-UNCAPGD4.js → core-memory-O6D5UC3T.js} +0 -0
  489. /package/dist/{hook-tamper-log-Z4PWC7N4.js → hook-tamper-log-ARGWCXKJ.js} +0 -0
  490. /package/dist/{memory-isolation-ALPJWLR5.js → memory-isolation-EBFFC6HF.js} +0 -0
  491. /package/dist/{oauth-server-AC2KB7NB.js → oauth-server-ZKBUHDFI.js} +0 -0
  492. /package/dist/{webhook-pipe-W2FVXY7M.js → webhook-pipe-PXH5MBRM.js} +0 -0
  493. /package/dist/{wiki-client-W65IOSWF.js → wiki-client-DD2NVWK2.js} +0 -0
@@ -1,6 +1,8 @@
1
1
  // src/lib/registry-proxy.ts
2
2
  import { createServer } from "http";
3
3
  import { readFileSync } from "fs";
4
+ import path from "path";
5
+ import { fileURLToPath, pathToFileURL } from "url";
4
6
  import { Readable } from "stream";
5
7
 
6
8
  // src/lib/stack-release-publish.ts
@@ -136,7 +138,7 @@ async function assertManifestSignature(manifest, publicKeyPem) {
136
138
  "manifest carries no `signature`. Fleets that enforce EXE_STACK_PUBLIC_KEY reject unsigned manifests, so publishing one would ship a release no host can install. Re-sign with the custodied key: node scripts/sign-stack-manifest.mjs deploy/stack-manifests/v0.9.json"
137
139
  );
138
140
  }
139
- const { verifyStackManifestSignature } = await import("./stack-update-Z53KG2P5.js");
141
+ const { verifyStackManifestSignature } = await import("./stack-update-ZQQ5YYPJ.js");
140
142
  try {
141
143
  verifyStackManifestSignature(manifest, publicKeyPem);
142
144
  } catch (err) {
@@ -228,6 +230,94 @@ async function publishStackRelease(db, body, options) {
228
230
  await assertManifestSignature(validated.manifest, options.publicKeyPem);
229
231
  return insertStackRelease(db, validated);
230
232
  }
233
+ async function promoteStackRelease(db, body) {
234
+ const version = typeof body.version === "string" ? body.version.trim() : "";
235
+ if (!version) {
236
+ throw reject(400, "version_missing", "`version` is required and must be a non-empty string.");
237
+ }
238
+ const declaredSha = typeof body.manifestSha256 === "string" ? body.manifestSha256.trim().toLowerCase() : "";
239
+ if (!/^[a-f0-9]{64}$/.test(declaredSha)) {
240
+ throw reject(
241
+ 400,
242
+ "manifest_sha256_missing",
243
+ "`manifestSha256` is required (64 hex chars): a promotion must name the exact bytes it promotes, so it can never land on content the caller has not seen."
244
+ );
245
+ }
246
+ const existing = await db.query(
247
+ "SELECT manifest, manifest_sha256, status FROM billing.stack_releases WHERE version = $1",
248
+ [version]
249
+ );
250
+ const row = existing.rows[0];
251
+ if (!row) {
252
+ throw reject(
253
+ 409,
254
+ "version_not_published",
255
+ `stack version ${version} has no row in billing.stack_releases. Publish it first \u2014 promotion changes an existing release's status, it does not create one.`
256
+ );
257
+ }
258
+ const existingSha = String(row.manifest_sha256 ?? "");
259
+ if (existingSha !== declaredSha) {
260
+ throw reject(
261
+ 409,
262
+ "promote_content_mismatch",
263
+ `stack version ${version} holds sha256 ${existingSha || "<none>"} but this promotion declares ${declaredSha}. Refusing: the row does not contain the bytes you are promoting.`
264
+ );
265
+ }
266
+ const existingStatus = String(row.status ?? "");
267
+ if (existingStatus === "released") {
268
+ return { outcome: "already-released", version, manifestSha256: existingSha, status: "released" };
269
+ }
270
+ if (existingStatus !== "canary") {
271
+ throw reject(
272
+ 409,
273
+ "promote_status_invalid",
274
+ `stack version ${version} has status "${existingStatus || "<none>"}" \u2014 only a "canary" row can be promoted to released.`
275
+ );
276
+ }
277
+ const manifest = row.manifest;
278
+ let latest;
279
+ let rolloutStage;
280
+ try {
281
+ const parsed = (typeof manifest === "string" ? JSON.parse(manifest) : manifest) ?? {};
282
+ latest = parsed.latest;
283
+ rolloutStage = (parsed.stacks?.[version] ?? {}).rolloutStage;
284
+ } catch {
285
+ throw reject(
286
+ 409,
287
+ "promote_manifest_unreadable",
288
+ `stack version ${version} holds a manifest that could not be parsed, so its \`latest\` could not be checked. Refusing to promote something unverifiable.`
289
+ );
290
+ }
291
+ if (latest !== version) {
292
+ throw reject(
293
+ 409,
294
+ "promote_would_not_be_latest",
295
+ `stack version ${version} holds a manifest whose latest is "${String(latest)}". Promoting it would serve a released manifest that does not declare itself latest. A canary cut with --canary deliberately does not bump \`latest\` and is NOT promotable in place: re-cut it for GA with \`exe-os stack-promote --version ` + version + "`, which edits the manifest and publishes a new released row. Only a canary published from a latest-bumping manifest (publish --status canary) can be promoted by status alone."
296
+ );
297
+ }
298
+ if (rolloutStage === "canary") {
299
+ throw reject(
300
+ 409,
301
+ "promote_entry_declares_canary",
302
+ `stack version ${version} holds a SIGNED manifest whose stacks["${version}"].rolloutStage is "canary". Promotion changes status only \u2014 it cannot edit the signed bytes \u2014 so flipping this row would serve a release every updater refuses to install implicitly (assertRolloutStageAllowed). Re-cut it for GA with \`exe-os stack-promote --version ` + version + "`, which edits rolloutStage and re-signs. Status-only promotion is for an artifact that is already GA in its own bytes and was staged with `--status canary`."
303
+ );
304
+ }
305
+ const updated = await db.query(
306
+ `UPDATE billing.stack_releases
307
+ SET status = 'released'
308
+ WHERE version = $1 AND manifest_sha256 = $2 AND status = 'canary'
309
+ RETURNING version`,
310
+ [version, declaredSha]
311
+ );
312
+ if (updated.rows.length !== 1) {
313
+ throw reject(
314
+ 409,
315
+ "promote_race",
316
+ `stack version ${version} changed underneath this promotion (hash or status moved between read and write). Re-read the row and retry.`
317
+ );
318
+ }
319
+ return { outcome: "promoted", version, manifestSha256: declaredSha, status: "released" };
320
+ }
231
321
 
232
322
  // src/lib/registry-proxy.ts
233
323
  function readJsonSafe(url) {
@@ -244,16 +334,41 @@ function nonPlaceholderString(value) {
244
334
  if (!trimmed || trimmed === "unknown") return void 0;
245
335
  return trimmed;
246
336
  }
337
+ var BUILD_IDENTITY_MAX_WALK = 6;
338
+ function readJsonAt(file) {
339
+ return readJsonSafe(pathToFileURL(file));
340
+ }
247
341
  function resolveRegistryProxyBuildIdentity(moduleUrl = import.meta.url) {
248
- const pkg = readJsonSafe(new URL("../../package.json", moduleUrl));
249
- const stamp = readJsonSafe(new URL("../version.json", moduleUrl));
342
+ const startDir = path.dirname(fileURLToPath(new URL(String(moduleUrl))));
343
+ let pkg;
344
+ let appRoot;
345
+ let dir = startDir;
346
+ for (let level = 0; level <= BUILD_IDENTITY_MAX_WALK; level++) {
347
+ const candidate = readJsonAt(path.join(dir, "package.json"));
348
+ if (candidate && typeof candidate.version === "string") {
349
+ pkg = candidate;
350
+ appRoot = dir;
351
+ break;
352
+ }
353
+ const parent = path.dirname(dir);
354
+ if (parent === dir) break;
355
+ dir = parent;
356
+ }
357
+ const stamp = readJsonAt(path.join(startDir, "version.json")) ?? readJsonAt(path.join(path.dirname(startDir), "version.json")) ?? (appRoot ? readJsonAt(path.join(appRoot, "dist", "version.json")) : void 0);
250
358
  return {
251
359
  version: nonPlaceholderString(pkg?.version) ?? "unknown",
252
360
  buildSha: nonPlaceholderString(stamp?.sha),
253
- builtAt: nonPlaceholderString(stamp?.built)
361
+ builtAt: nonPlaceholderString(stamp?.built),
362
+ ...stamp?.ref !== void 0 ? { buildRef: nonPlaceholderString(stamp.ref) } : {},
363
+ ...stamp?.repo !== void 0 ? { buildRepo: nonPlaceholderString(stamp.repo) } : {}
254
364
  };
255
365
  }
256
366
  var BUILD_IDENTITY = resolveRegistryProxyBuildIdentity();
367
+ if (BUILD_IDENTITY.version === "unknown") {
368
+ console.error(
369
+ `[registry-proxy] BUILD IDENTITY UNRESOLVED \u2014 no package.json with a \`version\` was found within ${BUILD_IDENTITY_MAX_WALK} levels above ${import.meta.url}. GET /health and GET /__version will report version:"unknown", which leaves the serving-code drift axis of scripts/check-stack-release-drift.mjs blind (bug b01bbe35). This is a packaging defect in the image, not a runtime condition to wait out.`
370
+ );
371
+ }
257
372
  function parsePullTokens(raw) {
258
373
  return (raw ?? "").split(/[\n,]/).map((s) => s.trim()).filter(Boolean);
259
374
  }
@@ -343,6 +458,18 @@ function unauthorized(res, scheme = "Basic") {
343
458
  }
344
459
  var READ_ONLY_METHODS = ["GET", "HEAD"];
345
460
  var STACK_RELEASE_PUBLISH_PATH = "/v1/stack-releases";
461
+ var SERVED_VERSION_PATH = "/__version";
462
+ var STACK_RELEASE_PROMOTE_PATH = "/v1/stack-releases/promote";
463
+ var STACK_MANIFEST_CHANNELS = ["released", "canary"];
464
+ function resolveStackManifestChannel(raw) {
465
+ if (raw === null || raw === "") return { channel: "released" };
466
+ if (STACK_MANIFEST_CHANNELS.includes(raw)) {
467
+ return { channel: raw };
468
+ }
469
+ return {
470
+ error: `unknown channel "${raw}" \u2014 expected one of ${STACK_MANIFEST_CHANNELS.join(", ")}. Refusing rather than falling back to the released channel: a caller that asked for something this endpoint does not understand must not be handed something else.`
471
+ };
472
+ }
346
473
  function isReadOnlyRegistryMethod(method) {
347
474
  return readOnlyRegistryMethod(method) !== null;
348
475
  }
@@ -423,9 +550,15 @@ function classifyRegistryProxyRequest(req, namespace) {
423
550
  if (url.pathname === "/health") {
424
551
  return method ? { kind: "health", method, url } : { kind: "method-not-allowed", method: req.method, url };
425
552
  }
553
+ if (url.pathname === SERVED_VERSION_PATH) {
554
+ return method ? { kind: "served-version", method, url } : { kind: "method-not-allowed", method: req.method, url };
555
+ }
426
556
  if (url.pathname === "/v1/stack-manifest.json") {
427
557
  return method ? { kind: "stack-manifest", method, url } : { kind: "method-not-allowed", method: req.method, url };
428
558
  }
559
+ if (url.pathname === STACK_RELEASE_PROMOTE_PATH) {
560
+ return (req.method ?? "").toUpperCase() === "POST" ? { kind: "stack-release-promote", url } : { kind: "method-not-allowed", method: req.method, url, allow: ["POST"] };
561
+ }
429
562
  if (url.pathname === STACK_RELEASE_PUBLISH_PATH) {
430
563
  return (req.method ?? "").toUpperCase() === "POST" ? { kind: "stack-release-publish", url } : { kind: "method-not-allowed", method: req.method, url, allow: ["POST"] };
431
564
  }
@@ -434,7 +567,7 @@ function classifyRegistryProxyRequest(req, namespace) {
434
567
  return method ? { kind: "registry-read", method, url } : { kind: "method-not-allowed", method: req.method, url };
435
568
  }
436
569
  if (pathKind === "write" && !method) {
437
- return { kind: "method-not-allowed", method: req.method, url };
570
+ return { kind: "method-not-allowed", method: req.method, url, attemptedWrite: true };
438
571
  }
439
572
  return { kind: "not-found", url };
440
573
  }
@@ -530,6 +663,15 @@ function createRegistryProxyServer(options) {
530
663
  unauthorized(res, "Bearer");
531
664
  return;
532
665
  }
666
+ const resolved = resolveStackManifestChannel(
667
+ new URL(req.url ?? "/", "http://localhost").searchParams.get("channel")
668
+ );
669
+ if ("error" in resolved) {
670
+ res.writeHead(400, { "content-type": "application/json" });
671
+ res.end(JSON.stringify({ error: resolved.error, code: "channel_invalid" }));
672
+ return;
673
+ }
674
+ const channel = resolved.channel;
533
675
  const pool = await getManifestPool();
534
676
  if (!pool) {
535
677
  res.writeHead(503, { "content-type": "application/json" });
@@ -539,11 +681,15 @@ function createRegistryProxyServer(options) {
539
681
  try {
540
682
  const result = await pool.query(
541
683
  "SELECT manifest FROM billing.stack_releases WHERE status = $1 ORDER BY string_to_array(version, '.')::int[] DESC LIMIT 1",
542
- ["released"]
684
+ [channel]
543
685
  );
544
686
  if (result.rows.length === 0) {
545
687
  res.writeHead(503, { "content-type": "application/json" });
546
- res.end(JSON.stringify({ error: "no released stack manifest available" }));
688
+ res.end(JSON.stringify({
689
+ error: `no ${channel} stack manifest available`,
690
+ code: "no_manifest_for_channel",
691
+ channel
692
+ }));
547
693
  return;
548
694
  }
549
695
  const manifest = result.rows[0].manifest;
@@ -635,12 +781,72 @@ function createRegistryProxyServer(options) {
635
781
  res.end(JSON.stringify({ error: "stack release publish failed", code: "publish_failed", detail }));
636
782
  }
637
783
  }
784
+ async function handleStackReleasePromote(req, res) {
785
+ const publisherTokens = options.publisherTokens ?? [];
786
+ const token = parseBearerToken(req.headers.authorization);
787
+ if (publisherTokens.length === 0) {
788
+ console.error(
789
+ "[registry-proxy] promote attempt refused: EXE_REGISTRY_PROXY_PUBLISHER_TOKENS is not configured."
790
+ );
791
+ res.writeHead(503, { "content-type": "application/json" });
792
+ res.end(JSON.stringify({
793
+ error: "stack release publishing is not enabled on this host",
794
+ code: "publisher_not_configured"
795
+ }));
796
+ return;
797
+ }
798
+ if (!token || !constantTimeTokenMatch(token, publisherTokens)) {
799
+ console.warn(
800
+ `[registry-proxy] REFUSED stack-release promote: bad or missing publisher token from ${req.socket.remoteAddress ?? "unknown"}.`
801
+ );
802
+ res.writeHead(401, { "content-type": "application/json" });
803
+ res.end(JSON.stringify({ error: "publisher authentication required", code: "publisher_unauthorized" }));
804
+ return;
805
+ }
806
+ try {
807
+ const body = await readJsonBody(req, 64 * 1024);
808
+ const pool = await getManifestPool();
809
+ if (!pool) {
810
+ throw new StackReleasePublishError({
811
+ httpStatus: 503,
812
+ code: "release_store_unavailable",
813
+ detail: "no database configured/reachable for billing.stack_releases"
814
+ });
815
+ }
816
+ const result = await promoteStackRelease(pool, body);
817
+ console.log(
818
+ `[registry-proxy] stack release ${result.version} ${result.outcome} (status=${result.status}, manifest_sha256=${result.manifestSha256}).`
819
+ );
820
+ res.writeHead(200, { "content-type": "application/json" });
821
+ res.end(JSON.stringify(result));
822
+ } catch (err) {
823
+ if (err instanceof StackReleasePublishError) {
824
+ const { httpStatus, code, detail: detail2 } = err.rejection;
825
+ console.error(`[registry-proxy] stack-release promote REFUSED (${httpStatus} ${code}): ${detail2}`);
826
+ res.writeHead(httpStatus, { "content-type": "application/json" });
827
+ res.end(JSON.stringify({ error: detail2, code }));
828
+ return;
829
+ }
830
+ const detail = err instanceof Error ? err.message : String(err);
831
+ console.error(`[registry-proxy] stack-release promote FAILED: ${detail}`);
832
+ res.writeHead(500, { "content-type": "application/json" });
833
+ res.end(JSON.stringify({ error: "stack release promote failed", code: "promote_failed", detail }));
834
+ }
835
+ }
638
836
  return createServer(async (req, res) => {
639
837
  const route = classifyRegistryProxyRequest(req, namespace);
640
838
  if (route.kind === "method-not-allowed") {
641
- console.warn(
642
- `[registry-proxy] BLOCKED write attempt: ${req.method} ${route.url?.pathname ?? "<unparseable>"} from ${req.socket.remoteAddress ?? "unknown"} \u2014 proxy is pull-through only.`
643
- );
839
+ const addr = req.socket.remoteAddress ?? "unknown";
840
+ const pathname = route.url?.pathname ?? "<unparseable>";
841
+ if (route.attemptedWrite) {
842
+ console.warn(
843
+ `[registry-proxy] BLOCKED write attempt: ${req.method} ${pathname} from ${addr} \u2014 proxy is pull-through only.`
844
+ );
845
+ } else {
846
+ console.warn(
847
+ `[registry-proxy] 405 method not allowed: ${req.method} ${pathname} from ${addr} (allow: ${(route.allow ?? READ_ONLY_METHODS).join(", ")})`
848
+ );
849
+ }
644
850
  methodNotAllowed(res, req.method, route.allow);
645
851
  return;
646
852
  }
@@ -648,6 +854,18 @@ function createRegistryProxyServer(options) {
648
854
  notFound(res);
649
855
  return;
650
856
  }
857
+ if (route.kind === "served-version") {
858
+ res.writeHead(200, { "content-type": "application/json", "cache-control": "no-store" });
859
+ res.end(JSON.stringify({
860
+ service: "exe-registry-proxy",
861
+ version: BUILD_IDENTITY.version,
862
+ ...BUILD_IDENTITY.buildSha ? { sha: BUILD_IDENTITY.buildSha } : {},
863
+ ...BUILD_IDENTITY.buildRef ? { ref: BUILD_IDENTITY.buildRef } : {},
864
+ ...BUILD_IDENTITY.buildRepo ? { repo: BUILD_IDENTITY.buildRepo } : {},
865
+ ...BUILD_IDENTITY.builtAt ? { built: BUILD_IDENTITY.builtAt } : {}
866
+ }));
867
+ return;
868
+ }
651
869
  if (route.kind === "health") {
652
870
  res.writeHead(200, { "content-type": "application/json" });
653
871
  res.end(JSON.stringify({
@@ -669,6 +887,10 @@ function createRegistryProxyServer(options) {
669
887
  await handleStackReleasePublish(req, res);
670
888
  return;
671
889
  }
890
+ if (route.kind === "stack-release-promote") {
891
+ await handleStackReleasePromote(req, res);
892
+ return;
893
+ }
672
894
  const auth = parseBasicAuth(req.headers.authorization);
673
895
  if (!auth) {
674
896
  unauthorized(res);
@@ -715,7 +937,7 @@ async function runRegistryProxy(options = registryProxyOptionsFromEnv()) {
715
937
  await new Promise((resolve) => server.listen(options.port, options.host, resolve));
716
938
  console.log(`exe-registry-proxy listening on ${options.host ?? "0.0.0.0"}:${options.port}`);
717
939
  console.log(`proxying /v2/${options.allowedNamespace ?? "askexe"}/* -> ${options.upstream ?? "https://ghcr.io"}`);
718
- const { licenseSyncConfigFromEnv, startLicenseSyncScheduler } = await import("./license-sync-ZCZ2LIHK.js");
940
+ const { licenseSyncConfigFromEnv, startLicenseSyncScheduler } = await import("./license-sync-BVSG3WMW.js");
719
941
  const syncConfig = licenseSyncConfigFromEnv();
720
942
  if (syncConfig) {
721
943
  startLicenseSyncScheduler(syncConfig);
@@ -731,6 +953,10 @@ export {
731
953
  registryProxyOptionsFromEnv,
732
954
  assertRegistryProxyConfig,
733
955
  STACK_RELEASE_PUBLISH_PATH,
956
+ SERVED_VERSION_PATH,
957
+ STACK_RELEASE_PROMOTE_PATH,
958
+ STACK_MANIFEST_CHANNELS,
959
+ resolveStackManifestChannel,
734
960
  isReadOnlyRegistryMethod,
735
961
  createRegistryProxyServer,
736
962
  runRegistryProxy
@@ -5,26 +5,26 @@ import {
5
5
  behaviorTruncationNotice,
6
6
  fetchInjectableBehaviors,
7
7
  selectInjectedBehaviors
8
- } from "./chunk-VZT66WWP.js";
8
+ } from "./chunk-4AAMFWJT.js";
9
9
  import {
10
10
  countActiveBehaviors,
11
11
  listBehaviors
12
- } from "./chunk-2YIB75UQ.js";
12
+ } from "./chunk-S26CV7BE.js";
13
13
  import {
14
14
  lightweightSearch
15
- } from "./chunk-TXTXC3QG.js";
15
+ } from "./chunk-3RGTLZNO.js";
16
16
  import {
17
17
  getCurrentSessionScope
18
- } from "./chunk-ZVBVPX4W.js";
18
+ } from "./chunk-7UHZBVP3.js";
19
19
  import {
20
20
  getSessionKey
21
21
  } from "./chunk-CVYC6DUW.js";
22
22
  import {
23
23
  getProjectName
24
- } from "./chunk-22LNFCDF.js";
24
+ } from "./chunk-UX2EO653.js";
25
25
  import {
26
26
  getClient
27
- } from "./chunk-AY2U4NZ5.js";
27
+ } from "./chunk-GL47M7NY.js";
28
28
 
29
29
  // src/lib/session-summary.ts
30
30
  var MAX_CHARS = 800;
@@ -160,17 +160,23 @@ function sanitizeSegment(s) {
160
160
  function sanitizeSessionKey(sessionKey) {
161
161
  return sanitizeSegment(sessionKey) || `unknown-${process.pid}`;
162
162
  }
163
- function sessionScratchDir(sessionKey, homeDir = os.homedir(), agentId) {
163
+ var MAIN_LOOP_INSTANCE = "main";
164
+ function scratchInstanceSegment(instanceId) {
165
+ if (typeof instanceId !== "string") return "";
166
+ return sanitizeSegment(instanceId);
167
+ }
168
+ function sessionScratchDir(sessionKey, homeDir = os.homedir(), agentId, instanceId) {
164
169
  const base = path.join(homeDir, ".exe-os", "session-cache", "scratch", sanitizeSessionKey(sessionKey));
165
- if (agentId === void 0) return base;
166
- const agentSegment = sanitizeSegment(agentId);
167
- return agentSegment ? path.join(base, agentSegment) : base;
170
+ const agentSegment = agentId === void 0 ? "" : sanitizeSegment(agentId);
171
+ const instanceSegment = scratchInstanceSegment(instanceId);
172
+ const segments = [agentSegment, instanceSegment].filter((s) => s.length > 0);
173
+ return segments.length > 0 ? path.join(base, ...segments) : base;
168
174
  }
169
- function resolveSessionScratchDir(homeDir = os.homedir(), agentId) {
170
- return sessionScratchDir(getSessionKey(), homeDir, agentId);
175
+ function resolveSessionScratchDir(homeDir = os.homedir(), agentId, instanceId) {
176
+ return sessionScratchDir(getSessionKey(), homeDir, agentId, instanceId);
171
177
  }
172
- function ensureSessionScratchDir(sessionKey, homeDir = os.homedir(), agentId) {
173
- const dir = sessionKey === void 0 ? resolveSessionScratchDir(homeDir, agentId) : sessionScratchDir(sessionKey, homeDir, agentId);
178
+ function ensureSessionScratchDir(sessionKey, homeDir = os.homedir(), agentId, instanceId) {
179
+ const dir = sessionKey === void 0 ? resolveSessionScratchDir(homeDir, agentId, instanceId) : sessionScratchDir(sessionKey, homeDir, agentId, instanceId);
174
180
  try {
175
181
  mkdirSync(dir, { recursive: true });
176
182
  } catch {
@@ -320,6 +326,28 @@ async function activeBehaviorBrief(agentId, projectName) {
320
326
  const injected = selectInjectedBehaviors(behaviors, BEHAVIOR_LIMIT);
321
327
  return renderBehaviorSection(injected, counts);
322
328
  }
329
+ function renderScratchSection(scratchDir, isolated) {
330
+ const shared = [
331
+ "The `scratchpad` path in your harness system prompt (e.g. /tmp/claude-*/<project>/<session>/scratchpad) is a DIFFERENT directory and is SHARED by every agent in this session, including the one that dispatched you. Do not put commit messages, PR bodies or anything you will consume back into it.",
332
+ "CLEANUP: delete only files you created yourself. Never `rm -rf` a scratch directory \u2014 list it first; files you do not recognise belong to another agent and may be in active use."
333
+ ];
334
+ if (isolated) {
335
+ return [
336
+ "## Private Scratch Directory",
337
+ "Unique to THIS agent instance (session + employee + spawn instance), so a concurrent agent \u2014 including another agent with your own identity \u2014 resolves a different directory:",
338
+ scratchDir,
339
+ "Write named intermediate artifacts (pr.md, commit messages, diffs, generated code, files staged for commit) HERE.",
340
+ ...shared
341
+ ].join("\n");
342
+ }
343
+ return [
344
+ "## Shared Scratch Directory \u2014 NOT private",
345
+ "This directory is scoped to your session and employee identity but NOT to your agent instance, because no instance id was available. Other agents running right now under the same identity resolve this SAME path:",
346
+ scratchDir,
347
+ "So: prefix every filename you write with a discriminator of your own (`$$` works), and verify a file's first line before consuming it \u2014 a file being present does NOT mean you wrote it. Never `git commit -F <file>` without checking that file's content in the same command.",
348
+ ...shared
349
+ ].join("\n");
350
+ }
323
351
  async function buildEmployeeBootBriefInner(input, degraded) {
324
352
  const agentId = input.agentId.trim();
325
353
  const projectName = input.projectName ?? getProjectName(input.cwd);
@@ -330,9 +358,11 @@ async function buildEmployeeBootBriefInner(input, degraded) {
330
358
  runSection("memories", () => recentProjectMemories(agentId, projectName, sessionScope ?? null, input.mode), "", degraded),
331
359
  runSection("behaviors", () => activeBehaviorBrief(agentId, projectName), "", degraded)
332
360
  ]);
361
+ const instanceId = input.mode === "session-start" ? MAIN_LOOP_INSTANCE : input.agentInstanceId ?? "";
362
+ const scratchIsolated = scratchInstanceSegment(instanceId).length > 0;
333
363
  let scratchDir = "";
334
364
  try {
335
- scratchDir = ensureSessionScratchDir(void 0, void 0, agentId);
365
+ scratchDir = ensureSessionScratchDir(void 0, void 0, agentId, instanceId);
336
366
  } catch {
337
367
  scratchDir = "";
338
368
  }
@@ -346,12 +376,7 @@ ${capBlock(summary, SUMMARY_CAP)}`);
346
376
  if (workingMemory) sections.push(`## Working Memory (auto-loaded)
347
377
  ${capBlock(workingMemory.trim(), WORKING_MEMORY_CAP)}`);
348
378
  if (scratchDir) {
349
- sections.push([
350
- "## Isolated Scratch Directory",
351
- `Per-session scratch dir (unique to THIS session, safe from concurrent agents):`,
352
- scratchDir,
353
- "Write named intermediate artifacts (pr.md, diffs, generated code, files staged for commit) HERE, not in a shared temp path. A file you place here cannot be read or overwritten by another agent's session."
354
- ].join("\n"));
379
+ sections.push(renderScratchSection(scratchDir, scratchIsolated));
355
380
  }
356
381
  if (memories) sections.push(`## Memory Brief
357
382
  Recent memories from this project:
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getClient
3
- } from "./chunk-AY2U4NZ5.js";
3
+ } from "./chunk-GL47M7NY.js";
4
4
 
5
5
  // src/lib/pipeline-router.ts
6
6
  import crypto from "crypto";
@@ -116,12 +116,12 @@ async function sinkCRM(msg, agentResponse, agentName) {
116
116
  }
117
117
  async function sinkWiki(msg, agentResponse) {
118
118
  try {
119
- const { createWikiClient } = await import("./wiki-client-W65IOSWF.js");
119
+ const { createWikiClient } = await import("./wiki-client-DD2NVWK2.js");
120
120
  const client = await createWikiClient();
121
121
  if (!client) return false;
122
122
  const content = msg.text ?? "";
123
123
  if (content.length < 50) return false;
124
- const { chatInWorkspace } = await import("./wiki-client-W65IOSWF.js");
124
+ const { chatInWorkspace } = await import("./wiki-client-DD2NVWK2.js");
125
125
  const ingestText = [
126
126
  `[${msg.platform}] Message from ${msg.senderName ?? msg.senderId} (${msg.timestamp}):`,
127
127
  content,
@@ -140,8 +140,8 @@ Agent response: ${agentResponse}` : ""
140
140
  }
141
141
  async function sinkEntityExtraction(msg, agentResponse, agentName) {
142
142
  try {
143
- const { extractFromConversation } = await import("./conversation-entity-extractor-4UG7BKWL.js");
144
- const { storeExtraction } = await import("./graph-rag-TZLH3CTQ.js");
143
+ const { extractFromConversation } = await import("./conversation-entity-extractor-7FRKLLBD.js");
144
+ const { storeExtraction } = await import("./graph-rag-BKAD2XQA.js");
145
145
  if ((msg.text?.length ?? 0) < 20) return false;
146
146
  if (msg.isHistorical) return false;
147
147
  const extraction = await extractFromConversation(msg, agentResponse, agentName);
@@ -149,7 +149,7 @@ async function sinkEntityExtraction(msg, agentResponse, agentName) {
149
149
  const client = getClient();
150
150
  const memoryId = `conv:${msg.messageId}`;
151
151
  await storeExtraction(client, extraction, memoryId, msg.timestamp);
152
- import("./conversation-wiki-populator-OS4C6W54.js").then(
152
+ import("./conversation-wiki-populator-YAOVCUGO.js").then(
153
153
  ({ populateWikiFromExtraction }) => populateWikiFromExtraction(extraction, msg, agentResponse, agentName)
154
154
  ).catch((err) => {
155
155
  process.stderr.write(
@@ -1,15 +1,16 @@
1
1
  import {
2
+ isTransientDaemonTransportError,
2
3
  retryOnDaemonTransportError
3
- } from "./chunk-QV5CQLQH.js";
4
+ } from "./chunk-EIOGV75A.js";
4
5
  import {
5
6
  vectorToSqlLiteral
6
- } from "./chunk-CO5ZVE3D.js";
7
+ } from "./chunk-UOPCVFVR.js";
7
8
  import {
8
9
  blobToVector
9
10
  } from "./chunk-OTVEIJUQ.js";
10
11
  import {
11
12
  getClient
12
- } from "./chunk-AY2U4NZ5.js";
13
+ } from "./chunk-GL47M7NY.js";
13
14
 
14
15
  // src/lib/behaviors.ts
15
16
  import crypto from "crypto";
@@ -121,15 +122,45 @@ async function storeBehavior(opts) {
121
122
  } catch {
122
123
  }
123
124
  }
124
- await retryOnDaemonTransportError(async () => {
125
- await getClient().execute({
126
- sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector, created_by_agent, created_by_device, source_session_id, device_id)
127
- VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?)`,
128
- args: [id, trimmedAgent, opts.projectName ?? null, opts.domain ?? null, opts.priority ?? "p1", trimmedContent, now, now, vector ? vectorToSqlLiteral(vector) : null, createdByAgent, createdByDevice, sourceSessionId, deviceId]
125
+ try {
126
+ await retryOnDaemonTransportError(async () => {
127
+ await getClient().execute({
128
+ sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector, created_by_agent, created_by_device, source_session_id, device_id)
129
+ VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?)`,
130
+ args: [id, trimmedAgent, opts.projectName ?? null, opts.domain ?? null, opts.priority ?? "p1", trimmedContent, now, now, vector ? vectorToSqlLiteral(vector) : null, createdByAgent, createdByDevice, sourceSessionId, deviceId]
131
+ });
129
132
  });
130
- });
133
+ } catch (err) {
134
+ if (!isTransientDaemonTransportError(err) && !isSelfInsertConflict(err)) throw err;
135
+ const landed = await behaviorRowExists(id);
136
+ if (landed === true) return id;
137
+ if (landed === null) {
138
+ const cause = err instanceof Error ? err.message : String(err);
139
+ throw new Error(
140
+ `[behaviors] Behavior store outcome is UNKNOWN for id ${id}. The daemon transport failed after the write was dispatched (${cause}), and the read-back that would settle whether it committed also failed. The row may or may not exist. Retrying this exact store is SAFE: the duplicate guard returns the existing row instead of inserting a second copy. Do NOT report that the behavior was not stored \u2014 that is not known.`
141
+ );
142
+ }
143
+ throw err;
144
+ }
131
145
  return id;
132
146
  }
147
+ function isSelfInsertConflict(err) {
148
+ const msg = err instanceof Error ? err.message : String(err ?? "");
149
+ return /UNIQUE constraint failed:\s*behaviors\.id/i.test(msg) || /PRIMARY KEY (?:constraint )?(?:must be unique|failed)/i.test(msg);
150
+ }
151
+ async function behaviorRowExists(id) {
152
+ try {
153
+ const check = await retryOnDaemonTransportError(async () => {
154
+ return await getClient().execute({
155
+ sql: "SELECT id FROM behaviors WHERE id = ? LIMIT 1",
156
+ args: [id]
157
+ });
158
+ });
159
+ return check.rows.length > 0;
160
+ } catch {
161
+ return null;
162
+ }
163
+ }
133
164
  async function countActiveBehaviors(agentId, projectName) {
134
165
  const client = getClient();
135
166
  let currentDeviceId = null;
@@ -157,7 +188,7 @@ async function countActiveBehaviors(agentId, projectName) {
157
188
  p0: Number(row?.p0 ?? 0)
158
189
  };
159
190
  }
160
- async function listBehaviors(agentId, projectName, limit = 30) {
191
+ async function listBehaviors(agentId, projectName, limit = 30, opts = {}) {
161
192
  const client = getClient();
162
193
  let currentDeviceId = null;
163
194
  try {
@@ -165,6 +196,14 @@ async function listBehaviors(agentId, projectName, limit = 30) {
165
196
  currentDeviceId = loadDeviceId() ?? null;
166
197
  } catch {
167
198
  }
199
+ const CANONICAL_UTC_GLOB = "'[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]Z'";
200
+ const MODIFIED_AT = "coalesce(nullif(trim(coalesce(updated_at, '')), ''), created_at)";
201
+ const cutoff = opts.unchangedAtOrBefore && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(opts.unchangedAtOrBefore) ? opts.unchangedAtOrBefore : void 0;
202
+ const stabilityClause = cutoff ? `AND (${MODIFIED_AT} <= ?
203
+ OR ${MODIFIED_AT} NOT GLOB ${CANONICAL_UTC_GLOB})` : "";
204
+ const stabilityArgs = cutoff ? [cutoff] : [];
205
+ const idClause = opts.id ? "AND id = ?" : "";
206
+ const idArgs = opts.id ? [opts.id] : [];
168
207
  const { offloadReadIfMain } = await import("./lib/database.js");
169
208
  const result = await offloadReadIfMain(
170
209
  client,
@@ -174,6 +213,8 @@ async function listBehaviors(agentId, projectName, limit = 30) {
174
213
  AND id IS NOT NULL AND trim(coalesce(content, '')) != ''
175
214
  AND (project_name IS NULL OR project_name = ?)
176
215
  AND (device_id IS NULL OR device_id = ?)
216
+ ${stabilityClause}
217
+ ${idClause}
177
218
  ORDER BY
178
219
  CASE WHEN priority = 'p0' THEN 0
179
220
  WHEN priority = 'p1' THEN 1
@@ -187,7 +228,7 @@ async function listBehaviors(agentId, projectName, limit = 30) {
187
228
  END,
188
229
  updated_at DESC
189
230
  LIMIT ?`,
190
- [agentId, projectName ?? "", currentDeviceId ?? "", limit],
231
+ [agentId, projectName ?? "", currentDeviceId ?? "", ...stabilityArgs, ...idArgs, limit],
191
232
  true
192
233
  );
193
234
  return result.rows.map((r) => ({
@@ -273,7 +314,7 @@ async function listBehaviorsSince(agentId, sinceIso, projectName, limit = 15) {
273
314
  device_id: r.device_id ? String(r.device_id) : null
274
315
  }));
275
316
  }
276
- async function listSharedSkills(currentAgentId, projectName, limit = 30) {
317
+ async function listSharedSkills(currentAgentId, projectName, limit = 30, priority) {
277
318
  const client = getClient();
278
319
  let currentDeviceId = null;
279
320
  try {
@@ -281,6 +322,8 @@ async function listSharedSkills(currentAgentId, projectName, limit = 30) {
281
322
  currentDeviceId = loadDeviceId() ?? null;
282
323
  } catch {
283
324
  }
325
+ const priorityClause = priority ? "AND coalesce(priority, 'p1') = ?" : "";
326
+ const priorityArgs = priority ? [priority] : [];
284
327
  const result = await client.execute({
285
328
  sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector, created_by_agent, created_by_device, source_session_id, device_id
286
329
  FROM behaviors
@@ -288,11 +331,12 @@ async function listSharedSkills(currentAgentId, projectName, limit = 30) {
288
331
  AND id IS NOT NULL AND trim(coalesce(content, '')) != ''
289
332
  AND (project_name IS NULL OR project_name = ?)
290
333
  AND (device_id IS NULL OR device_id = ?)
334
+ ${priorityClause}
291
335
  ORDER BY
292
336
  CASE WHEN agent_id = ? THEN 0 ELSE 1 END,
293
337
  updated_at DESC
294
338
  LIMIT ?`,
295
- args: [projectName ?? "", currentDeviceId ?? "", currentAgentId, limit]
339
+ args: [projectName ?? "", currentDeviceId ?? "", ...priorityArgs, currentAgentId, limit]
296
340
  });
297
341
  return result.rows.map((r) => ({
298
342
  id: String(r.id),