chainlesschain 0.162.175 → 0.162.177
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 +10 -10
- package/src/assets/web-panel/assets/{AIOps-DherW0Rh.js → AIOps-DT-VPWuN.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CDGfqt2Y.js → ActionButton-DyOreOVN.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BYhkzdgD.js → Analytics-DslNsKux.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-cEKk1cpb.js → AppLayout-BNJJAYME.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-_aXR3WWc.js → Artifacts-DoaAtEcY.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CYAf-gY7.js → Audit-DPG3WdJ9.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-D4Q20phR.js → BackgroundAgents-C_JO6R5G.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-Cq0Tyk58.js → Backup-Cv3BooyX.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CPj_CdAv.js → BaseInput-D2uQXWu-.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-BQ-Qq0es.js → Chat-B4Vczyf3.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DE6reP99.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-rke6l3yg.js → Checkbox-qTgk4VeP.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DiacrIPq.js → Codegen-DlLWcIzj.js} +1 -1
- package/src/assets/web-panel/assets/{Col-Cx3BY-Up.js → Col-DNO73qp7.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DfmWiQy8.js → Community-vRDNpc4j.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DdQnpxy5.js → Compact-CEWtIXni.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-lzliOH_r.js → Compliance-KgYC9Fxi.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CYx4Un5k.js → Cowork-zj5wvkpT.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-BGDcPFlo.js → Cron-BLDoCozU.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-0_X5g2ri.js → Crosschain-BYnff4VY.js} +1 -1
- package/src/assets/web-panel/assets/{DID-C0PEf3Eu.js → DID-C75VFsVm.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DULQjQ58.js → Dashboard-C4Gutni2.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DGRHRbW6.js → Dropdown-B5dbO4Kx.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-ChX8XPwB.js → EmailListRenderer-BDipZtHJ.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-Dyq6IBNu.js → FamilyGuardDashboard-DmIzt8jj.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DH1NfAL2.js → Federation-D9QOS-uW.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BN1I_uNi.js → FormItemContext-B47HRwAm.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-Dq_2UYpe.js → GenericCardRenderer-3R4mXmgV.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BAy1yvI2.js → Git-DrNXZf1C.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-Db6Q2iSy.js → Governance-BGd7JR98.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-0ub6yHcr.js → Inference-D-2he1ed.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DtLetM36.js → KnowledgeGraph-C0sHIbK5.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Bcoy7CUd.js → Logs-DiBQO-jL.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-BfEMFAXf.js → MarkdownRenderer-DL_5eV2D.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-tt2rzwRR.js → Marketplace-VR59OdrC.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BhOgX-MU.js → McpTools-DrPzwSd3.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-BJUxeWBL.js → Memory-CBgKALwQ.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BwUY2G9w.js → MobileBridge-pQ9Tn-Mn.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BLRfHhqi.js → MobileProjects-mASB6jyj.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-B2WMboOm.js → Mtc-DTMgE7HC.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-8pNEXO63.js → MtcAudit-CwTnCtiL.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-C1wm5a_1.js → Multisig-ngm6WU8f.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-C1QpKF7g.js → NLProgramming-4YO4Qww9.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CiQUcxFu.js → Notes-DP1k45mF.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-BblDPJ_x.js → NotificationSettings-r2H8yPKb.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DRjYcPtb.js → OrderTableRenderer-CoM_Zw0J.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-Dp3VKB0X.js → Organization-DrO7jRWS.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Czx161m9.js → Overflow-Cnwu4i4t.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-ClFi6wOs.js → P2P-zi-cDwA_.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CRweW0lz.js → PdhVaultBrowser-DBEryDv7.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BzcRoqTn.js → Permissions-lqXK2C3x.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-ChGTpNMd.js → PersonalDataHub-b63T3HJM.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-BMOOpKWA.js → Pipeline-Kep5KAGW.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-D0AZHObH.js → Privacy-CHdvOAh1.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-yYFlZ6Ja.js → ProjectInit-BhKfdwe9.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DJNVuMQs.js → ProjectSettings-Yavk9K8A.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Br0rBWH1.js → Projects-CN8E_5Mq.js} +1 -1
- package/src/assets/web-panel/assets/Providers-Bfym6SQn.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-81NZOitV.js → QrScannerModal-CLSQcrlR.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Dic2lCbJ.js → QuickAsk-VPa2WKQN.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Dh9iwViE.js → Recommend-CGXR8jVU.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-Bq9VYEFy.js → RemoteSession-C_20YfMB.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-CxFZ-NbJ.js → Reputation-awZh68UV.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BVSLcaX2.js → Row-Ctb4oiYN.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BbC-5DOH.js → RssFeed-D3sdjvUV.js} +3 -3
- package/src/assets/web-panel/assets/{Search-BfjZ1GCr.js → Search-C-zfA4kT.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CVjhOV5r.js → Security-D9XlmHA3.js} +4 -4
- package/src/assets/web-panel/assets/{Services-D45u-Aqe.js → Services-C3UKnr41.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-WkGoK4he.js → Skeleton-BQxagZfF.js} +1 -1
- package/src/assets/web-panel/assets/Skills-q6eb6KPZ.js +1 -0
- package/src/assets/web-panel/assets/{Sla-Bf4QTF3E.js → Sla-DveENvek.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DVpZdbMN.js → SpeechSettings-BFjXLNgF.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DEEojoMS.js → SyncSettings-BpHgbaP9.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-DvepRb8-.js +1 -0
- package/src/assets/web-panel/assets/{Templates-Bzl-9wY5.js → Templates-DEiaoyve.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-0khxUOB8.js → Tenant-ITg774nY.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DWGYhAYU.js → Terminal-D3ZBcvnb.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-B0Y4LONc.js → TimelineRenderer-BsLU6JjU.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DEE07SFh.js → Tokens-Cb5Pquc9.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BM7xvA5z.js → Trigger-Dwfy-m9N.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Dv3ijvvZ.js → Trust-CnlSRGG0.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B1-enmMt.js → UkeySign-Y4TlvKVo.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DYiIPByd.js → VideoEditing-BpKLtTTO.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-D-y374BQ.js → Wallet-LLBzIq8x.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-HBDjcUhi.js → WebAuthn-BeSRiusP.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-sKn4qTID.js → WorkflowEditor-BK_l1tXO.js} +1 -1
- package/src/assets/web-panel/assets/{chat-TVYhaBXj.js → chat-DYd-X7Wg.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DMADxY9v.js → colors-C9uip71j.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-OftcHpO_.js → compact-item-JBrfjUP6.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DW1zVUSN.js → createContext-D03fbuiq.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-B8LQ8leS.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CaUathNp.js → hasIn-DLQOR6l-.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cmdv6Dev.js → index-5YN7F5bO.js} +1 -1
- package/src/assets/web-panel/assets/{index-iDmgT2Dg.js → index-6GuLRpBQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-77kgkUgY.js → index-B0X76LjX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CM8W07sc.js → index-B46YcgsV.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9JoaYSs.js → index-BNCdRmWf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpDtN0dl.js → index-BYv-LWdy.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZXYI5LU.js → index-Ba-Ps_AJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWVZ3T0t.js → index-BcBZwlnG.js} +1 -1
- package/src/assets/web-panel/assets/{index--5UvwqH_.js → index-BdH9l8wl.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBNg08cD.js → index-BfOs_bmg.js} +3 -3
- package/src/assets/web-panel/assets/index-Bh8BPtqR.js +1 -0
- package/src/assets/web-panel/assets/{index-s-EnkUCn.js → index-BnQgRjsm.js} +1 -1
- package/src/assets/web-panel/assets/{index-Lr0MO-GU.js → index-BpYKLrUT.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-19mFhn.js → index-BuNFCZCx.js} +1 -1
- package/src/assets/web-panel/assets/{index-CeCIYYG7.js → index-ByHO3SqZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-hXq7QRA_.js → index-C2zmOsyD.js} +1 -1
- package/src/assets/web-panel/assets/{index-8YelceUU.js → index-CChQBM1d.js} +1 -1
- package/src/assets/web-panel/assets/{index-B52Ztt8Q.js → index-CChaISMb.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKjqFpYa.js → index-CILVyK3b.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAfT3EMd.js → index-CL0ixCxk.js} +1 -1
- package/src/assets/web-panel/assets/{index-sm1sGIxW.js → index-CS63r8h3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DHi634g9.js → index-CVZWiUE_.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEzLLVYd.js → index-Ce0Bf1YF.js} +1 -1
- package/src/assets/web-panel/assets/index-CeVrHLzZ.js +1 -0
- package/src/assets/web-panel/assets/{index-pSVCBsG4.js → index-Ck17i0OD.js} +1 -1
- package/src/assets/web-panel/assets/{index-GUKz4Pv9.js → index-Cpn19c9k.js} +1 -1
- package/src/assets/web-panel/assets/{index-CKNdnJRo.js → index-CqWk1FLG.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bg-7FpaL.js → index-CwoDpKzW.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYwwUKDg.js → index-D-1SqEpQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZdT8nio.js → index-D4UY5Z60.js} +1 -1
- package/src/assets/web-panel/assets/{index-BvRw4Fna.js → index-D8KvuDz0.js} +1 -1
- package/src/assets/web-panel/assets/{index-kdMl_0zL.js → index-DNMAAUVk.js} +1 -1
- package/src/assets/web-panel/assets/{index-CK-p7Hji.js → index-DYLZY4uh.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXcqvWBp.js → index-DaokIHt3.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFVbDpqg.js → index-Q7mmL6w4.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJ1PjRY3.js → index-SO6lgMg0.js} +1 -1
- package/src/assets/web-panel/assets/{index-BSp1Ofvx.js → index-iahNhZwm.js} +1 -1
- package/src/assets/web-panel/assets/{index-BupSWDcl.js → index-l08afIbV.js} +1 -1
- package/src/assets/web-panel/assets/{index-D63QVAiJ.js → index-rIxxfdTN.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-DdcKTlQR.js → initDefaultProps-CG9z1c6w.js} +1 -1
- package/src/assets/web-panel/assets/{motion-CL-hTBQj.js → motion-B1Ky7Zff.js} +1 -1
- package/src/assets/web-panel/assets/{move-qYSAkxNG.js → move-DME8X2P1.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-ZwRSZtRP.js → mtc-parser-cuJYSWB7.js} +1 -1
- package/src/assets/web-panel/assets/{omit-Bld-8ftI.js → omit-UI_EE0uZ.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DGHs-a9Z.js → pickAttrs-BIoE_Z_V.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DRQPMyI5.js → placementArrow-B48-9HKN.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-C5MJG_Yo.js → responsiveObserve-D7x_GDgD.js} +1 -1
- package/src/assets/web-panel/assets/{slide-VZ-fpZCD.js → slide-DjzC5_7m.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-9ocfCyHk.js → statusUtils-C6BIymhh.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-B6QAwAN5.js → styleChecker-B4dGrdD9.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Bq1twor3.js → useFlexGapSupport-Bken4aNE.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DKZq96tz.js → useFs-BMlqECqv.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-D0RmRVXf.js → usePersonalDataHub-DLdrfmMa.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-D6kEj_tt.js → vnode-CKJQmxa0.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-2yfasoQf.js → zoom-CaZunuau.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/auth/npm-auth.js +30 -5
- package/src/commands/agenda.js +83 -5
- package/src/commands/agent.js +42 -4
- package/src/commands/background-session.js +11 -4
- package/src/commands/batch.js +79 -27
- package/src/commands/changelog.js +15 -4
- package/src/commands/config.js +70 -5
- package/src/commands/context.js +36 -2
- package/src/commands/eval.js +21 -6
- package/src/commands/hook.js +2 -2
- package/src/commands/hub.js +19 -1
- package/src/commands/loop.js +9 -2
- package/src/commands/memory.js +21 -6
- package/src/commands/permissions.js +57 -1
- package/src/commands/plugin.js +2 -0
- package/src/commands/review.js +23 -11
- package/src/commands/routine.js +31 -8
- package/src/commands/session.js +11 -3
- package/src/commands/skill.js +2 -0
- package/src/commands/statusline.js +3 -3
- package/src/commands/team.js +20 -7
- package/src/commands/update.js +65 -10
- package/src/data/changelog.json +293 -51
- package/src/gateways/terminal/PtyManager.js +8 -1
- package/src/gateways/ws/message-dispatcher.js +3 -0
- package/src/gateways/ws/session-protocol.js +26 -0
- package/src/gateways/ws/ws-agent-handler.js +107 -69
- package/src/gateways/ws/ws-server.js +74 -2
- package/src/harness/background-task-manager.js +18 -6
- package/src/harness/background-task-worker.js +11 -18
- package/src/harness/jsonl-session-store.js +13 -6
- package/src/harness/mcp-client.js +195 -2
- package/src/harness/worktree-isolator.js +18 -21
- package/src/lib/__tests__/personal-data-hub-aichat-wizard.test.js +15 -0
- package/src/lib/agent-coordinator.js +4 -0
- package/src/lib/agent-core.js +5 -0
- package/src/lib/agent-ipc-bus.js +44 -5
- package/src/lib/agent-sandbox.js +16 -2
- package/src/lib/agent-schedule-store.js +55 -0
- package/src/lib/agent-team/team-worktree.js +28 -6
- package/src/lib/agent-tool-admission.js +104 -0
- package/src/lib/agent-worktree.js +20 -19
- package/src/lib/api-key-helper.js +10 -2
- package/src/lib/async-hook-supervisor.cjs +135 -15
- package/src/lib/async-hook-supervisor.js +47 -0
- package/src/lib/background-agent-supervisor.js +35 -12
- package/src/lib/background-task-manager.js +5 -1
- package/src/lib/changelog.js +76 -11
- package/src/lib/channels/channel-manager.js +6 -0
- package/src/lib/channels/telegram-channel.js +11 -1
- package/src/lib/channels/webhook-channel.js +15 -3
- package/src/lib/checkpoint-store.js +10 -2
- package/src/lib/chrome-connector.js +6 -2
- package/src/lib/claude-code-bridge.js +24 -8
- package/src/lib/cli-anything-bridge.js +82 -25
- package/src/lib/cloud/bundle.js +12 -2
- package/src/lib/code-review.js +32 -8
- package/src/lib/computer-use/control-backend.js +18 -3
- package/src/lib/context-breakdown.js +46 -0
- package/src/lib/context-source-ledger.js +43 -0
- package/src/lib/diff-review-follow-up.js +154 -0
- package/src/lib/doctor-checkup.js +18 -6
- package/src/lib/downloader.js +17 -3
- package/src/lib/ensure-utf8.js +11 -3
- package/src/lib/eval/tasks.js +25 -31
- package/src/lib/event-runtime-producer.js +58 -0
- package/src/lib/event-runtime-store.js +354 -0
- package/src/lib/event-runtime-worker.js +109 -0
- package/src/lib/execution-backend.js +72 -21
- package/src/lib/git-integration.js +19 -4
- package/src/lib/hook-manager.js +6 -15
- package/src/lib/hook-runner.cjs +88 -8
- package/src/lib/hook-runner.js +55 -0
- package/src/lib/hooks-v2-producers.js +15 -0
- package/src/lib/hooks-v2-runtime.js +70 -21
- package/src/lib/host-adb-bridge.js +129 -24
- package/src/lib/ide-context.js +128 -1
- package/src/lib/interaction-adapter.js +39 -0
- package/src/lib/json-schema-validate.js +190 -36
- package/src/lib/lan-pairing-preflight.js +13 -2
- package/src/lib/lsp/__tests__/benchmark.test.js +61 -0
- package/src/lib/lsp/__tests__/lsp-client.test.js +6 -1
- package/src/lib/lsp/__tests__/lsp-server-registry.test.js +18 -0
- package/src/lib/lsp/benchmark.js +20 -4
- package/src/lib/lsp/lsp-client.js +22 -3
- package/src/lib/lsp/lsp-manager.js +4 -0
- package/src/lib/lsp/lsp-server-registry.js +11 -2
- package/src/lib/mcp-oauth.js +8 -2
- package/src/lib/npm-invocation.js +29 -0
- package/src/lib/orchestrator.js +8 -2
- package/src/lib/packer/pack-update-applier.js +14 -2
- package/src/lib/packer/pkg-runner.js +13 -2
- package/src/lib/packer/precheck.js +33 -16
- package/src/lib/packer/smoke-runner.js +18 -5
- package/src/lib/packer/web-panel-builder.js +16 -2
- package/src/lib/paths.js +1 -1
- package/src/lib/permission-rules.cjs +5 -1
- package/src/lib/personal-data-hub-aichat-wizard.js +22 -6
- package/src/lib/personal-data-hub-wiring.js +27 -3
- package/src/lib/plan-mode.js +204 -11
- package/src/lib/plugin-monitor-supervisor.js +48 -6
- package/src/lib/plugin-runtime/bin.js +45 -0
- package/src/lib/plugin-runtime/hooks.js +14 -1
- package/src/lib/plugin-runtime/install.js +11 -3
- package/src/lib/plugin-runtime/lsp.js +3 -0
- package/src/lib/plugin-runtime/mcp.js +8 -1
- package/src/lib/plugin-runtime/monitors.js +4 -0
- package/src/lib/plugin-runtime/plugin-options.js +74 -7
- package/src/lib/plugin-runtime/signature.js +45 -0
- package/src/lib/pr-create.js +21 -8
- package/src/lib/pr-link-ledger.js +15 -3
- package/src/lib/process-execution-broker/credential-agent.js +23 -3
- package/src/lib/process-execution-broker/index.js +315 -38
- package/src/lib/process-execution-broker/patch-child-process.js +2 -3
- package/src/lib/process-manager.js +18 -3
- package/src/lib/publish-workspace.js +14 -6
- package/src/lib/repl-bang-memorize.js +10 -2
- package/src/lib/repl-goal.js +19 -2
- package/src/lib/secret-store.js +159 -0
- package/src/lib/service-manager.js +64 -29
- package/src/lib/settings-hook-events.cjs +74 -9
- package/src/lib/settings-hook-events.js +20 -0
- package/src/lib/settings-hooks.cjs +4 -0
- package/src/lib/side-effect-ledger.js +22 -0
- package/src/lib/skill-packs/generator.js +18 -9
- package/src/lib/skill-process-broker.js +71 -0
- package/src/lib/slash-commands.js +10 -2
- package/src/lib/status-line.cjs +28 -7
- package/src/lib/status-line.js +33 -0
- package/src/lib/sub-agent-context.js +5 -0
- package/src/lib/sub-agent-profiles.js +4 -0
- package/src/lib/turn-context.js +14 -8
- package/src/lib/unattended-action-policy.js +83 -0
- package/src/lib/update-notice.js +6 -2
- package/src/lib/with-file-lock.js +7 -0
- package/src/lib/ws-server.js +1 -0
- package/src/repl/agent-repl.js +60 -23
- package/src/repl/clipboard-copy.js +8 -2
- package/src/repl/pr-comments.js +30 -7
- package/src/runtime/agent-core.js +554 -118
- package/src/runtime/agent-runtime.js +1 -0
- package/src/runtime/coding-agent-contract-shared.cjs +52 -0
- package/src/runtime/coding-agent-policy.cjs +20 -0
- package/src/runtime/diagnostics.js +73 -8
- package/src/runtime/headless-runner.js +88 -10
- package/src/runtime/headless-stream.js +343 -21
- package/src/runtime/mcp-config.js +16 -1
- package/src/runtime/session-slash-commands.js +506 -0
- package/src/skills/video-editing/extractors/audio-extractor.js +13 -5
- package/src/skills/video-editing/extractors/video-extractor.js +13 -3
- package/src/skills/video-editing/media-process.js +20 -0
- package/src/skills/video-editing/render/audio-mix.js +13 -3
- package/src/skills/video-editing/render/ffmpeg-concat.js +7 -2
- package/src/skills/video-editing/render/ffmpeg-extract.js +7 -2
- package/src/workers/background-agent-worker.js +6 -2
- package/src/assets/web-panel/assets/ChatBubbleRenderer-Ci97vNTs.js +0 -1
- package/src/assets/web-panel/assets/Providers-zZRhNtSu.js +0 -1
- package/src/assets/web-panel/assets/Skills-D_jvQZcj.js +0 -1
- package/src/assets/web-panel/assets/Tasks-DFwxpLIk.js +0 -1
- package/src/assets/web-panel/assets/devWarning-CLOk6rdE.js +0 -1
- package/src/assets/web-panel/assets/index-CSgUfMTM.js +0 -1
- package/src/assets/web-panel/assets/index-DliSZvAP.js +0 -1
|
@@ -106,6 +106,10 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
106
106
|
this._credentialAgent = credentialAgent;
|
|
107
107
|
this._credentialFilteringEnabled = true;
|
|
108
108
|
this._sandboxEnabled = true;
|
|
109
|
+
// Keep the legacy aliases used by older call sites and make the strict
|
|
110
|
+
// plugin path use the same switches as the general broker path.
|
|
111
|
+
this._credentialAgentEnabled = true;
|
|
112
|
+
this._platformSandboxEnabled = true;
|
|
109
113
|
|
|
110
114
|
this._ensureLogDir();
|
|
111
115
|
this._loadPermissions();
|
|
@@ -176,6 +180,75 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
176
180
|
return safe;
|
|
177
181
|
}
|
|
178
182
|
|
|
183
|
+
_credentialBoundaryEnabled() {
|
|
184
|
+
return (
|
|
185
|
+
this._credentialFilteringEnabled !== false &&
|
|
186
|
+
this._credentialAgentEnabled !== false
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
_sanitizeAuditArgs(args) {
|
|
191
|
+
const values = Array.isArray(args) ? args : [];
|
|
192
|
+
try {
|
|
193
|
+
return this._credentialAgent.sanitizeArgs(values).sanitizedArgs;
|
|
194
|
+
} catch {
|
|
195
|
+
return values.map(() => "***REDACTION_FAILED***");
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
_applyCredentialBoundary(command, args, spawnOptions, origin) {
|
|
200
|
+
const originalArgs = Array.isArray(args) ? [...args] : [];
|
|
201
|
+
const originalEnv = spawnOptions.env || process.env;
|
|
202
|
+
const input = {
|
|
203
|
+
...spawnOptions,
|
|
204
|
+
env: originalEnv,
|
|
205
|
+
args: originalArgs,
|
|
206
|
+
file: command,
|
|
207
|
+
origin,
|
|
208
|
+
};
|
|
209
|
+
let filtered;
|
|
210
|
+
let report = null;
|
|
211
|
+
if (typeof this._credentialAgent.applyWithReport === "function") {
|
|
212
|
+
const result = this._credentialAgent.applyWithReport(input);
|
|
213
|
+
filtered = result.spawnOptions;
|
|
214
|
+
report = result.report;
|
|
215
|
+
} else {
|
|
216
|
+
filtered = this._credentialAgent.apply(input);
|
|
217
|
+
}
|
|
218
|
+
const filteredArgs = Array.isArray(filtered?.args)
|
|
219
|
+
? filtered.args
|
|
220
|
+
: originalArgs;
|
|
221
|
+
const filteredEnv = filtered?.env || {};
|
|
222
|
+
const inferredEnvCount = Object.keys(originalEnv).filter(
|
|
223
|
+
(key) =>
|
|
224
|
+
this._credentialAgent.isSensitiveKey?.(key) &&
|
|
225
|
+
!Object.prototype.hasOwnProperty.call(filteredEnv, key),
|
|
226
|
+
).length;
|
|
227
|
+
const inferredArgCount = originalArgs.reduce(
|
|
228
|
+
(count, value, index) =>
|
|
229
|
+
count + (String(value) === String(filteredArgs[index]) ? 0 : 1),
|
|
230
|
+
0,
|
|
231
|
+
);
|
|
232
|
+
const credentialReport = report || {
|
|
233
|
+
envCount: inferredEnvCount,
|
|
234
|
+
argCount: inferredArgCount,
|
|
235
|
+
filtered: inferredEnvCount > 0 || inferredArgCount > 0,
|
|
236
|
+
};
|
|
237
|
+
return {
|
|
238
|
+
args: filteredArgs,
|
|
239
|
+
env: filteredEnv,
|
|
240
|
+
report: credentialReport,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
_recordCredentialReport(auditEntry, report) {
|
|
245
|
+
const filtered = report?.filtered === true;
|
|
246
|
+
auditEntry.credentialFiltered = filtered;
|
|
247
|
+
auditEntry.credentialEnvCount = Number(report?.envCount || 0);
|
|
248
|
+
auditEntry.credentialArgCount = Number(report?.argCount || 0);
|
|
249
|
+
if (filtered) this._stats.credFiltered++;
|
|
250
|
+
}
|
|
251
|
+
|
|
179
252
|
_getTraceContext() {
|
|
180
253
|
const traceCtx = getTraceCtx();
|
|
181
254
|
if (traceCtx && traceCtx.activeContext) {
|
|
@@ -252,7 +325,7 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
252
325
|
origin,
|
|
253
326
|
scope,
|
|
254
327
|
command,
|
|
255
|
-
args: args
|
|
328
|
+
args: this._sanitizeAuditArgs(args),
|
|
256
329
|
cwd,
|
|
257
330
|
startTime,
|
|
258
331
|
permissionDecision: decision,
|
|
@@ -263,6 +336,9 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
263
336
|
exitCode: null,
|
|
264
337
|
endTime: null,
|
|
265
338
|
durationMs: null,
|
|
339
|
+
pluginId: options.pluginId || null,
|
|
340
|
+
pluginVersion: options.pluginVersion || null,
|
|
341
|
+
pluginSource: options.pluginSource || null,
|
|
266
342
|
};
|
|
267
343
|
|
|
268
344
|
if (decision === "deny" || decision === "prompt") {
|
|
@@ -298,21 +374,17 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
298
374
|
}
|
|
299
375
|
|
|
300
376
|
// P0-1: Credential filtering (default-on) — strip secrets from env/args
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
file: command,
|
|
307
|
-
args: args || [],
|
|
377
|
+
if (this._credentialBoundaryEnabled()) {
|
|
378
|
+
const credentialBoundary = this._applyCredentialBoundary(
|
|
379
|
+
command,
|
|
380
|
+
args,
|
|
381
|
+
spawnOpts,
|
|
308
382
|
origin,
|
|
309
|
-
|
|
310
|
-
spawnOpts.env =
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if (credInfo.redacted) this._stats.credFiltered++;
|
|
315
|
-
auditEntry.credentialFiltered = !!credInfo.redacted;
|
|
383
|
+
);
|
|
384
|
+
spawnOpts.env = credentialBoundary.env;
|
|
385
|
+
args = credentialBoundary.args;
|
|
386
|
+
auditEntry.args = [...args];
|
|
387
|
+
this._recordCredentialReport(auditEntry, credentialBoundary.report);
|
|
316
388
|
}
|
|
317
389
|
|
|
318
390
|
// P0-1: Platform sandbox wrapping — apply macOS/Windows/Linux sandbox
|
|
@@ -354,8 +426,8 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
354
426
|
}
|
|
355
427
|
|
|
356
428
|
// Use native spawn from _native (set by patch-child-process.js)
|
|
357
|
-
const
|
|
358
|
-
const proc =
|
|
429
|
+
const nativeSpawnFn = this._native?.spawn || nativeSpawn;
|
|
430
|
+
const proc = nativeSpawnFn(command, args, optsForSpawn);
|
|
359
431
|
|
|
360
432
|
// P0-1: Post-spawn sandbox setup (Windows Job Object association, etc.)
|
|
361
433
|
if (sandboxApplied && proc.pid) {
|
|
@@ -409,7 +481,10 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
409
481
|
error: err.message,
|
|
410
482
|
component: origin,
|
|
411
483
|
});
|
|
412
|
-
|
|
484
|
+
// EventEmitter treats an unhandled `error` event as an exception. A
|
|
485
|
+
// process ENOENT must reach the child-process listener/callback instead
|
|
486
|
+
// of crashing callers that did not subscribe to broker diagnostics.
|
|
487
|
+
if (this.listenerCount("error") > 0) this.emit("error", auditEntry);
|
|
413
488
|
});
|
|
414
489
|
return proc;
|
|
415
490
|
}
|
|
@@ -435,7 +510,7 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
435
510
|
origin,
|
|
436
511
|
scope,
|
|
437
512
|
command,
|
|
438
|
-
args: args
|
|
513
|
+
args: this._sanitizeAuditArgs(args),
|
|
439
514
|
cwd,
|
|
440
515
|
startTime,
|
|
441
516
|
permissionDecision: decision,
|
|
@@ -443,6 +518,9 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
443
518
|
isDangerous,
|
|
444
519
|
shell: !!options.shell,
|
|
445
520
|
sync: true,
|
|
521
|
+
pluginId: options.pluginId || null,
|
|
522
|
+
pluginVersion: options.pluginVersion || null,
|
|
523
|
+
pluginSource: options.pluginSource || null,
|
|
446
524
|
};
|
|
447
525
|
|
|
448
526
|
if (decision === "deny" || decision === "prompt") {
|
|
@@ -471,20 +549,17 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
471
549
|
}
|
|
472
550
|
|
|
473
551
|
// P0-1: Credential filtering agent — strip secrets from env/args before spawn
|
|
474
|
-
if (this.
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
`Credential agent apply failed: ${credErr.message}`,
|
|
486
|
-
);
|
|
487
|
-
}
|
|
552
|
+
if (this._credentialBoundaryEnabled()) {
|
|
553
|
+
const credentialBoundary = this._applyCredentialBoundary(
|
|
554
|
+
command,
|
|
555
|
+
args,
|
|
556
|
+
spawnOpts,
|
|
557
|
+
origin,
|
|
558
|
+
);
|
|
559
|
+
spawnOpts.env = credentialBoundary.env;
|
|
560
|
+
args = credentialBoundary.args;
|
|
561
|
+
auditEntry.args = [...args];
|
|
562
|
+
this._recordCredentialReport(auditEntry, credentialBoundary.report);
|
|
488
563
|
}
|
|
489
564
|
|
|
490
565
|
// P0-1: Platform sandbox wrapping (sync path)
|
|
@@ -523,9 +598,9 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
523
598
|
}
|
|
524
599
|
}
|
|
525
600
|
|
|
526
|
-
const
|
|
601
|
+
const nativeSpawnSyncFn = this._native?.spawnSync || nativeSpawnSync;
|
|
527
602
|
try {
|
|
528
|
-
const result =
|
|
603
|
+
const result = nativeSpawnSyncFn(command, args, optsForSync);
|
|
529
604
|
auditEntry.exitCode = result.status;
|
|
530
605
|
auditEntry.endTime = Date.now();
|
|
531
606
|
auditEntry.durationMs = auditEntry.endTime - startTime;
|
|
@@ -542,6 +617,94 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
542
617
|
}
|
|
543
618
|
}
|
|
544
619
|
|
|
620
|
+
/**
|
|
621
|
+
* Route a node-pty session through the same provenance and credential
|
|
622
|
+
* boundary as child_process execution. node-pty owns the native PTY
|
|
623
|
+
* allocation, so the platform sandbox is reported as unavailable here
|
|
624
|
+
* rather than being falsely marked as applied.
|
|
625
|
+
*/
|
|
626
|
+
spawnPty(ptyModule, command, args = [], options = {}) {
|
|
627
|
+
if (!ptyModule || typeof ptyModule.spawn !== "function") {
|
|
628
|
+
throw new TypeError("pty_module_spawn_unavailable");
|
|
629
|
+
}
|
|
630
|
+
const executionId = crypto.randomUUID();
|
|
631
|
+
const startTime = Date.now();
|
|
632
|
+
const origin = options.origin || "terminal:pty";
|
|
633
|
+
const scope = options.scope || "terminal";
|
|
634
|
+
const policy = options.policy || "allow";
|
|
635
|
+
const auditEntry = {
|
|
636
|
+
executionId,
|
|
637
|
+
traceId: this._getTraceContext()?.traceId || null,
|
|
638
|
+
origin,
|
|
639
|
+
scope,
|
|
640
|
+
command,
|
|
641
|
+
args: this._sanitizeAuditArgs(args),
|
|
642
|
+
cwd: options.cwd || process.cwd(),
|
|
643
|
+
startTime,
|
|
644
|
+
permissionDecision: policy,
|
|
645
|
+
policy,
|
|
646
|
+
operation: "pty.spawn",
|
|
647
|
+
pty: true,
|
|
648
|
+
sandboxed: false,
|
|
649
|
+
sandboxReason: "native_pty_host_boundary",
|
|
650
|
+
pluginId: options.pluginId || null,
|
|
651
|
+
pluginVersion: options.pluginVersion || null,
|
|
652
|
+
pluginSource: options.pluginSource || null,
|
|
653
|
+
};
|
|
654
|
+
if (policy === "deny" || policy === "prompt") {
|
|
655
|
+
auditEntry.deniedReason = `policy_${policy}`;
|
|
656
|
+
auditEntry.endTime = Date.now();
|
|
657
|
+
auditEntry.durationMs = 0;
|
|
658
|
+
this._recordAudit(auditEntry);
|
|
659
|
+
this._writeRplEntry(
|
|
660
|
+
auditEntry,
|
|
661
|
+
"denied",
|
|
662
|
+
new Error(auditEntry.deniedReason),
|
|
663
|
+
);
|
|
664
|
+
const error = new Error(`PTY spawn denied: ${auditEntry.deniedReason}`);
|
|
665
|
+
error.auditEntry = auditEntry;
|
|
666
|
+
throw error;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
const spawnOptions = { ...options, args: [...auditEntry.args] };
|
|
670
|
+
delete spawnOptions.origin;
|
|
671
|
+
delete spawnOptions.policy;
|
|
672
|
+
delete spawnOptions.scope;
|
|
673
|
+
delete spawnOptions.pluginId;
|
|
674
|
+
delete spawnOptions.pluginVersion;
|
|
675
|
+
delete spawnOptions.pluginSource;
|
|
676
|
+
try {
|
|
677
|
+
if (this._credentialBoundaryEnabled()) {
|
|
678
|
+
const credentialBoundary = this._applyCredentialBoundary(
|
|
679
|
+
command,
|
|
680
|
+
args,
|
|
681
|
+
spawnOptions,
|
|
682
|
+
origin,
|
|
683
|
+
);
|
|
684
|
+
spawnOptions.env = credentialBoundary.env;
|
|
685
|
+
spawnOptions.args = credentialBoundary.args;
|
|
686
|
+
auditEntry.args = [...credentialBoundary.args];
|
|
687
|
+
this._recordCredentialReport(auditEntry, credentialBoundary.report);
|
|
688
|
+
}
|
|
689
|
+
const filteredArgs = spawnOptions.args || [];
|
|
690
|
+
delete spawnOptions.args;
|
|
691
|
+
const proc = ptyModule.spawn(command, filteredArgs, spawnOptions);
|
|
692
|
+
auditEntry.pid = proc?.pid ?? null;
|
|
693
|
+
auditEntry.endTime = Date.now();
|
|
694
|
+
auditEntry.durationMs = auditEntry.endTime - startTime;
|
|
695
|
+
this._recordAudit(auditEntry);
|
|
696
|
+
this._writeRplEntry(auditEntry, "started");
|
|
697
|
+
return proc;
|
|
698
|
+
} catch (error) {
|
|
699
|
+
auditEntry.error = error.message;
|
|
700
|
+
auditEntry.endTime = Date.now();
|
|
701
|
+
auditEntry.durationMs = auditEntry.endTime - startTime;
|
|
702
|
+
this._recordAudit(auditEntry);
|
|
703
|
+
this._writeRplEntry(auditEntry, "error", error);
|
|
704
|
+
throw error;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
545
708
|
exec(command, options, callback) {
|
|
546
709
|
const opts = typeof options === "function" ? {} : options;
|
|
547
710
|
const cb = typeof options === "function" ? options : callback;
|
|
@@ -558,15 +721,129 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
558
721
|
shell: true,
|
|
559
722
|
origin: options.origin || "shell:execSync",
|
|
560
723
|
};
|
|
561
|
-
|
|
724
|
+
const result = this.spawnSync(command, [], spawnOpts);
|
|
725
|
+
if (result?.error) throw result.error;
|
|
726
|
+
if (result?.status != null && result.status !== 0) {
|
|
727
|
+
const error = new Error(
|
|
728
|
+
`Command failed (exit ${result.status}): ${command}`,
|
|
729
|
+
);
|
|
730
|
+
error.status = result.status;
|
|
731
|
+
error.stdout = result.stdout;
|
|
732
|
+
error.stderr = result.stderr;
|
|
733
|
+
throw error;
|
|
734
|
+
}
|
|
735
|
+
return result?.stdout ?? "";
|
|
562
736
|
}
|
|
563
737
|
|
|
564
738
|
execFile(file, args, options, callback) {
|
|
565
|
-
|
|
739
|
+
if (typeof args === "function") {
|
|
740
|
+
callback = args;
|
|
741
|
+
args = [];
|
|
742
|
+
options = {};
|
|
743
|
+
} else if (!Array.isArray(args)) {
|
|
744
|
+
callback = typeof options === "function" ? options : callback;
|
|
745
|
+
options = args || {};
|
|
746
|
+
args = [];
|
|
747
|
+
} else if (typeof options === "function") {
|
|
748
|
+
callback = options;
|
|
749
|
+
options = {};
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
options = options || {};
|
|
753
|
+
const proc = this.spawn(file, args, options);
|
|
754
|
+
if (typeof callback !== "function") return proc;
|
|
755
|
+
|
|
756
|
+
const stdoutChunks = [];
|
|
757
|
+
const stderrChunks = [];
|
|
758
|
+
const outputEncoding = options.encoding ?? "utf8";
|
|
759
|
+
const returnBuffers =
|
|
760
|
+
outputEncoding === "buffer" || outputEncoding === null;
|
|
761
|
+
const configuredMaxBuffer = options.maxBuffer;
|
|
762
|
+
const maxBuffer =
|
|
763
|
+
configuredMaxBuffer === Infinity
|
|
764
|
+
? Infinity
|
|
765
|
+
: Number.isFinite(configuredMaxBuffer) && configuredMaxBuffer >= 0
|
|
766
|
+
? configuredMaxBuffer
|
|
767
|
+
: 1024 * 1024;
|
|
768
|
+
let stdoutBytes = 0;
|
|
769
|
+
let stderrBytes = 0;
|
|
770
|
+
let completionError = null;
|
|
771
|
+
let completed = false;
|
|
772
|
+
|
|
773
|
+
const asBuffer = (chunk) =>
|
|
774
|
+
Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
|
|
775
|
+
const render = (chunks) => {
|
|
776
|
+
const value = Buffer.concat(chunks);
|
|
777
|
+
return returnBuffers ? value : value.toString(outputEncoding);
|
|
778
|
+
};
|
|
779
|
+
const finish = (error, code = null, signal = null) => {
|
|
780
|
+
if (completed) return;
|
|
781
|
+
completed = true;
|
|
782
|
+
const stdout = render(stdoutChunks);
|
|
783
|
+
const stderr = render(stderrChunks);
|
|
784
|
+
if (error) {
|
|
785
|
+
error.stdout = stdout;
|
|
786
|
+
error.stderr = stderr;
|
|
787
|
+
if (error.status === undefined) error.status = code;
|
|
788
|
+
if (error.signal === undefined) error.signal = signal;
|
|
789
|
+
}
|
|
790
|
+
callback(error, stdout, stderr);
|
|
791
|
+
};
|
|
792
|
+
const collect = (stream, chunks, streamName) => {
|
|
793
|
+
if (!stream || typeof stream.on !== "function") return;
|
|
794
|
+
stream.on("data", (chunk) => {
|
|
795
|
+
const value = asBuffer(chunk);
|
|
796
|
+
chunks.push(value);
|
|
797
|
+
if (streamName === "stdout") stdoutBytes += value.length;
|
|
798
|
+
else stderrBytes += value.length;
|
|
799
|
+
const streamBytes = streamName === "stdout" ? stdoutBytes : stderrBytes;
|
|
800
|
+
if (!completionError && streamBytes > maxBuffer) {
|
|
801
|
+
completionError = new Error(`${streamName} maxBuffer exceeded`);
|
|
802
|
+
completionError.code = "ERR_CHILD_PROCESS_STDIO_MAXBUFFER";
|
|
803
|
+
completionError.stream = streamName;
|
|
804
|
+
try {
|
|
805
|
+
proc.kill(options.killSignal || "SIGTERM");
|
|
806
|
+
} catch {}
|
|
807
|
+
}
|
|
808
|
+
});
|
|
809
|
+
};
|
|
810
|
+
|
|
811
|
+
collect(proc.stdout, stdoutChunks, "stdout");
|
|
812
|
+
collect(proc.stderr, stderrChunks, "stderr");
|
|
813
|
+
proc.once("error", (error) => finish(error));
|
|
814
|
+
proc.once("close", (code, signal) => {
|
|
815
|
+
if (completionError) return finish(completionError, code, signal);
|
|
816
|
+
if (code === 0) return finish(null, code, signal);
|
|
817
|
+
const error = new Error(
|
|
818
|
+
`Command failed (exit ${code ?? "unknown"}): ${file}`,
|
|
819
|
+
);
|
|
820
|
+
error.code = code;
|
|
821
|
+
error.killed = Boolean(proc.killed);
|
|
822
|
+
error.signal = signal;
|
|
823
|
+
error.status = code;
|
|
824
|
+
return finish(error, code, signal);
|
|
825
|
+
});
|
|
826
|
+
return proc;
|
|
566
827
|
}
|
|
567
828
|
|
|
568
829
|
execFileSync(file, args, options = {}) {
|
|
569
|
-
|
|
830
|
+
if (!Array.isArray(args)) {
|
|
831
|
+
options = args || {};
|
|
832
|
+
args = [];
|
|
833
|
+
}
|
|
834
|
+
const result = this.spawnSync(file, args, options);
|
|
835
|
+
if (result?.error) throw result.error;
|
|
836
|
+
if (result?.status !== 0) {
|
|
837
|
+
const error = new Error(
|
|
838
|
+
`Command failed (exit ${result?.status ?? "unknown"}): ${file}`,
|
|
839
|
+
);
|
|
840
|
+
error.status = result?.status ?? null;
|
|
841
|
+
error.signal = result?.signal ?? null;
|
|
842
|
+
error.stdout = result?.stdout;
|
|
843
|
+
error.stderr = result?.stderr;
|
|
844
|
+
throw error;
|
|
845
|
+
}
|
|
846
|
+
return result?.stdout ?? "";
|
|
570
847
|
}
|
|
571
848
|
|
|
572
849
|
fork(modulePath, args, options = {}) {
|
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
* This runs at CLI startup, before any other imports, ensuring every subprocess is audited
|
|
4
4
|
*/
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
|
-
|
|
6
|
+
import { executionBroker } from "./index.js";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
const { executionBroker } = require("./index.js");
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
10
9
|
|
|
11
10
|
// Get the REAL native child_process module (unpatched, from Node.js internals)
|
|
12
11
|
const nativeCp = require("node:child_process");
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { spawn, execSync } from "node:child_process";
|
|
2
1
|
import {
|
|
3
2
|
readFileSync,
|
|
4
3
|
writeFileSync,
|
|
@@ -10,6 +9,12 @@ import { join } from "node:path";
|
|
|
10
9
|
import { getPidFilePath, getBinDir, ensureDir, getStatePath } from "./paths.js";
|
|
11
10
|
import { isWindows } from "./platform.js";
|
|
12
11
|
import logger from "./logger.js";
|
|
12
|
+
import { executionBroker } from "./process-execution-broker/index.js";
|
|
13
|
+
|
|
14
|
+
export const _deps = {
|
|
15
|
+
spawn: (...args) => executionBroker.spawn(...args),
|
|
16
|
+
execFileSync: (...args) => executionBroker.execFileSync(...args),
|
|
17
|
+
};
|
|
13
18
|
|
|
14
19
|
export function startApp(options = {}) {
|
|
15
20
|
ensureDir(getStatePath());
|
|
@@ -44,10 +49,14 @@ export function startApp(options = {}) {
|
|
|
44
49
|
|
|
45
50
|
logger.verbose(`Starting: ${appPath} ${args.join(" ")}`);
|
|
46
51
|
|
|
47
|
-
const child = spawn(appPath, args, {
|
|
52
|
+
const child = _deps.spawn(appPath, args, {
|
|
48
53
|
detached: true,
|
|
49
54
|
stdio: "ignore",
|
|
50
55
|
env: { ...process.env, ...options.env },
|
|
56
|
+
origin: "app:start",
|
|
57
|
+
policy: "allow",
|
|
58
|
+
scope: "app",
|
|
59
|
+
shell: false,
|
|
51
60
|
});
|
|
52
61
|
|
|
53
62
|
child.unref();
|
|
@@ -90,7 +99,13 @@ export function stopApp() {
|
|
|
90
99
|
|
|
91
100
|
try {
|
|
92
101
|
if (isWindows()) {
|
|
93
|
-
|
|
102
|
+
_deps.execFileSync("taskkill", ["/PID", String(pid), "/T", "/F"], {
|
|
103
|
+
stdio: "ignore",
|
|
104
|
+
origin: "app:stop",
|
|
105
|
+
policy: "allow",
|
|
106
|
+
scope: "app",
|
|
107
|
+
shell: false,
|
|
108
|
+
});
|
|
94
109
|
} else {
|
|
95
110
|
process.kill(pid, "SIGTERM");
|
|
96
111
|
}
|
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
* @module lib/publish-workspace
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import executionBroker from "./process-execution-broker/index.js";
|
|
8
8
|
import { logger } from "./logger.js";
|
|
9
9
|
import path from "path";
|
|
10
10
|
import fs from "fs";
|
|
11
11
|
|
|
12
|
+
export const _deps = {
|
|
13
|
+
execFileSync: (...args) => executionBroker.execFileSync(...args),
|
|
14
|
+
};
|
|
15
|
+
|
|
12
16
|
/**
|
|
13
17
|
* Get all workspace packages
|
|
14
18
|
* @returns {Array<{name: string, path: string, version: string}>}
|
|
@@ -60,16 +64,20 @@ export function getWorkspacePackages() {
|
|
|
60
64
|
export function publishPackage(pkg, options = {}) {
|
|
61
65
|
try {
|
|
62
66
|
logger.info(`Publishing ${pkg.name}@${pkg.version}...`);
|
|
63
|
-
|
|
64
|
-
if (options.tag)
|
|
65
|
-
if (options.access)
|
|
67
|
+
const args = ["publish"];
|
|
68
|
+
if (options.tag) args.push("--tag", String(options.tag));
|
|
69
|
+
if (options.access) args.push("--access", String(options.access));
|
|
66
70
|
|
|
67
|
-
|
|
71
|
+
_deps.execFileSync("npm", args, {
|
|
72
|
+
origin: "publish-workspace:npm",
|
|
73
|
+
scope: "publish",
|
|
74
|
+
policy: "allow",
|
|
75
|
+
shell: false,
|
|
68
76
|
cwd: pkg.path,
|
|
69
77
|
stdio: "inherit",
|
|
70
78
|
encoding: "utf8",
|
|
71
79
|
});
|
|
72
|
-
logger.
|
|
80
|
+
logger.success(`Published ${pkg.name}@${pkg.version}`);
|
|
73
81
|
return true;
|
|
74
82
|
} catch (err) {
|
|
75
83
|
logger.error(`Failed to publish ${pkg.name}: ${err.message}`);
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
* All process/fs access goes through `_deps` for tests.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { spawnSync as spawnSyncDefault } from "child_process";
|
|
21
20
|
import fsDefault from "fs";
|
|
22
21
|
import pathDefault from "path";
|
|
23
22
|
import { findProjectRoot } from "./project-instructions.js";
|
|
23
|
+
import executionBroker from "./process-execution-broker/index.js";
|
|
24
24
|
|
|
25
25
|
export const BANG_TIMEOUT_MS = 120_000;
|
|
26
26
|
export const BANG_MAX_BUFFER = 10 * 1024 * 1024;
|
|
@@ -32,7 +32,7 @@ export const BANG_OUTPUT_CAP = 30_000;
|
|
|
32
32
|
export const MEMO_NOTE_MAX = 4_000;
|
|
33
33
|
|
|
34
34
|
export const _deps = {
|
|
35
|
-
spawnSync:
|
|
35
|
+
spawnSync: (...args) => executionBroker.spawnSync(...args),
|
|
36
36
|
fs: fsDefault,
|
|
37
37
|
path: pathDefault,
|
|
38
38
|
};
|
|
@@ -83,12 +83,20 @@ export function runBangCommand(line, opts = {}) {
|
|
|
83
83
|
timeout: BANG_TIMEOUT_MS,
|
|
84
84
|
maxBuffer: BANG_MAX_BUFFER,
|
|
85
85
|
cwd,
|
|
86
|
+
origin: "repl:bang-command",
|
|
87
|
+
policy: "allow",
|
|
88
|
+
scope: "repl",
|
|
89
|
+
shell: false,
|
|
86
90
|
})
|
|
87
91
|
: spawnSync("/bin/sh", ["-c", cmd], {
|
|
88
92
|
encoding: "utf-8",
|
|
89
93
|
timeout: BANG_TIMEOUT_MS,
|
|
90
94
|
maxBuffer: BANG_MAX_BUFFER,
|
|
91
95
|
cwd,
|
|
96
|
+
origin: "repl:bang-command",
|
|
97
|
+
policy: "allow",
|
|
98
|
+
scope: "repl",
|
|
99
|
+
shell: false,
|
|
92
100
|
});
|
|
93
101
|
|
|
94
102
|
const exitCode = res.status == null ? (res.error ? -1 : 0) : res.status;
|
package/src/lib/repl-goal.js
CHANGED
|
@@ -19,6 +19,23 @@ import {
|
|
|
19
19
|
GoalConditionEngine,
|
|
20
20
|
GOAL_DECISION,
|
|
21
21
|
} from "./goal-condition-engine.js";
|
|
22
|
+
import executionBroker from "./process-execution-broker/index.js";
|
|
23
|
+
|
|
24
|
+
const brokerRunner = executionBroker.spawnSync.bind(executionBroker);
|
|
25
|
+
|
|
26
|
+
export const _processDeps = {
|
|
27
|
+
run: brokerRunner,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function runReplGoalCommand(command, options = {}) {
|
|
31
|
+
return _processDeps.run(command, [], {
|
|
32
|
+
...options,
|
|
33
|
+
timeout: options.timeout ?? 30000,
|
|
34
|
+
origin: "repl-goal:exit-zero",
|
|
35
|
+
policy: "allow",
|
|
36
|
+
scope: "repl-goal",
|
|
37
|
+
});
|
|
38
|
+
}
|
|
22
39
|
|
|
23
40
|
// Interactive sessions are human-paced, so the turn-count budget is generous —
|
|
24
41
|
// it exists only as a backstop (the engine hard-caps at 100 regardless). The
|
|
@@ -94,7 +111,7 @@ export function renderGoalVerdict(decision, events) {
|
|
|
94
111
|
/**
|
|
95
112
|
* Evaluate the session goal against a completed turn's final text. Deterministic
|
|
96
113
|
* conditions run inline (contains/regex on the text; exit-zero/file-exists via
|
|
97
|
-
* injected
|
|
114
|
+
* injected process runner/`existsSync`); a model condition delegates to `judge`.
|
|
98
115
|
*
|
|
99
116
|
* @param {GoalConditionEngine} engine
|
|
100
117
|
* @param {string} finalText the assistant's answer this turn
|
|
@@ -110,7 +127,7 @@ export async function evaluateReplGoalTurn(engine, finalText, deps = {}) {
|
|
|
110
127
|
evaluation = runDeterministicCheck(cond, {
|
|
111
128
|
lastOutput: finalText,
|
|
112
129
|
cwd: deps.cwd,
|
|
113
|
-
spawnSync: deps.spawnSync,
|
|
130
|
+
spawnSync: deps.spawnSync || runReplGoalCommand,
|
|
114
131
|
existsSync: deps.existsSync,
|
|
115
132
|
});
|
|
116
133
|
} else if (typeof deps.judge === "function") {
|