chainlesschain 0.162.176 → 0.162.178
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 +10 -0
- package/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-BDLu5Elz.js → AIOps-DRftcSue.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DH5us-CK.js → ActionButton-BFvUaMKR.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BZ0u8IFG.js → Analytics-C0-Rru4P.js} +3 -3
- package/src/assets/web-panel/assets/AppLayout-bx-BCljj.js +9 -0
- package/src/assets/web-panel/assets/{Artifacts-Br2YBbh_.js → Artifacts-DAJ8B3Un.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-C3C6a482.js → Audit-hOk4L1lr.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-CzHvebcj.js → BackgroundAgents-3pbDpM9z.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DZNHYDFd.js → Backup-BtziGDn9.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-VRiC4fIx.js → BaseInput-kmshphJ3.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-Cm08WWAD.js → Chat-d7tGSosA.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CGHYrugQ.js → ChatBubbleRenderer-p-_PBpX_.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-DtByk7d7.js → Checkbox-C4Eh4Tz5.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CphXXOfD.js → Codegen-r7gmhZyA.js} +1 -1
- package/src/assets/web-panel/assets/{Col-Hz86TnLR.js → Col-U7mDaGlL.js} +1 -1
- package/src/assets/web-panel/assets/{Community-HP03ltpD.js → Community-Bpu8aH1T.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-B_N1mqQz.js → Compact-CHb2XBJe.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CVztRpi8.js → Compliance-Cn_r4dey.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-wUVOyZih.js → Cowork-CdMWfDcz.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-DW5TLJKw.js → Cron-BtnREHWy.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CrAFGhWH.js → Crosschain-BKI9TSzr.js} +1 -1
- package/src/assets/web-panel/assets/{DID-pA-oD8ke.js → DID-pkNubzzJ.js} +2 -2
- package/src/assets/web-panel/assets/Dashboard-1rrz1snN.js +3 -0
- package/src/assets/web-panel/assets/{Dropdown-EweJcsek.js → Dropdown-DLyFVxDc.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-C9xVLPG4.js → EmailListRenderer-CtUWfYVq.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-CDcEEqlu.js → FamilyGuardDashboard-B8eX2Qe4.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DtZda9A_.js → Federation-D8lsDGus.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CiYdcVz3.js → FormItemContext-CRYt_aIw.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DA13uwA0.js → GenericCardRenderer-ClKzY8_N.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DzRhZD1O.js → Git-BXj5Dney.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-D5RMgOSb.js → Governance-Cm-I8RMz.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BgrPfSNk.js → Inference-CPvbhvgt.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DzjnD571.js → KnowledgeGraph-sYNDZaoi.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BhWzVDtN.js → Logs-BZY_3CRZ.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-BDape9cx.js → MarkdownRenderer-up0BW6pv.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-DJtL5GV7.js → Marketplace-C5MEJ2Qe.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CZcQygI7.js → McpTools-ihdrn43I.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-DUWSDUUu.js → Memory-Br8bPMlh.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BTwq2WKY.js → MobileBridge-BNntgrYW.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-BdV915mw.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-BiGugEQm.js → Mtc-A3wDmlqL.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-DY7a6gUe.js → MtcAudit-CF-mBLWM.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-BQbDu_w7.js → Multisig-Iy2k_MSo.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CM2wXTLv.js → NLProgramming-kk0W7HUb.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DI6gGs1v.js → Notes-B5u5t_4S.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-BsZOLWAB.js → NotificationSettings-BN0POf6_.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-CHkSUrXB.js +1 -0
- package/src/assets/web-panel/assets/{Organization-Cds0_tXr.js → Organization-DwWQESuN.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-WunYMD87.js → Overflow-DG6klrcC.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Bo6j4DDv.js → P2P-BwJcKkgZ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-Bh2XPD5f.js → PdhVaultBrowser-BwOHG0in.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-EMvMMC8N.js → Permissions-CGMXe4TX.js} +4 -4
- package/src/assets/web-panel/assets/PersonalDataHub-ziYqg7-A.js +8 -0
- package/src/assets/web-panel/assets/{Pipeline-BOx8HOgL.js → Pipeline-BzJfeoGt.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-tBeTVQVM.js → Privacy-DLh3Bblx.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CVYg1W4M.js → ProjectInit-USVWW36c.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Dvt5I7y1.js → ProjectSettings-CiiOn62h.js} +2 -2
- package/src/assets/web-panel/assets/Projects-6V-PNmcA.js +1 -0
- package/src/assets/web-panel/assets/{Providers-Ct8xqY-E.js → Providers-CBPWWzpu.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Cni8Ooja.js → QrScannerModal-QVwoRUq3.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BJVLKdxr.js → QuickAsk-CXnR-2Vn.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DPG8Rbbm.js → Recommend-ClaNzjmF.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DsdR7dCt.js → RemoteSession-C3rGw8vJ.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-Csg1YM-b.js → Reputation-Ci-OWAoP.js} +1 -1
- package/src/assets/web-panel/assets/{Row-D9DoFoEf.js → Row-DRhAwXOS.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BsvKrXMS.js → RssFeed-BQLJQ2_y.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DFUStfgQ.js → Search-QQUpkfFd.js} +1 -1
- package/src/assets/web-panel/assets/{Security-ILg1zxdK.js → Security-DdXKzuKT.js} +4 -4
- package/src/assets/web-panel/assets/{Services-Dd41PCaY.js → Services-x2Zh62Qd.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-Bzo1cN80.js → Skeleton-GdY4KwRz.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BDHh17P0.js → Skills-Bv4tY1Fd.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-jl7UTiRY.js → Sla-C3QnM-11.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BePa-RF6.js → SpeechSettings-Bl3ytvmI.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DiqqDKGZ.js → SyncSettings-Wp9IwTsP.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DYQ_6lxj.js → Tasks-CF3rIrDe.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-JiDeI06L.js → Templates-CGfvVVM9.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-hhgI6zwS.js → Tenant-CVXmwQ3U.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-bvwrt03E.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-B8uB5Llk.js → TimelineRenderer-D0g74KhH.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-C3b_6r2z.js → Tokens-BH4IwzlT.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-tIP7HKVe.js → Trigger-DJOpM533.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-vjoc11vJ.js → Trust-B43EPRLr.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DUPBnGuH.js → UkeySign-BmBFG-em.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CBvhUY5T.js → VideoEditing-n9oJwB8k.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-DUaQ0uA5.js → Wallet-D5QeivHp.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DllSivjE.js → WebAuthn-DcNy7igO.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-xc8D3uO6.js → WorkflowEditor-BVjc7-5-.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BVicU7oA.js → chat-Dy5Tfj3m.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DJzLmhLm.js → colors-C4c2CNZU.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BvYRfThE.js → compact-item-DPa3O5vN.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DGXxCBKR.js → createContext-TLcfNA6_.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BAwdDA_5.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-SBDJB1y4.js → hasIn-D41LVFkp.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7HimK0M.js → index-0oevYjfT.js} +1 -1
- package/src/assets/web-panel/assets/{index-DCdRAgjy.js → index-388pLGJ1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BO1itZaY.js → index-B8nLBZbv.js} +3 -3
- package/src/assets/web-panel/assets/{index-DvUTDYXX.js → index-BPTGAjee.js} +1 -1
- package/src/assets/web-panel/assets/{index-hxTODbM1.js → index-BPtrOBmW.js} +1 -1
- package/src/assets/web-panel/assets/{index-wcCL-miV.js → index-BQiIxHBy.js} +1 -1
- package/src/assets/web-panel/assets/{index-CKyEivf8.js → index-BSM1cHVK.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJZf9DhV.js → index-BYPr9fkz.js} +1 -1
- package/src/assets/web-panel/assets/{index-DHVLJ8q0.js → index-BsQ7Ev6i.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cs2rmLFt.js → index-Btk9qLL2.js} +1 -1
- package/src/assets/web-panel/assets/{index-z1ZylsLq.js → index-BvmziZSG.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf-O_g_8.js → index-BvopLC_T.js} +1 -1
- package/src/assets/web-panel/assets/{index-DMarmfrv.js → index-C7xhTVyP.js} +1 -1
- package/src/assets/web-panel/assets/{index-CoJAO1Lm.js → index-CNk_ZooP.js} +1 -1
- package/src/assets/web-panel/assets/{index-9gdI7uUW.js → index-CQrEHoOG.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bf-ctERC.js → index-CSxex23J.js} +1 -1
- package/src/assets/web-panel/assets/{index-MjC4G09d.js → index-CVjgm992.js} +1 -1
- package/src/assets/web-panel/assets/{index-e4fXH_WO.js → index-CWK4zOPe.js} +1 -1
- package/src/assets/web-panel/assets/{index-xfluRkCT.js → index-CX0VsoP4.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRfiXB_p.js → index-CXl0YPNG.js} +1 -1
- package/src/assets/web-panel/assets/{index-d5BVd-cL.js → index-Cip7LWml.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dm_77jgR.js → index-Cq_hlWNt.js} +1 -1
- package/src/assets/web-panel/assets/{index-YJkzy8ZF.js → index-CzZ49YZL.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtwqO5qo.js → index-D2Nkivlm.js} +1 -1
- package/src/assets/web-panel/assets/{index-BYqz4Wrr.js → index-DBUgRs4D.js} +1 -1
- package/src/assets/web-panel/assets/index-DEjVkdzq.js +1 -0
- package/src/assets/web-panel/assets/{index-CdGY9P8a.js → index-DNsBj2Ob.js} +1 -1
- package/src/assets/web-panel/assets/{index-DonCnfMr.js → index-Di4X8cfI.js} +1 -1
- package/src/assets/web-panel/assets/{index-1SdDS6lR.js → index-DljFsVGI.js} +1 -1
- package/src/assets/web-panel/assets/{index-DnjPdvR6.js → index-Korc3QIe.js} +1 -1
- package/src/assets/web-panel/assets/index-LMOc5xrS.js +1 -0
- package/src/assets/web-panel/assets/{index-VMfwIH5G.js → index-MKZDje0H.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKrvvWm4.js → index-OHAfRu_3.js} +1 -1
- package/src/assets/web-panel/assets/{index-FxZzRyE1.js → index-WEJr8PL5.js} +1 -1
- package/src/assets/web-panel/assets/{index-Crk5NTb0.js → index-WinCp6du.js} +1 -1
- package/src/assets/web-panel/assets/{index-DCqRS6da.js → index-Yjr6cqSK.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTrBGBJs.js → index-iQ6gtFih.js} +1 -1
- package/src/assets/web-panel/assets/{index-lpaGoTH3.js → index-pt3s7yvV.js} +1 -1
- package/src/assets/web-panel/assets/{index-CloCgBUR.js → index-tQ3igERQ.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-C1zO1KnY.js → initDefaultProps-BFZu87WZ.js} +1 -1
- package/src/assets/web-panel/assets/{motion-CWLtEGmC.js → motion-DJIo7qvt.js} +1 -1
- package/src/assets/web-panel/assets/{move-DzD_C3Vm.js → move-Cfr5qknL.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-D880PYJl.js → mtc-parser-Bgc-OadH.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CFR_z2ov.js → omit-X3WI-TNp.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-srIhgrSC.js → pickAttrs-pJhU9IxK.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-C1rXpibP.js → placementArrow-BNg_Vj3T.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-C30gRcSS.js → responsiveObserve-TeSEGQ5-.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CvtKiMfV.js → slide-D_t_P0bv.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DNHO7ITG.js → statusUtils-DrrIMwAT.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Dt_Sl-g4.js → styleChecker-BjZCuFRm.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Cjev42Gh.js → useFlexGapSupport-rTFdlqdQ.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Baxglj2V.js → useFs-BidCpfLX.js} +1 -1
- package/src/assets/web-panel/assets/usePersonalDataHub-C5mHttA9.js +1 -0
- package/src/assets/web-panel/assets/{vnode-mIRkdT7o.js → vnode-BrbcRiHZ.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-HzI5DlH_.js → zoom-PISX7AkR.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/__tests__/hub-wechat.test.js +45 -0
- package/src/commands/agenda.js +22 -6
- package/src/commands/agent.js +3 -3
- package/src/commands/background-session.js +16 -6
- package/src/commands/batch.js +79 -27
- package/src/commands/changelog.js +15 -4
- package/src/commands/context.js +33 -1
- package/src/commands/eval.js +21 -6
- package/src/commands/hook.js +2 -2
- package/src/commands/hub.js +473 -39
- package/src/commands/init.js +212 -110
- package/src/commands/llm.js +22 -6
- package/src/commands/loop.js +9 -2
- package/src/commands/skill.js +13 -1
- package/src/commands/statusline.js +3 -3
- package/src/data/changelog.json +53 -5
- package/src/gateways/ws/personal-data-hub-protocol.js +22 -2
- package/src/harness/background-task-manager.js +18 -6
- package/src/harness/background-task-worker.js +11 -18
- package/src/harness/golden-transcript.js +3 -0
- package/src/harness/mcp-client.js +9 -15
- package/src/harness/worktree-isolator.js +18 -21
- package/src/index.js +18 -7
- package/src/lib/agent-core.js +5 -0
- package/src/lib/agent-ipc-bus.js +12 -3
- package/src/lib/agent-team/team-worktree.js +28 -6
- package/src/lib/agent-worktree.js +20 -19
- package/src/lib/approval-authority-store.js +891 -0
- package/src/lib/async-hook-supervisor.cjs +134 -24
- package/src/lib/async-hook-supervisor.js +47 -0
- package/src/lib/background-agent-supervisor.js +35 -12
- package/src/lib/background-interaction-resolver.js +399 -54
- package/src/lib/background-session-transport.js +3 -1
- package/src/lib/background-task-manager.js +5 -1
- package/src/lib/changelog.js +57 -0
- 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/context-breakdown.js +82 -3
- package/src/lib/doctor-checkup.js +18 -6
- package/src/lib/eval/tasks.js +25 -31
- package/src/lib/event-runtime-host.js +225 -0
- package/src/lib/event-runtime-store.js +102 -21
- package/src/lib/event-runtime-worker.js +70 -2
- package/src/lib/hook-runner.cjs +71 -36
- package/src/lib/hook-runner.js +55 -0
- package/src/lib/hooks-v2-producers.js +33 -8
- package/src/lib/hooks-v2-runtime.js +360 -40
- package/src/lib/host-adb-bridge.js +18 -3
- package/src/lib/interaction-adapter.js +66 -0
- 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/benchmark.js +20 -4
- package/src/lib/lsp/lsp-client.js +6 -4
- package/src/lib/lsp/lsp-server-registry.js +0 -2
- package/src/lib/operation-fingerprint.js +107 -2
- package/src/lib/orchestrator.js +8 -2
- package/src/lib/packer/pack-update-applier.js +14 -2
- package/src/lib/packer/smoke-runner.js +18 -5
- package/src/lib/paths.js +1 -1
- package/src/lib/pdh-dedicated-batch-collectors.js +124 -0
- package/src/lib/personal-data-hub-wiring.js +327 -52
- package/src/lib/plugin-monitor-supervisor.js +20 -13
- package/src/lib/plugin-runtime/install.js +10 -3
- package/src/lib/process-execution-broker/credential-agent.js +954 -111
- package/src/lib/process-execution-broker/index.js +369 -85
- package/src/lib/process-execution-broker/platform-sandbox.js +320 -140
- package/src/lib/provider-http-error.js +94 -0
- package/src/lib/remote-approval-bridge.js +222 -26
- package/src/lib/repl-bang-memorize.js +10 -2
- package/src/lib/repl-goal.js +19 -2
- package/src/lib/settings-hook-events.cjs +13 -8
- package/src/lib/settings-hook-events.js +20 -0
- package/src/lib/side-effect-ledger-store.js +65 -14
- package/src/lib/skill-loader.js +215 -12
- package/src/lib/skill-packs/generator.js +18 -9
- package/src/lib/skill-process-broker.js +85 -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 +42 -0
- package/src/lib/turn-binding-store.js +64 -15
- package/src/lib/turn-binding.js +85 -16
- package/src/repl/agent-repl.js +88 -49
- package/src/repl/remote-approval.js +13 -13
- package/src/repl/repl-turn-binding.js +46 -16
- package/src/runtime/agent-core.js +419 -84
- package/src/runtime/coding-agent-contract-shared.cjs +16 -0
- package/src/runtime/headless-runner.js +172 -44
- package/src/runtime/headless-stream.js +221 -11
- 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 +76 -40
- package/src/assets/web-panel/assets/AppLayout-Duu8xR14.js +0 -9
- package/src/assets/web-panel/assets/Dashboard-CXrd5gAw.js +0 -3
- package/src/assets/web-panel/assets/MobileProjects-NZvvfDME.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-C48mu09U.js +0 -1
- package/src/assets/web-panel/assets/PersonalDataHub-AX3ypUDV.js +0 -9
- package/src/assets/web-panel/assets/Projects-Cc7FC9-e.js +0 -1
- package/src/assets/web-panel/assets/Terminal-CjTZPa37.js +0 -3
- package/src/assets/web-panel/assets/devWarning-BT46Y_QI.js +0 -1
- package/src/assets/web-panel/assets/index-B7nuIywP.js +0 -1
- package/src/assets/web-panel/assets/index-ycwAfC-i.js +0 -1
- package/src/assets/web-panel/assets/usePersonalDataHub-B4NkcLaP.js +0 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider HTTP error parsing shared by agent/chat streaming and `cc llm test`.
|
|
3
|
+
* Keep structured provider diagnostics while redacting credential-shaped text.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
function safePart(value) {
|
|
7
|
+
if (value == null) return "";
|
|
8
|
+
return String(value)
|
|
9
|
+
.replace(/\s+/g, " ")
|
|
10
|
+
.replace(/\b(Bearer\s+)[A-Za-z0-9._~+/-]+=*\b/gi, "$1***")
|
|
11
|
+
.replace(/\bsk-[A-Za-z0-9_-]{8,}\b/gi, "sk-***")
|
|
12
|
+
.trim()
|
|
13
|
+
.slice(0, 400);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function errorDetail(payload) {
|
|
17
|
+
if (payload == null) return { code: "", message: "" };
|
|
18
|
+
const raw =
|
|
19
|
+
typeof payload === "object" && payload.error != null
|
|
20
|
+
? payload.error
|
|
21
|
+
: payload;
|
|
22
|
+
if (typeof raw === "string") {
|
|
23
|
+
return { code: "", message: safePart(raw) };
|
|
24
|
+
}
|
|
25
|
+
if (!raw || typeof raw !== "object") {
|
|
26
|
+
return { code: "", message: safePart(raw) };
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
code: safePart(raw.code || raw.type),
|
|
30
|
+
message: safePart(raw.message || raw.error_description || raw.detail),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A 403 is not necessarily a bad key: providers also use it for overdue
|
|
36
|
+
* accounts and model-access denials. Preserve the safe code/message so clients
|
|
37
|
+
* can show the real corrective action.
|
|
38
|
+
*/
|
|
39
|
+
export function formatProviderHttpError(provider, status, payload = null) {
|
|
40
|
+
const base = `${provider} API error: HTTP ${status}`;
|
|
41
|
+
const detail = errorDetail(payload);
|
|
42
|
+
const detailText = [detail.code, detail.message].filter(Boolean).join(": ");
|
|
43
|
+
const detailSentence = detailText.replace(/[.!?]+$/, "");
|
|
44
|
+
const classified = `${detail.code} ${detail.message}`.toLowerCase();
|
|
45
|
+
const authDetail =
|
|
46
|
+
/unauthori[sz]ed|authentication|invalid.*api[\s_-]*key|api[\s_-]*key.*invalid|incorrect.*api[\s_-]*key|missing.*api[\s_-]*key/.test(
|
|
47
|
+
classified,
|
|
48
|
+
);
|
|
49
|
+
const billingDetail =
|
|
50
|
+
/account.?overdue|overdue balance|insufficient.*balance|billing|payment required/.test(
|
|
51
|
+
classified,
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (status === 401 || (status === 403 && authDetail)) {
|
|
55
|
+
return (
|
|
56
|
+
`${base} — authentication failed: the API key for provider "${provider}" ` +
|
|
57
|
+
`is missing or invalid. Check "cc config get llm.provider" and ` +
|
|
58
|
+
`"cc config get llm.apiKey" (or run Configure LLM).` +
|
|
59
|
+
(detailSentence ? ` Provider response: ${detailSentence}.` : "")
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
if (status === 403 && billingDetail) {
|
|
63
|
+
return (
|
|
64
|
+
`${base} — ${detailSentence || "the provider account cannot be billed"}. ` +
|
|
65
|
+
"Check the provider account balance/billing status, then retry."
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
if (status === 403) {
|
|
69
|
+
return (
|
|
70
|
+
`${base} — access forbidden` +
|
|
71
|
+
(detailSentence ? `: ${detailSentence}` : "") +
|
|
72
|
+
". Check the API key, model access permissions, and account status/balance."
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (status === 429) return `${base} — rate limited; please retry shortly.`;
|
|
76
|
+
return detailSentence ? `${base} — ${detailSentence}` : base;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function formatProviderResponseError(provider, response) {
|
|
80
|
+
let payload = null;
|
|
81
|
+
try {
|
|
82
|
+
const text = await response.text();
|
|
83
|
+
if (text) {
|
|
84
|
+
try {
|
|
85
|
+
payload = JSON.parse(text);
|
|
86
|
+
} catch {
|
|
87
|
+
payload = text;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} catch {
|
|
91
|
+
// A broken/empty body still retains the HTTP status diagnosis.
|
|
92
|
+
}
|
|
93
|
+
return formatProviderHttpError(provider, response.status, payload);
|
|
94
|
+
}
|
|
@@ -23,10 +23,12 @@
|
|
|
23
23
|
|
|
24
24
|
import { randomBytes } from "crypto";
|
|
25
25
|
import { WsRpcClient } from "./ws-rpc-client.js";
|
|
26
|
+
import { ORIGIN, approvalBindingDigest } from "./agent-authority.js";
|
|
26
27
|
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
} from "./
|
|
28
|
+
ApprovalAuthorityStore,
|
|
29
|
+
defaultApprovalAuthorityStatePath,
|
|
30
|
+
} from "./approval-authority-store.js";
|
|
31
|
+
import { OperationApprovalRegistry } from "./operation-fingerprint.js";
|
|
30
32
|
import {
|
|
31
33
|
buildDirectPairingUri,
|
|
32
34
|
pickLanAddress,
|
|
@@ -46,6 +48,9 @@ export class RemoteApprovalBridge {
|
|
|
46
48
|
decisionTimeoutMs = DEFAULT_DECISION_TIMEOUT_MS,
|
|
47
49
|
createClient = null,
|
|
48
50
|
now = Date.now,
|
|
51
|
+
approvalStore = undefined,
|
|
52
|
+
approvalStateFile = null,
|
|
53
|
+
onSecurityError = null,
|
|
49
54
|
} = {}) {
|
|
50
55
|
if (!wsUrl) throw new Error("wsUrl is required");
|
|
51
56
|
if (!agentSessionId) throw new Error("agentSessionId is required");
|
|
@@ -63,12 +68,65 @@ export class RemoteApprovalBridge {
|
|
|
63
68
|
this._pending = new Map(); // requestId → { resolve, timer, fingerprint }
|
|
64
69
|
this._counter = 0;
|
|
65
70
|
this._closed = false;
|
|
71
|
+
this._securityErrors = [];
|
|
72
|
+
this._onSecurityError =
|
|
73
|
+
typeof onSecurityError === "function" ? onSecurityError : null;
|
|
74
|
+
const durableStore =
|
|
75
|
+
approvalStore === undefined
|
|
76
|
+
? new ApprovalAuthorityStore({
|
|
77
|
+
filePath:
|
|
78
|
+
approvalStateFile ||
|
|
79
|
+
defaultApprovalAuthorityStatePath(agentSessionId),
|
|
80
|
+
now: () => this._now(),
|
|
81
|
+
})
|
|
82
|
+
: approvalStore;
|
|
83
|
+
if (
|
|
84
|
+
!durableStore ||
|
|
85
|
+
typeof durableStore.issueRequest !== "function" ||
|
|
86
|
+
typeof durableStore.resolveRequest !== "function" ||
|
|
87
|
+
typeof durableStore.cancelRequest !== "function"
|
|
88
|
+
) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
"approvalStore must implement issueRequest/resolveRequest/cancelRequest",
|
|
91
|
+
);
|
|
92
|
+
}
|
|
66
93
|
// §8.2 cross-device approval registry: full-tuple operation fingerprints,
|
|
67
94
|
// single-winner across concurrent cards for one logical operation, at-most-
|
|
68
95
|
// once resolution, and validity-window enforcement — all fail-closed.
|
|
69
96
|
this._registry = new OperationApprovalRegistry({
|
|
70
97
|
clock: () => this._now(),
|
|
98
|
+
store: durableStore,
|
|
71
99
|
});
|
|
100
|
+
this._approvalStore = durableStore;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
_recordSecurityError({ action, requestId = null, reason, errorCode = null }) {
|
|
104
|
+
const entry = {
|
|
105
|
+
timestamp: this._now(),
|
|
106
|
+
action: String(action || "approval"),
|
|
107
|
+
requestId: requestId ? String(requestId) : null,
|
|
108
|
+
reason: String(reason || "rejected"),
|
|
109
|
+
errorCode: errorCode ? String(errorCode) : null,
|
|
110
|
+
};
|
|
111
|
+
this._securityErrors.push(entry);
|
|
112
|
+
if (this._securityErrors.length > 1000) this._securityErrors.shift();
|
|
113
|
+
if (this._onSecurityError) {
|
|
114
|
+
try {
|
|
115
|
+
this._onSecurityError({ ...entry });
|
|
116
|
+
} catch {
|
|
117
|
+
// Observability is advisory; the approval remains denied.
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return entry;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
getSecurityErrors(limit = this._securityErrors.length) {
|
|
124
|
+
const count = Math.max(
|
|
125
|
+
0,
|
|
126
|
+
Math.min(Math.floor(Number(limit) || 0), this._securityErrors.length),
|
|
127
|
+
);
|
|
128
|
+
if (count === 0) return [];
|
|
129
|
+
return this._securityErrors.slice(-count).map((entry) => ({ ...entry }));
|
|
72
130
|
}
|
|
73
131
|
|
|
74
132
|
/** Connect, register the client-hosted remote session, start listening. */
|
|
@@ -123,34 +181,76 @@ export class RemoteApprovalBridge {
|
|
|
123
181
|
const requestId = message.event.requestId || message.event.approvalId;
|
|
124
182
|
const pending = requestId ? this._pending.get(requestId) : null;
|
|
125
183
|
if (!pending) return;
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
184
|
+
// The device must echo the complete durable capability tuple. Missing,
|
|
185
|
+
// mismatched, stale, duplicate, or expired resolutions never settle an
|
|
186
|
+
// approval; only the store's successful CAS can return approved=true.
|
|
187
|
+
const rawAnswer = message.event.answer ?? message.event.approved;
|
|
188
|
+
const hasDecision =
|
|
189
|
+
rawAnswer === true ||
|
|
190
|
+
rawAnswer === false ||
|
|
191
|
+
rawAnswer === "true" ||
|
|
192
|
+
rawAnswer === "false" ||
|
|
193
|
+
rawAnswer === "yes" ||
|
|
194
|
+
rawAnswer === "no";
|
|
195
|
+
if (!hasDecision) {
|
|
196
|
+
this._recordSecurityError({
|
|
197
|
+
action: "approval.resolve",
|
|
198
|
+
requestId,
|
|
199
|
+
reason: "decision-required",
|
|
200
|
+
});
|
|
135
201
|
return;
|
|
136
202
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
203
|
+
const decision =
|
|
204
|
+
rawAnswer === true || rawAnswer === "true" || rawAnswer === "yes";
|
|
205
|
+
const authority = {
|
|
206
|
+
origin: ORIGIN.REMOTE,
|
|
207
|
+
authenticated: true,
|
|
208
|
+
scopes: ["approve"],
|
|
209
|
+
principalId: message.from || "paired-device",
|
|
210
|
+
sessionId: this.agentSessionId,
|
|
211
|
+
};
|
|
140
212
|
const verdict = this._registry.resolve(pending.fingerprint, {
|
|
213
|
+
requestId,
|
|
214
|
+
fingerprint: message.event.fingerprint,
|
|
215
|
+
binding: message.event.binding,
|
|
216
|
+
sessionId: this.agentSessionId,
|
|
217
|
+
decision,
|
|
218
|
+
authority,
|
|
219
|
+
expectedRevision: message.event.revision,
|
|
141
220
|
now: this._now(),
|
|
142
221
|
});
|
|
143
|
-
if (!verdict.ok)
|
|
222
|
+
if (!verdict.ok) {
|
|
223
|
+
this._recordSecurityError({
|
|
224
|
+
action: "approval.resolve",
|
|
225
|
+
requestId,
|
|
226
|
+
reason: verdict.reason,
|
|
227
|
+
errorCode: verdict.errorCode,
|
|
228
|
+
});
|
|
229
|
+
if (verdict.reason === "state-unavailable") {
|
|
230
|
+
this._settleDeniedForStateFailure(requestId, pending, verdict);
|
|
231
|
+
}
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
144
234
|
this._pending.delete(requestId);
|
|
145
235
|
clearTimeout(pending.timer);
|
|
146
|
-
const answer = message.event.answer ?? message.event.approved;
|
|
147
236
|
pending.resolve({
|
|
148
|
-
approved:
|
|
237
|
+
approved: verdict.ok === true && verdict.approved === true,
|
|
149
238
|
via: "remote",
|
|
150
239
|
from: message.from || null,
|
|
151
240
|
});
|
|
152
241
|
}
|
|
153
242
|
|
|
243
|
+
_settleDeniedForStateFailure(requestId, pending, verdict) {
|
|
244
|
+
this._pending.delete(requestId);
|
|
245
|
+
clearTimeout(pending.timer);
|
|
246
|
+
pending.resolve({
|
|
247
|
+
approved: false,
|
|
248
|
+
via: "state-error",
|
|
249
|
+
from: null,
|
|
250
|
+
errorCode: verdict?.errorCode || null,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
154
254
|
/** Number of devices that can approve (excludes this host). */
|
|
155
255
|
async approverCount() {
|
|
156
256
|
try {
|
|
@@ -202,7 +302,42 @@ export class RemoteApprovalBridge {
|
|
|
202
302
|
? askedAt + effectiveTimeout
|
|
203
303
|
: null,
|
|
204
304
|
};
|
|
205
|
-
const
|
|
305
|
+
const binding = approvalBindingDigest({
|
|
306
|
+
toolCallId: requestId,
|
|
307
|
+
args: {
|
|
308
|
+
tool: tool || null,
|
|
309
|
+
action,
|
|
310
|
+
detail,
|
|
311
|
+
workspace,
|
|
312
|
+
session: desc.session,
|
|
313
|
+
targetEnv,
|
|
314
|
+
},
|
|
315
|
+
policyDigest: policyVersion,
|
|
316
|
+
});
|
|
317
|
+
let card;
|
|
318
|
+
try {
|
|
319
|
+
// Persist first. A card that was not durably issued must never become
|
|
320
|
+
// visible to a device and can therefore never authorize a side effect.
|
|
321
|
+
card = this._registry.issue(desc, {
|
|
322
|
+
requestId,
|
|
323
|
+
binding,
|
|
324
|
+
now: askedAt,
|
|
325
|
+
});
|
|
326
|
+
} catch (error) {
|
|
327
|
+
const errorCode = error?.code || "CC_APPROVAL_STATE_UNKNOWN";
|
|
328
|
+
this._recordSecurityError({
|
|
329
|
+
action: "approval.request",
|
|
330
|
+
requestId,
|
|
331
|
+
reason: "state-unavailable",
|
|
332
|
+
errorCode,
|
|
333
|
+
});
|
|
334
|
+
return Promise.resolve({
|
|
335
|
+
approved: false,
|
|
336
|
+
via: "state-error",
|
|
337
|
+
from: null,
|
|
338
|
+
errorCode,
|
|
339
|
+
});
|
|
340
|
+
}
|
|
206
341
|
if (onRequestId) {
|
|
207
342
|
try {
|
|
208
343
|
onRequestId(requestId);
|
|
@@ -212,6 +347,20 @@ export class RemoteApprovalBridge {
|
|
|
212
347
|
}
|
|
213
348
|
return new Promise((resolve) => {
|
|
214
349
|
const timer = setTimeout(() => {
|
|
350
|
+
const verdict = this._registry.cancel(card.fingerprint, {
|
|
351
|
+
requestId,
|
|
352
|
+
expectedRevision: card.revision,
|
|
353
|
+
reason: "timeout",
|
|
354
|
+
now: this._now(),
|
|
355
|
+
});
|
|
356
|
+
if (!verdict.ok) {
|
|
357
|
+
this._recordSecurityError({
|
|
358
|
+
action: "approval.cancel",
|
|
359
|
+
requestId,
|
|
360
|
+
reason: verdict.reason,
|
|
361
|
+
errorCode: verdict.errorCode,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
215
364
|
this._pending.delete(requestId);
|
|
216
365
|
this._publish({
|
|
217
366
|
type: "permission.resolved",
|
|
@@ -225,6 +374,8 @@ export class RemoteApprovalBridge {
|
|
|
225
374
|
this._pending.set(requestId, {
|
|
226
375
|
timer,
|
|
227
376
|
fingerprint: card.fingerprint,
|
|
377
|
+
binding,
|
|
378
|
+
revision: card.revision,
|
|
228
379
|
resolve: (decision) => {
|
|
229
380
|
this._publish({
|
|
230
381
|
type: "permission.resolved",
|
|
@@ -244,6 +395,8 @@ export class RemoteApprovalBridge {
|
|
|
244
395
|
// Full fingerprint (protocol) + short id / secret-free summary (what the
|
|
245
396
|
// operator eyeballs on the device to confirm it is the SAME card).
|
|
246
397
|
fingerprint: card.fingerprint,
|
|
398
|
+
binding,
|
|
399
|
+
revision: card.revision,
|
|
247
400
|
shortId: card.shortId,
|
|
248
401
|
summary: card.summary,
|
|
249
402
|
notBefore: desc.notBefore,
|
|
@@ -257,12 +410,39 @@ export class RemoteApprovalBridge {
|
|
|
257
410
|
resolveLocally(requestId, approved) {
|
|
258
411
|
const pending = this._pending.get(requestId);
|
|
259
412
|
if (!pending) return false;
|
|
413
|
+
const verdict = this._registry.resolve(pending.fingerprint, {
|
|
414
|
+
requestId,
|
|
415
|
+
fingerprint: pending.fingerprint,
|
|
416
|
+
binding: pending.binding,
|
|
417
|
+
sessionId: this.agentSessionId,
|
|
418
|
+
decision: approved === true,
|
|
419
|
+
authority: {
|
|
420
|
+
origin: ORIGIN.USER,
|
|
421
|
+
principalId: "local-terminal",
|
|
422
|
+
sessionId: this.agentSessionId,
|
|
423
|
+
},
|
|
424
|
+
expectedRevision: pending.revision,
|
|
425
|
+
now: this._now(),
|
|
426
|
+
});
|
|
427
|
+
if (!verdict.ok) {
|
|
428
|
+
this._recordSecurityError({
|
|
429
|
+
action: "approval.resolve",
|
|
430
|
+
requestId,
|
|
431
|
+
reason: verdict.reason,
|
|
432
|
+
errorCode: verdict.errorCode,
|
|
433
|
+
});
|
|
434
|
+
if (verdict.reason === "state-unavailable") {
|
|
435
|
+
this._settleDeniedForStateFailure(requestId, pending, verdict);
|
|
436
|
+
}
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
260
439
|
this._pending.delete(requestId);
|
|
261
440
|
clearTimeout(pending.timer);
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
441
|
+
pending.resolve({
|
|
442
|
+
approved: verdict.ok === true && verdict.approved === true,
|
|
443
|
+
via: "local",
|
|
444
|
+
from: null,
|
|
445
|
+
});
|
|
266
446
|
return true;
|
|
267
447
|
}
|
|
268
448
|
|
|
@@ -327,10 +507,12 @@ export class RemoteApprovalBridge {
|
|
|
327
507
|
const decision = await Promise.race([remote, local]);
|
|
328
508
|
// Local answer won → settle the remote ask too (publishes
|
|
329
509
|
// permission.resolved so device UIs clear the pending card).
|
|
330
|
-
if (decision.via === "local"
|
|
331
|
-
|
|
510
|
+
if (decision.via === "local") {
|
|
511
|
+
if (!requestId) return false;
|
|
512
|
+
const persisted = this.resolveLocally(requestId, decision.approved);
|
|
513
|
+
return persisted && decision.approved === true;
|
|
332
514
|
}
|
|
333
|
-
return decision.approved;
|
|
515
|
+
return decision.approved === true;
|
|
334
516
|
};
|
|
335
517
|
}
|
|
336
518
|
|
|
@@ -338,6 +520,20 @@ export class RemoteApprovalBridge {
|
|
|
338
520
|
this._closed = true;
|
|
339
521
|
for (const [requestId, pending] of this._pending) {
|
|
340
522
|
clearTimeout(pending.timer);
|
|
523
|
+
const verdict = this._registry.cancel(pending.fingerprint, {
|
|
524
|
+
requestId,
|
|
525
|
+
expectedRevision: pending.revision,
|
|
526
|
+
reason: "closed",
|
|
527
|
+
now: this._now(),
|
|
528
|
+
});
|
|
529
|
+
if (!verdict.ok) {
|
|
530
|
+
this._recordSecurityError({
|
|
531
|
+
action: "approval.cancel",
|
|
532
|
+
requestId,
|
|
533
|
+
reason: verdict.reason,
|
|
534
|
+
errorCode: verdict.errorCode,
|
|
535
|
+
});
|
|
536
|
+
}
|
|
341
537
|
pending.resolve({ approved: false, via: "closed", from: null });
|
|
342
538
|
this._pending.delete(requestId);
|
|
343
539
|
}
|
|
@@ -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") {
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
const { collectHooks } = require("./settings-hooks.cjs");
|
|
20
|
-
const
|
|
20
|
+
const hookRunner = require("./hook-runner.cjs");
|
|
21
|
+
const _deps = { runHooks: hookRunner.runHooks };
|
|
21
22
|
const { buildHookEnvelope } = require("./hook-event-bus.cjs");
|
|
22
23
|
const hookEventLog = require("./hook-event-log.cjs");
|
|
23
24
|
|
|
@@ -143,7 +144,7 @@ function runUserPromptSubmitHooks(
|
|
|
143
144
|
},
|
|
144
145
|
{ sessionId },
|
|
145
146
|
);
|
|
146
|
-
const outcome = runHooks(sync, payload, {
|
|
147
|
+
const outcome = _deps.runHooks(sync, payload, {
|
|
147
148
|
cwd,
|
|
148
149
|
event: "UserPromptSubmit",
|
|
149
150
|
});
|
|
@@ -211,7 +212,10 @@ function runSessionStartHooks(settingsHooks, { source, cwd, sessionId } = {}) {
|
|
|
211
212
|
},
|
|
212
213
|
{ sessionId },
|
|
213
214
|
);
|
|
214
|
-
const outcome = runHooks(matched, payload, {
|
|
215
|
+
const outcome = _deps.runHooks(matched, payload, {
|
|
216
|
+
cwd,
|
|
217
|
+
event: "SessionStart",
|
|
218
|
+
});
|
|
215
219
|
return { additionalContext: aggregateContext(outcome.results) };
|
|
216
220
|
}
|
|
217
221
|
|
|
@@ -247,7 +251,7 @@ function runCwdChangedHooks(
|
|
|
247
251
|
},
|
|
248
252
|
{ sessionId },
|
|
249
253
|
);
|
|
250
|
-
const outcome = runHooks(sync, payload, {
|
|
254
|
+
const outcome = _deps.runHooks(sync, payload, {
|
|
251
255
|
cwd: newCwd || cwd,
|
|
252
256
|
event: "CwdChanged",
|
|
253
257
|
});
|
|
@@ -291,7 +295,7 @@ function runWorktreeCreateHooks(
|
|
|
291
295
|
},
|
|
292
296
|
{ sessionId },
|
|
293
297
|
);
|
|
294
|
-
const outcome = runHooks(sync, payload, {
|
|
298
|
+
const outcome = _deps.runHooks(sync, payload, {
|
|
295
299
|
cwd: cwd || worktreePath,
|
|
296
300
|
event: "WorktreeCreate",
|
|
297
301
|
});
|
|
@@ -337,7 +341,7 @@ function runWorktreeRemoveHooks(
|
|
|
337
341
|
},
|
|
338
342
|
{ sessionId },
|
|
339
343
|
);
|
|
340
|
-
const outcome = runHooks(sync, payload, {
|
|
344
|
+
const outcome = _deps.runHooks(sync, payload, {
|
|
341
345
|
cwd: cwd || worktreePath,
|
|
342
346
|
event: "WorktreeRemove",
|
|
343
347
|
});
|
|
@@ -386,7 +390,7 @@ function runInstructionsLoadedHooks(
|
|
|
386
390
|
},
|
|
387
391
|
{ sessionId },
|
|
388
392
|
);
|
|
389
|
-
const outcome = runHooks(sync, payload, {
|
|
393
|
+
const outcome = _deps.runHooks(sync, payload, {
|
|
390
394
|
cwd,
|
|
391
395
|
event: "InstructionsLoaded",
|
|
392
396
|
});
|
|
@@ -417,7 +421,7 @@ function runObserveHooks(
|
|
|
417
421
|
const matched = collectHooks(settingsHooks, event, matchTarget || "");
|
|
418
422
|
const { sync } = partitionAsyncHooks(matched);
|
|
419
423
|
if (sync.length === 0) return { decision: "continue", results: [] };
|
|
420
|
-
return runHooks(
|
|
424
|
+
return _deps.runHooks(
|
|
421
425
|
sync,
|
|
422
426
|
withDeliveryId(
|
|
423
427
|
event,
|
|
@@ -440,4 +444,5 @@ module.exports = {
|
|
|
440
444
|
aggregateContext,
|
|
441
445
|
partitionAsyncHooks,
|
|
442
446
|
dispatchAsyncHooks,
|
|
447
|
+
_deps,
|
|
443
448
|
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { runHooks } from "./hook-runner.js";
|
|
2
|
+
import events from "./settings-hook-events.cjs";
|
|
3
|
+
|
|
4
|
+
events._deps.runHooks = runHooks;
|
|
5
|
+
|
|
6
|
+
export const {
|
|
7
|
+
withDeliveryId,
|
|
8
|
+
runUserPromptSubmitHooks,
|
|
9
|
+
runSessionStartHooks,
|
|
10
|
+
runCwdChangedHooks,
|
|
11
|
+
runWorktreeCreateHooks,
|
|
12
|
+
runWorktreeRemoveHooks,
|
|
13
|
+
runInstructionsLoadedHooks,
|
|
14
|
+
runObserveHooks,
|
|
15
|
+
aggregateContext,
|
|
16
|
+
partitionAsyncHooks,
|
|
17
|
+
dispatchAsyncHooks,
|
|
18
|
+
} = events;
|
|
19
|
+
|
|
20
|
+
export default events;
|