chainlesschain 0.165.1 → 0.165.3
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/README.md +248 -2
- package/package.json +4 -1
- package/src/assets/web-panel/assets/{AIOps-CYxFDrcm.js → AIOps-BiHNUlbU.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CPBtdiU2.js → ActionButton-D-UFjDRQ.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Dayq7Dp7.js → Analytics-DazVsDgW.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-6U7bPb2s.js → AppLayout-DXh9UfNJ.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-D2Iqg_3D.js → Artifacts-CZ6tsceY.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CdoOB7WV.js → Audit-RyxnBr_h.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DrnAVB8w.js → BackgroundAgents-BWS51Q6X.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CesMi5cy.js → Backup-BRtPcUul.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DaX9ptax.js → BaseInput-CGd4vZYY.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-OrwOPxDS.js → Chat-h8ijVwCg.js} +4 -4
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CvPZFRxM.js → ChatBubbleRenderer-D7tcdDS9.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-DiHbcysC.js → Checkbox-NyF6dPl8.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CbgCkaBJ.js → Codegen-Ci4OOxr5.js} +1 -1
- package/src/assets/web-panel/assets/{Col-Du5hgrh4.js → Col-CwTkc9BM.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DsPOBW-p.js → Community-DW_tM82m.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BwHIFkNC.js → Compact-DEvHRV4S.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BvrDQSgd.js → Compliance-BbjBEEfD.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-gwAE6arx.js → Cowork-10IXBaBa.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-DW-0l4uF.js → Cron-BZkbpd5I.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-j-NsLesB.js → Crosschain-CFQ8L_6v.js} +1 -1
- package/src/assets/web-panel/assets/{DID-CibVEBOI.js → DID-BDF6AkXe.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-W4z9vSfe.js → Dashboard-CoOdWMi4.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DAcrkKxG.js → Dropdown-DEsGmu8Y.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-6GXah-89.js → EmailListRenderer-BS89SWlK.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-TKDCq8Ku.js → FamilyGuardDashboard-C1FpCHiI.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BXBLlcNm.js → Federation-BzvpVmLA.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BoJJBkG3.js → FormItemContext-BeC259PQ.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-okjsl46v.js → GenericCardRenderer-azgG3bmV.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Rvs7i6nn.js → Git-BmSSowc5.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CHSUxXXS.js → Governance-CTBCSyQZ.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-V3BlfxsB.js → Inference-DA5xyk4a.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-C_NlD4aR.js → KnowledgeGraph-D1gPHNig.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Nn4LNxhA.js → Logs-BPmLf1AR.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-SVAgNnkt.js → MarkdownRenderer-SVLOg49H.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-DEmjFcg-.js → Marketplace-DtUFcR0E.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DlopXipI.js → McpTools-DS_kqBv-.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-BG3ynX60.js → Memory-Fvh7XL7V.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DeRzWOfT.js → MobileBridge-C7itAP45.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-DGbP36-3.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-BoPbOv1C.js → Mtc-B57MiNLK.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-un-rTHp7.js → MtcAudit-BXfCUcM7.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-Ds0oveEB.js → Multisig-yaJ-ZcF6.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-D09JI-yY.js → NLProgramming-CoaUCKrO.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DTRhiKJn.js → Notes-BKLM_65R.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-BAnnNCim.js → NotificationSettings-DoDtK9uZ.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-Yr-1fSYi.js → OrderTableRenderer-BJ28TGr-.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-S9EAolpj.js → Organization-MuGsdoIb.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CqcLKqJ8.js → Overflow-BLUN9J4R.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Dw0F9EcU.js → P2P-DWuoBUPd.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BDRwUevN.js → PdhVaultBrowser-CUi37YPj.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-D3_c3nKB.js → Permissions-BYQg2pcr.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CxdMV98x.js → PersonalDataHub-CAxoV2xu.js} +6 -6
- package/src/assets/web-panel/assets/{Pipeline-CgjNQFLI.js → Pipeline-B33wGvIO.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BHghIIht.js → Privacy-A8yXTORP.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-De6pqaKM.js → ProjectInit-D49I2I1O.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Bg4ZkNYQ.js → ProjectSettings-Ci73jJDw.js} +2 -2
- package/src/assets/web-panel/assets/Projects-CF-yD6Cn.js +1 -0
- package/src/assets/web-panel/assets/Providers-D-etEhg5.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-DA2f3Wts.js → QrScannerModal-Brza0ykJ.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-C1FeHDqp.js → QuickAsk-DFydhjxL.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-B5guaUMN.js → Recommend-DLF8_NhA.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-PDADSds3.js → RemoteSession-dyuStW3x.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-eTlRhgvK.js → Reputation-5F3tA6yw.js} +1 -1
- package/src/assets/web-panel/assets/{Row-D7AqSGY0.js → Row-Ca2A57S5.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-JiuLm4Ja.js → RssFeed-B0bxBkq_.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CwruahW3.js → Search-CFNvHalZ.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CdhqaR0b.js → Security-DSoH3Hav.js} +4 -4
- package/src/assets/web-panel/assets/{Services-CU0ZIlcT.js → Services-BHpfEmBQ.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CtduPfAb.js → Skeleton-Dsh-QNmn.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CROXm6AY.js → Skills-BhT1NkSU.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DiZiABFD.js → Sla-DY9snPeJ.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-B5pLcXUw.js → SpeechSettings-CWaX0_Cx.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DBX6J1Oe.js → SyncSettings-B690y_TC.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BLyRJd3-.js → Tasks-2N-w3zWd.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BKa5qzmk.js → Templates-BjwQOQYC.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DnD3a4M6.js → Tenant-CUqHErxY.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DEitQeTb.js → Terminal-C13rXvNy.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-CjHggTDq.js → TimelineRenderer-CpbWcya_.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CsGT7sfl.js → Tokens-BXHLGXYC.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-yr4rFDrW.js → Trigger-1e5i65o3.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CLvu1Sjp.js → Trust-FLGqNHs5.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B0m7yUP8.js → UkeySign-BbaR_LJB.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C0VvP4lc.js → VideoEditing-NOp4RIov.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-kllBAG1M.js → Wallet-B7DW7bG4.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-C54UQNLx.js → WebAuthn-BptSUWix.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-B7y8qSvU.js → WorkflowEditor-CAJnDOXS.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DRzTh8CJ.js → chat-I8LgG1-Z.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BSMwSnCx.js → colors-CWe7SOVD.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BTg602H5.js → compact-item-Cx3u3CA3.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-B6EGsdvp.js → createContext-CgD5ArwY.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DLv_872g.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DDKqJ8RD.js → hasIn-BfQWiXN8.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5CsBShd.js → index-3iKP9OTJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dfv2lKu3.js → index-87gMxqhN.js} +1 -1
- package/src/assets/web-panel/assets/{index-C66NpWy5.js → index-B1cX4Rxu.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBT3YeQ9.js → index-B6yChzt1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVTAl5N2.js → index-BREnPKGo.js} +1 -1
- package/src/assets/web-panel/assets/{index-CwPUZbMI.js → index-BUAR7RY-.js} +1 -1
- package/src/assets/web-panel/assets/{index-th2ihDc0.js → index-Bi24S7Dw.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmAubjDi.js → index-BiI-xPRH.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUEU48o1.js → index-BuEQSorC.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf23wVMs.js → index-Bx7BNIRH.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRqt4fO-.js → index-C-rIKccl.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_JzIXUq.js → index-C0nDKhWv.js} +1 -1
- package/src/assets/web-panel/assets/{index-DiW0sDkz.js → index-C0ztiqtB.js} +1 -1
- package/src/assets/web-panel/assets/{index-BICn3Qh1.js → index-C1UjHdgZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpTHIRfZ.js → index-CAUnl4Jv.js} +1 -1
- package/src/assets/web-panel/assets/{index-Co7oM1qr.js → index-CMu16vPC.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNxg61YP.js → index-CNYFQxAW.js} +1 -1
- package/src/assets/web-panel/assets/{index-XFe-1twF.js → index-CQDKYbnv.js} +1 -1
- package/src/assets/web-panel/assets/{index-p2HYn89m.js → index-CWZ3REg6.js} +3 -3
- package/src/assets/web-panel/assets/{index-Bx044qDj.js → index-CcX4FSPf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BMuGd2--.js → index-Cd79NQAx.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGNklbP6.js → index-CdRkCwm4.js} +1 -1
- package/src/assets/web-panel/assets/index-CdiGCibe.js +1 -0
- package/src/assets/web-panel/assets/{index-rjzk9z1Q.js → index-Cy_cCJlr.js} +1 -1
- package/src/assets/web-panel/assets/{index-323Hhxxt.js → index-DAVy98u7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CDTvsX8t.js → index-DCJEY2T0.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLdrHhML.js → index-DFb-XIKy.js} +1 -1
- package/src/assets/web-panel/assets/{index-pqfux8vZ.js → index-DGMYTN5W.js} +1 -1
- package/src/assets/web-panel/assets/index-D_0z-gyz.js +1 -0
- package/src/assets/web-panel/assets/{index-u2YVld9W.js → index-Dcdm_Z2c.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmAInUkX.js → index-DeizoQVZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CHfLYwcW.js → index-DlIyt1qF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWGax2QW.js → index-DmgtY58H.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dc77VR3H.js → index-DmrdUwzU.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1naNj4U.js → index-Doc0Ftpd.js} +1 -1
- package/src/assets/web-panel/assets/{index-BsR7Y2NG.js → index-DsQcURkA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQlHFN_g.js → index-DslTuqro.js} +1 -1
- package/src/assets/web-panel/assets/{index-DqFXGzzC.js → index-V-kIHzAV.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1GFfuqN.js → index-e8BM1yY1.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-C3Djh9fa.js → initDefaultProps-DiBszVdG.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BzqFmbSe.js → motion-BGIFFozv.js} +1 -1
- package/src/assets/web-panel/assets/{move-DJo_FFaW.js → move-D5W7mp7B.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-_tlTiBvk.js → mtc-parser-JFIlxJ7F.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CB2ZyxUg.js → omit-CQ3o6LIU.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DZwIFD4u.js → pickAttrs-R8MIlXo3.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DxZY0dgk.js → placementArrow-sW7ylSky.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CzzGt7GL.js → responsiveObserve-Cnl39Vbz.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BaIK52yz.js → slide-sn8tFd14.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-3-FHu9_M.js → statusUtils-IKKY_QxZ.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BkRT68fK.js → styleChecker-BNpV4Nqs.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DHYwKS-s.js → useFlexGapSupport-BWyT_eoU.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DVVUhV8p.js → useFs-D09p6_U9.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CkrFKAzQ.js → usePersonalDataHub-CzW3TkJZ.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BuBLFz0c.js → vnode-3s3WoAKB.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-kpm6LtXU.js → zoom-Cjy_673s.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/cowork.js +280 -5
- package/src/commands/plugin.js +819 -64
- package/src/commands/session-location.js +318 -7
- package/src/constants.js +2 -2
- package/src/data/changelog.json +27 -1
- package/src/gateways/ws/action-protocol.js +1 -1
- package/src/harness/jsonl-session-store.js +638 -2
- package/src/harness/prompt-compressor.js +4 -0
- package/src/lib/background-agent-keeper-client.js +29 -0
- package/src/lib/background-agent-keeper-protocol.js +78 -3
- package/src/lib/background-agent-launch-barrier.js +74 -0
- package/src/lib/background-agent-supervisor.js +208 -34
- package/src/lib/background-turn-bootstrap-protocol.js +4 -0
- package/src/lib/cowork-task-runner.js +70 -0
- package/src/lib/cowork-workflow.js +42 -9
- package/src/lib/doctor-checkup.js +34 -10
- package/src/lib/dynamic-workflow-draft.js +535 -0
- package/src/lib/dynamic-workflow-facade.js +11 -11
- package/src/lib/dynamic-workflow-runtime.js +2974 -0
- package/src/lib/execution-location-contract.js +111 -7
- package/src/lib/execution-location-runtime.js +3 -1
- package/src/lib/execution-location-target.js +910 -0
- package/src/lib/llm-providers.js +1 -0
- package/src/lib/mcp-call-ledger-store.js +35 -0
- package/src/lib/mcp-call-ledger.js +30 -0
- package/src/lib/plugin-runtime/__tests__/remote-source.test.js +34 -16
- package/src/lib/plugin-runtime/install.js +4956 -657
- package/src/lib/plugin-runtime/manifest.js +3 -1
- package/src/lib/plugin-runtime/marketplace-artifact-readback.js +671 -31
- package/src/lib/plugin-runtime/marketplace-catalog.js +68 -2
- package/src/lib/plugin-runtime/marketplace-impact.js +208 -15
- package/src/lib/plugin-runtime/marketplace-network.js +317 -0
- package/src/lib/plugin-runtime/marketplace-pac-worker.js +15 -0
- package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +25 -2
- package/src/lib/plugin-runtime/marketplace-source-cache.js +359 -0
- package/src/lib/plugin-runtime/policy.js +21 -6
- package/src/lib/plugin-runtime/publisher-trust.js +332 -0
- package/src/lib/plugin-runtime/remote-source.js +323 -27
- package/src/lib/plugin-runtime/scopes.js +317 -41
- package/src/lib/plugin-runtime/transaction-journal.js +806 -0
- package/src/lib/public-ide-capability-manifest.js +1 -1
- package/src/lib/remote-membership-coordinator.js +8 -6
- package/src/lib/sub-agent-context.js +268 -2
- package/src/lib/task-model-selector.js +1 -1
- package/src/lib/with-file-lock.js +266 -27
- package/src/runtime/agent-core.js +595 -41
- package/src/workers/background-agent-keeper.js +147 -24
- package/src/workers/background-agent-worker.js +383 -134
- package/src/workers/background-turn-bootstrap.js +13 -8
- package/src/assets/web-panel/assets/MobileProjects-Tyd3o2A0.js +0 -1
- package/src/assets/web-panel/assets/Projects-CP8vPvzs.js +0 -1
- package/src/assets/web-panel/assets/Providers-CUnHbNf-.js +0 -1
- package/src/assets/web-panel/assets/devWarning-Dol8jLEP.js +0 -1
- package/src/assets/web-panel/assets/index-C3QX5tOl.js +0 -1
- package/src/assets/web-panel/assets/index-xYybvEic.js +0 -1
|
@@ -9,8 +9,15 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import net from "node:net";
|
|
12
|
-
import {
|
|
13
|
-
|
|
12
|
+
import {
|
|
13
|
+
readFileSync,
|
|
14
|
+
renameSync,
|
|
15
|
+
rmSync,
|
|
16
|
+
unlinkSync,
|
|
17
|
+
writeFileSync,
|
|
18
|
+
writeSync,
|
|
19
|
+
} from "node:fs";
|
|
20
|
+
import { dirname, resolve } from "node:path";
|
|
14
21
|
import { fileURLToPath } from "node:url";
|
|
15
22
|
import { createNdjsonReader } from "../lib/background-session-transport.js";
|
|
16
23
|
import {
|
|
@@ -27,18 +34,24 @@ import {
|
|
|
27
34
|
BACKGROUND_AGENT_KEEPER_ARMED,
|
|
28
35
|
BACKGROUND_AGENT_KEEPER_CLEANUP_CONFIRM_TIMEOUT_MS,
|
|
29
36
|
BACKGROUND_AGENT_KEEPER_HELLO,
|
|
37
|
+
BACKGROUND_AGENT_KEEPER_HEARTBEAT,
|
|
38
|
+
BACKGROUND_AGENT_KEEPER_IDENTITY_PROBE_DELAY_MS,
|
|
39
|
+
BACKGROUND_AGENT_KEEPER_HEARTBEAT_TIMEOUT_MS,
|
|
30
40
|
BACKGROUND_AGENT_KEEPER_PERSIST_RETRY_TIMEOUT_MS,
|
|
31
41
|
BACKGROUND_AGENT_KEEPER_PROTOCOL_VERSION,
|
|
32
42
|
BACKGROUND_AGENT_KEEPER_READY,
|
|
33
43
|
BACKGROUND_AGENT_KEEPER_RETIRE,
|
|
34
44
|
BACKGROUND_AGENT_KEEPER_RETIRED,
|
|
35
45
|
BACKGROUND_AGENT_KEEPER_STATE_LOCK_TIMEOUT_MS,
|
|
46
|
+
backgroundAgentKeeperLaunchClaimPath,
|
|
36
47
|
cleanupBackgroundAgentKeeperPipeDirectory,
|
|
48
|
+
createBackgroundAgentKeeperLaunchClaim,
|
|
37
49
|
createBackgroundAgentKeeperMessage,
|
|
38
50
|
normalizeBackgroundAgentKeeperHello,
|
|
39
51
|
normalizeBackgroundAgentKeeperTurn,
|
|
40
52
|
sameBackgroundAgentKeeperTurn,
|
|
41
53
|
} from "../lib/background-agent-keeper-protocol.js";
|
|
54
|
+
import { waitForBackgroundAgentLaunchBarrier } from "../lib/background-agent-launch-barrier.js";
|
|
42
55
|
|
|
43
56
|
const STARTUP_TIMEOUT_MS = 30_000;
|
|
44
57
|
const HEARTBEAT_INTERVAL_MS = 1_000;
|
|
@@ -121,6 +134,7 @@ export function runBackgroundAgentKeeperHeartbeat({
|
|
|
121
134
|
workerSocket,
|
|
122
135
|
authenticatedHello,
|
|
123
136
|
authenticatedWorkerStartedAt,
|
|
137
|
+
workerHeartbeatAt,
|
|
124
138
|
armedTurn,
|
|
125
139
|
persistKeeper,
|
|
126
140
|
finishForWorkerDisconnect,
|
|
@@ -129,25 +143,47 @@ export function runBackgroundAgentKeeperHeartbeat({
|
|
|
129
143
|
reportPersistenceFailure = reportKeeperPersistenceFailure,
|
|
130
144
|
}) {
|
|
131
145
|
if (finishing) return false;
|
|
132
|
-
|
|
146
|
+
// Startup is deliberately serialized: the keeper publishes its listening
|
|
147
|
+
// claim, then remains read-only until the worker has claimed and
|
|
148
|
+
// authenticated. Persisting a pre-auth heartbeat would reintroduce the
|
|
149
|
+
// first-write lock race the launch barrier prevents.
|
|
150
|
+
if (!workerSocket || !authenticatedHello) return false;
|
|
151
|
+
const currentTime = now();
|
|
152
|
+
const workerHeartbeatAge = Number.isFinite(workerHeartbeatAt)
|
|
153
|
+
? Math.max(0, currentTime - workerHeartbeatAt)
|
|
154
|
+
: 0;
|
|
155
|
+
const workerHeartbeatExpired =
|
|
133
156
|
workerSocket &&
|
|
134
157
|
authenticatedHello &&
|
|
158
|
+
Number.isFinite(workerHeartbeatAt) &&
|
|
159
|
+
workerHeartbeatAge > BACKGROUND_AGENT_KEEPER_HEARTBEAT_TIMEOUT_MS;
|
|
160
|
+
const workerIdentityProbeDue =
|
|
135
161
|
armedTurn &&
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
162
|
+
Number.isFinite(workerHeartbeatAt) &&
|
|
163
|
+
workerHeartbeatAge > BACKGROUND_AGENT_KEEPER_IDENTITY_PROBE_DELAY_MS;
|
|
164
|
+
if (
|
|
165
|
+
workerSocket &&
|
|
166
|
+
authenticatedHello &&
|
|
167
|
+
(workerHeartbeatExpired ||
|
|
168
|
+
(workerIdentityProbeDue &&
|
|
169
|
+
!workerIdentityAlive(
|
|
170
|
+
authenticatedHello.workerPid,
|
|
171
|
+
authenticatedWorkerStartedAt,
|
|
172
|
+
)))
|
|
140
173
|
) {
|
|
141
|
-
// A Windows named-pipe handle
|
|
142
|
-
// platform helper retained a duplicate.
|
|
143
|
-
//
|
|
144
|
-
//
|
|
174
|
+
// A Windows named-pipe handle and process object can remain observable
|
|
175
|
+
// after its worker dies if a platform helper retained a duplicate.
|
|
176
|
+
// Socket EOF and PID visibility are therefore not sufficient lifetime
|
|
177
|
+
// signals. The authenticated application heartbeat provides an
|
|
178
|
+
// independent bounded fence. Delay the PID/start probe until application
|
|
179
|
+
// heartbeats are already stale so healthy Windows keepers do not create a
|
|
180
|
+
// synchronized WMIC/PowerShell probe storm under normal operation.
|
|
145
181
|
finishForWorkerDisconnect();
|
|
146
182
|
workerSocket.destroy();
|
|
147
183
|
return false;
|
|
148
184
|
}
|
|
149
185
|
try {
|
|
150
|
-
persistKeeper({ keeperHeartbeatAt:
|
|
186
|
+
persistKeeper({ keeperHeartbeatAt: currentTime });
|
|
151
187
|
return true;
|
|
152
188
|
} catch (error) {
|
|
153
189
|
try {
|
|
@@ -226,7 +262,9 @@ export function stopBackgroundAgentKeeperTurnTrees(targets, options = {}) {
|
|
|
226
262
|
leaderAlive ||
|
|
227
263
|
(platform !== "win32" &&
|
|
228
264
|
target.processGroup === true &&
|
|
229
|
-
processTreeExecutionAlive(target.pid, target.startedAt
|
|
265
|
+
processTreeExecutionAlive(target.pid, target.startedAt, {
|
|
266
|
+
processGroup: true,
|
|
267
|
+
}));
|
|
230
268
|
if (residualAlive) {
|
|
231
269
|
failures.push(error?.message || String(error));
|
|
232
270
|
}
|
|
@@ -235,6 +273,46 @@ export function stopBackgroundAgentKeeperTurnTrees(targets, options = {}) {
|
|
|
235
273
|
return failures;
|
|
236
274
|
}
|
|
237
275
|
|
|
276
|
+
export async function waitForBackgroundAgentKeeperTurnTreesToStop(
|
|
277
|
+
targets,
|
|
278
|
+
options = {},
|
|
279
|
+
) {
|
|
280
|
+
const now = options.now || Date.now;
|
|
281
|
+
const sleep =
|
|
282
|
+
options.sleep ||
|
|
283
|
+
((milliseconds) =>
|
|
284
|
+
new Promise((resolvePromise) =>
|
|
285
|
+
setTimeout(resolvePromise, milliseconds),
|
|
286
|
+
));
|
|
287
|
+
const processTreeExecutionAlive =
|
|
288
|
+
options.isProcessTreeExecutionAlive ||
|
|
289
|
+
isBackgroundProcessTreeExecutionAlive;
|
|
290
|
+
const timeoutMs = Math.max(
|
|
291
|
+
1,
|
|
292
|
+
Number(options.timeoutMs) ||
|
|
293
|
+
BACKGROUND_AGENT_KEEPER_CLEANUP_CONFIRM_TIMEOUT_MS,
|
|
294
|
+
);
|
|
295
|
+
// Each strict macOS liveness probe invokes ps. Polling every 10 ms across
|
|
296
|
+
// 20 keepers created a process storm precisely while launchd was trying to
|
|
297
|
+
// reap the killed groups. A 100 ms cadence remains responsive and bounded
|
|
298
|
+
// while leaving the host enough scheduling capacity to establish absence.
|
|
299
|
+
const pollMs = Math.max(1, Number(options.pollMs) || 100);
|
|
300
|
+
const deadline = now() + timeoutMs;
|
|
301
|
+
const observeAlive = () =>
|
|
302
|
+
targets.filter((target) =>
|
|
303
|
+
processTreeExecutionAlive(target.pid, target.startedAt, {
|
|
304
|
+
processGroup: target.processGroup !== false,
|
|
305
|
+
}),
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
let alive = observeAlive();
|
|
309
|
+
while (alive.length > 0 && now() < deadline) {
|
|
310
|
+
await sleep(Math.max(1, Math.min(pollMs, deadline - now())));
|
|
311
|
+
alive = observeAlive();
|
|
312
|
+
}
|
|
313
|
+
return alive;
|
|
314
|
+
}
|
|
315
|
+
|
|
238
316
|
async function cleanupTurn(job, turn, reason) {
|
|
239
317
|
const requestedAt = Date.now();
|
|
240
318
|
const requestedPersistence = await retryKeeperPersistence(() =>
|
|
@@ -262,17 +340,7 @@ async function cleanupTurn(job, turn, reason) {
|
|
|
262
340
|
);
|
|
263
341
|
const failures = stopBackgroundAgentKeeperTurnTrees(targets);
|
|
264
342
|
|
|
265
|
-
const
|
|
266
|
-
Date.now() + BACKGROUND_AGENT_KEEPER_CLEANUP_CONFIRM_TIMEOUT_MS;
|
|
267
|
-
let alive = targets.filter((target) =>
|
|
268
|
-
isBackgroundProcessTreeExecutionAlive(target.pid, target.startedAt),
|
|
269
|
-
);
|
|
270
|
-
while (alive.length > 0 && Date.now() < deadline) {
|
|
271
|
-
await new Promise((resolvePromise) => setTimeout(resolvePromise, 10));
|
|
272
|
-
alive = targets.filter((target) =>
|
|
273
|
-
isBackgroundProcessTreeExecutionAlive(target.pid, target.startedAt),
|
|
274
|
-
);
|
|
275
|
-
}
|
|
343
|
+
const alive = await waitForBackgroundAgentKeeperTurnTreesToStop(targets);
|
|
276
344
|
const confirmed = alive.length === 0 && failures.length === 0;
|
|
277
345
|
let finalPersistenceAttempts = 0;
|
|
278
346
|
const finalPersistence = await retryKeeperPersistence(() => {
|
|
@@ -309,6 +377,24 @@ async function cleanupTurn(job, turn, reason) {
|
|
|
309
377
|
|
|
310
378
|
export async function runBackgroundAgentKeeper(jobFile, options = {}) {
|
|
311
379
|
const job = JSON.parse(readFileSync(jobFile, "utf8"));
|
|
380
|
+
const launchClaimPath = backgroundAgentKeeperLaunchClaimPath(
|
|
381
|
+
job.id,
|
|
382
|
+
job.keeperGeneration,
|
|
383
|
+
options.backgroundAgentsDirectory || dirname(resolve(jobFile)),
|
|
384
|
+
);
|
|
385
|
+
const launchBarrier = await waitForBackgroundAgentLaunchBarrier({
|
|
386
|
+
id: job.id,
|
|
387
|
+
workerGeneration: job.workerGeneration,
|
|
388
|
+
expectedPid: process.pid,
|
|
389
|
+
pidField: "keeperPid",
|
|
390
|
+
readState: options.readBackgroundAgentState || readBackgroundAgentState,
|
|
391
|
+
timeoutMs: Number(options.launchBarrierTimeoutMs) || undefined,
|
|
392
|
+
sleep: options.launchBarrierSleep,
|
|
393
|
+
});
|
|
394
|
+
if (launchBarrier.status !== "ready") {
|
|
395
|
+
removeJobFile(jobFile);
|
|
396
|
+
return { status: `launch-${launchBarrier.status}` };
|
|
397
|
+
}
|
|
312
398
|
removeJobFile(jobFile);
|
|
313
399
|
const startedAt = Date.now();
|
|
314
400
|
const claim = mutateBackgroundAgentState(job.id, (current) => {
|
|
@@ -329,6 +415,25 @@ export async function runBackgroundAgentKeeper(jobFile, options = {}) {
|
|
|
329
415
|
};
|
|
330
416
|
});
|
|
331
417
|
if (!claim.applied) return { status: "unclaimed" };
|
|
418
|
+
const launchClaim = createBackgroundAgentKeeperLaunchClaim({
|
|
419
|
+
id: job.id,
|
|
420
|
+
workerGeneration: job.workerGeneration,
|
|
421
|
+
keeperGeneration: job.keeperGeneration,
|
|
422
|
+
keeperPid: process.pid,
|
|
423
|
+
token: job.token,
|
|
424
|
+
});
|
|
425
|
+
const launchClaimCandidate = `${launchClaimPath}.${process.pid}.tmp`;
|
|
426
|
+
try {
|
|
427
|
+
writeFileSync(launchClaimCandidate, JSON.stringify(launchClaim), {
|
|
428
|
+
encoding: "utf8",
|
|
429
|
+
mode: 0o600,
|
|
430
|
+
flag: "wx",
|
|
431
|
+
});
|
|
432
|
+
renameSync(launchClaimCandidate, launchClaimPath);
|
|
433
|
+
} catch (error) {
|
|
434
|
+
rmSync(launchClaimCandidate, { force: true });
|
|
435
|
+
throw error;
|
|
436
|
+
}
|
|
332
437
|
|
|
333
438
|
if (process.platform !== "win32") {
|
|
334
439
|
try {
|
|
@@ -342,6 +447,7 @@ export async function runBackgroundAgentKeeper(jobFile, options = {}) {
|
|
|
342
447
|
let candidateSocket = null;
|
|
343
448
|
let authenticatedHello = null;
|
|
344
449
|
let authenticatedWorkerStartedAt = null;
|
|
450
|
+
let workerHeartbeatAt = null;
|
|
345
451
|
let armedTurn = null;
|
|
346
452
|
let finishing = false;
|
|
347
453
|
let finishResolve;
|
|
@@ -460,6 +566,7 @@ export async function runBackgroundAgentKeeper(jobFile, options = {}) {
|
|
|
460
566
|
authenticated = true;
|
|
461
567
|
authenticatedHello = hello;
|
|
462
568
|
authenticatedWorkerStartedAt = Number(current.startedAt);
|
|
569
|
+
workerHeartbeatAt = Date.now();
|
|
463
570
|
workerSocket = socket;
|
|
464
571
|
clearTimeout(helloTimer);
|
|
465
572
|
persistKeeper({ keeperStatus: "ready", keeperReadyAt: Date.now() });
|
|
@@ -477,6 +584,20 @@ export async function runBackgroundAgentKeeper(jobFile, options = {}) {
|
|
|
477
584
|
return;
|
|
478
585
|
}
|
|
479
586
|
|
|
587
|
+
if (message.type === BACKGROUND_AGENT_KEEPER_HEARTBEAT) {
|
|
588
|
+
if (
|
|
589
|
+
message.id !== authenticatedHello.id ||
|
|
590
|
+
message.workerGeneration !==
|
|
591
|
+
authenticatedHello.workerGeneration ||
|
|
592
|
+
Number(message.workerPid) !== authenticatedHello.workerPid
|
|
593
|
+
) {
|
|
594
|
+
socket.destroy();
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
workerHeartbeatAt = Date.now();
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
|
|
480
601
|
if (
|
|
481
602
|
message.type !== BACKGROUND_AGENT_KEEPER_ARM &&
|
|
482
603
|
message.type !== BACKGROUND_AGENT_KEEPER_RETIRE
|
|
@@ -613,6 +734,7 @@ export async function runBackgroundAgentKeeper(jobFile, options = {}) {
|
|
|
613
734
|
workerSocket,
|
|
614
735
|
authenticatedHello,
|
|
615
736
|
authenticatedWorkerStartedAt,
|
|
737
|
+
workerHeartbeatAt,
|
|
616
738
|
armedTurn,
|
|
617
739
|
persistKeeper,
|
|
618
740
|
finishForWorkerDisconnect,
|
|
@@ -656,6 +778,7 @@ export async function runBackgroundAgentKeeper(jobFile, options = {}) {
|
|
|
656
778
|
// Another keeper can still own a sibling socket in the shared namespace.
|
|
657
779
|
}
|
|
658
780
|
}
|
|
781
|
+
rmSync(launchClaimPath, { force: true });
|
|
659
782
|
return {
|
|
660
783
|
...result,
|
|
661
784
|
authenticatedWorkerPid: authenticatedHello?.workerPid || null,
|