@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.
- package/delivery/catalog.json +1254 -0
- package/deploy/compose/.env.customer.example +5 -5
- package/deploy/compose/.env.example +3 -3
- package/deploy/compose/docker-compose.yml +1 -1
- package/deploy/compose/generate-env.ts +65 -9
- package/deploy/compose/setup.sh +205 -7
- package/deploy/compose/sso-edge/default.conf.template +45 -0
- package/deploy/compose/sso-edge/sso-redirect.conf +11 -2
- package/deploy/stack-manifests/v0.9.30-apps.json +1 -1
- package/deploy/stack-manifests/v0.9.json +254 -2
- package/dist/.dist-verified.json +3 -3
- package/dist/{active-agent-GFUUCFLD.js → active-agent-F5V4E4UL.js} +7 -7
- package/dist/{active-agent-LE6FE6SO.js → active-agent-YTBB4ZQM.js} +7 -7
- package/dist/{agent-defs-generator-EIUA3SH5.js → agent-defs-generator-7TFISIJQ.js} +6 -6
- package/dist/{agent-loop-7ZRH56EX.js → agent-loop-EZ7LDAGD.js} +1 -1
- package/dist/{agentic-ontology-67JGSP7G.js → agentic-ontology-XVTUVV7W.js} +1 -1
- package/dist/{artifact-backup-NYXAYASJ.js → artifact-backup-TF6YWQT2.js} +5 -5
- package/dist/{backfill-gate-KWJQ35YX.js → backfill-gate-FWYLCGNJ.js} +3 -3
- package/dist/{backfill-metadata-RQYG2WUJ.js → backfill-metadata-J6MXIDCW.js} +10 -10
- package/dist/{background-jobs-6VMD55PK.js → background-jobs-V3DZRFKU.js} +3 -3
- package/dist/{backup-verify-HC4YDSGN.js → backup-verify-6DVBQMDP.js} +67 -18
- package/dist/{behavior-injection-6HSXP43Q.js → behavior-injection-XDA7ZCYN.js} +21 -20
- package/dist/{behavior-promotion-SJDQ2Y3U.js → behavior-promotion-4VLQ7LXK.js} +20 -19
- package/dist/{behaviors-6ITLA2CK.js → behaviors-SCCZP7RZ.js} +19 -18
- package/dist/bin/age-ontology-load.js +3 -3
- package/dist/bin/agentic-ontology-backfill.js +12 -12
- package/dist/bin/agentic-reflection-backfill.js +13 -13
- package/dist/bin/agentic-semantic-label.js +12 -12
- package/dist/bin/backfill-conversations.js +17 -16
- package/dist/bin/backfill-responses.js +17 -16
- package/dist/bin/backfill-vectors.js +23 -22
- package/dist/bin/bulk-sync-postgres.js +28 -27
- package/dist/bin/cc-doctor.js +17 -16
- package/dist/bin/cleanup-stale-review-tasks.js +29 -28
- package/dist/bin/cli.js +35 -26
- package/dist/bin/deferred-daemon-restart.js +124 -123
- package/dist/bin/exe-actions.js +1 -1
- package/dist/bin/exe-agent-config.js +6 -6
- package/dist/bin/exe-agent.js +22 -22
- package/dist/bin/exe-assign.js +19 -18
- package/dist/bin/exe-boot.js +57 -56
- package/dist/bin/exe-call.js +7 -7
- package/dist/bin/exe-cicd.js +38 -8
- package/dist/bin/exe-cloud.js +30 -29
- package/dist/bin/exe-config-dump.js +6 -6
- package/dist/bin/exe-dispatch.js +30 -29
- package/dist/bin/exe-doctor.js +11 -11
- package/dist/bin/exe-export-behaviors.js +23 -22
- package/dist/bin/exe-forget.js +13 -13
- package/dist/bin/exe-gateway.js +47 -14
- package/dist/bin/exe-grant.js +6 -6
- package/dist/bin/exe-healthcheck.js +17 -16
- package/dist/bin/exe-heartbeat.js +41 -35
- package/dist/bin/exe-kill.js +35 -34
- package/dist/bin/exe-launch-agent.js +43 -42
- package/dist/bin/exe-mcp.js +9 -9
- package/dist/bin/exe-memory-reads.js +10 -10
- package/dist/bin/exe-new-employee.js +11 -11
- package/dist/bin/exe-os-mcp-proxy.js +9 -9
- package/dist/bin/exe-pending-messages.js +30 -29
- package/dist/bin/exe-pending-notifications.js +29 -28
- package/dist/bin/exe-pending-reviews.js +30 -29
- package/dist/bin/exe-preflight.js +1 -1
- package/dist/bin/exe-rename.js +9 -9
- package/dist/bin/exe-review.js +34 -33
- package/dist/bin/exe-search.js +12 -12
- package/dist/bin/exe-session-cleanup.js +35 -34
- package/dist/bin/exe-settings.js +29 -28
- package/dist/bin/exe-start-codex.js +30 -29
- package/dist/bin/exe-start-opencode.js +27 -26
- package/dist/bin/exe-status.js +31 -30
- package/dist/bin/exe-support.js +5 -5
- package/dist/bin/exe-team.js +7 -7
- package/dist/bin/exe-verify-running-images.js +1 -1
- package/dist/bin/exe-watchdog.js +8 -8
- package/dist/bin/generate-hook-manifest.js +7 -1
- package/dist/bin/git-sweep.js +30 -29
- package/dist/bin/graph-backfill.js +12 -12
- package/dist/bin/graph-export.js +11 -11
- package/dist/bin/hooks-cli.js +1 -1
- package/dist/bin/import-history.js +15 -15
- package/dist/bin/install.js +130 -129
- package/dist/bin/intercom-check.js +11 -7
- package/dist/bin/mcp-sessions.js +2 -2
- package/dist/bin/orchestration-metrics.js +7 -7
- package/dist/bin/postgres-agentic-reflection-backfill.js +5 -5
- package/dist/bin/postgres-agentic-semantic-backfill.js +4 -4
- package/dist/bin/reconcile-backlog.js +2 -2
- package/dist/bin/registry-proxy.js +1 -1
- package/dist/bin/repair-document-chunks.js +161 -0
- package/dist/bin/scan-tasks.js +30 -29
- package/dist/bin/setup.js +5 -5
- package/dist/bin/shard-migrate.js +11 -11
- package/dist/bin/stack-update.js +625 -33
- package/dist/bin/update.js +96 -22
- package/dist/bin/verify-stack.js +2 -2
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/{boot-generation-L55QANCX.js → boot-generation-Q7LGQ3AO.js} +6 -6
- package/dist/{boot-review-sections-AON5ZCR2.js → boot-review-sections-G5774FR5.js} +28 -27
- package/dist/{branch-hygiene-QLD77IMJ.js → branch-hygiene-44WLSOZR.js} +2 -2
- package/dist/{branding-I6KIMB7F.js → branding-KMWCY5HZ.js} +3 -3
- package/dist/build-manifest.json +1259 -1219
- package/dist/{capability-cards-WTOXY7O6.js → capability-cards-I3RHCF4F.js} +5 -5
- package/dist/{capacity-monitor-ZLG7FSWM.js → capacity-monitor-7I7GDONU.js} +30 -29
- package/dist/{catchup-brief-QHY7D7N2.js → catchup-brief-3T5PARIR.js} +39 -36
- package/dist/check-image-pullability-2AIVB4BX.js +338 -0
- package/dist/{chunk-CTCCYKOV.js → chunk-2FKU4ZEO.js} +55 -29
- package/dist/{chunk-M7O7TGGU.js → chunk-2NW4LRDU.js} +1 -1
- package/dist/{chunk-XTFM4KMW.js → chunk-2PZTMSMG.js} +6 -6
- package/dist/{chunk-UWX6MMCX.js → chunk-3B6FLNLV.js} +1 -1
- package/dist/{chunk-GPJIBLP4.js → chunk-3DAEZILW.js} +1 -1
- package/dist/{chunk-NY6SBR4O.js → chunk-3FGBBJYM.js} +15 -3
- package/dist/{chunk-C4OZVVSG.js → chunk-3OX34OC3.js} +50 -18
- package/dist/{chunk-TXTXC3QG.js → chunk-3RGTLZNO.js} +12 -12
- package/dist/{chunk-PYRO25A5.js → chunk-3SUPEE6H.js} +10 -11
- package/dist/{chunk-PPMGQFLJ.js → chunk-3XY57PKT.js} +2 -2
- package/dist/{chunk-CRHI5QTZ.js → chunk-46VSBDUW.js} +2 -2
- package/dist/{chunk-VZT66WWP.js → chunk-4AAMFWJT.js} +2 -2
- package/dist/{chunk-4GZTBLJG.js → chunk-4AR5XKCH.js} +1 -1
- package/dist/{chunk-IHXW4VUI.js → chunk-5IADGFGR.js} +1 -1
- package/dist/{chunk-GLQEJOXE.js → chunk-5MVKTNZP.js} +57 -0
- package/dist/{chunk-AVMLC2MR.js → chunk-5U2IJBFV.js} +290 -41
- package/dist/{chunk-JUKDL5MF.js → chunk-6BJCDWSM.js} +1 -1
- package/dist/{chunk-6WWNK7UX.js → chunk-6FIC57PH.js} +1 -1
- package/dist/{chunk-ASUICGPX.js → chunk-6YDY6ZTD.js} +4 -4
- package/dist/{chunk-FU5O2REK.js → chunk-72V3S44T.js} +108 -29
- package/dist/{chunk-LTIIZHNA.js → chunk-7J2ZQ4XN.js} +1 -1
- package/dist/{chunk-7RI2CNXJ.js → chunk-7OTR2OET.js} +1 -1
- package/dist/{chunk-ZVBVPX4W.js → chunk-7UHZBVP3.js} +82 -51
- package/dist/{chunk-PTY2N23C.js → chunk-AGC2V7JS.js} +26 -13
- package/dist/{chunk-44VR3PFW.js → chunk-AHESD3KW.js} +1 -1
- package/dist/{chunk-NPGV4MZ3.js → chunk-ALRHGEAJ.js} +1 -1
- package/dist/{chunk-WJC6AAJN.js → chunk-ANVHWV2X.js} +2 -2
- package/dist/{chunk-AGZSGAEN.js → chunk-APL7HUE3.js} +105 -32
- package/dist/{chunk-7UH2JWBF.js → chunk-AZSTIAVL.js} +176 -11
- package/dist/chunk-AZXMR25O.js +545 -0
- package/dist/{chunk-WPWEBZ37.js → chunk-B7AMNZTC.js} +2 -2
- package/dist/{chunk-4CF5KUWH.js → chunk-BPVFZ6Q4.js} +3 -3
- package/dist/{chunk-XTQ7R2PA.js → chunk-BV2IET6B.js} +73 -17
- package/dist/{chunk-4F5CNI65.js → chunk-C5ISP5FO.js} +2 -2
- package/dist/{chunk-NPWNXJ3U.js → chunk-CH7BUBP3.js} +7 -7
- package/dist/{chunk-X5Q66EOG.js → chunk-CHIUS5QB.js} +16 -16
- package/dist/{chunk-ZG62LIK3.js → chunk-CIPDQRFO.js} +1 -1
- package/dist/{chunk-4PYIRIU6.js → chunk-CM7N5MBY.js} +5 -5
- package/dist/{chunk-L5YDAFUH.js → chunk-CYCIX7AW.js} +5 -5
- package/dist/{chunk-76YRJKKF.js → chunk-D3LXVAIQ.js} +28 -16
- package/dist/{chunk-2GNAHBRD.js → chunk-DMUOTCDN.js} +1 -1
- package/dist/{chunk-QMUFSRQX.js → chunk-DN3ZR3UE.js} +1 -1
- package/dist/{chunk-V3WLC5TJ.js → chunk-DRTJCG6B.js} +1 -1
- package/dist/{chunk-275WHBEN.js → chunk-DYVLEMKS.js} +1 -1
- package/dist/{chunk-O34F5EP5.js → chunk-DZN7SDY2.js} +1 -1
- package/dist/{chunk-ZDIXMHY7.js → chunk-E3ZM32LF.js} +8 -8
- package/dist/{chunk-N2HXR5MB.js → chunk-E7C2WNR5.js} +4 -4
- package/dist/{chunk-VVGXWVZU.js → chunk-EGOEB42T.js} +3 -3
- package/dist/{chunk-QV5CQLQH.js → chunk-EIOGV75A.js} +2 -2
- package/dist/{chunk-ZY4IGUOS.js → chunk-ELCRJGCH.js} +3 -3
- package/dist/{chunk-5QCIWWFA.js → chunk-ELEGH4DX.js} +130 -14
- package/dist/{chunk-S7CTCPSW.js → chunk-EOTZSAQL.js} +1 -1
- package/dist/{chunk-PPLQ4ECD.js → chunk-EUGEFBGV.js} +3 -3
- package/dist/{chunk-UFNCL6MS.js → chunk-EYMFVITZ.js} +1 -1
- package/dist/{chunk-F6H7GP2O.js → chunk-F4BBMIPG.js} +3 -3
- package/dist/{chunk-FNEZ4BWT.js → chunk-FEU6QEEL.js} +1 -1
- package/dist/{chunk-JKOC2L6P.js → chunk-FHIFTSPL.js} +1 -1
- package/dist/{chunk-4RTKETV3.js → chunk-FMIYFHLE.js} +3 -3
- package/dist/{chunk-TK544DEW.js → chunk-FVLNNNH6.js} +3 -3
- package/dist/{chunk-AY2U4NZ5.js → chunk-GL47M7NY.js} +85 -17
- package/dist/{chunk-DN24VTS5.js → chunk-GSLFH4AI.js} +25 -13
- package/dist/{chunk-CHO5SNWR.js → chunk-HA63SH5W.js} +1 -1
- package/dist/{chunk-4IK2K3B3.js → chunk-HME6ITKV.js} +1 -1
- package/dist/{chunk-H2T6TFJZ.js → chunk-HU3VD4MQ.js} +2 -2
- package/dist/{chunk-ZW32RI66.js → chunk-I5XIW2BP.js} +49 -11
- package/dist/{chunk-3CL2I3RG.js → chunk-IGJMS7C5.js} +2 -2
- package/dist/{chunk-BRPO6GOH.js → chunk-JA3Y5TV6.js} +2 -2
- package/dist/{chunk-SFFXAPYK.js → chunk-JDDM6C57.js} +1 -1
- package/dist/{chunk-W4EGAQXW.js → chunk-JFJP6ATJ.js} +2 -2
- package/dist/{chunk-ENCUOZXX.js → chunk-JFTUAV4J.js} +1 -1
- package/dist/{chunk-3UOQH2DJ.js → chunk-JJTPPAZY.js} +2568 -345
- package/dist/{chunk-A6QBAUJH.js → chunk-KILR4FBR.js} +4 -4
- package/dist/{chunk-CGFGNHSP.js → chunk-KTKIFXIP.js} +1 -1
- package/dist/{chunk-NCJBPXGM.js → chunk-KXYKSLW4.js} +108 -24
- package/dist/{chunk-3MUARHPO.js → chunk-L3VUW5M4.js} +1 -1
- package/dist/{chunk-GZOG2MAX.js → chunk-L5EPGGDP.js} +1 -1
- package/dist/{chunk-T7VSKWES.js → chunk-L63V25HS.js} +6 -5
- package/dist/{chunk-R4VNGRKU.js → chunk-LFBLQE2P.js} +1 -1
- package/dist/{chunk-W5MCOZTW.js → chunk-LFUBEHFW.js} +12 -2
- package/dist/{chunk-AIBIEP4R.js → chunk-LKTN22L6.js} +61 -25
- package/dist/{chunk-3KFQCFQB.js → chunk-LR5O2XWZ.js} +5 -5
- package/dist/{chunk-VUOAPKPI.js → chunk-LSNBTGW4.js} +1 -1
- package/dist/{chunk-P5U3GAWU.js → chunk-MB47DRF5.js} +2 -2
- package/dist/{chunk-HZESME3B.js → chunk-MC4IM2CC.js} +16 -13
- package/dist/{chunk-ZKJ5S23O.js → chunk-MFAOAIUE.js} +12 -9
- package/dist/{chunk-62J64CHO.js → chunk-MKM6D7JM.js} +26 -7
- package/dist/{chunk-ZIG7VPJV.js → chunk-MMS2HBRT.js} +15 -3
- package/dist/{chunk-FHSV4BSW.js → chunk-MOANZQXF.js} +12 -4
- package/dist/{chunk-RTZZBWQC.js → chunk-MPZ2AVNS.js} +16 -5
- package/dist/{chunk-AZ6KLVDX.js → chunk-MROSARM5.js} +2 -2
- package/dist/{chunk-RV2FFCDS.js → chunk-MUAWCFW6.js} +6 -2
- package/dist/{chunk-K4ESASPL.js → chunk-MUCNYSJP.js} +1 -1
- package/dist/{chunk-5QGKMP6T.js → chunk-NF5FOSLD.js} +1 -1
- package/dist/{chunk-CKOJP7JI.js → chunk-NKEFYE4R.js} +2 -2
- package/dist/{chunk-3SXHEQ7X.js → chunk-NPXIS2RY.js} +1 -1
- package/dist/{chunk-A5USSF66.js → chunk-NVFNADTX.js} +12 -8
- package/dist/{chunk-VVUO3RJS.js → chunk-NYLJQ2M2.js} +4 -4
- package/dist/{chunk-HIVOLPLD.js → chunk-OAFENIHN.js} +1 -1
- package/dist/{chunk-PMZHZQ6K.js → chunk-OBBO6EJR.js} +1 -1
- package/dist/{chunk-SS6EMDLL.js → chunk-P2UY34XE.js} +6 -6
- package/dist/{chunk-Y4T5IUEP.js → chunk-P3QQ52QK.js} +2 -2
- package/dist/{chunk-GGEKMY6G.js → chunk-P3UX5EH4.js} +4 -4
- package/dist/{chunk-F7IRZU5G.js → chunk-P4PIZOL2.js} +3 -3
- package/dist/{chunk-GEPFKUUR.js → chunk-P4XLIPB7.js} +1 -1
- package/dist/{chunk-GPUOUUHA.js → chunk-PCV52RYM.js} +1 -1
- package/dist/{chunk-XR3773KZ.js → chunk-PL4CFSQ7.js} +1 -1
- package/dist/{chunk-LLZNPOGB.js → chunk-PLII76NJ.js} +58 -0
- package/dist/{chunk-FT5PPV2C.js → chunk-PRDDPQLC.js} +5 -5
- package/dist/{chunk-BZ546I4Q.js → chunk-PUBA5B4M.js} +24 -0
- package/dist/{chunk-2TGJ5XCV.js → chunk-PWC3C5ME.js} +4 -4
- package/dist/{chunk-A4YCLD3L.js → chunk-QFAFKEB5.js} +40 -4
- package/dist/{chunk-CL4J4757.js → chunk-QH5ZQ5SJ.js} +26 -0
- package/dist/{chunk-UJWZYK46.js → chunk-QNZ4562V.js} +1 -1
- package/dist/{chunk-IPHLUZ37.js → chunk-QPTSA4PP.js} +2 -2
- package/dist/{chunk-O3YJTHWI.js → chunk-R5E7WNAC.js} +3 -3
- package/dist/{chunk-V3M4LJRA.js → chunk-RB3J2WYQ.js} +1 -1
- package/dist/{chunk-IUCWOI4Y.js → chunk-RDWIKDMY.js} +237 -11
- package/dist/{chunk-ENN6DY4T.js → chunk-RVO5O5SR.js} +46 -21
- package/dist/{chunk-LY4AXCYJ.js → chunk-RZN2LEAK.js} +6 -6
- package/dist/{chunk-2YIB75UQ.js → chunk-S26CV7BE.js} +57 -13
- package/dist/{chunk-XC36HYP6.js → chunk-SDYWZRPN.js} +1 -1
- package/dist/{chunk-PHBU4LGO.js → chunk-SNHYZYGZ.js} +1 -1
- package/dist/{chunk-4KTTBKWQ.js → chunk-T5FEAQES.js} +1 -1
- package/dist/{chunk-XU57KFD6.js → chunk-T5SM4RXY.js} +5 -1
- package/dist/{chunk-KUV5VBAO.js → chunk-TKAU7IJ2.js} +1 -1
- package/dist/{chunk-KBR5LIWD.js → chunk-TKS5GMYA.js} +1 -1
- package/dist/{chunk-5DFE2NAF.js → chunk-TNS63ATU.js} +96 -22
- package/dist/{chunk-RFPMXR6B.js → chunk-U4GMOT4M.js} +1 -1
- package/dist/{chunk-CO5ZVE3D.js → chunk-UOPCVFVR.js} +17 -17
- package/dist/{chunk-22LNFCDF.js → chunk-UX2EO653.js} +1 -1
- package/dist/{chunk-LGC6TBA3.js → chunk-UXN4BICC.js} +2 -2
- package/dist/{chunk-7J5X4AK7.js → chunk-VF2KRROX.js} +1 -1
- package/dist/{chunk-7THUQU44.js → chunk-VF3BZOZK.js} +5 -2
- package/dist/{chunk-M2B35MUK.js → chunk-VHHX4UCP.js} +1 -1
- package/dist/{chunk-AZBJXATK.js → chunk-VJEJ7JNB.js} +1 -1
- package/dist/{chunk-4TRVALTR.js → chunk-VLBHZ6TF.js} +2 -2
- package/dist/{chunk-7BMSBACY.js → chunk-VOVFUKEB.js} +5 -5
- package/dist/{chunk-MDPGZS6C.js → chunk-VROK4X2L.js} +1 -1
- package/dist/{chunk-J6ABJDZ4.js → chunk-W3KPQE7H.js} +4 -4
- package/dist/{chunk-3Q7NEDHB.js → chunk-W6BZ4UGA.js} +48 -9
- package/dist/{chunk-IZ3IFLL2.js → chunk-XEBKIWI7.js} +14 -14
- package/dist/{chunk-UZDF6FLJ.js → chunk-XHU3KOKJ.js} +1 -1
- package/dist/{chunk-PA37MXV5.js → chunk-XSUALA32.js} +2 -2
- package/dist/{chunk-GR5WJPKF.js → chunk-XUZK23V7.js} +11 -6
- package/dist/{chunk-IDB3EZLW.js → chunk-YLB365YX.js} +148 -5
- package/dist/{chunk-JDQ7JU3A.js → chunk-YLFCH3VA.js} +24 -16
- package/dist/{chunk-ZJJL2Z23.js → chunk-YRQ26MNP.js} +4 -4
- package/dist/chunk-YRUZK2QA.js +35 -0
- package/dist/{chunk-7HLJ4BSF.js → chunk-ZAEUEDTN.js} +2 -2
- package/dist/{chunk-NY74W3S4.js → chunk-ZBPZDADW.js} +313 -43
- package/dist/{chunk-ZLPS3GR7.js → chunk-ZJQ56DZZ.js} +42 -1
- package/dist/{chunk-VMZZTFXT.js → chunk-ZOTTYCP5.js} +4 -4
- package/dist/{chunk-MP4ST7RO.js → chunk-ZPP63JSQ.js} +51 -11
- package/dist/{chunk-N4J5WHO2.js → chunk-ZT4LFTUJ.js} +1 -1
- package/dist/{cleanup-graph-garbage-GE2DYOTB.js → cleanup-graph-garbage-VQAJ2RBT.js} +11 -11
- package/dist/{cloud-sync-command-T6KF3ARK.js → cloud-sync-command-J7NEFUY7.js} +2 -2
- package/dist/{cloud-sync-db-init-RSHCCY74.js → cloud-sync-db-init-KWEMNMGA.js} +1 -1
- package/dist/{cloud-sync-shutdown-6IVCSLM5.js → cloud-sync-shutdown-P63AUTUI.js} +5 -5
- package/dist/{co-activation-AF7RCJPX.js → co-activation-7IHRPBZN.js} +5 -5
- package/dist/{co-occurrence-DMOOGBVV.js → co-occurrence-R5AG4OAU.js} +9 -9
- package/dist/{code-context-index-LIDOFKOR.js → code-context-index-WFLLZBVB.js} +10 -9
- package/dist/{code-context-watcher-4F7K2N3U.js → code-context-watcher-3QAPHO7N.js} +10 -9
- package/dist/{codex-consolidation-SH4UKFBQ.js → codex-consolidation-ONZ2AQFX.js} +2 -2
- package/dist/{consent-passphrase-WV7MZPMO.js → consent-passphrase-5ZBDJ5G7.js} +2 -2
- package/dist/{content-extractor-DJM5EUDA.js → content-extractor-ZLXC6GNR.js} +2 -2
- package/dist/{conversation-entity-extractor-4UG7BKWL.js → conversation-entity-extractor-7FRKLLBD.js} +4 -4
- package/dist/{conversation-wiki-populator-OS4C6W54.js → conversation-wiki-populator-YAOVCUGO.js} +1 -1
- package/dist/{crdt-sync-VL4KXZB7.js → crdt-sync-IFRZOEIS.js} +4 -4
- package/dist/{crm-webhook-IDBJ7X5Y.js → crm-webhook-L2S63ASV.js} +2 -2
- package/dist/{cto-delegation-gate-4FLSHSLO.js → cto-delegation-gate-3WU7OHX7.js} +29 -28
- package/dist/{daemon-auth-PNKHERLV.js → daemon-auth-OWLFYEFR.js} +3 -3
- package/dist/{daemon-orchestration-HFCB6OK4.js → daemon-orchestration-3VQYKLOR.js} +33 -32
- package/dist/{daemon-ready-BN6EZLTQ.js → daemon-ready-VZ6ZHA2C.js} +1 -1
- package/dist/{db-integrity-events-GYGANKZV.js → db-integrity-events-7NKWS5MT.js} +3 -3
- package/dist/{db-restore-events-G6NOQOVE.js → db-restore-events-XYL6CGPC.js} +2 -2
- package/dist/{destructive-data-guard-HHWUBIGS.js → destructive-data-guard-JDUJ2ULM.js} +58 -2
- package/dist/{dispatch-ack-X4DXUSKP.js → dispatch-ack-UYEAKON5.js} +2 -1
- package/dist/{doc-graph-extractor-E36PQUCS.js → doc-graph-extractor-YIR5E7OF.js} +9 -9
- package/dist/{documents-SCKKHDR7.js → documents-QEHPTYIY.js} +19 -18
- package/dist/{dreaming-Q26JBH56.js → dreaming-LNFE7DTN.js} +34 -33
- package/dist/{employee-boot-brief-XU6EI2EO.js → employee-boot-brief-ZTXDYNWM.js} +39 -38
- package/dist/{entity-boost-VNQLLR3Q.js → entity-boost-R5N6JWXD.js} +1 -1
- package/dist/{exe-drift-YZ6OIUAY.js → exe-drift-WYSJVZFO.js} +6 -6
- package/dist/{exe-export-HHRQMLSS.js → exe-export-GOLNAEAV.js} +20 -19
- package/dist/{exe-import-5XR4NQAB.js → exe-import-U4BSI6OH.js} +20 -19
- package/dist/{exe-key-5XOFVP3I.js → exe-key-V42G3NGO.js} +152 -130
- package/dist/{exe-org-TPAX4AAK.js → exe-org-U4GLQ6OP.js} +27 -27
- package/dist/{exe-snapshot-GIRP3XCJ.js → exe-snapshot-U7ONBYNY.js} +38 -37
- package/dist/{fast-db-init-MGY6VCLG.js → fast-db-init-W3NGKAEU.js} +1 -1
- package/dist/{founder-context-WD72OL2P.js → founder-context-ZSIBRVDM.js} +4 -4
- package/dist/{founder-monitor-envelope-XGYMHT4W.js → founder-monitor-envelope-L3IWZLFY.js} +7 -7
- package/dist/{fts-integrity-PLAL6NMG.js → fts-integrity-PHCKKOBC.js} +3 -3
- package/dist/gateway/index.js +23 -22
- package/dist/{gateway-client-VO3BRLV5.js → gateway-client-DJFCVIPT.js} +1 -1
- package/dist/{git-staleness-KGZABPP3.js → git-staleness-OF24QXFZ.js} +5 -5
- package/dist/{global-procedures-KOU6A5E5.js → global-procedures-WSIOWO43.js} +6 -6
- package/dist/{graph-auto-extract-OZNRDAHE.js → graph-auto-extract-IEVVN3L3.js} +9 -9
- package/dist/{graph-query-36K6VXFF.js → graph-query-JDZWAVCU.js} +1 -1
- package/dist/{graph-rag-TZLH3CTQ.js → graph-rag-BKAD2XQA.js} +4 -4
- package/dist/{hook-integrity-BWFFISJV.js → hook-integrity-TPWDGX2M.js} +3 -1
- package/dist/{hook-prefetch-MFUJRAIM.js → hook-prefetch-FD6VGJJA.js} +29 -28
- package/dist/hooks/bug-report-worker.js +34 -33
- package/dist/hooks/codex-stop-task-finalizer.js +36 -35
- package/dist/hooks/commit-complete.js +40 -36
- package/dist/hooks/error-recall.js +15 -15
- package/dist/hooks/exe-heartbeat-hook.js +8 -8
- package/dist/hooks/ingest-worker.js +21 -20
- package/dist/hooks/ingest.js +23 -23
- package/dist/hooks/instructions-loaded.js +10 -10
- package/dist/hooks/manifest.json +20 -20
- package/dist/hooks/notification.js +9 -9
- package/dist/hooks/post-compact.js +8 -8
- package/dist/hooks/post-tool-combined.js +15 -15
- package/dist/hooks/pre-compact.js +33 -32
- package/dist/hooks/pre-tool-use.js +2 -2
- package/dist/hooks/prompt-submit.js +52 -51
- package/dist/hooks/session-end.js +38 -37
- package/dist/hooks/session-start.js +25 -22
- package/dist/hooks/stop.js +40 -39
- package/dist/hooks/subagent-stop.js +36 -35
- package/dist/hooks/summary-worker.js +41 -40
- package/dist/index.js +43 -42
- package/dist/{inrun-inbox-DRKVDPLY.js → inrun-inbox-RGNFFGMU.js} +5 -0
- package/dist/{installer-RM4ASY7U.js → installer-NMOBSEZ2.js} +11 -11
- package/dist/{installer-IESPHXVH.js → installer-OTI5SA43.js} +11 -11
- package/dist/{installer-SQZRVD36.js → installer-SRJGE4GU.js} +11 -11
- package/dist/{intercom-queue-DGLAC224.js → intercom-queue-4FFXCBHO.js} +28 -27
- package/dist/{key-backup-status-LQPINQ3W.js → key-backup-status-6U7D5GOD.js} +2 -2
- package/dist/lib/agent-config.js +3 -3
- package/dist/lib/cloud-sync.js +28 -27
- package/dist/lib/config.js +4 -2
- package/dist/lib/consolidation.js +14 -12
- package/dist/lib/crypto.js +5 -3
- package/dist/lib/database.js +5 -5
- package/dist/lib/db-backup.js +11 -3
- package/dist/lib/db-daemon-client.js +11 -10
- package/dist/lib/db-write-worker.js +4 -4
- package/dist/lib/db.js +5 -5
- package/dist/lib/delivery-catalog.js +431 -0
- package/dist/lib/delivery-schemas.js +62 -0
- package/dist/lib/delivery-truth.js +1 -1
- package/dist/lib/device-registry.js +3 -3
- package/dist/lib/embed-worker.js +2 -2
- package/dist/lib/embedder.js +10 -9
- package/dist/lib/employee-templates.js +7 -7
- package/dist/lib/employees.js +5 -5
- package/dist/lib/exe-daemon-client.js +9 -8
- package/dist/lib/exe-daemon.js +186 -117
- package/dist/lib/hybrid-search.js +12 -12
- package/dist/lib/identity.js +5 -5
- package/dist/lib/keychain.js +13 -1
- package/dist/lib/license.js +8 -4
- package/dist/lib/messaging.js +39 -30
- package/dist/lib/post-tool-memory.js +9 -9
- package/dist/lib/registry-proxy.js +9 -1
- package/dist/lib/reminders.js +6 -6
- package/dist/lib/schedules.js +11 -11
- package/dist/lib/session-registry.js +7 -7
- package/dist/lib/skill-learning.js +20 -19
- package/dist/lib/status-brief.js +5 -4
- package/dist/lib/store.js +10 -10
- package/dist/lib/task-router.js +6 -6
- package/dist/lib/tasks.js +30 -29
- package/dist/lib/tmux-routing.js +28 -27
- package/dist/lib/tmux-status.js +3 -1
- package/dist/lib/token-spend.js +6 -6
- package/dist/lib/ws-client.js +1 -1
- package/dist/{license-gate-E6GTRYBA.js → license-gate-R4JWTWM4.js} +5 -5
- package/dist/{license-recheck-RBAO6Z2H.js → license-recheck-3MBJ4IJX.js} +1 -1
- package/dist/{license-sync-ZCZ2LIHK.js → license-sync-BVSG3WMW.js} +4 -4
- package/dist/local-secret-inventory-JWNBHZZ4.js +20 -0
- package/dist/mailbox-inbox-MTAT4MXX.js +13 -0
- package/dist/{mailbox-outbox-DNDDP2HW.js → mailbox-outbox-OY4IU6S4.js} +2 -1
- package/dist/mcp/register-tools.js +121 -120
- package/dist/mcp/server.js +123 -122
- package/dist/mcp/tools/complete-reminder.js +7 -7
- package/dist/mcp/tools/create-reminder.js +7 -7
- package/dist/mcp/tools/create-task.js +35 -32
- package/dist/mcp/tools/deactivate-behavior.js +22 -21
- package/dist/mcp/tools/list-reminders.js +7 -7
- package/dist/mcp/tools/list-tasks.js +33 -32
- package/dist/mcp/tools/send-message.js +32 -31
- package/dist/mcp/tools/update-task.js +31 -30
- package/dist/{mcp-child-registry-DVHYAHPW.js → mcp-child-registry-TIZERM7O.js} +5 -5
- package/dist/{mcp-health-B5EKRCZG.js → mcp-health-4ZHU67LM.js} +9 -3
- package/dist/{mcp-http-config-ME67QDOF.js → mcp-http-config-VUMSFWFH.js} +12 -12
- package/dist/{mcp-session-identity-DNG4ULAE.js → mcp-session-identity-DZHWEJRV.js} +28 -27
- package/dist/{memory-cards-WCISXY62.js → memory-cards-JVXTMSAT.js} +10 -10
- package/dist/{memory-graph-extractor-GXIK4QUF.js → memory-graph-extractor-PPBJMYFJ.js} +10 -10
- package/dist/{memory-poisoning-defense-25LZ5FJI.js → memory-poisoning-defense-K5Q74XQ4.js} +5 -5
- package/dist/{memory-pressure-watchdog-XGXI7WGE.js → memory-pressure-watchdog-YMJH5CSA.js} +29 -28
- package/dist/{memory-queue-YF7IDSFY.js → memory-queue-2MA67TAA.js} +3 -3
- package/dist/{memory-queue-client-QC2OTMJB.js → memory-queue-client-4G7HVRSX.js} +11 -10
- package/dist/{memory-reflection-GFGT44NT.js → memory-reflection-7BZWIHRE.js} +10 -10
- package/dist/{monitor-grants-Z2SEFE6E.js → monitor-grants-Q7X3MYQP.js} +6 -6
- package/dist/{monitor-identity-AEMHCVHV.js → monitor-identity-ZQB4IXEE.js} +2 -2
- package/dist/{notification-ledger-ETQBGRP7.js → notification-ledger-XRAXL5OI.js} +32 -29
- package/dist/{notifications-LPRCFJYY.js → notifications-JE3PX55X.js} +28 -27
- package/dist/{orchestration-events-T2GXV2NG.js → orchestration-events-JCQ5F5IJ.js} +6 -6
- package/dist/{orchestration-phase-T2WD45UA.js → orchestration-phase-QKTGQ2YT.js} +3 -3
- package/dist/{orchestrator-HY2IB3NA.js → orchestrator-X65INDTR.js} +30 -29
- package/dist/{org-brief-session-UWFCFEEB.js → org-brief-session-3PQ22UIX.js} +19 -18
- package/dist/{org-consent-policy-XXMST37J.js → org-consent-policy-VGELJ7K7.js} +7 -6
- package/dist/{org-join-72QKM7JR.js → org-join-6TO5ZYUZ.js} +12 -12
- package/dist/{org-key-admin-YCIAYP7V.js → org-key-admin-XHYVRRAZ.js} +12 -12
- package/dist/{org-key-pin-F7BQPI5P.js → org-key-pin-TTTYGTQL.js} +6 -6
- package/dist/{org-membership-JQSU4Z5P.js → org-membership-Y7T2BS57.js} +7 -7
- package/dist/{org-partner-config-PVJ45SLC.js → org-partner-config-OP4NEUNF.js} +10 -10
- package/dist/{org-partner-runtime-U4CTLWLC.js → org-partner-runtime-YNVUNT2R.js} +20 -19
- package/dist/{org-row-visibility-WUX4N3FX.js → org-row-visibility-JBBXNYXD.js} +1 -1
- package/dist/{pipeline-router-2RMBCBRM.js → pipeline-router-EIBB7QNG.js} +6 -6
- package/dist/{plan-limits-Z47XYEJR.js → plan-limits-MEWXYLEN.js} +8 -8
- package/dist/{postinstall-failure-O6TSSNJB.js → postinstall-failure-VETYYWEZ.js} +3 -3
- package/dist/{pre-tool-use-impl-JPE6XMRJ.js → pre-tool-use-impl-C6KJY22W.js} +60 -49
- package/dist/{project-boot-UFQDAFU5.js → project-boot-VEYFCCSL.js} +2 -2
- package/dist/{project-name-V4IREGHO.js → project-name-UYORSNGE.js} +6 -6
- package/dist/{projection-worker-HAD6H3VJ.js → projection-worker-WYFDWS57.js} +5 -5
- package/dist/{prospective-memory-KIF4JLFF.js → prospective-memory-E6XBQFJA.js} +5 -5
- package/dist/{push-notifications-GDKRTYXH.js → push-notifications-M7YU63FY.js} +29 -28
- package/dist/{reproject-worktree-memories-SG4BZJ3Z.js → reproject-worktree-memories-B5XMGJSD.js} +28 -27
- package/dist/{reranker-G2AZ67JP.js → reranker-SRA4BR7N.js} +3 -3
- package/dist/{retrieval-health-GBJRXTBZ.js → retrieval-health-P2JPZUPV.js} +4 -4
- package/dist/{review-polling-VUZPAAGT.js → review-polling-KQPN7IQE.js} +29 -28
- package/dist/runtime/index.js +37 -36
- package/dist/{session-events-BI6NIFIR.js → session-events-6LDDKKY3.js} +29 -28
- package/dist/{session-kill-telemetry-HPBDOPHT.js → session-kill-telemetry-5DSRGWCL.js} +29 -28
- package/dist/{session-mcp-config-WFZAH6R5.js → session-mcp-config-F7RCERUG.js} +3 -3
- package/dist/{session-scope-UB3HA5E7.js → session-scope-XG5R3P3D.js} +28 -27
- package/dist/{setup-wizard-6XULOT3L.js → setup-wizard-7QFLZIKT.js} +5 -5
- package/dist/{shard-manager-DYEJ6ETD.js → shard-manager-HHHHV2KZ.js} +3 -3
- package/dist/{skill-refinement-MKBQIWZ6.js → skill-refinement-I5RMAHSC.js} +6 -6
- package/dist/{stack-generate-manifest-7ODQ6W2O.js → stack-generate-manifest-AKMZ3AUX.js} +246 -13
- package/dist/stack-init-5VKL5PL5.js +136 -0
- package/dist/{stack-promote-3UKJBJSP.js → stack-promote-34CE2HHF.js} +7 -6
- package/dist/{stack-release-5CVXMJM5.js → stack-release-5PGWV5D4.js} +123 -12
- package/dist/{stack-update-Z53KG2P5.js → stack-update-ZQQ5YYPJ.js} +20 -5
- package/dist/{steward-gate-OKUYYIX6.js → steward-gate-AQJ6KT2C.js} +6 -6
- package/dist/{subagent-brief-injection-T2CVQLAS.js → subagent-brief-injection-3GU7YAWY.js} +50 -42
- package/dist/{subagent-spawn-ledger-E6U3OY6Z.js → subagent-spawn-ledger-52I66CLW.js} +3 -3
- package/dist/{supervisor-handoff-SGLEPOCY.js → supervisor-handoff-BWJW6CKZ.js} +4 -4
- package/dist/{support-inbox-WJIDCKJC.js → support-inbox-NY5TB3FN.js} +12 -12
- package/dist/{support-outbox-G2NG2U5K.js → support-outbox-KNI3FR3G.js} +3 -2
- package/dist/{task-enforcement-JL5ADPS6.js → task-enforcement-CAA6D2MH.js} +29 -28
- package/dist/{task-request-inbox-54BRRFHZ.js → task-request-inbox-QBZVU66E.js} +9 -6
- package/dist/{task-scope-OBPZBID5.js → task-scope-NHXB4ZRN.js} +32 -27
- package/dist/{tasks-crud-YBCPT7TY.js → tasks-crud-JHSWL5NM.js} +28 -27
- package/dist/{tasks-notify-CEEQSDJF.js → tasks-notify-7PBE4U7T.js} +29 -28
- package/dist/{tasks-review-JIEI656P.js → tasks-review-PPPVEE62.js} +28 -27
- package/dist/{telemetry-upload-ZZSEZR2U.js → telemetry-upload-YU2VRNHX.js} +10 -10
- package/dist/{token-budget-AUFMEMQ2.js → token-budget-QCMWKG3K.js} +6 -6
- package/dist/{tool-capability-index-6HLZU437.js → tool-capability-index-7AWQAJRP.js} +1 -1
- package/dist/{tool-gates-VXITVRFQ.js → tool-gates-5Q3RSQEG.js} +1 -1
- package/dist/{tool-gates-JWVSAYTW.js → tool-gates-QD26D2NE.js} +1 -1
- package/dist/{tool-telemetry-RHSEK2TO.js → tool-telemetry-LTOIC64I.js} +1 -1
- package/dist/tui/App.js +43 -42
- package/dist/{tui-data-PBZNN5YB.js → tui-data-NDBXD6U7.js} +32 -31
- package/dist/{update-support-V3ZCJR6L.js → update-support-BMJM4NG7.js} +27 -26
- package/dist/{whatsapp-NAM2CRVQ.js → whatsapp-QQLDAHUX.js} +2 -2
- package/dist/{wiki-acl-NUBAPLCD.js → wiki-acl-W6WDCVCP.js} +1 -1
- package/dist/{work-claims-Q2NU6JON.js → work-claims-6DM32MGO.js} +6 -6
- package/dist/{work-state-heartbeat-HAQRV3RK.js → work-state-heartbeat-HG7D4AWJ.js} +1 -1
- package/dist/{worker-gate-NUUSQMBT.js → worker-gate-FTMW7GBB.js} +3 -3
- package/dist/{workflow-engine-GEWPU5YR.js → workflow-engine-ZWC6CCXE.js} +2 -2
- package/dist/{worktree-C7LFMRKW.js → worktree-EMQCPGFE.js} +7 -7
- package/dist/{worktree-ownership-guard-4LKMW6PW.js → worktree-ownership-guard-O6JQF2CL.js} +2 -2
- package/dist/{worktree-sweep-SYF62ANH.js → worktree-sweep-XVUJZBXV.js} +8 -8
- package/package.json +23 -7
- package/release-notes.json +39 -12
- package/stack.release.json +4 -4
- package/dist/mailbox-inbox-XE72D3AX.js +0 -10
- /package/dist/{chunk-QIEYJ4KZ.js → chunk-2KY7WZZF.js} +0 -0
- /package/dist/{chunk-T3667X2B.js → chunk-2Q2CD6CD.js} +0 -0
- /package/dist/{chunk-JZJZYKMW.js → chunk-AJK2PVQW.js} +0 -0
- /package/dist/{chunk-ZEGEFBZV.js → chunk-AWWDKF22.js} +0 -0
- /package/dist/{chunk-QNTKRGJ6.js → chunk-GIRD7O5X.js} +0 -0
- /package/dist/{chunk-FWA4MYTA.js → chunk-JRIH6I7D.js} +0 -0
- /package/dist/{chunk-C7H2D7LX.js → chunk-M4XY4JRK.js} +0 -0
- /package/dist/{chunk-Q3DN5J6F.js → chunk-P2VVMGMI.js} +0 -0
- /package/dist/{chunk-BRAIWGMF.js → chunk-Q46NYJ77.js} +0 -0
- /package/dist/{chunk-3LQ2N4H7.js → chunk-U2D6PJ5T.js} +0 -0
- /package/dist/{chunk-3O6OGZL3.js → chunk-XDVOGDBC.js} +0 -0
- /package/dist/{core-memory-UNCAPGD4.js → core-memory-O6D5UC3T.js} +0 -0
- /package/dist/{hook-tamper-log-Z4PWC7N4.js → hook-tamper-log-ARGWCXKJ.js} +0 -0
- /package/dist/{memory-isolation-ALPJWLR5.js → memory-isolation-EBFFC6HF.js} +0 -0
- /package/dist/{oauth-server-AC2KB7NB.js → oauth-server-ZKBUHDFI.js} +0 -0
- /package/dist/{webhook-pipe-W2FVXY7M.js → webhook-pipe-PXH5MBRM.js} +0 -0
- /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-
|
|
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
|
|
249
|
-
|
|
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
|
-
[
|
|
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({
|
|
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
|
-
|
|
642
|
-
|
|
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-
|
|
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-
|
|
8
|
+
} from "./chunk-4AAMFWJT.js";
|
|
9
9
|
import {
|
|
10
10
|
countActiveBehaviors,
|
|
11
11
|
listBehaviors
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-S26CV7BE.js";
|
|
13
13
|
import {
|
|
14
14
|
lightweightSearch
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-3RGTLZNO.js";
|
|
16
16
|
import {
|
|
17
17
|
getCurrentSessionScope
|
|
18
|
-
} from "./chunk-
|
|
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-
|
|
24
|
+
} from "./chunk-UX2EO653.js";
|
|
25
25
|
import {
|
|
26
26
|
getClient
|
|
27
|
-
} from "./chunk-
|
|
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
|
-
|
|
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
|
-
|
|
166
|
-
const
|
|
167
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
144
|
-
const { storeExtraction } = await import("./graph-rag-
|
|
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-
|
|
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-
|
|
4
|
+
} from "./chunk-EIOGV75A.js";
|
|
4
5
|
import {
|
|
5
6
|
vectorToSqlLiteral
|
|
6
|
-
} from "./chunk-
|
|
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-
|
|
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
|
-
|
|
125
|
-
await
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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),
|