@askexenow/exe-os 0.9.312 → 0.9.313

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 (344) hide show
  1. package/deploy/compose/.env.askexe-control-plane.example +1 -1
  2. package/deploy/compose/.env.customer.example +11 -7
  3. package/deploy/compose/.env.default +4 -4
  4. package/deploy/compose/.env.example +7 -7
  5. package/deploy/compose/docker-compose.yml +43 -19
  6. package/deploy/compose/gateway.json +2 -2
  7. package/deploy/compose/init-db.sql +6 -20
  8. package/deploy/compose/setup.sh +74 -132
  9. package/deploy/compose/status.sh +5 -0
  10. package/deploy/stack-manifests/v0.9.json +21 -0
  11. package/dist/{active-agent-ORX47ZKW.js → active-agent-EWF2HJ3W.js} +6 -6
  12. package/dist/{active-agent-S5T2YMOR.js → active-agent-FFN5ARMC.js} +6 -6
  13. package/dist/{agentic-ontology-6KBAXLSJ.js → agentic-ontology-AAUATKUS.js} +1 -1
  14. package/dist/{backfill-metadata-FV7GX6AS.js → backfill-metadata-FBYFDOTH.js} +7 -7
  15. package/dist/{background-jobs-A2LV36UX.js → background-jobs-2QZ5IQKE.js} +5 -3
  16. package/dist/{behaviors-47CPEKJ7.js → behaviors-PQ77IPJR.js} +8 -8
  17. package/dist/bin/age-ontology-load.js +3 -3
  18. package/dist/bin/agentic-ontology-backfill.js +9 -9
  19. package/dist/bin/agentic-reflection-backfill.js +10 -10
  20. package/dist/bin/agentic-semantic-label.js +9 -9
  21. package/dist/bin/backfill-conversations.js +10 -10
  22. package/dist/bin/backfill-responses.js +10 -10
  23. package/dist/bin/backfill-vectors.js +13 -13
  24. package/dist/bin/bulk-sync-postgres.js +16 -16
  25. package/dist/bin/cc-doctor.js +9 -9
  26. package/dist/bin/cleanup-stale-review-tasks.js +15 -15
  27. package/dist/bin/cli.js +21 -21
  28. package/dist/bin/deferred-daemon-restart.js +1 -1
  29. package/dist/bin/exe-agent-config.js +6 -6
  30. package/dist/bin/exe-agent.js +14 -14
  31. package/dist/bin/exe-assign.js +12 -12
  32. package/dist/bin/exe-boot.js +78 -57
  33. package/dist/bin/exe-call.js +7 -7
  34. package/dist/bin/exe-cloud.js +17 -17
  35. package/dist/bin/exe-config-dump.js +7 -7
  36. package/dist/bin/exe-dispatch.js +15 -15
  37. package/dist/bin/exe-doctor.js +11 -2
  38. package/dist/bin/exe-export-behaviors.js +10 -10
  39. package/dist/bin/exe-forget.js +9 -9
  40. package/dist/bin/exe-gateway.js +10 -10
  41. package/dist/bin/exe-healthcheck.js +9 -9
  42. package/dist/bin/exe-heartbeat.js +15 -15
  43. package/dist/bin/exe-kill.js +18 -18
  44. package/dist/bin/exe-launch-agent.js +30 -28
  45. package/dist/bin/exe-new-employee.js +36 -15
  46. package/dist/bin/exe-pending-messages.js +16 -16
  47. package/dist/bin/exe-pending-notifications.js +15 -15
  48. package/dist/bin/exe-pending-reviews.js +15 -15
  49. package/dist/bin/exe-preflight.js +1 -1
  50. package/dist/bin/exe-rename.js +19 -29
  51. package/dist/bin/exe-review.js +17 -17
  52. package/dist/bin/exe-search.js +8 -8
  53. package/dist/bin/exe-session-cleanup.js +41 -20
  54. package/dist/bin/exe-settings.js +18 -18
  55. package/dist/bin/exe-start-codex.js +15 -15
  56. package/dist/bin/exe-start-opencode.js +11 -11
  57. package/dist/bin/exe-status.js +16 -16
  58. package/dist/bin/exe-support.js +5 -5
  59. package/dist/bin/exe-team.js +6 -6
  60. package/dist/bin/exe-watchdog.js +32 -3
  61. package/dist/bin/git-sweep.js +16 -16
  62. package/dist/bin/graph-backfill.js +8 -8
  63. package/dist/bin/graph-export.js +8 -8
  64. package/dist/bin/import-history.js +10 -10
  65. package/dist/bin/install-launchd.js +2 -2
  66. package/dist/bin/install.js +15 -15
  67. package/dist/bin/intercom-check.js +4 -4
  68. package/dist/bin/mcp-sessions.js +2 -2
  69. package/dist/bin/orchestration-metrics.js +7 -7
  70. package/dist/bin/postgres-agentic-reflection-backfill.js +5 -5
  71. package/dist/bin/postgres-agentic-semantic-backfill.js +4 -4
  72. package/dist/bin/pre-build-guard.js +12 -1
  73. package/dist/bin/scan-tasks.js +15 -15
  74. package/dist/bin/setup.js +3 -3
  75. package/dist/bin/shard-migrate.js +8 -8
  76. package/dist/bin/stack-update.js +8 -8
  77. package/dist/bin/verify-stack.js +3 -1
  78. package/dist/bin/vps-health-gate.js +1 -1
  79. package/dist/{branding-SC4BOPUY.js → branding-EDUC7TUP.js} +2 -2
  80. package/dist/{browser-session-store-DV5TDXXD.js → browser-session-store-CXQMOSEC.js} +1 -1
  81. package/dist/{capability-cards-WQVY7WSS.js → capability-cards-2U3XWCDP.js} +5 -5
  82. package/dist/{capacity-monitor-BUKYPSWR.js → capacity-monitor-ZRLW7TVL.js} +16 -16
  83. package/dist/{catchup-brief-X5IVQAOH.js → catchup-brief-FSBZVYPL.js} +18 -18
  84. package/dist/{chunk-PMEOSD6S.js → chunk-24BUDF3J.js} +9 -6
  85. package/dist/{chunk-2NVEKSSP.js → chunk-2FULKRDO.js} +56 -38
  86. package/dist/{chunk-QB5JOGPK.js → chunk-2PI6JBJL.js} +5 -4
  87. package/dist/{chunk-MTIJ2NXY.js → chunk-2PWRUIKZ.js} +1 -1
  88. package/dist/{chunk-NIZQ3CIS.js → chunk-3AMGSCRH.js} +1 -1
  89. package/dist/{chunk-7ODTYODO.js → chunk-3LGID56M.js} +10 -7
  90. package/dist/{chunk-GSY6HL3T.js → chunk-4JI54RHR.js} +5 -5
  91. package/dist/{chunk-ISILDO7P.js → chunk-4THK7IA4.js} +1 -1
  92. package/dist/{chunk-IRIPGGGL.js → chunk-4UHQYBMQ.js} +1 -1
  93. package/dist/{chunk-HQODUV3G.js → chunk-552IGUBB.js} +2 -2
  94. package/dist/{chunk-IRHNV4GY.js → chunk-5KLQCGI5.js} +72 -18
  95. package/dist/{chunk-SOT23KWW.js → chunk-63UEWYM3.js} +4 -4
  96. package/dist/{chunk-QE7UVQDP.js → chunk-6PR2RAKM.js} +1 -1
  97. package/dist/{chunk-ZZXADKAP.js → chunk-6SPUK67A.js} +2 -2
  98. package/dist/{chunk-RVXWGPD3.js → chunk-75TM3APG.js} +29 -6
  99. package/dist/{chunk-IZPO6IOZ.js → chunk-7QSXARI3.js} +1 -1
  100. package/dist/{chunk-A2YZG4AD.js → chunk-AIUXE3ZJ.js} +6 -6
  101. package/dist/{chunk-U63BZI2B.js → chunk-AJERMFD6.js} +3 -3
  102. package/dist/{chunk-BUOMSIXH.js → chunk-BMNX3YWX.js} +2 -2
  103. package/dist/{chunk-YUBTHJVV.js → chunk-BRSMAFBN.js} +1 -1
  104. package/dist/{chunk-JZW5AOWI.js → chunk-BSPALHIR.js} +2 -2
  105. package/dist/{chunk-VDYUKTNS.js → chunk-CLAYNAXC.js} +4 -5
  106. package/dist/{chunk-J3QZPDNH.js → chunk-CNQ25C4C.js} +1 -1
  107. package/dist/{chunk-GWPICNSO.js → chunk-CSTL7BMK.js} +49 -4
  108. package/dist/{chunk-5DPE7B7K.js → chunk-CTYHSVHP.js} +1 -1
  109. package/dist/{chunk-EM4EYF3P.js → chunk-CVTWQZOR.js} +13 -5
  110. package/dist/{chunk-JNARUXDC.js → chunk-CW3FPWUW.js} +2 -2
  111. package/dist/{chunk-V42BSVX6.js → chunk-CWACO2D4.js} +51 -4
  112. package/dist/{chunk-RPBTYQKJ.js → chunk-CWUCD7C7.js} +1 -1
  113. package/dist/{chunk-DFUCFLZH.js → chunk-D4EMVYI7.js} +2 -2
  114. package/dist/{chunk-W2J2RF5N.js → chunk-DIHMGQGV.js} +3 -3
  115. package/dist/{chunk-YB7U4WTY.js → chunk-DJ4RG3RK.js} +2 -2
  116. package/dist/{chunk-KSMITUGY.js → chunk-DR7QPGX4.js} +3 -3
  117. package/dist/{chunk-QNXM2HXW.js → chunk-ELFFRVNL.js} +1 -1
  118. package/dist/{chunk-QEGXNJGR.js → chunk-EV2SMRLF.js} +4 -4
  119. package/dist/{chunk-VFSYVQX4.js → chunk-F3QMXKKJ.js} +8 -2
  120. package/dist/{chunk-NCC3F6GM.js → chunk-F5XPKUPK.js} +2 -2
  121. package/dist/{chunk-43R2GILO.js → chunk-FIBL4JRZ.js} +2 -2
  122. package/dist/{chunk-B2J3BBJC.js → chunk-FQH4R6UG.js} +2 -2
  123. package/dist/{chunk-AC6DKMVS.js → chunk-FSAKWKWU.js} +1 -1
  124. package/dist/{chunk-GL5NU6IK.js → chunk-FXS5OFGH.js} +1 -1
  125. package/dist/{chunk-K7KBAJQL.js → chunk-GHJRLETI.js} +10 -10
  126. package/dist/{chunk-VQRTO7IS.js → chunk-H73TUI4Y.js} +9 -2
  127. package/dist/{chunk-IIHE3FNC.js → chunk-HSXWUZOD.js} +3 -3
  128. package/dist/{chunk-JV225JBX.js → chunk-I6RHLHVW.js} +2 -2
  129. package/dist/{chunk-S6HVQF27.js → chunk-IEDCQRGG.js} +88 -4
  130. package/dist/{chunk-4Q5VNQTV.js → chunk-IFSOVXGN.js} +3 -3
  131. package/dist/{chunk-JMHKK7A5.js → chunk-ITVMRPCQ.js} +1 -1
  132. package/dist/{chunk-VT6P7FV4.js → chunk-IU44MPY3.js} +1 -1
  133. package/dist/{chunk-6OD2RVIA.js → chunk-IXTDBQYU.js} +273 -397
  134. package/dist/{chunk-2NGPZCWX.js → chunk-JB7QUK3D.js} +3 -3
  135. package/dist/{chunk-VT2B5BHM.js → chunk-JBSCL2XT.js} +2 -1
  136. package/dist/{chunk-MPX3TRMQ.js → chunk-JD5S5AAV.js} +1 -1
  137. package/dist/{chunk-XYG722JW.js → chunk-JIJKUZIO.js} +3 -3
  138. package/dist/{chunk-KMIAYKIH.js → chunk-K5C6LC2G.js} +159 -39
  139. package/dist/{chunk-DAOHCXM2.js → chunk-KH6BCYLC.js} +1 -1
  140. package/dist/{chunk-4L4R6AQJ.js → chunk-KMI4TUTW.js} +1 -1
  141. package/dist/{chunk-PHFPIUWU.js → chunk-KWOAM7TA.js} +3 -0
  142. package/dist/{chunk-RZJ6DXVE.js → chunk-L6QI2NNG.js} +1 -1
  143. package/dist/{chunk-HED6D5KR.js → chunk-MMNMQNLD.js} +43 -29
  144. package/dist/{chunk-KAVUTP5G.js → chunk-N3CRJ2VW.js} +3 -3
  145. package/dist/{chunk-OBJXZII2.js → chunk-N7LBAQGK.js} +3 -3
  146. package/dist/{chunk-LMX7UKGX.js → chunk-OUAGTQC4.js} +17 -11
  147. package/dist/{chunk-WZBUKC5N.js → chunk-OUJI2ZTY.js} +2 -2
  148. package/dist/{chunk-YUGLOZOR.js → chunk-OXTZEKVA.js} +1 -1
  149. package/dist/{chunk-OR3TAZL3.js → chunk-P4ULFI2N.js} +1 -1
  150. package/dist/{chunk-6LNSZADA.js → chunk-PVC4RNHQ.js} +50 -11
  151. package/dist/{chunk-FM7XZDZI.js → chunk-R2WP3XIN.js} +1 -1
  152. package/dist/{chunk-IBDPPBFK.js → chunk-R5IPZ5ZC.js} +1 -1
  153. package/dist/{chunk-7WDIGRSO.js → chunk-R5TZ2FC3.js} +1 -1
  154. package/dist/{chunk-2UVN2NBN.js → chunk-RICNNGYH.js} +3 -3
  155. package/dist/{chunk-WBJXJ2R4.js → chunk-RLBVY5FE.js} +17 -14
  156. package/dist/{chunk-XXJRZ75E.js → chunk-RV634O2W.js} +5 -2
  157. package/dist/{chunk-3KH6GXXX.js → chunk-RYPFOZQH.js} +2 -2
  158. package/dist/{chunk-DNFU56ZS.js → chunk-SB7W6XI4.js} +1 -1
  159. package/dist/{chunk-PPXQE7AS.js → chunk-SE6MLUOK.js} +33 -34
  160. package/dist/{chunk-65DBIEM2.js → chunk-SHIICYJW.js} +7 -1
  161. package/dist/{chunk-KPVVTHPK.js → chunk-SRMNWAHN.js} +15 -10
  162. package/dist/chunk-T2DJR7ND.js +367 -0
  163. package/dist/{chunk-Z6H6Y4BS.js → chunk-TA22MGGN.js} +1 -1
  164. package/dist/{chunk-ZOVHXTGC.js → chunk-TN7SC2ZQ.js} +1 -1
  165. package/dist/{chunk-XV5HRIXG.js → chunk-TRPGNCVB.js} +8 -8
  166. package/dist/{chunk-4BANMHJ5.js → chunk-UDZP2SHJ.js} +3 -3
  167. package/dist/{chunk-GMZMBLHT.js → chunk-UM6WUSQ7.js} +2 -2
  168. package/dist/{chunk-2EJ636HI.js → chunk-UST3MKK7.js} +1 -1
  169. package/dist/{chunk-RQ7OVXUZ.js → chunk-V2CZVZUO.js} +2 -2
  170. package/dist/{chunk-4RJJ5FJ2.js → chunk-V4UKBUUA.js} +1 -1
  171. package/dist/{chunk-EOS7VPVT.js → chunk-VA2MDALR.js} +8 -8
  172. package/dist/{chunk-SCYWCWKY.js → chunk-VG4ZH2Z3.js} +24 -10
  173. package/dist/{chunk-255DIG4B.js → chunk-VHLI6CTD.js} +1 -1
  174. package/dist/{chunk-DFIOOK5R.js → chunk-WCES22KG.js} +4 -3
  175. package/dist/{chunk-5A6KTWQL.js → chunk-WOTKNUKK.js} +126 -2
  176. package/dist/{chunk-62UZWGFX.js → chunk-WZZBGGSD.js} +63 -2
  177. package/dist/{chunk-ELXR65AN.js → chunk-X2FHTDIU.js} +6 -3
  178. package/dist/{chunk-V4BW5HFQ.js → chunk-X5I5QRC2.js} +3 -3
  179. package/dist/{chunk-X4AFBL4N.js → chunk-XCORXJ3M.js} +1 -1
  180. package/dist/{chunk-66JPZELX.js → chunk-Y5CNGG4F.js} +24 -16
  181. package/dist/{chunk-SPOXL7HF.js → chunk-YEWNIBNA.js} +9 -9
  182. package/dist/{chunk-WJ2PZGRV.js → chunk-ZAA344BL.js} +29 -2
  183. package/dist/{chunk-TN2YCFQE.js → chunk-ZGLJ2VD7.js} +5 -5
  184. package/dist/{co-activation-WN25AJOC.js → co-activation-RH46OQ3N.js} +5 -5
  185. package/dist/{co-occurrence-YP2Q3OEA.js → co-occurrence-MJWERUWY.js} +5 -5
  186. package/dist/{code-context-index-ZWONKBKX.js → code-context-index-WFUBYGQT.js} +6 -6
  187. package/dist/{content-extractor-EYRVGD6O.js → content-extractor-RHITF2KM.js} +1 -1
  188. package/dist/{conversation-wiki-populator-XFUC7S5P.js → conversation-wiki-populator-SK233TL4.js} +1 -1
  189. package/dist/{crdt-sync-ZFIFL2QM.js → crdt-sync-4R7SXTNB.js} +1 -1
  190. package/dist/{crm-webhook-DGPHULOO.js → crm-webhook-YDXX5FDK.js} +2 -2
  191. package/dist/{cto-delegation-gate-OF2A3TSS.js → cto-delegation-gate-ZJHLPK4Y.js} +14 -14
  192. package/dist/{daemon-auth-N6P2MZAV.js → daemon-auth-5FCYVQIZ.js} +3 -3
  193. package/dist/{daemon-orchestration-G4RRTPP7.js → daemon-orchestration-NBU5RZ2O.js} +18 -18
  194. package/dist/{daemon-ready-signal-3L2MJT7C.js → daemon-ready-signal-KXLL6ZFL.js} +1 -1
  195. package/dist/{db-backup-EORG4LBO.js → db-backup-BTL2FBBL.js} +9 -3
  196. package/dist/{db-restore-events-3R7G4FP4.js → db-restore-events-3A57GMLW.js} +2 -2
  197. package/dist/{doc-graph-extractor-APZS3DFD.js → doc-graph-extractor-ADYRG7DB.js} +5 -5
  198. package/dist/documents-VWPZTDFA.js +56 -0
  199. package/dist/{dreaming-Q4E3WBGY.js → dreaming-76WKGTL6.js} +15 -15
  200. package/dist/embeddings-config-FANLORDH.js +21 -0
  201. package/dist/{exe-drift-CI5R6GUT.js → exe-drift-T3IO2SPX.js} +6 -6
  202. package/dist/{exe-export-HQIQASIT.js → exe-export-6YEHSJMP.js} +9 -9
  203. package/dist/{exe-import-ULZK56WC.js → exe-import-3NERK63O.js} +9 -9
  204. package/dist/{exe-key-ILNSBGRN.js → exe-key-RCMBMLSQ.js} +8 -8
  205. package/dist/{exe-org-WQWQZRLR.js → exe-org-KCOOLUTW.js} +3 -3
  206. package/dist/{exe-snapshot-RUZTWZOF.js → exe-snapshot-JIY7MNRI.js} +18 -18
  207. package/dist/{fast-db-init-KNJRL7T3.js → fast-db-init-PVJ72264.js} +1 -1
  208. package/dist/{founder-context-QCTMEK66.js → founder-context-A4VUEKDH.js} +4 -4
  209. package/dist/gateway/index.js +17 -17
  210. package/dist/{git-staleness-KIA5YI4H.js → git-staleness-IOAHAGBI.js} +5 -5
  211. package/dist/{git-task-sweep-WH6QE7HL.js → git-task-sweep-IGM5RILF.js} +17 -15
  212. package/dist/{global-procedures-SYZZCGDS.js → global-procedures-VZL2X4RK.js} +6 -6
  213. package/dist/{graph-auto-extract-J2TIWZEE.js → graph-auto-extract-TIXRGBC5.js} +5 -5
  214. package/dist/{hook-integrity-I6PWJQER.js → hook-integrity-XNPNCMAS.js} +1 -1
  215. package/dist/hooks/bug-report-worker.js +47 -17
  216. package/dist/hooks/codex-stop-task-finalizer.js +47 -17
  217. package/dist/hooks/commit-complete.js +18 -18
  218. package/dist/hooks/error-recall.js +11 -11
  219. package/dist/hooks/exe-heartbeat-hook.js +7 -7
  220. package/dist/hooks/ingest-worker.js +39 -9
  221. package/dist/hooks/ingest.js +17 -17
  222. package/dist/hooks/instructions-loaded.js +8 -8
  223. package/dist/hooks/manifest.json +20 -20
  224. package/dist/hooks/notification.js +8 -8
  225. package/dist/hooks/post-compact.js +17 -17
  226. package/dist/hooks/post-tool-combined.js +60 -7
  227. package/dist/hooks/pre-compact.js +23 -23
  228. package/dist/hooks/pre-tool-use.js +64 -34
  229. package/dist/hooks/prompt-submit.js +40 -32
  230. package/dist/hooks/session-end.js +29 -29
  231. package/dist/hooks/session-start.js +17 -17
  232. package/dist/hooks/stop.js +24 -24
  233. package/dist/hooks/subagent-stop.js +17 -17
  234. package/dist/hooks/summary-worker.js +55 -25
  235. package/dist/index.js +27 -27
  236. package/dist/{installer-PSDYMGN7.js → installer-D7D5O4KL.js} +10 -10
  237. package/dist/{installer-3NB3IBHF.js → installer-EQP2EMNZ.js} +10 -10
  238. package/dist/{installer-IIJFCTMH.js → installer-IWRYH55Z.js} +10 -10
  239. package/dist/{key-backup-status-FNSN3NXH.js → key-backup-status-ZNGDSPLT.js} +2 -2
  240. package/dist/lib/agent-config.js +3 -3
  241. package/dist/lib/cloud-sync.js +16 -16
  242. package/dist/lib/config.js +2 -2
  243. package/dist/lib/consolidation.js +8 -8
  244. package/dist/lib/database.js +7 -5
  245. package/dist/lib/db-daemon-client.js +6 -6
  246. package/dist/lib/db.js +7 -5
  247. package/dist/lib/device-registry.js +3 -3
  248. package/dist/lib/embed-worker.js +2 -2
  249. package/dist/lib/embedder.js +6 -6
  250. package/dist/lib/employee-templates.js +7 -7
  251. package/dist/lib/employees.js +5 -5
  252. package/dist/lib/exe-daemon-client.js +5 -5
  253. package/dist/lib/exe-daemon.js +449 -89
  254. package/dist/lib/hybrid-search.js +8 -8
  255. package/dist/lib/identity.js +5 -5
  256. package/dist/lib/license.js +4 -4
  257. package/dist/lib/messaging.js +15 -15
  258. package/dist/lib/post-tool-memory.js +2 -2
  259. package/dist/lib/reminders.js +6 -6
  260. package/dist/lib/schedules.js +8 -8
  261. package/dist/lib/session-registry.js +9 -7
  262. package/dist/lib/session-wrappers.js +1 -1
  263. package/dist/lib/skill-learning.js +9 -9
  264. package/dist/lib/store.js +7 -7
  265. package/dist/lib/task-router.js +6 -6
  266. package/dist/lib/tasks.js +16 -16
  267. package/dist/lib/tmux-routing.js +14 -14
  268. package/dist/lib/token-spend.js +6 -6
  269. package/dist/{license-gate-7SDHCJUO.js → license-gate-PZOP7S2S.js} +5 -5
  270. package/dist/mcp/register-tools.js +73 -72
  271. package/dist/mcp/server.js +74 -73
  272. package/dist/mcp/tools/complete-reminder.js +7 -7
  273. package/dist/mcp/tools/create-reminder.js +7 -7
  274. package/dist/mcp/tools/create-task.js +18 -18
  275. package/dist/mcp/tools/deactivate-behavior.js +10 -10
  276. package/dist/mcp/tools/list-reminders.js +7 -7
  277. package/dist/mcp/tools/list-tasks.js +18 -18
  278. package/dist/mcp/tools/send-message.js +17 -17
  279. package/dist/mcp/tools/update-task.js +17 -17
  280. package/dist/{mcp-http-config-QSOVFXHW.js → mcp-http-config-23DHJAU4.js} +7 -7
  281. package/dist/{mcp-port-config-AWWRZA22.js → mcp-port-config-FFAMMLLE.js} +2 -1
  282. package/dist/{memory-cards-II67WFL2.js → memory-cards-CNLMHSZC.js} +5 -5
  283. package/dist/{memory-graph-extractor-PM4Q2KJG.js → memory-graph-extractor-HIXP2BQS.js} +6 -6
  284. package/dist/{memory-poisoning-defense-ECXSX7HK.js → memory-poisoning-defense-YL53IBBF.js} +5 -5
  285. package/dist/{memory-queue-VAE6WMSS.js → memory-queue-3Q5P43AM.js} +3 -3
  286. package/dist/memory-queue-client-YP2QKX6J.js +16 -0
  287. package/dist/{memory-reflection-PXF6YFDU.js → memory-reflection-VHQRUZWK.js} +5 -5
  288. package/dist/{notifications-UP7WQGG4.js → notifications-Q5NEAP6K.js} +14 -14
  289. package/dist/{orchestration-events-PZLLPCKY.js → orchestration-events-7SNWRJYE.js} +6 -6
  290. package/dist/{orchestration-phase-SJOXDB7X.js → orchestration-phase-U45T4VG3.js} +3 -3
  291. package/dist/{orchestrator-PUT45J4O.js → orchestrator-XWLKNWUG.js} +16 -16
  292. package/dist/{pipeline-router-5CRWKESM.js → pipeline-router-5IBJBH7P.js} +6 -6
  293. package/dist/{plan-limits-SH2NDFNX.js → plan-limits-PBEZVHRQ.js} +8 -8
  294. package/dist/{preferences-YWBTKW3M.js → preferences-TYTGDXQZ.js} +2 -2
  295. package/dist/{project-boot-2TCPDZ4S.js → project-boot-OHEGJD2L.js} +2 -2
  296. package/dist/{projection-worker-HWY37MNC.js → projection-worker-HELRBNDR.js} +5 -5
  297. package/dist/{prospective-memory-FQSVMCGG.js → prospective-memory-N55XRGJP.js} +5 -5
  298. package/dist/{push-notifications-DK6XA5B3.js → push-notifications-PAFNP3EC.js} +3 -3
  299. package/dist/{reranker-AALRMGMM.js → reranker-MNJSTOPR.js} +3 -3
  300. package/dist/{retrieval-health-PNWJSJNG.js → retrieval-health-W4HNR3WX.js} +1 -1
  301. package/dist/{review-polling-65JZUE3T.js → review-polling-SRYZU2PI.js} +15 -15
  302. package/dist/runtime/index.js +22 -22
  303. package/dist/{session-events-EJ3OSAA6.js → session-events-L4DK5J6J.js} +15 -15
  304. package/dist/{session-kill-telemetry-3HGM7SNQ.js → session-kill-telemetry-U2YHKHCB.js} +15 -15
  305. package/dist/{session-scope-JGDYAMJO.js → session-scope-JTPHECAU.js} +14 -14
  306. package/dist/{setup-wizard-44LMFM2C.js → setup-wizard-IP5R66LR.js} +3 -3
  307. package/dist/{shard-manager-KUCJPLC6.js → shard-manager-RASGFMGS.js} +3 -3
  308. package/dist/{skill-refinement-DUOO6B7V.js → skill-refinement-VTYL4OMJ.js} +5 -5
  309. package/dist/{stack-release-XYMKU7NT.js → stack-release-TOCCJQOF.js} +244 -45
  310. package/dist/{stack-update-TUBZTY7Z.js → stack-update-MRNVHUZZ.js} +11 -5
  311. package/dist/{steward-gate-6NWRDLX2.js → steward-gate-JEVUDTBI.js} +6 -6
  312. package/dist/{task-enforcement-UOULTGFB.js → task-enforcement-VFSAAZUN.js} +14 -14
  313. package/dist/{task-scope-P5STKYAC.js → task-scope-P4VLIQNP.js} +14 -14
  314. package/dist/{tasks-crud-24HMTULR.js → tasks-crud-SC3ERIUR.js} +14 -14
  315. package/dist/{tasks-notify-LAIU7UUI.js → tasks-notify-WJYBUCIB.js} +15 -15
  316. package/dist/{tasks-review-AFJAU2DY.js → tasks-review-XPVPHCGD.js} +14 -14
  317. package/dist/{telemetry-upload-DWFGC2XJ.js → telemetry-upload-4QEYQROW.js} +10 -10
  318. package/dist/{token-budget-4RFZKWGH.js → token-budget-UBOP3HVE.js} +6 -6
  319. package/dist/{tool-capability-index-ZEXBWKUZ.js → tool-capability-index-SHYCBE2Z.js} +1 -1
  320. package/dist/{tool-telemetry-BS5JXM5M.js → tool-telemetry-CDNPES5B.js} +1 -1
  321. package/dist/tui/App.js +27 -27
  322. package/dist/{tui-data-UNO5B7PU.js → tui-data-HVYY7GRK.js} +14 -14
  323. package/dist/{worker-gate-C6CTTYMD.js → worker-gate-KQTODSUQ.js} +3 -3
  324. package/dist/{workflow-engine-4W2KYCDV.js → workflow-engine-OP2DQISD.js} +2 -2
  325. package/dist/{working-memory-FXHQCJJE.js → working-memory-PY4AG577.js} +22 -2
  326. package/dist/{worktree-2CXY6NEB.js → worktree-Z2G4CP4Z.js} +7 -7
  327. package/dist/{worktree-sweep-K3CJFSUL.js → worktree-sweep-LWSCAZW6.js} +8 -8
  328. package/package.json +2 -2
  329. package/release-notes.json +56 -113
  330. package/stack.release.json +7 -7
  331. package/dist/memory-queue-client-HLURQEV6.js +0 -16
  332. /package/dist/{chunk-J3SR5MGG.js → chunk-GIS4GBZE.js} +0 -0
  333. /package/dist/{chunk-AE74NOE6.js → chunk-NAPBIDGH.js} +0 -0
  334. /package/dist/{chunk-I3DPCSDG.js → chunk-OJS2H5HR.js} +0 -0
  335. /package/dist/{chunk-K4BKJJ4F.js → chunk-PCRRDXGL.js} +0 -0
  336. /package/dist/{chunk-MQCTK6EF.js → chunk-RRYJTPVW.js} +0 -0
  337. /package/dist/{chunk-2NS3QRMJ.js → chunk-ZIVUMDHA.js} +0 -0
  338. /package/dist/{core-memory-OC5ITKKV.js → core-memory-4JWCAGJI.js} +0 -0
  339. /package/dist/{entity-boost-NF3LE6OJ.js → entity-boost-AU342QRK.js} +0 -0
  340. /package/dist/{message-queue-client-4VDU6BZY.js → message-queue-client-IXYLJJVJ.js} +0 -0
  341. /package/dist/{oauth-server-EWUL7DMD.js → oauth-server-F4QWESK2.js} +0 -0
  342. /package/dist/{webhook-pipe-DHIGZHPW.js → webhook-pipe-S4CWK6H5.js} +0 -0
  343. /package/dist/{wiki-acl-CONNF6ES.js → wiki-acl-6GZHUA44.js} +0 -0
  344. /package/dist/{wiki-client-N6PT5P7W.js → wiki-client-CIJXRMKL.js} +0 -0
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  assertPreflightGate,
4
4
  runPreflightOnManifest
