chainlesschain 0.163.8 → 0.165.1
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/package.json +7 -4
- package/scripts/macos-mcp-launcher-build.mjs +317 -0
- package/scripts/macos-mcp-launcher-postinstall.sh +54 -0
- package/scripts/macos-mcp-launcher-preinstall.sh +61 -0
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-CavM7W3k.js → AIOps-CYxFDrcm.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CUvZGabQ.js → ActionButton-CPBtdiU2.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DeBnWnbe.js → Analytics-Dayq7Dp7.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DbI5kxvd.js → AppLayout-6U7bPb2s.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-D93bigKm.js → Artifacts-D2Iqg_3D.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CBNvfUZa.js → Audit-CdoOB7WV.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-CJLyh_YU.js → BackgroundAgents-DrnAVB8w.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-D_0yoehD.js → Backup-CesMi5cy.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-TJxmbObW.js → BaseInput-DaX9ptax.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CE0dto1q.js → Chat-OrwOPxDS.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CZ5-yYiD.js → ChatBubbleRenderer-CvPZFRxM.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-Ck1RVIVo.js → Checkbox-DiHbcysC.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-qpoyf6DK.js → Codegen-CbgCkaBJ.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DUyPWjIE.js → Col-Du5hgrh4.js} +1 -1
- package/src/assets/web-panel/assets/{Community-D_S1BemS.js → Community-DsPOBW-p.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BjxeK-Gc.js → Compact-BwHIFkNC.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-Dd3CEJsu.js → Compliance-BvrDQSgd.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-B4QG7-ad.js → Cowork-gwAE6arx.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-BtZnids5.js → Cron-DW-0l4uF.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CHPfCBFD.js → Crosschain-j-NsLesB.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DT8DCEOK.js → DID-CibVEBOI.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-COQab5_U.js → Dashboard-W4z9vSfe.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BY1PsQuU.js → Dropdown-DAcrkKxG.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CsuAuaq3.js → EmailListRenderer-6GXah-89.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BqpinD-j.js → FamilyGuardDashboard-TKDCq8Ku.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-D0gkfQFv.js → Federation-BXBLlcNm.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BqgE-axK.js → FormItemContext-BoJJBkG3.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-D0hJ2KvC.js → GenericCardRenderer-okjsl46v.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CmMB0uPY.js → Git-Rvs7i6nn.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BnVEI0Dk.js → Governance-CHSUxXXS.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-YTAMihRP.js → Inference-V3BlfxsB.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-0ax7VHop.js → KnowledgeGraph-C_NlD4aR.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-B9TRcokL.js → Logs-Nn4LNxhA.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-SVAgNnkt.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-B6CSuD_H.js → Marketplace-DEmjFcg-.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CjMXvOVU.js → McpTools-DlopXipI.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-CXRF71U3.js → Memory-BG3ynX60.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DQgNp_oS.js → MobileBridge-DeRzWOfT.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-DlPwcCbq.js → MobileProjects-Tyd3o2A0.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-6hDTRPe1.js → Mtc-BoPbOv1C.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-BlVHU1DS.js → MtcAudit-un-rTHp7.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DP9pzEbV.js → Multisig-Ds0oveEB.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Djorh8EV.js → NLProgramming-D09JI-yY.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-oLZ-JkUg.js → Notes-DTRhiKJn.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-Cg288VH3.js → NotificationSettings-BAnnNCim.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-Yr-1fSYi.js +1 -0
- package/src/assets/web-panel/assets/{Organization-CBdo-bHs.js → Organization-S9EAolpj.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-qZdnVumx.js → Overflow-CqcLKqJ8.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-D4kNfGNQ.js → P2P-Dw0F9EcU.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DnlMemM7.js → PdhVaultBrowser-BDRwUevN.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-DHucHFBJ.js → Permissions-D3_c3nKB.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BovlOIPR.js → PersonalDataHub-CxdMV98x.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-Deru3CQY.js → Pipeline-CgjNQFLI.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Bq5oTTbU.js → Privacy-BHghIIht.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BfzxVWAz.js → ProjectInit-De6pqaKM.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CKC6XBtH.js → ProjectSettings-Bg4ZkNYQ.js} +2 -2
- package/src/assets/web-panel/assets/Projects-CP8vPvzs.js +1 -0
- package/src/assets/web-panel/assets/{Providers-C_jx4TWX.js → Providers-CUnHbNf-.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BdIHeVGC.js → QrScannerModal-DA2f3Wts.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BwZwAcPD.js → QuickAsk-C1FeHDqp.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BNTt0L-m.js → Recommend-B5guaUMN.js} +1 -1
- package/src/assets/web-panel/assets/RemoteSession-PDADSds3.js +5 -0
- package/src/assets/web-panel/assets/{Reputation-D6VpG32B.js → Reputation-eTlRhgvK.js} +1 -1
- package/src/assets/web-panel/assets/{Row-D_74OvQQ.js → Row-D7AqSGY0.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BTr0a-BQ.js → RssFeed-JiuLm4Ja.js} +3 -3
- package/src/assets/web-panel/assets/{Search-C3MCFoNU.js → Search-CwruahW3.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CqW9aJ6s.js → Security-CdhqaR0b.js} +4 -4
- package/src/assets/web-panel/assets/{Services-Cw5GNaHF.js → Services-CU0ZIlcT.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DZps5qeY.js → Skeleton-CtduPfAb.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-C6NQ1znT.js → Skills-CROXm6AY.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DFP8G2Sh.js → Sla-DiZiABFD.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-ESt6MB6v.js → SpeechSettings-B5pLcXUw.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BHnN98aM.js → SyncSettings-DBX6J1Oe.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-NiSCaOf-.js → Tasks-BLyRJd3-.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-DsKFhW2C.js → Templates-BKa5qzmk.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CQ0E0ze5.js → Tenant-DnD3a4M6.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-D_rBu_by.js → Terminal-DEitQeTb.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-D3Vm4Po4.js → TimelineRenderer-CjHggTDq.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DNTxRH6q.js → Tokens-CsGT7sfl.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-Dgprz1ms.js → Trigger-yr4rFDrW.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-B2rUnVBD.js → Trust-CLvu1Sjp.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DEGQNc6_.js → UkeySign-B0m7yUP8.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-jlsAx3Eh.js → VideoEditing-C0VvP4lc.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-8jQih1ij.js → Wallet-kllBAG1M.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-XLeO6xIB.js → WebAuthn-C54UQNLx.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-De_dgDAG.js → WorkflowEditor-B7y8qSvU.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CI19R_Sk.js → chat-DRzTh8CJ.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DsYTOYN3.js → colors-BSMwSnCx.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CM3-t_Qr.js → compact-item-BTg602H5.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BjxlBRZv.js → createContext-B6EGsdvp.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-Dol8jLEP.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-RDaWX_4i.js → hasIn-DDKqJ8RD.js} +1 -1
- package/src/assets/web-panel/assets/{index-nAH87mQP.js → index-323Hhxxt.js} +1 -1
- package/src/assets/web-panel/assets/{index-DIUnNOjG.js → index-BICn3Qh1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DyIWssPC.js → index-BMuGd2--.js} +1 -1
- package/src/assets/web-panel/assets/{index-DX7tuWVJ.js → index-BRqt4fO-.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cd3euP_4.js → index-BVTAl5N2.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cpqm1qfU.js → index-BsR7Y2NG.js} +1 -1
- package/src/assets/web-panel/assets/{index-DcPFB8qJ.js → index-Bx044qDj.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cd9OJhHG.js → index-C1GFfuqN.js} +1 -1
- package/src/assets/web-panel/assets/index-C3QX5tOl.js +1 -0
- package/src/assets/web-panel/assets/{index-B-Z8eFUJ.js → index-C66NpWy5.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlT2VAEK.js → index-CDTvsX8t.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dsij_KsN.js → index-CGNklbP6.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4gkzxkw.js → index-CHfLYwcW.js} +1 -1
- package/src/assets/web-panel/assets/{index-D6sm5-Xq.js → index-CNxg61YP.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0yx-jtQ.js → index-CQlHFN_g.js} +1 -1
- package/src/assets/web-panel/assets/{index-CjTrRt13.js → index-CUEU48o1.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7WBt_4T.js → index-CWGax2QW.js} +1 -1
- package/src/assets/web-panel/assets/{index-IeiL9RKc.js → index-C_JzIXUq.js} +1 -1
- package/src/assets/web-panel/assets/{index-CnHH7bnD.js → index-Cf23wVMs.js} +1 -1
- package/src/assets/web-panel/assets/{index-BKJr-TZp.js → index-CmAInUkX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CiECJi-Q.js → index-CmAubjDi.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCnZyIMA.js → index-Co7oM1qr.js} +1 -1
- package/src/assets/web-panel/assets/{index-Drlnwr8F.js → index-CwPUZbMI.js} +1 -1
- package/src/assets/web-panel/assets/{index-9R6BxAr0.js → index-D1naNj4U.js} +1 -1
- package/src/assets/web-panel/assets/{index-BGqqJfL0.js → index-D5CsBShd.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bi46Xu4u.js → index-DBT3YeQ9.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXXtGMUJ.js → index-DLdrHhML.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0PMlbMs.js → index-Dc77VR3H.js} +1 -1
- package/src/assets/web-panel/assets/{index-D0zcy54x.js → index-Dfv2lKu3.js} +1 -1
- package/src/assets/web-panel/assets/{index-BN6UPD2E.js → index-DiW0sDkz.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dxge-xWl.js → index-DpTHIRfZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CyOGN6a5.js → index-DqFXGzzC.js} +1 -1
- package/src/assets/web-panel/assets/{index-B9O9YyWE.js → index-XFe-1twF.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHNYPO0b.js → index-p2HYn89m.js} +3 -3
- package/src/assets/web-panel/assets/{index-CVQMeiwH.js → index-pqfux8vZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-pPL66J85.js → index-rjzk9z1Q.js} +1 -1
- package/src/assets/web-panel/assets/{index-DoQA0-52.js → index-th2ihDc0.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5REnKt8.js → index-u2YVld9W.js} +1 -1
- package/src/assets/web-panel/assets/index-xYybvEic.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-BTL88of4.js → initDefaultProps-C3Djh9fa.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BUB2pXwB.js → motion-BzqFmbSe.js} +1 -1
- package/src/assets/web-panel/assets/{move-egCkkOMm.js → move-DJo_FFaW.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DAWhZC8c.js → mtc-parser-_tlTiBvk.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CvOxe_6d.js → omit-CB2ZyxUg.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DZUSLZ5Z.js → pickAttrs-DZwIFD4u.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BERxGNMY.js → placementArrow-DxZY0dgk.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DZuDfZ9n.js → responsiveObserve-CzzGt7GL.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DO756sgI.js → slide-BaIK52yz.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BRQlIz28.js → statusUtils-3-FHu9_M.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DCSfdybl.js → styleChecker-BkRT68fK.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-LD8dWVve.js → useFlexGapSupport-DHYwKS-s.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BX9uW2LK.js → useFs-DVVUhV8p.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BPSlPuHU.js → usePersonalDataHub-CkrFKAzQ.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BmOILC9V.js → vnode-BuBLFz0c.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-1iKowKGg.js → zoom-kpm6LtXU.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/cowork.js +418 -41
- package/src/commands/permissions.js +240 -16
- package/src/commands/plugin.js +1293 -56
- package/src/commands/session-location.js +276 -0
- package/src/commands/session.js +2 -0
- package/src/data/changelog.json +28 -2
- package/src/gateways/ws/action-protocol.js +316 -17
- package/src/gateways/ws/message-dispatcher.js +30 -0
- package/src/gateways/ws/remote-session-protocol.js +565 -35
- package/src/gateways/ws/ws-agent-handler.js +12 -0
- package/src/gateways/ws/ws-approval-gate.js +5 -0
- package/src/gateways/ws/ws-server.js +510 -50
- package/src/harness/jsonl-session-store.js +341 -24
- package/src/harness/mcp-client.js +8 -1
- package/src/harness/remote-session-audit.js +2 -0
- package/src/harness/remote-session-crypto.js +929 -21
- package/src/harness/remote-session-registry.js +945 -24
- package/src/harness/session-list-index.js +233 -14
- package/src/lib/agent-authority.js +6 -0
- package/src/lib/auto-mode-config.js +98 -3
- package/src/lib/background-agent-keeper-client.js +248 -0
- package/src/lib/background-agent-keeper-protocol.js +291 -0
- package/src/lib/background-agent-supervisor.js +1357 -85
- package/src/lib/background-interaction-resolver.js +12 -0
- package/src/lib/background-session-transport.js +23 -6
- package/src/lib/background-turn-bootstrap-protocol.js +190 -0
- package/src/lib/cowork-workflow.js +1188 -76
- package/src/lib/delivery-production-adapter.js +38 -2
- package/src/lib/dynamic-workflow-facade.js +1736 -0
- package/src/lib/execution-location-contract.js +551 -0
- package/src/lib/execution-location-runtime.js +130 -0
- package/src/lib/ide-context.js +94 -6
- package/src/lib/mcp-stdio-package-materialization.js +166 -14
- package/src/lib/packer/pkg-config-generator.js +2 -0
- package/src/lib/permission-authority.js +77 -0
- package/src/lib/permission-side-effect-center.js +495 -0
- package/src/lib/plugin-runtime/install.js +514 -13
- package/src/lib/plugin-runtime/marketplace-artifact-readback.js +900 -0
- package/src/lib/plugin-runtime/marketplace-catalog.js +1181 -0
- package/src/lib/plugin-runtime/marketplace-impact.js +408 -0
- package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1567 -0
- package/src/lib/plugin-security.js +60 -3
- package/src/lib/process-execution-broker/index.js +1095 -57
- package/src/lib/process-execution-broker/linux-bwrap-descriptor-launch.js +375 -0
- package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +90 -16
- package/src/lib/process-execution-broker/linux-generic-bwrap.js +159 -18
- package/src/lib/process-execution-broker/macos-mcp-launcher-contract.js +278 -0
- package/src/lib/process-execution-broker/macos-mcp-launcher-protocol.json +23 -0
- package/src/lib/process-execution-broker/macos-mcp-launcher.c +1497 -0
- package/src/lib/process-execution-broker/mcp-fd-entry-bootstrap.js +37 -0
- package/src/lib/process-execution-broker/platform-sandbox.js +2330 -279
- package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
- package/src/lib/process-execution-broker/windows-sandbox.cs +50 -4
- package/src/lib/public-ide-capability-manifest.js +3 -0
- package/src/lib/remote-approval-bridge.js +777 -34
- package/src/lib/remote-control.js +2 -0
- package/src/lib/remote-membership-authority.js +632 -0
- package/src/lib/remote-membership-coordinator.js +2973 -0
- package/src/lib/remote-membership-host-store.js +1799 -0
- package/src/lib/runtime-provenance-ledger.js +171 -46
- package/src/lib/scoped-permission-store.js +369 -0
- package/src/lib/session-anti-rollback-anchor.js +262 -5
- package/src/lib/shell-approval.js +169 -6
- package/src/lib/sub-agent-context.js +4 -0
- package/src/lib/with-file-lock.js +73 -38
- package/src/lib/workflow-definition-contract.js +149 -0
- package/src/repl/agent-repl.js +111 -36
- package/src/repl/chat-repl.js +2 -0
- package/src/repl/clipboard-image.js +735 -16
- package/src/repl/ide-status.js +1 -1
- package/src/repl/prompt-interactions.js +59 -6
- package/src/repl/remote-approval.js +29 -7
- package/src/runtime/agent-core.js +1182 -155
- package/src/runtime/headless-runner.js +52 -30
- package/src/runtime/headless-stream.js +51 -28
- package/src/workers/background-agent-keeper.js +689 -0
- package/src/workers/background-agent-worker.js +365 -13
- package/src/workers/background-turn-bootstrap.js +170 -0
- package/src/assets/web-panel/assets/MarkdownRenderer-yySN5YNM.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-Bb1O3Ofr.js +0 -1
- package/src/assets/web-panel/assets/Projects-CMolGhae.js +0 -1
- package/src/assets/web-panel/assets/RemoteSession-Biyn2-Ro.js +0 -5
- package/src/assets/web-panel/assets/devWarning-S1ld2LwU.js +0 -1
- package/src/assets/web-panel/assets/index-Drz6yq0m.js +0 -1
- package/src/assets/web-panel/assets/index-uWiUs7S_.js +0 -1
|
@@ -52,6 +52,22 @@ import {
|
|
|
52
52
|
withSessionHostDelegatedWriteAuthority,
|
|
53
53
|
withSessionHostRecoveryLease,
|
|
54
54
|
} from "../lib/session-host-lease.js";
|
|
55
|
+
import {
|
|
56
|
+
BACKGROUND_TURN_BOOTSTRAP_ENV,
|
|
57
|
+
BACKGROUND_TURN_BOOTSTRAP_READY,
|
|
58
|
+
BACKGROUND_TURN_BOOTSTRAP_RELEASE,
|
|
59
|
+
createBackgroundTurnBootstrapMessage,
|
|
60
|
+
matchesBackgroundTurnBootstrapMessage,
|
|
61
|
+
normalizeBackgroundTurnBootstrapAuthority,
|
|
62
|
+
normalizeBackgroundTurnBootstrapBinding,
|
|
63
|
+
} from "../lib/background-turn-bootstrap-protocol.js";
|
|
64
|
+
import { connectBackgroundAgentKeeper } from "../lib/background-agent-keeper-client.js";
|
|
65
|
+
|
|
66
|
+
const TURN_BOOTSTRAP_MODULE_URL = new URL(
|
|
67
|
+
"./background-turn-bootstrap.js",
|
|
68
|
+
import.meta.url,
|
|
69
|
+
).href;
|
|
70
|
+
const TURN_BOOTSTRAP_IMPORT_ARGUMENT = `--import=${TURN_BOOTSTRAP_MODULE_URL}`;
|
|
55
71
|
|
|
56
72
|
const jobFile = process.argv[2];
|
|
57
73
|
let job;
|
|
@@ -65,10 +81,14 @@ let turnCount = 0;
|
|
|
65
81
|
let lastExit = { code: 0, signal: null };
|
|
66
82
|
let transportState = null;
|
|
67
83
|
let detachInteractionHandler = null;
|
|
84
|
+
let detachTurnBootstrapHandler = null;
|
|
85
|
+
let keeperClient = null;
|
|
86
|
+
let activeKeeperTurn = null;
|
|
68
87
|
let interactionJournal = null;
|
|
69
88
|
let interactionFinalSweep = null;
|
|
70
89
|
let turnLaunchUncertainty = null;
|
|
71
90
|
let turnLaunchSettlement = null;
|
|
91
|
+
let initialTurnStarted = false;
|
|
72
92
|
const promptQueue = [];
|
|
73
93
|
// P0-2: 保存 pending 的交互请求,等 attach 客户端连接后转发
|
|
74
94
|
const pendingInteractions = new Map();
|
|
@@ -135,6 +155,109 @@ export function attachTurnChildTerminationSettlement(
|
|
|
135
155
|
};
|
|
136
156
|
}
|
|
137
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Release a pre-main turn child only after its actual runtime PID is durably
|
|
160
|
+
* committed and every worker listener needed to supervise it is installed.
|
|
161
|
+
* The ChildProcess PID may name a Windows sandbox helper, so the actual Node
|
|
162
|
+
* PID arrives over the nonce-bound private IPC channel instead of being
|
|
163
|
+
* inferred from `child.pid`.
|
|
164
|
+
*/
|
|
165
|
+
export function attachTurnChildBootstrapRelease(
|
|
166
|
+
childProcess,
|
|
167
|
+
authority,
|
|
168
|
+
commitReady,
|
|
169
|
+
onFailure = () => {},
|
|
170
|
+
) {
|
|
171
|
+
if (!childProcess || typeof childProcess.on !== "function") {
|
|
172
|
+
throw new TypeError("turn bootstrap child must expose message events");
|
|
173
|
+
}
|
|
174
|
+
if (typeof childProcess.send !== "function") {
|
|
175
|
+
throw new TypeError("turn bootstrap child must expose dedicated IPC");
|
|
176
|
+
}
|
|
177
|
+
if (typeof commitReady !== "function") {
|
|
178
|
+
throw new TypeError("turn bootstrap durable commit callback is required");
|
|
179
|
+
}
|
|
180
|
+
if (typeof onFailure !== "function") {
|
|
181
|
+
throw new TypeError("turn bootstrap failure callback must be a function");
|
|
182
|
+
}
|
|
183
|
+
const expected = normalizeBackgroundTurnBootstrapAuthority(authority);
|
|
184
|
+
let releasedBinding = null;
|
|
185
|
+
let pendingBinding = null;
|
|
186
|
+
let failed = false;
|
|
187
|
+
let detached = false;
|
|
188
|
+
|
|
189
|
+
const failOnce = (error) => {
|
|
190
|
+
if (failed || detached) return;
|
|
191
|
+
failed = true;
|
|
192
|
+
onFailure(error instanceof Error ? error : new Error(String(error)));
|
|
193
|
+
};
|
|
194
|
+
const onMessage = (message) => {
|
|
195
|
+
if (message?.type !== BACKGROUND_TURN_BOOTSTRAP_READY) return;
|
|
196
|
+
if (
|
|
197
|
+
!matchesBackgroundTurnBootstrapMessage(
|
|
198
|
+
message,
|
|
199
|
+
BACKGROUND_TURN_BOOTSTRAP_READY,
|
|
200
|
+
expected,
|
|
201
|
+
)
|
|
202
|
+
) {
|
|
203
|
+
failOnce(new Error("background turn bootstrap ready binding mismatch"));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const readyBinding = normalizeBackgroundTurnBootstrapBinding(message);
|
|
207
|
+
if (releasedBinding) {
|
|
208
|
+
if (readyBinding.pid !== releasedBinding.pid) {
|
|
209
|
+
failOnce(new Error("background turn bootstrap runtime pid changed"));
|
|
210
|
+
}
|
|
211
|
+
// READY is retransmitted until the child observes RELEASE. Matching
|
|
212
|
+
// duplicates are idempotent; never answer with a second RELEASE.
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (pendingBinding) {
|
|
216
|
+
if (readyBinding.pid !== pendingBinding.pid) {
|
|
217
|
+
failOnce(new Error("background turn bootstrap runtime pid changed"));
|
|
218
|
+
}
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
pendingBinding = readyBinding;
|
|
222
|
+
Promise.resolve()
|
|
223
|
+
.then(() => commitReady(readyBinding))
|
|
224
|
+
.then((committed) => {
|
|
225
|
+
if (failed || detached) return;
|
|
226
|
+
if (committed !== true) {
|
|
227
|
+
failOnce(
|
|
228
|
+
new Error("background turn runtime pid commit was rejected"),
|
|
229
|
+
);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
releasedBinding = readyBinding;
|
|
233
|
+
try {
|
|
234
|
+
childProcess.send(
|
|
235
|
+
createBackgroundTurnBootstrapMessage(
|
|
236
|
+
BACKGROUND_TURN_BOOTSTRAP_RELEASE,
|
|
237
|
+
readyBinding,
|
|
238
|
+
),
|
|
239
|
+
(error) => {
|
|
240
|
+
if (error) failOnce(error);
|
|
241
|
+
},
|
|
242
|
+
);
|
|
243
|
+
} catch (error) {
|
|
244
|
+
failOnce(error);
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
.catch(failOnce);
|
|
248
|
+
};
|
|
249
|
+
const detach = () => {
|
|
250
|
+
if (detached) return;
|
|
251
|
+
detached = true;
|
|
252
|
+
childProcess.off?.("message", onMessage);
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
childProcess.on("message", onMessage);
|
|
256
|
+
childProcess.once?.("exit", detach);
|
|
257
|
+
childProcess.once?.("disconnect", detach);
|
|
258
|
+
return detach;
|
|
259
|
+
}
|
|
260
|
+
|
|
138
261
|
/**
|
|
139
262
|
* Deliver an already-durable interaction outcome after best-effort cleanup of
|
|
140
263
|
* the worker-state projection.
|
|
@@ -398,6 +521,8 @@ function finalize(code, signal, errorMessage) {
|
|
|
398
521
|
}
|
|
399
522
|
}
|
|
400
523
|
const done = () => {
|
|
524
|
+
keeperClient?.close();
|
|
525
|
+
keeperClient = null;
|
|
401
526
|
try {
|
|
402
527
|
log?.close();
|
|
403
528
|
} catch {
|
|
@@ -650,7 +775,20 @@ function startTurn(argv, promptText) {
|
|
|
650
775
|
// Private spawn-generation binding for the dedicated child IPC channel.
|
|
651
776
|
// It is never persisted in state or exposed through attach transports.
|
|
652
777
|
const turnIpcToken = randomBytes(32).toString("hex");
|
|
778
|
+
const turnBootstrapNonce = randomBytes(32).toString("hex");
|
|
653
779
|
let turnLaunchAttempt = 0;
|
|
780
|
+
let turnTerminated = false;
|
|
781
|
+
let keeperBootstrapStarted = false;
|
|
782
|
+
let keeperBootstrapOutcome = null;
|
|
783
|
+
let resolveKeeperBootstrap;
|
|
784
|
+
const keeperBootstrapSettled = new Promise((resolvePromise) => {
|
|
785
|
+
resolveKeeperBootstrap = resolvePromise;
|
|
786
|
+
});
|
|
787
|
+
const settleKeeperBootstrap = (outcome) => {
|
|
788
|
+
if (keeperBootstrapOutcome) return;
|
|
789
|
+
keeperBootstrapOutcome = outcome;
|
|
790
|
+
resolveKeeperBootstrap(outcome);
|
|
791
|
+
};
|
|
654
792
|
let prepared;
|
|
655
793
|
try {
|
|
656
794
|
prepared = mutateBackgroundAgentState(job.id, (current) => {
|
|
@@ -723,13 +861,17 @@ function startTurn(argv, promptText) {
|
|
|
723
861
|
agentStartedAt = Date.now();
|
|
724
862
|
spawned = executionBroker.spawn(
|
|
725
863
|
process.execPath,
|
|
726
|
-
[job.cliEntry, ...argv],
|
|
864
|
+
[TURN_BOOTSTRAP_IMPORT_ARGUMENT, job.cliEntry, ...argv],
|
|
727
865
|
{
|
|
728
866
|
cwd: job.cwd,
|
|
729
867
|
env: {
|
|
730
868
|
...process.env,
|
|
731
869
|
CC_BACKGROUND_AGENT_ID: job.id,
|
|
732
870
|
CC_BACKGROUND_TURN_IPC_NONCE: turnIpcToken,
|
|
871
|
+
[BACKGROUND_TURN_BOOTSTRAP_ENV.nonce]: turnBootstrapNonce,
|
|
872
|
+
[BACKGROUND_TURN_BOOTSTRAP_ENV.workerGeneration]:
|
|
873
|
+
job.workerGeneration,
|
|
874
|
+
[BACKGROUND_TURN_BOOTSTRAP_ENV.attempt]: String(turnLaunchAttempt),
|
|
733
875
|
},
|
|
734
876
|
stdio: ["ignore", log.fd, log.fd, "ipc"],
|
|
735
877
|
windowsHide: true,
|
|
@@ -756,6 +898,17 @@ function startTurn(argv, promptText) {
|
|
|
756
898
|
},
|
|
757
899
|
agentPid: spawned.pid,
|
|
758
900
|
agentStartedAt,
|
|
901
|
+
agentRuntimePid: null,
|
|
902
|
+
agentRuntimeStartedAt: null,
|
|
903
|
+
turnBootstrapStatus: "awaiting-ready",
|
|
904
|
+
turnBootstrapCommittedAt: null,
|
|
905
|
+
turnKeeperStatus: "waiting-for-runtime",
|
|
906
|
+
turnKeeperPid: null,
|
|
907
|
+
turnKeeperArmedAt: null,
|
|
908
|
+
turnKeeperCleanupReason: null,
|
|
909
|
+
turnKeeperCleanupRequestedAt: null,
|
|
910
|
+
turnKeeperCleanupConfirmedAt: null,
|
|
911
|
+
turnKeeperCleanupError: null,
|
|
759
912
|
turnLaunchIntent: null,
|
|
760
913
|
turnLaunchResolution: {
|
|
761
914
|
token: turnLaunchToken,
|
|
@@ -982,38 +1135,190 @@ function startTurn(argv, promptText) {
|
|
|
982
1135
|
},
|
|
983
1136
|
);
|
|
984
1137
|
|
|
1138
|
+
detachTurnBootstrapHandler = attachTurnChildBootstrapRelease(
|
|
1139
|
+
child,
|
|
1140
|
+
{
|
|
1141
|
+
nonce: turnBootstrapNonce,
|
|
1142
|
+
workerGeneration: job.workerGeneration,
|
|
1143
|
+
attempt: turnLaunchAttempt,
|
|
1144
|
+
},
|
|
1145
|
+
async (readyBinding) => {
|
|
1146
|
+
keeperBootstrapStarted = true;
|
|
1147
|
+
const committedAt = Date.now();
|
|
1148
|
+
const commit = mutateBackgroundAgentState(job.id, (current) => {
|
|
1149
|
+
if (
|
|
1150
|
+
!current ||
|
|
1151
|
+
current.status !== "running" ||
|
|
1152
|
+
current.stopRequestedAt ||
|
|
1153
|
+
current.workerGeneration !== job.workerGeneration ||
|
|
1154
|
+
Number(current.workerClaimedPid) !== process.pid ||
|
|
1155
|
+
current.turnLaunchResolution?.token !== turnLaunchToken ||
|
|
1156
|
+
Number(current.turnLaunchResolution?.attempt) !== turnLaunchAttempt ||
|
|
1157
|
+
current.turnLaunchResolution?.outcome !== "spawned" ||
|
|
1158
|
+
Number(current.agentPid) !== Number(spawned.pid)
|
|
1159
|
+
) {
|
|
1160
|
+
return null;
|
|
1161
|
+
}
|
|
1162
|
+
return {
|
|
1163
|
+
...current,
|
|
1164
|
+
agentRuntimePid: readyBinding.pid,
|
|
1165
|
+
// The host timestamp immediately before native spawn is a positive
|
|
1166
|
+
// lower-bound anchor for the runtime creation window. Destructive
|
|
1167
|
+
// identity checks still require a fresh OS creation-time probe.
|
|
1168
|
+
agentRuntimeStartedAt: agentStartedAt,
|
|
1169
|
+
turnBootstrapStatus: "awaiting-keeper",
|
|
1170
|
+
turnBootstrapCommittedAt: null,
|
|
1171
|
+
turnKeeperStatus: "arming",
|
|
1172
|
+
};
|
|
1173
|
+
});
|
|
1174
|
+
if (!commit.applied || !keeperClient) {
|
|
1175
|
+
settleKeeperBootstrap("failed");
|
|
1176
|
+
return false;
|
|
1177
|
+
}
|
|
1178
|
+
if (turnTerminated || child !== spawned || turnLaunchSettlement) {
|
|
1179
|
+
settleKeeperBootstrap("retired");
|
|
1180
|
+
return false;
|
|
1181
|
+
}
|
|
1182
|
+
const keeperTurn = {
|
|
1183
|
+
id: job.id,
|
|
1184
|
+
workerGeneration: job.workerGeneration,
|
|
1185
|
+
turnLaunchToken,
|
|
1186
|
+
attempt: turnLaunchAttempt,
|
|
1187
|
+
agentPid: Number(spawned.pid),
|
|
1188
|
+
agentStartedAt,
|
|
1189
|
+
agentRuntimePid: readyBinding.pid,
|
|
1190
|
+
agentRuntimeStartedAt: agentStartedAt,
|
|
1191
|
+
};
|
|
1192
|
+
try {
|
|
1193
|
+
await keeperClient.arm(keeperTurn);
|
|
1194
|
+
} catch (error) {
|
|
1195
|
+
settleKeeperBootstrap("failed");
|
|
1196
|
+
throw error;
|
|
1197
|
+
}
|
|
1198
|
+
activeKeeperTurn = keeperTurn;
|
|
1199
|
+
if (turnTerminated || child !== spawned || turnLaunchSettlement) {
|
|
1200
|
+
await keeperClient.retire(keeperTurn);
|
|
1201
|
+
if (activeKeeperTurn === keeperTurn) activeKeeperTurn = null;
|
|
1202
|
+
settleKeeperBootstrap("retired");
|
|
1203
|
+
return false;
|
|
1204
|
+
}
|
|
1205
|
+
const released = mutateBackgroundAgentState(job.id, (current) => {
|
|
1206
|
+
if (
|
|
1207
|
+
!current ||
|
|
1208
|
+
current.status !== "running" ||
|
|
1209
|
+
current.stopRequestedAt ||
|
|
1210
|
+
current.workerGeneration !== job.workerGeneration ||
|
|
1211
|
+
Number(current.workerClaimedPid) !== process.pid ||
|
|
1212
|
+
current.turnLaunchResolution?.token !== turnLaunchToken ||
|
|
1213
|
+
Number(current.turnLaunchResolution?.attempt) !== turnLaunchAttempt ||
|
|
1214
|
+
current.turnLaunchResolution?.outcome !== "spawned" ||
|
|
1215
|
+
Number(current.agentPid) !== Number(spawned.pid) ||
|
|
1216
|
+
Number(current.agentRuntimePid) !== readyBinding.pid ||
|
|
1217
|
+
current.turnKeeperStatus !== "armed" ||
|
|
1218
|
+
Number(current.turnKeeperPid) !== Number(current.keeperPid)
|
|
1219
|
+
) {
|
|
1220
|
+
return null;
|
|
1221
|
+
}
|
|
1222
|
+
return {
|
|
1223
|
+
...current,
|
|
1224
|
+
turnBootstrapStatus: "released",
|
|
1225
|
+
turnBootstrapCommittedAt: committedAt,
|
|
1226
|
+
};
|
|
1227
|
+
});
|
|
1228
|
+
if (!released.applied) {
|
|
1229
|
+
await keeperClient.retire(keeperTurn);
|
|
1230
|
+
if (activeKeeperTurn === keeperTurn) activeKeeperTurn = null;
|
|
1231
|
+
settleKeeperBootstrap("failed");
|
|
1232
|
+
return false;
|
|
1233
|
+
}
|
|
1234
|
+
settleKeeperBootstrap("released");
|
|
1235
|
+
return true;
|
|
1236
|
+
},
|
|
1237
|
+
(error) => {
|
|
1238
|
+
settleKeeperBootstrap("failed");
|
|
1239
|
+
detachInteractionHandler?.();
|
|
1240
|
+
detachInteractionHandler = null;
|
|
1241
|
+
if (
|
|
1242
|
+
keeperBootstrapOutcome !== "retired" &&
|
|
1243
|
+
(child === spawned || turnTerminated) &&
|
|
1244
|
+
!turnLaunchSettlement
|
|
1245
|
+
) {
|
|
1246
|
+
beginTurnLaunchSettlement({
|
|
1247
|
+
owned: spawned,
|
|
1248
|
+
error,
|
|
1249
|
+
turnLaunchToken,
|
|
1250
|
+
turnLaunchAttempt,
|
|
1251
|
+
agentStartedAt,
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
},
|
|
1255
|
+
);
|
|
1256
|
+
|
|
985
1257
|
attachTurnChildTerminationSettlement(
|
|
986
1258
|
child,
|
|
987
1259
|
({ code, signal, errorMessage }) => {
|
|
1260
|
+
turnTerminated = true;
|
|
988
1261
|
lastExit = {
|
|
989
1262
|
code,
|
|
990
1263
|
signal,
|
|
991
1264
|
...(errorMessage ? { errorMessage } : {}),
|
|
992
1265
|
};
|
|
993
1266
|
child = null;
|
|
1267
|
+
detachTurnBootstrapHandler?.();
|
|
1268
|
+
detachTurnBootstrapHandler = null;
|
|
994
1269
|
// 清理交互处理器
|
|
995
1270
|
detachInteractionHandler?.();
|
|
996
1271
|
detachInteractionHandler = null;
|
|
997
1272
|
// Reject any request that survived an abnormal child exit. Normal
|
|
998
1273
|
// responses remove themselves from this map before the turn continues.
|
|
999
|
-
for (const
|
|
1274
|
+
for (const pending of pendingInteractions.values()) {
|
|
1000
1275
|
const error = new Error("Agent exited");
|
|
1001
1276
|
error.code = "INTERACTION_CHILD_EXITED";
|
|
1002
1277
|
pending.deliverRejected?.(error);
|
|
1003
1278
|
}
|
|
1004
1279
|
pendingInteractions.clear();
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1280
|
+
const finishTurn = () =>
|
|
1281
|
+
beginFinalInteractionSweep(() => {
|
|
1282
|
+
server?.broadcast({
|
|
1283
|
+
type: "turn-ended",
|
|
1284
|
+
turn: turnCount,
|
|
1285
|
+
exitCode: code,
|
|
1286
|
+
});
|
|
1287
|
+
if (lastExit.errorMessage) {
|
|
1288
|
+
finalize(1, signal, lastExit.errorMessage);
|
|
1289
|
+
} else {
|
|
1290
|
+
maybeContinue();
|
|
1291
|
+
}
|
|
1010
1292
|
});
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1293
|
+
void (async () => {
|
|
1294
|
+
if (keeperBootstrapStarted) {
|
|
1295
|
+
const outcome = await keeperBootstrapSettled;
|
|
1296
|
+
// The bootstrap failure callback owns process-tree settlement and
|
|
1297
|
+
// must not race a normal continuation into the next queued turn.
|
|
1298
|
+
if (outcome === "failed") return;
|
|
1015
1299
|
}
|
|
1016
|
-
|
|
1300
|
+
if (turnLaunchSettlement) return;
|
|
1301
|
+
const keeperTurn = activeKeeperTurn;
|
|
1302
|
+
if (!keeperTurn || !keeperClient) {
|
|
1303
|
+
finishTurn();
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1306
|
+
try {
|
|
1307
|
+
await keeperClient.retire(keeperTurn);
|
|
1308
|
+
if (activeKeeperTurn === keeperTurn) activeKeeperTurn = null;
|
|
1309
|
+
finishTurn();
|
|
1310
|
+
} catch (error) {
|
|
1311
|
+
if (!turnLaunchSettlement) {
|
|
1312
|
+
beginTurnLaunchSettlement({
|
|
1313
|
+
owned: spawned,
|
|
1314
|
+
error,
|
|
1315
|
+
turnLaunchToken,
|
|
1316
|
+
turnLaunchAttempt,
|
|
1317
|
+
agentStartedAt,
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
})();
|
|
1017
1322
|
},
|
|
1018
1323
|
);
|
|
1019
1324
|
return true;
|
|
@@ -1059,6 +1364,17 @@ function maybeContinue() {
|
|
|
1059
1364
|
uncertainSideEffects: 0,
|
|
1060
1365
|
agentPid: null,
|
|
1061
1366
|
agentStartedAt: null,
|
|
1367
|
+
agentRuntimePid: null,
|
|
1368
|
+
agentRuntimeStartedAt: null,
|
|
1369
|
+
turnBootstrapStatus: null,
|
|
1370
|
+
turnBootstrapCommittedAt: null,
|
|
1371
|
+
turnKeeperStatus: null,
|
|
1372
|
+
turnKeeperPid: null,
|
|
1373
|
+
turnKeeperArmedAt: null,
|
|
1374
|
+
turnKeeperCleanupReason: null,
|
|
1375
|
+
turnKeeperCleanupRequestedAt: null,
|
|
1376
|
+
turnKeeperCleanupConfirmedAt: null,
|
|
1377
|
+
turnKeeperCleanupError: null,
|
|
1062
1378
|
heartbeatAt: Date.now(),
|
|
1063
1379
|
});
|
|
1064
1380
|
server.broadcast({ type: "idle", turn: turnCount });
|
|
@@ -1147,11 +1463,22 @@ async function main() {
|
|
|
1147
1463
|
}
|
|
1148
1464
|
promptQueue.push(text);
|
|
1149
1465
|
const queued = promptQueue.length;
|
|
1150
|
-
|
|
1466
|
+
// The transport is intentionally published before keeper/bootstrap
|
|
1467
|
+
// readiness. Prompts arriving in that window belong behind turn 1;
|
|
1468
|
+
// consuming one immediately would skip the launch job and make the
|
|
1469
|
+
// queue cap timing-dependent.
|
|
1470
|
+
if (!child && initialTurnStarted) maybeContinue();
|
|
1151
1471
|
return { queued };
|
|
1152
1472
|
},
|
|
1153
1473
|
onStop: () => {
|
|
1154
1474
|
if (!child) return;
|
|
1475
|
+
// An explicit stop owns this turn's termination. Detach the bootstrap
|
|
1476
|
+
// release callback before killing the child so a late IPC EPIPE cannot
|
|
1477
|
+
// reclassify the intentional stop as a post-spawn launch failure. The
|
|
1478
|
+
// child termination settlement remains attached and advances any
|
|
1479
|
+
// queued follow-up turn after the tree is confirmed closed.
|
|
1480
|
+
detachTurnBootstrapHandler?.();
|
|
1481
|
+
detachTurnBootstrapHandler = null;
|
|
1155
1482
|
// The agent child is detached into its own group on POSIX; Windows
|
|
1156
1483
|
// requires brokered taskkill /T /F so tool grandchildren cannot
|
|
1157
1484
|
// survive an attached-session stop.
|
|
@@ -1265,12 +1592,37 @@ async function main() {
|
|
|
1265
1592
|
finalize(launchReadiness === "timeout" ? 1 : 0, null);
|
|
1266
1593
|
return;
|
|
1267
1594
|
}
|
|
1595
|
+
if (!job.keeper) {
|
|
1596
|
+
throw new Error("background agent keeper launch authority is missing");
|
|
1597
|
+
}
|
|
1598
|
+
keeperClient = await connectBackgroundAgentKeeper({
|
|
1599
|
+
id: job.id,
|
|
1600
|
+
workerGeneration: job.workerGeneration,
|
|
1601
|
+
workerPid: process.pid,
|
|
1602
|
+
pipePath: job.keeper.pipePath,
|
|
1603
|
+
token: job.keeper.token,
|
|
1604
|
+
onDisconnect(error, keeperTurn) {
|
|
1605
|
+
if (finalized || turnLaunchSettlement) return;
|
|
1606
|
+
if (child && keeperTurn) {
|
|
1607
|
+
beginTurnLaunchSettlement({
|
|
1608
|
+
owned: child,
|
|
1609
|
+
error,
|
|
1610
|
+
turnLaunchToken: keeperTurn.turnLaunchToken,
|
|
1611
|
+
turnLaunchAttempt: keeperTurn.attempt,
|
|
1612
|
+
agentStartedAt: keeperTurn.agentStartedAt,
|
|
1613
|
+
});
|
|
1614
|
+
return;
|
|
1615
|
+
}
|
|
1616
|
+
finalize(1, null, error?.message || "background keeper disconnected");
|
|
1617
|
+
},
|
|
1618
|
+
});
|
|
1268
1619
|
// Launch finalization can take long enough for an external stop/remove to
|
|
1269
1620
|
// win after bootstrap. Re-claim immediately before the first native turn.
|
|
1270
1621
|
if (!writeHeartbeat()) {
|
|
1271
1622
|
finalize(0, null);
|
|
1272
1623
|
return;
|
|
1273
1624
|
}
|
|
1625
|
+
initialTurnStarted = true;
|
|
1274
1626
|
if (!startTurn(job.argv, null)) finalize(0, null);
|
|
1275
1627
|
}
|
|
1276
1628
|
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-main barrier for one background-agent turn.
|
|
3
|
+
*
|
|
4
|
+
* Node loads this module through `--import` before executing the real CLI
|
|
5
|
+
* entrypoint. Top-level await keeps both ESM and CommonJS entry semantics
|
|
6
|
+
* intact while making execution contingent on the worker's durable PID
|
|
7
|
+
* commit and listener installation.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { writeSync } from "node:fs";
|
|
11
|
+
import {
|
|
12
|
+
BACKGROUND_TURN_BOOTSTRAP_ENV,
|
|
13
|
+
BACKGROUND_TURN_BOOTSTRAP_READY,
|
|
14
|
+
BACKGROUND_TURN_BOOTSTRAP_RELEASE,
|
|
15
|
+
backgroundTurnBootstrapBindingFromEnvironment,
|
|
16
|
+
clearBackgroundTurnBootstrapEnvironment,
|
|
17
|
+
containReleasedBackgroundTurnDisconnect,
|
|
18
|
+
createBackgroundTurnBootstrapMessage,
|
|
19
|
+
matchesBackgroundTurnBootstrapMessage,
|
|
20
|
+
removeBackgroundTurnBootstrapImport,
|
|
21
|
+
} from "../lib/background-turn-bootstrap-protocol.js";
|
|
22
|
+
|
|
23
|
+
const DEFAULT_RELEASE_TIMEOUT_MS = 30_000;
|
|
24
|
+
const TEST_RELEASE_TIMEOUT_MAX_MS = 2_000;
|
|
25
|
+
|
|
26
|
+
function releaseTimeoutMs() {
|
|
27
|
+
if (process.env.NODE_ENV !== "test") return DEFAULT_RELEASE_TIMEOUT_MS;
|
|
28
|
+
const requested = Number(
|
|
29
|
+
process.env[BACKGROUND_TURN_BOOTSTRAP_ENV.testTimeoutMs],
|
|
30
|
+
);
|
|
31
|
+
if (!Number.isFinite(requested)) return DEFAULT_RELEASE_TIMEOUT_MS;
|
|
32
|
+
return Math.max(10, Math.min(TEST_RELEASE_TIMEOUT_MAX_MS, requested));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function reportFailure(message) {
|
|
36
|
+
try {
|
|
37
|
+
writeSync(2, `[background-turn-bootstrap] ${message}\n`);
|
|
38
|
+
} catch {
|
|
39
|
+
// The inherited diagnostic handle may already be closed.
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function failClosed(message) {
|
|
44
|
+
reportFailure(message);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let binding;
|
|
49
|
+
try {
|
|
50
|
+
binding = backgroundTurnBootstrapBindingFromEnvironment(
|
|
51
|
+
process.env,
|
|
52
|
+
process.pid,
|
|
53
|
+
);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
failClosed(error?.message || String(error));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (typeof process.send !== "function" || process.connected === false) {
|
|
59
|
+
failClosed("dedicated worker IPC is unavailable");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
await new Promise((resolve) => {
|
|
63
|
+
let released = false;
|
|
64
|
+
let failed = false;
|
|
65
|
+
let timer = null;
|
|
66
|
+
let readyTimer = null;
|
|
67
|
+
|
|
68
|
+
const failOnce = (message) => {
|
|
69
|
+
if (failed) return;
|
|
70
|
+
failed = true;
|
|
71
|
+
if (timer) clearTimeout(timer);
|
|
72
|
+
if (readyTimer) clearInterval(readyTimer);
|
|
73
|
+
failClosed(message);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const containDisconnectOnce = (message) => {
|
|
77
|
+
if (failed) return;
|
|
78
|
+
failed = true;
|
|
79
|
+
if (timer) clearTimeout(timer);
|
|
80
|
+
if (readyTimer) clearInterval(readyTimer);
|
|
81
|
+
// Emit the original diagnostic before SIGSTOP freezes this process and
|
|
82
|
+
// every descendant in its detached POSIX group. If the stop fails (or a
|
|
83
|
+
// later SIGCONT lets the helper's fail-safe SIGKILL fail), retain the
|
|
84
|
+
// historical single-process fail-closed exit.
|
|
85
|
+
reportFailure(message);
|
|
86
|
+
if (
|
|
87
|
+
containReleasedBackgroundTurnDisconnect({
|
|
88
|
+
released,
|
|
89
|
+
currentPid: binding.pid,
|
|
90
|
+
onResumedKillFailure: () => process.exit(1),
|
|
91
|
+
})
|
|
92
|
+
) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
process.exit(1);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const onMessage = (message) => {
|
|
99
|
+
if (message?.type !== BACKGROUND_TURN_BOOTSTRAP_RELEASE) return;
|
|
100
|
+
if (released) {
|
|
101
|
+
failOnce("duplicate release rejected");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (
|
|
105
|
+
!matchesBackgroundTurnBootstrapMessage(
|
|
106
|
+
message,
|
|
107
|
+
BACKGROUND_TURN_BOOTSTRAP_RELEASE,
|
|
108
|
+
binding,
|
|
109
|
+
)
|
|
110
|
+
) {
|
|
111
|
+
failOnce("release binding mismatch");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
released = true;
|
|
115
|
+
if (timer) clearTimeout(timer);
|
|
116
|
+
if (readyTimer) clearInterval(readyTimer);
|
|
117
|
+
try {
|
|
118
|
+
process.execArgv = removeBackgroundTurnBootstrapImport(
|
|
119
|
+
process.execArgv,
|
|
120
|
+
import.meta.url,
|
|
121
|
+
);
|
|
122
|
+
clearBackgroundTurnBootstrapEnvironment(process.env);
|
|
123
|
+
// Keep the disconnect listener as a fail-closed worker-death signal,
|
|
124
|
+
// but do not make this private bootstrap channel keep an otherwise
|
|
125
|
+
// completed Agent process alive. Interaction requests explicitly ref
|
|
126
|
+
// the same channel for the duration of a pending same-turn answer.
|
|
127
|
+
process.channel?.unref?.();
|
|
128
|
+
} catch (error) {
|
|
129
|
+
failOnce(error?.message || String(error));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
resolve();
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// Keep both listeners after release. A repeated release or loss of the
|
|
136
|
+
// supervising worker remains fail-closed even after the real CLI starts.
|
|
137
|
+
process.on("message", onMessage);
|
|
138
|
+
process.once("disconnect", () =>
|
|
139
|
+
containDisconnectOnce("worker IPC disconnected before turn completion"),
|
|
140
|
+
);
|
|
141
|
+
timer = setTimeout(
|
|
142
|
+
() => failOnce("timed out waiting for durable turn release"),
|
|
143
|
+
releaseTimeoutMs(),
|
|
144
|
+
);
|
|
145
|
+
timer.unref?.();
|
|
146
|
+
|
|
147
|
+
const sendReady = () => {
|
|
148
|
+
if (released || failed) return;
|
|
149
|
+
try {
|
|
150
|
+
process.send(
|
|
151
|
+
createBackgroundTurnBootstrapMessage(
|
|
152
|
+
BACKGROUND_TURN_BOOTSTRAP_READY,
|
|
153
|
+
binding,
|
|
154
|
+
),
|
|
155
|
+
(error) => {
|
|
156
|
+
if (error) failOnce(`ready delivery failed: ${error.message}`);
|
|
157
|
+
},
|
|
158
|
+
);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
failOnce(`ready delivery failed: ${error?.message || String(error)}`);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
sendReady();
|
|
164
|
+
// A very fast preload can publish readiness while the worker is still
|
|
165
|
+
// fsyncing the PID commit. Repeat only READY (never RELEASE) until the
|
|
166
|
+
// post-commit listener answers, so an early unobserved event cannot strand
|
|
167
|
+
// the child. Matching duplicates are intentionally idempotent parent-side.
|
|
168
|
+
readyTimer = setInterval(sendReady, 100);
|
|
169
|
+
readyTimer.unref?.();
|
|
170
|
+
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as c,J as p,b as s}from"./vendor-Bn1JzzAn.js";import{r as a}from"./markdown-Yo_c6Krv.js";import{_ as d}from"./index-BHNYPO0b.js";const _={__name:"MarkdownRenderer",props:{content:{type:String,default:""}},setup(t,{expose:o}){o();const e=t,r=s(()=>a(e.content||"")),n={props:e,rendered:r,computed:s,get renderMarkdown(){return a}};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}},i=["innerHTML"];function l(t,o,e,r,n,m){return c(),p("div",{class:"markdown-content",innerHTML:r.rendered},null,8,i)}const b=d(_,[["render",l],["__scopeId","data-v-0b0b9f63"],["__file","/tmp/cc-web-panel-blIgp5/repo/packages/web-panel/src/components/MarkdownRenderer.vue"]]);export{b as M};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as w,P as d,J as u,U as s,R as n,c as i,K as v,Q as _,V as g,b as a}from"./vendor-Bn1JzzAn.js";import{_ as S}from"./index-BHNYPO0b.js";import"./icons-DG5UD-6K.js";const k={__name:"OrderTableRenderer",props:{event:{type:Object,required:!0}},setup(p,{expose:r}){r();const o=p,e=a(()=>o.event.content||{}),l=a(()=>o.event.extra||{}),m=a(()=>l.value.merchant||e.value.merchant||e.value.counterparty||"—"),c=a(()=>e.value.title||e.value.name||e.value.itemName||e.value.text||"—"),y=a(()=>{const t=e.value.amount??e.value.price??e.value.total;return t==null?"—":`${e.value.currency||"¥"} ${typeof t=="number"?t.toFixed(2):t}`}),T=a(()=>l.value.orderNo||e.value.orderNo||e.value.orderId),f=a(()=>e.value.status||e.value.state),b=a(()=>{const t=(f.value||"").toLowerCase();return t.includes("成功")||t.includes("succe")||t.includes("paid")?"green":t.includes("退")||t.includes("refund")?"orange":t.includes("失败")||t.includes("fail")?"red":"default"}),h=a(()=>{if(!o.event.occurredAt)return"";const t=new Date(o.event.occurredAt);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}),x={props:o,c:e,e:l,merchantText:m,itemText:c,amountText:y,orderNo:T,statusText:f,statusColor:b,formattedTime:h,computed:a};return Object.defineProperty(x,"__isScriptSetup",{enumerable:!1,value:!0}),x}},N={class:"order-card"},C={class:"head"},O={class:"time"},V={class:"row"},I={class:"val"},R={class:"row"},B={class:"val"},D={class:"row amount-row"},j={class:"val amount"},A={key:0,class:"row"},F={class:"val mono"},M={key:1,class:"row"};function P(p,r,o,e,l,m){const c=w("a-tag");return d(),u("div",N,[s("div",C,[s("span",O,n(e.formattedTime),1),i(c,{color:"gold"},{default:v(()=>[_(n(o.event.source.adapter),1)]),_:1}),i(c,null,{default:v(()=>[_(n(o.event.subtype),1)]),_:1})]),s("div",V,[r[0]||(r[0]=s("span",{class:"key"},"商户",-1)),s("span",I,n(e.merchantText),1)]),s("div",R,[r[1]||(r[1]=s("span",{class:"key"},"商品/项目",-1)),s("span",B,n(e.itemText),1)]),s("div",D,[r[2]||(r[2]=s("span",{class:"key"},"金额",-1)),s("span",j,n(e.amountText),1)]),e.orderNo?(d(),u("div",A,[r[3]||(r[3]=s("span",{class:"key"},"单号",-1)),s("span",F,n(e.orderNo),1)])):g("v-if",!0),e.statusText?(d(),u("div",M,[r[4]||(r[4]=s("span",{class:"key"},"状态",-1)),i(c,{color:e.statusColor},{default:v(()=>[_(n(e.statusText),1)]),_:1},8,["color"])])):g("v-if",!0)])}const K=S(k,[["render",P],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-blIgp5/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{K as default};
|