5
- } from "./chunk-7ODTYODO.js";
5
+ } from "./chunk-3LGID56M.js";
6
6
  import "./chunk-MLKGABMK.js";
7
7
 
8
8
  // src/bin/stack-release.ts
@@ -247,6 +247,13 @@ async function detectChanges(repos) {
247
247
  }
248
248
  return changes;
249
249
  }
250
+ function rebaseImageTag(image, newVersion) {
251
+ if (/@sha256:[0-9a-f]{64}/i.test(image)) return image;
252
+ if (/:v[^:/]+$/.test(image)) {
253
+ return `${image.replace(/:v[^:/]+$/, "")}:v${newVersion}`;
254
+ }
255
+ return `${image}:v${newVersion}`;
256
+ }
250
257
  async function bumpVersions(changes, mode, dryRun) {
251
258
  for (const change of changes) {
252
259
  const newVersion = bumpVersion(change.currentVersion, mode);
@@ -265,21 +272,18 @@ async function bumpVersions(changes, mode, dryRun) {
265
272
  srf.version = newVersion;
266
273
  srf.sourceVersion = newVersion;
267
274
  if (typeof srf.image === "string") {
268
- const imageBase = srf.image.replace(/:v[^:]+$/, "");
269
- srf.image = `${imageBase}:v${newVersion}`;
275
+ srf.image = rebaseImageTag(srf.image, newVersion);
270
276
  }
271
277
  if (srf.components && typeof srf.components === "object") {
272
278
  const components = srf.components;
273
279
  for (const key of Object.keys(components)) {
274
280
  const val = components[key];
275
281
  if (typeof val === "string") {
276
- const base = val.replace(/:v[^:]+$/, "");
277
- components[key] = `${base}:v${newVersion}`;
282
+ components[key] = rebaseImageTag(val, newVersion);
278
283
  } else if (val && typeof val === "object" && "image" in val) {
279
284
  const obj = val;
280
285
  if (typeof obj.image === "string") {
281
- const base = obj.image.replace(/:v[^:]+$/, "");
282
- obj.image = `${base}:v${newVersion}`;
286
+ obj.image = rebaseImageTag(obj.image, newVersion);
283
287
  }
284
288
  }
285
289
  }
@@ -291,8 +295,7 @@ async function bumpVersions(changes, mode, dryRun) {
291
295
  }
292
296
  await git(change.repo.localPath, "add", "package.json", "stack.release.json");
293
297
  await git(change.repo.localPath, "commit", "-m", `chore: bump v${newVersion} for stack release`);
294
- await git(change.repo.localPath, "push", "origin", change.repo.defaultBranch);
295
- log("ok", `${change.repo.serviceKey}: bumped ${change.currentVersion} -> ${newVersion}`);
298
+ log("ok", `${change.repo.serviceKey}: bumped ${change.currentVersion} -> ${newVersion} (local commit, push deferred)`);
296
299
  }
297
300
  }
298
301
  async function tagAndTriggerCI(changes, dryRun) {
@@ -302,8 +305,43 @@ async function tagAndTriggerCI(changes, dryRun) {
302
305
  continue;
303
306
  }
304
307
  await git(change.repo.localPath, "tag", change.tag);
305
- await git(change.repo.localPath, "push", "origin", change.tag);
306
- log("ok", `Tagged ${change.repo.serviceKey} ${change.tag} \u2014 CI triggered`);
308
+ try {
309
+ await git(change.repo.localPath, "push", "--atomic", "origin", change.repo.defaultBranch, change.tag);
310
+ } catch {
311
+ log("warn", `Atomic push not supported for ${change.repo.serviceKey} \u2014 falling back to sequential push`);
312
+ await git(change.repo.localPath, "push", "origin", change.repo.defaultBranch);
313
+ await git(change.repo.localPath, "push", "origin", change.tag);
314
+ }
315
+ log("ok", `Pushed ${change.repo.serviceKey} ${change.tag} (bump + tag) \u2014 CI triggered`);
316
+ }
317
+ }
318
+ async function rollbackFailedReleases(changes, ciStatuses, dryRun) {
319
+ if (dryRun) return;
320
+ const failed = changes.filter((c) => {
321
+ const ci = ciStatuses.find((s) => s.repo.serviceKey === c.repo.serviceKey);
322
+ return ci && (ci.status !== "completed" || ci.conclusion !== "success");
323
+ });
324
+ if (failed.length === 0) return;
325
+ log("warn", `Rolling back ${failed.length} failed release(s)...`);
326
+ for (const change of failed) {
327
+ const name = repoName(change.repo);
328
+ try {
329
+ await git(change.repo.localPath, "push", "origin", `:refs/tags/${change.tag}`);
330
+ log("ok", `Deleted remote tag ${change.tag} from ${name}`);
331
+ } catch (err) {
332
+ log("warn", `Could not delete remote tag ${change.tag} from ${name}: ${err instanceof Error ? err.message : String(err)}`);
333
+ }
334
+ try {
335
+ await git(change.repo.localPath, "tag", "-d", change.tag);
336
+ } catch {
337
+ }
338
+ try {
339
+ await git(change.repo.localPath, "revert", "--no-edit", "HEAD");
340
+ await git(change.repo.localPath, "push", "origin", change.repo.defaultBranch);
341
+ log("ok", `Reverted bump commit for ${name} on ${change.repo.defaultBranch}`);
342
+ } catch (err) {
343
+ log("fail", `Could not revert bump commit for ${name}: ${err instanceof Error ? err.message : String(err)}. Manual cleanup required.`);
344
+ }
307
345
  }
308
346
  }
309
347
  async function waitForCI(changes, dryRun) {
@@ -381,7 +419,13 @@ async function checkRegistryManifest(registry, repo, tag, token) {
381
419
  const url = `https://${registry}/v2/${repo}/manifests/${tag}`;
382
420
  const headers = [
383
421
  "-H",
384
- "Accept: application/vnd.oci.image.index.v1+json"
422
+ "Accept: application/vnd.oci.image.index.v1+json",
423
+ // Also accept legacy Docker v2 manifest list / single manifest so the
424
+ // registry returns a Docker-Content-Digest for non-OCI images too.
425
+ "-H",
426
+ "Accept: application/vnd.docker.distribution.manifest.list.v2+json",
427
+ "-H",
428
+ "Accept: application/vnd.docker.distribution.manifest.v2+json"
385
429
  ];
386
430
  if (token) {
387
431
  headers.push("-H", `Authorization: Bearer ${token}`);
@@ -391,15 +435,15 @@ async function checkRegistryManifest(registry, repo, tag, token) {
391
435
  "-sS",
392
436
  "-m",
393
437
  "30",
394
- "-o",
395
- "/dev/null",
396
- "-w",
397
- "%{http_code}",
438
+ "-I",
398
439
  ...headers,
399
440
  url
400
441
  ]);
401
- const code = parseInt(stdout.trim(), 10);
402
- return { status: code, ok: code >= 200 && code < 300 };
442
+ const statusMatch = stdout.match(/^HTTP\/[\d.]+\s+(\d{3})/m);
443
+ const code = statusMatch ? parseInt(statusMatch[1], 10) : 0;
444
+ const digestMatch = stdout.match(/^docker-content-digest:\s*(sha256:[0-9a-f]{64})/im);
445
+ const digest = digestMatch ? digestMatch[1] : void 0;
446
+ return { status: code, ok: code >= 200 && code < 300, digest };
403
447
  } catch {
404
448
  return { status: 0, ok: false };
405
449
  }
@@ -412,6 +456,45 @@ async function warmProxyCache(imageRef) {
412
456
  return false;
413
457
  }
414
458
  }
459
+ async function resolveDigestViaInspect(imageName, tag) {
460
+ const shortName = shortImageName(imageName);
461
+ const refs = [
462
+ `${GHCR_REGISTRY}/askexe/${shortName}:${tag}`,
463
+ `${PROXY_REGISTRY}/askexe/${shortName}:${tag}`
464
+ ];
465
+ for (const ref of refs) {
466
+ try {
467
+ const { stdout } = await execFile("docker", ["manifest", "inspect", ref, "--verbose"], {
468
+ timeout: 6e4
469
+ });
470
+ const parsed = JSON.parse(stdout);
471
+ let digest;
472
+ if (Array.isArray(parsed)) {
473
+ digest = parsed[0]?.Descriptor?.digest;
474
+ } else {
475
+ digest = parsed.Descriptor?.digest;
476
+ }
477
+ if (digest && /^sha256:[0-9a-f]{64}$/i.test(digest)) {
478
+ log("ok", `Resolved digest via docker manifest inspect: ${shortName}:${tag} -> ${digest.slice(0, 19)}...`);
479
+ return digest;
480
+ }
481
+ } catch {
482
+ }
483
+ }
484
+ try {
485
+ const ghcrRef = `${GHCR_REGISTRY}/askexe/${shortName}:${tag}`;
486
+ const { stdout } = await execFile("docker", ["manifest", "inspect", ghcrRef], {
487
+ timeout: 6e4
488
+ });
489
+ const parsed = JSON.parse(stdout);
490
+ if (parsed.digest && /^sha256:[0-9a-f]{64}$/i.test(parsed.digest)) {
491
+ log("ok", `Resolved digest via docker manifest inspect (non-verbose): ${shortName}:${tag} -> ${parsed.digest.slice(0, 19)}...`);
492
+ return parsed.digest;
493
+ }
494
+ } catch {
495
+ }
496
+ return void 0;
497
+ }
415
498
  async function verifyImages(changes, ciStatuses, dryRun) {
416
499
  if (dryRun) {
417
500
  return changes.map((c) => ({
@@ -423,7 +506,16 @@ async function verifyImages(changes, ciStatuses, dryRun) {
423
506
  }
424
507
  const proxyToken = process.env.EXE_REGISTRY_PROXY_PULL_TOKEN ?? void 0;
425
508
  const results = [];
426
- log("info", "Verifying Docker images are pullable...");
509
+ let ghcrToken = process.env.GHCR_TOKEN?.trim() || void 0;
510
+ if (!ghcrToken) {
511
+ try {
512
+ const { stdout } = await execFile("gh", ["auth", "token"]);
513
+ ghcrToken = stdout.trim();
514
+ } catch {
515
+ }
516
+ }
517
+ const ghcrBearer = ghcrToken ? Buffer.from(ghcrToken).toString("base64") : void 0;
518
+ log("info", "Verifying Docker images are pullable (with retry for digest resolution)...");
427
519
  for (const change of changes) {
428
520
  const ci = ciStatuses.find((s) => s.repo.serviceKey === change.repo.serviceKey);
429
521
  if (!ci || ci.status !== "completed" || ci.conclusion !== "success") continue;
@@ -437,31 +529,59 @@ async function verifyImages(changes, ciStatuses, dryRun) {
437
529
  ghcr: "error",
438
530
  proxy: "error"
439
531
  };
440
- const proxyCheck = await checkRegistryManifest(PROXY_REGISTRY, proxyRepo, tag, proxyToken);
441
- if (proxyCheck.ok) {
442
- result.proxy = "ok";
443
- } else {
444
- result.proxy = "pending";
445
- }
446
- let ghcrToken = process.env.GHCR_TOKEN?.trim() || void 0;
447
- if (!ghcrToken) {
448
- try {
449
- const { stdout } = await execFile("gh", ["auth", "token"]);
450
- ghcrToken = stdout.trim();
451
- } catch {
532
+ const GHCR_RETRY_DELAYS = [5e3, 1e4, 2e4, 4e4];
533
+ let ghcrCheck = { status: 0, ok: false };
534
+ for (let attempt = 0; attempt <= GHCR_RETRY_DELAYS.length; attempt++) {
535
+ ghcrCheck = await checkRegistryManifest(GHCR_REGISTRY, ghcrRepo, tag, ghcrBearer);
536
+ if (ghcrCheck.ok && ghcrCheck.digest) {
537
+ break;
538
+ }
539
+ if (ghcrCheck.status === 401 || ghcrCheck.status === 403) {
540
+ break;
541
+ }
542
+ if (attempt < GHCR_RETRY_DELAYS.length) {
543
+ const delayMs = GHCR_RETRY_DELAYS[attempt];
544
+ log("info", `${shortName}:${tag} not yet available on GHCR (HTTP ${ghcrCheck.status}) \u2014 retry in ${delayMs / 1e3}s (${attempt + 1}/${GHCR_RETRY_DELAYS.length})`);
545
+ await sleep(delayMs);
452
546
  }
453
547
  }
454
- const ghcrBearer = ghcrToken ? Buffer.from(ghcrToken).toString("base64") : void 0;
455
- const ghcrCheck = await checkRegistryManifest(GHCR_REGISTRY, ghcrRepo, tag, ghcrBearer);
456
548
  if (ghcrCheck.ok) {
457
549
  result.ghcr = "ok";
550
+ result.digest = ghcrCheck.digest;
551
+ if (!ghcrCheck.digest) {
552
+ log("warn", `${shortName}:${tag} is on GHCR but Docker-Content-Digest header missing \u2014 trying docker manifest inspect fallback`);
553
+ const inspectDigest = await resolveDigestViaInspect(change.repo.imageName, tag);
554
+ if (inspectDigest) {
555
+ result.digest = inspectDigest;
556
+ } else {
557
+ log("warn", `${shortName}:${tag} \u2014 docker manifest inspect also failed to resolve digest. Manifest entry will be tag-only.`);
558
+ }
559
+ }
458
560
  } else if (ghcrCheck.status === 401 || ghcrCheck.status === 403) {
459
- result.ghcr = "error";
460
- result.detail = `GHCR auth failed (${ghcrCheck.status}) \u2014 cannot verify image. Fix gh auth or GHCR_TOKEN.`;
461
- log("fail", `GHCR auth returned ${ghcrCheck.status} for ${shortName}:${tag} \u2014 cannot verify, treating as error`);
561
+ log("warn", `GHCR auth returned ${ghcrCheck.status} for ${shortName}:${tag} \u2014 trying docker manifest inspect fallback`);
562
+ const inspectDigest = await resolveDigestViaInspect(change.repo.imageName, tag);
563
+ if (inspectDigest) {
564
+ result.ghcr = "ok";
565
+ result.digest = inspectDigest;
566
+ log("ok", `${shortName}:${tag} \u2014 digest resolved via docker manifest inspect despite GHCR HEAD ${ghcrCheck.status}`);
567
+ } else {
568
+ result.ghcr = "error";
569
+ result.detail = `GHCR auth failed (${ghcrCheck.status}) and docker manifest inspect failed \u2014 cannot verify image. Fix gh auth or GHCR_TOKEN.`;
570
+ log("fail", `GHCR auth returned ${ghcrCheck.status} for ${shortName}:${tag} and inspect fallback failed \u2014 cannot verify`);
571
+ }
462
572
  } else {
463
573
  result.ghcr = "missing";
464
- result.detail = `GHCR returned ${ghcrCheck.status} for ${ghcrRepo}:${tag}`;
574
+ result.detail = `GHCR returned ${ghcrCheck.status} for ${ghcrRepo}:${tag} after ${GHCR_RETRY_DELAYS.length} retries`;
575
+ log("fail", `Image NOT FOUND on GHCR after retries: ${shortName}:${tag} \u2014 release may be broken!`);
576
+ }
577
+ const proxyCheck = await checkRegistryManifest(PROXY_REGISTRY, proxyRepo, tag, proxyToken);
578
+ if (proxyCheck.ok) {
579
+ result.proxy = "ok";
580
+ if (!result.digest && proxyCheck.digest) {
581
+ result.digest = proxyCheck.digest;
582
+ }
583
+ } else {
584
+ result.proxy = "pending";
465
585
  }
466
586
  if (result.ghcr === "ok" && result.proxy !== "ok") {
467
587
  log("info", `Warming proxy cache for ${shortName}:${tag}...`);
@@ -476,11 +596,10 @@ async function verifyImages(changes, ciStatuses, dryRun) {
476
596
  }
477
597
  }
478
598
  if (result.ghcr === "ok" && result.proxy === "ok") {
479
- log("ok", `Image verified: ${shortName}:${tag} (GHCR + proxy)`);
599
+ const digestSuffix = result.digest ? ` [${result.digest.slice(0, 19)}...]` : "";
600
+ log("ok", `Image verified: ${shortName}:${tag} (GHCR + proxy)${digestSuffix}`);
480
601
  } else if (result.ghcr === "ok" && result.proxy === "pending") {
481
602
  log("warn", `Image on GHCR only: ${shortName}:${tag} (proxy will cache on first pull)`);
482
- } else if (result.ghcr === "missing") {
483
- log("fail", `Image NOT FOUND on GHCR: ${shortName}:${tag} \u2014 release may be broken!`);
484
603
  }
485
604
  results.push(result);
486
605
  }
@@ -500,7 +619,7 @@ function printImageVerification(results) {
500
619
  }
501
620
  console.log("");
502
621
  }
503
- function updateStackManifest(changes, ciStatuses, dryRun, imageResults) {
622
+ async function updateStackManifest(changes, ciStatuses, dryRun, imageResults) {
504
623
  const manifest = JSON.parse(readFileSync(MANIFEST_PATH, "utf8"));
505
624
  const currentLatest = manifest.latest;
506
625
  const currentParts = currentLatest.split(".").map(Number);
@@ -518,9 +637,17 @@ function updateStackManifest(changes, ciStatuses, dryRun, imageResults) {
518
637
  successfulChanges.push(change);
519
638
  const svc = services[change.repo.serviceKey];
520
639
  if (svc) {
521
- const imageTag = `${change.repo.imageName}:v${change.newVersion}`;
522
- const imgResult = imageResults?.find((r) => r.repo.serviceKey === change.repo.serviceKey);
523
- svc.image = imgResult?.digest ? `${imageTag}@${imgResult.digest}` : imageTag;
640
+ const tag = `v${change.newVersion}`;
641
+ const imageTag = `${change.repo.imageName}:${tag}`;
642
+ let digest = imageResults?.find((r) => r.repo.serviceKey === change.repo.serviceKey)?.digest;
643
+ if (!digest && !dryRun) {
644
+ log("info", `No digest from image verification for ${imageTag} \u2014 trying docker manifest inspect fallback (bug 85034df0)`);
645
+ digest = await resolveDigestViaInspect(change.repo.imageName, tag);
646
+ }
647
+ if (!digest && !dryRun) {
648
+ log("warn", `No content digest resolved for ${imageTag} \u2014 manifest entry will be tag-only and the digest-pinning gate will reject it.`);
649
+ }
650
+ svc.image = digest ? `${imageTag}@${digest}` : imageTag;
524
651
  }
525
652
  }
526
653
  }
@@ -590,6 +717,63 @@ function gatePublishWithPreflight(newStackVersion, dryRun, allowRed) {
590
717
  warn: (m) => log("warn", m.replace(/^\[stack-release\]\s*/, ""))
591
718
  });
592
719
  }
720
+ function gatePreMutationStructure(changes, dryRun, allowRed) {
721
+ let baseManifest;
722
+ try {
723
+ baseManifest = JSON.parse(readFileSync(MANIFEST_PATH, "utf8"));
724
+ } catch (err) {
725
+ throw new Error(`Pre-mutation gate: cannot read manifest ${MANIFEST_PATH}: ${err instanceof Error ? err.message : String(err)}`);
726
+ }
727
+ const currentLatest = baseManifest.latest ?? "";
728
+ const baseServices = baseManifest.stacks?.[currentLatest]?.services ?? {};
729
+ const services = {};
730
+ for (const [key, svc] of Object.entries(baseServices)) services[key] = { ...svc };
731
+ for (const change of changes) {
732
+ const svc = services[change.repo.serviceKey];
733
+ if (svc) svc.image = `${change.repo.imageName}:v${change.newVersion}`;
734
+ }
735
+ const currentParts = currentLatest.split(".").map(Number);
736
+ const simVersion = `${currentParts[0] ?? 0}.${currentParts[1] ?? 9}.${(currentParts[2] ?? 0) + 1}`;
737
+ const simManifest = {
738
+ schemaVersion: 1,
739
+ latest: simVersion,
740
+ stacks: { [simVersion]: { version: simVersion, services } }
741
+ };
742
+ const composeDir = path.join(EXE_OS_ROOT, "deploy", "compose");
743
+ const report = runPreflightOnManifest({
744
+ manifest: simManifest,
745
+ stackVersion: simVersion,
746
+ label: `pre-mutation simulated manifest (stack ${simVersion})`,
747
+ envExamplePath: path.join(composeDir, ".env.example"),
748
+ composePath: path.join(composeDir, "docker-compose.yml"),
749
+ monitorComposePath: path.join(EXE_OS_ROOT, "deploy", "monitor", "docker-compose.hub.yml")
750
+ });
751
+ const adjusted = {
752
+ ...report,
753
+ findings: report.findings.map(
754
+ (f) => f.check === "digest-pinning" && f.status === "fail" ? { ...f, status: "warn", message: `${f.message} (pending image build \u2014 enforced after build)` } : f
755
+ )
756
+ };
757
+ const failed = adjusted.findings.filter((f) => f.status === "fail").length;
758
+ const warned = adjusted.findings.filter((f) => f.status === "warn").length;
759
+ const passed = adjusted.findings.filter((f) => f.status === "pass").length;
760
+ const verdict = failed > 0 ? "RED" : warned > 0 ? "YELLOW" : "GREEN";
761
+ const adjustedReport = { ...adjusted, verdict, failed, warned, passed };
762
+ log("info", "Running pre-mutation structural gate (before any remote push)...");
763
+ if (dryRun) {
764
+ console.log(` [dry-run] pre-mutation verdict: ${adjustedReport.verdict} (pass ${passed} / warn ${warned} / fail ${failed})`);
765
+ for (const f of adjustedReport.findings) {
766
+ if (f.status !== "pass") log(f.status === "fail" ? "fail" : "warn", `${f.check}: ${f.message}`);
767
+ }
768
+ return;
769
+ }
770
+ assertPreflightGate(adjustedReport, {
771
+ context: "stack-release:pre-mutation",
772
+ allowRed,
773
+ log: (m) => log("ok", m.replace(/^\[stack-release:pre-mutation\]\s*/, "")),
774
+ warn: (m) => log("warn", m.replace(/^\[stack-release:pre-mutation\]\s*/, ""))
775
+ });
776
+ }
593
777
  async function commitAndTagExeOs(newStackVersion, _exeOsChange, dryRun) {
594
778
  if (dryRun) {
595
779
  log("dry", `Would commit manifest + tag exe-os stack-v${newStackVersion}`);
@@ -724,6 +908,7 @@ async function runStackRelease(flags) {
724
908
  ` ${change.repo.serviceKey.padEnd(14)} ${change.currentVersion} -> ${change.newVersion} (${change.commits.length} commit${change.commits.length === 1 ? "" : "s"})`
725
909
  );
726
910
  }
911
+ gatePreMutationStructure(changes, flags.dryRun, flags.allowRed);
727
912
  if (!flags.yes && !flags.dryRun) {
728
913
  const ok = await confirm("Proceed with release?");
729
914
  if (!ok) {
@@ -735,6 +920,20 @@ async function runStackRelease(flags) {
735
920
  log("info", "Tagging repos and triggering CI...");
736
921
  await tagAndTriggerCI(changes, flags.dryRun);
737
922
  const ciStatuses = await waitForCI(changes, flags.dryRun);
923
+ const ciFailures = ciStatuses.filter(
924
+ (s) => s.status !== "completed" || s.conclusion !== "success"
925
+ );
926
+ if (ciFailures.length > 0 && !flags.dryRun) {
927
+ await rollbackFailedReleases(changes, ciStatuses, flags.dryRun);
928
+ const ciSuccesses = ciStatuses.filter(
929
+ (s) => s.status === "completed" && s.conclusion === "success"
930
+ );
931
+ if (ciSuccesses.length === 0) {
932
+ log("fail", "All CI builds failed. Release aborted, all bumps rolled back.");
933
+ process.exit(1);
934
+ }
935
+ log("warn", `${ciFailures.length} CI build(s) failed and were rolled back. Continuing with ${ciSuccesses.length} successful build(s).`);
936
+ }
738
937
  let imageResults = [];
739
938
  if (flags.skipImageVerify) {
740
939
  log("warn", "Image verification skipped (--skip-image-verify)");
@@ -761,7 +960,7 @@ async function runStackRelease(flags) {
761
960
  printImageVerification(imageResults);
762
961
  }
763
962
  log("info", "Updating stack manifest...");
764
- const newStackVersion = updateStackManifest(changes, ciStatuses, flags.dryRun, imageResults);
963
+ const newStackVersion = await updateStackManifest(changes, ciStatuses, flags.dryRun, imageResults);
765
964
  gatePublishWithPreflight(newStackVersion, flags.dryRun, flags.allowRed);
766
965
  const exeOsChange = changes.find((c) => c.repo.serviceKey === "exe-os");
767
966
  await commitAndTagExeOs(newStackVersion, exeOsChange, flags.dryRun);
@@ -22,13 +22,16 @@ import {
22
22
  findLatestBackupEnvFile,
23
23
  hardenHost,
24
24
  httpStatus,
25
+ isCloudflaredTunnelMisconfigured,
25
26
  isExecFormMigration,
26
27
  isStrictDigestEnabled,
28
+ isUsableTunnelToken,
27
29
  listAvailableVersions,
28
30
  loadServiceSelection,
29
31
  loadStackManifest,
30
32
  pairMonitorAgent,
31
33
  parseComposeDependsOn,
34
+ parseComposeServiceNames,
32
35
  parseEnv,
33
36
  parseRequiredEnvRefs,
34
37
  parseStackManifest,
@@ -50,11 +53,11 @@ import {
50
53
  verifyReleaseHealth,
51
54
  verifyStackManifestSignature,
52
55
  waitForHttpOk
53
- } from "./chunk-KMIAYKIH.js";
54
- import "./chunk-JV225JBX.js";
55
- import "./chunk-2EJ636HI.js";
56
- import "./chunk-DFIOOK5R.js";
57
- import "./chunk-65DBIEM2.js";
56
+ } from "./chunk-K5C6LC2G.js";
57
+ import "./chunk-I6RHLHVW.js";
58
+ import "./chunk-UST3MKK7.js";
59
+ import "./chunk-WCES22KG.js";
60
+ import "./chunk-SHIICYJW.js";
58
61
  import "./chunk-MLKGABMK.js";
59
62
  export {
60
63
  ProgressReporter,
@@ -80,13 +83,16 @@ export {
80
83
  findLatestBackupEnvFile,
81
84
  hardenHost,
82
85
  httpStatus,
86
+ isCloudflaredTunnelMisconfigured,
83
87
  isExecFormMigration,
84
88
  isStrictDigestEnabled,
89
+ isUsableTunnelToken,
85
90
  listAvailableVersions,
86
91
  loadServiceSelection,
87
92
  loadStackManifest,
88
93
  pairMonitorAgent,
89
94
  parseComposeDependsOn,
95
+ parseComposeServiceNames,
90
96
  parseEnv,
91
97
  parseRequiredEnvRefs,
92
98
  parseStackManifest,
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  StewardGate
3
- } from "./chunk-IRIPGGGL.js";
4
- import "./chunk-SCYWCWKY.js";
3
+ } from "./chunk-4UHQYBMQ.js";
4
+ import "./chunk-VG4ZH2Z3.js";
5
5
  import "./chunk-2I23RPSI.js";
6
- import "./chunk-GWPICNSO.js";
6
+ import "./chunk-CSTL7BMK.js";
7
7
  import "./chunk-PNQDP3OA.js";
8
- import "./chunk-VQRTO7IS.js";
8
+ import "./chunk-H73TUI4Y.js";
9
9
  import "./chunk-7HLWBYH7.js";
10
10
  import "./chunk-FXU7JOXK.js";
11
- import "./chunk-DFIOOK5R.js";
12
- import "./chunk-65DBIEM2.js";
11
+ import "./chunk-WCES22KG.js";
12
+ import "./chunk-SHIICYJW.js";
13
13
  import "./chunk-MLKGABMK.js";
14
14
  export {
15
15
  StewardGate
@@ -1,40 +1,40 @@
1
1
  import {
2
2
  sendIntercom,
3
3
  updateTaskStatus
4
- } from "./chunk-HED6D5KR.js";
5
- import "./chunk-RZJ6DXVE.js";
4
+ } from "./chunk-MMNMQNLD.js";
5
+ import "./chunk-L6QI2NNG.js";
6
6
  import "./chunk-4JERP7NT.js";
7
7
  import "./chunk-4FVVJ7ME.js";
8
8
  import "./chunk-E23LNUWJ.js";
9
- import "./chunk-WJ2PZGRV.js";
9
+ import "./chunk-ZAA344BL.js";
10
10
  import "./chunk-SSTLTIF3.js";
11
11
  import "./chunk-KOO3J5PV.js";
12
12
  import "./chunk-22TVSRQQ.js";
13
13
  import {
14
14
  recordOrchestrationEventBestEffort
15
- } from "./chunk-OR3TAZL3.js";
16
- import "./chunk-QB5JOGPK.js";
15
+ } from "./chunk-P4ULFI2N.js";
16
+ import "./chunk-2PI6JBJL.js";
17
17
  import "./chunk-NGP6LSV2.js";
18
- import "./chunk-XYG722JW.js";
18
+ import "./chunk-JIJKUZIO.js";
19
19
  import "./chunk-CVYC6DUW.js";
20
20
  import "./chunk-OPU3NYOO.js";
21
21
  import "./chunk-GJV3WDWM.js";
22
22
  import "./chunk-MP2AFCGL.js";
23
- import "./chunk-NIZQ3CIS.js";
23
+ import "./chunk-3AMGSCRH.js";
24
24
  import "./chunk-HYZV25LY.js";
25
25
  import {
26
26
  isCoordinatorName
27
- } from "./chunk-SCYWCWKY.js";
27
+ } from "./chunk-VG4ZH2Z3.js";
28
28
  import "./chunk-2I23RPSI.js";
29
- import "./chunk-GWPICNSO.js";
29
+ import "./chunk-CSTL7BMK.js";
30
30
  import "./chunk-PNQDP3OA.js";
31
- import "./chunk-VQRTO7IS.js";
31
+ import "./chunk-H73TUI4Y.js";
32
32
  import "./chunk-7HLWBYH7.js";
33
33
  import "./chunk-FXU7JOXK.js";
34
- import "./chunk-JV225JBX.js";
35
- import "./chunk-2EJ636HI.js";
36
- import "./chunk-DFIOOK5R.js";
37
- import "./chunk-65DBIEM2.js";
34
+ import "./chunk-I6RHLHVW.js";
35
+ import "./chunk-UST3MKK7.js";
36
+ import "./chunk-WCES22KG.js";
37
+ import "./chunk-SHIICYJW.js";
38
38
  import "./chunk-MLKGABMK.js";
39
39
 
40
40
  // src/lib/task-enforcement.ts
@@ -2,36 +2,36 @@ import {
2
2
  getCurrentSessionScope,
3
3
  sessionScopeFilter,
4
4
  strictSessionScopeFilter
5
- } from "./chunk-HED6D5KR.js";
6
- import "./chunk-RZJ6DXVE.js";
5
+ } from "./chunk-MMNMQNLD.js";
6
+ import "./chunk-L6QI2NNG.js";
7
7
  import "./chunk-4JERP7NT.js";
8
8
  import "./chunk-4FVVJ7ME.js";
9
9
  import "./chunk-E23LNUWJ.js";
10
- import "./chunk-WJ2PZGRV.js";
10
+ import "./chunk-ZAA344BL.js";
11
11
  import "./chunk-SSTLTIF3.js";
12
12
  import "./chunk-KOO3J5PV.js";
13
13
  import "./chunk-22TVSRQQ.js";
14
- import "./chunk-OR3TAZL3.js";
15
- import "./chunk-QB5JOGPK.js";
14
+ import "./chunk-P4ULFI2N.js";
15
+ import "./chunk-2PI6JBJL.js";
16
16
  import "./chunk-NGP6LSV2.js";
17
- import "./chunk-XYG722JW.js";
17
+ import "./chunk-JIJKUZIO.js";
18
18
  import "./chunk-CVYC6DUW.js";
19
19
  import "./chunk-OPU3NYOO.js";
20
20
  import "./chunk-GJV3WDWM.js";
21
21
  import "./chunk-MP2AFCGL.js";
22
- import "./chunk-NIZQ3CIS.js";
22
+ import "./chunk-3AMGSCRH.js";
23
23
  import "./chunk-HYZV25LY.js";
24
- import "./chunk-SCYWCWKY.js";
24
+ import "./chunk-VG4ZH2Z3.js";
25
25
  import "./chunk-2I23RPSI.js";
26
- import "./chunk-GWPICNSO.js";
26
+ import "./chunk-CSTL7BMK.js";
27
27
  import "./chunk-PNQDP3OA.js";
28
- import "./chunk-VQRTO7IS.js";
28
+ import "./chunk-H73TUI4Y.js";
29
29
  import "./chunk-7HLWBYH7.js";
30
30
  import "./chunk-FXU7JOXK.js";
31
- import "./chunk-JV225JBX.js";
32
- import "./chunk-2EJ636HI.js";
33
- import "./chunk-DFIOOK5R.js";
34
- import "./chunk-65DBIEM2.js";
31
+ import "./chunk-I6RHLHVW.js";
32
+ import "./chunk-UST3MKK7.js";
33
+ import "./chunk-WCES22KG.js";
34
+ import "./chunk-SHIICYJW.js";
35
35
  import "./chunk-MLKGABMK.js";
36
36
  export {
37
37
  getCurrentSessionScope,
@@ -25,36 +25,36 @@ import {
25
25
  slugify,
26
26
  updateTaskStatus,
27
27
  writeCheckpoint
28
- } from "./chunk-HED6D5KR.js";
29
- import "./chunk-RZJ6DXVE.js";
28
+ } from "./chunk-MMNMQNLD.js";
29
+ import "./chunk-L6QI2NNG.js";
30
30
  import "./chunk-4JERP7NT.js";
31
31
  import "./chunk-4FVVJ7ME.js";
32
32
  import "./chunk-E23LNUWJ.js";
33
- import "./chunk-WJ2PZGRV.js";
33
+ import "./chunk-ZAA344BL.js";
34
34
  import "./chunk-SSTLTIF3.js";
35
35
  import "./chunk-KOO3J5PV.js";
36
36
  import "./chunk-22TVSRQQ.js";
37
- import "./chunk-OR3TAZL3.js";
38
- import "./chunk-QB5JOGPK.js";
37
+ import "./chunk-P4ULFI2N.js";
38
+ import "./chunk-2PI6JBJL.js";
39
39
  import "./chunk-NGP6LSV2.js";
40
- import "./chunk-XYG722JW.js";
40
+ import "./chunk-JIJKUZIO.js";
41
41
  import "./chunk-CVYC6DUW.js";
42
42
  import "./chunk-OPU3NYOO.js";
43
43
  import "./chunk-GJV3WDWM.js";
44
44
  import "./chunk-MP2AFCGL.js";
45
- import "./chunk-NIZQ3CIS.js";
45
+ import "./chunk-3AMGSCRH.js";
46
46
  import "./chunk-HYZV25LY.js";
47
- import "./chunk-SCYWCWKY.js";
47
+ import "./chunk-VG4ZH2Z3.js";
48
48
  import "./chunk-2I23RPSI.js";
49
- import "./chunk-GWPICNSO.js";
49
+ import "./chunk-CSTL7BMK.js";
50
50
  import "./chunk-PNQDP3OA.js";
51
- import "./chunk-VQRTO7IS.js";
51
+ import "./chunk-H73TUI4Y.js";
52
52
  import "./chunk-7HLWBYH7.js";
53
53
  import "./chunk-FXU7JOXK.js";
54
- import "./chunk-JV225JBX.js";
55
- import "./chunk-2EJ636HI.js";
56
- import "./chunk-DFIOOK5R.js";
57
- import "./chunk-65DBIEM2.js";
54
+ import "./chunk-I6RHLHVW.js";
55
+ import "./chunk-UST3MKK7.js";
56
+ import "./chunk-WCES22KG.js";
57
+ import "./chunk-SHIICYJW.js";
58
58
  import "./chunk-MLKGABMK.js";
59
59
  export {
60
60
  DEFAULT_TASK_PRIORITY,