chainlesschain 0.162.174 → 0.162.176
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-Dcl-X1Hw.js → AIOps-BDLu5Elz.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-ClMh9HzT.js → ActionButton-DH5us-CK.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DPj0rSQ5.js → Analytics-BZ0u8IFG.js} +3 -3
- package/src/assets/web-panel/assets/AppLayout-Duu8xR14.js +9 -0
- package/src/assets/web-panel/assets/{Artifacts-L8781rE8.js → Artifacts-Br2YBbh_.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CffB6WIP.js → Audit-C3C6a482.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BkLhayyY.js → BackgroundAgents-CzHvebcj.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BQnwFI78.js → Backup-DZNHYDFd.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-xuUGHQch.js → BaseInput-VRiC4fIx.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-feQXwWrg.js → Chat-Cm08WWAD.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-CGHYrugQ.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-DVaIiUGW.js → Checkbox-DtByk7d7.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-D2kEnzeU.js → Codegen-CphXXOfD.js} +1 -1
- package/src/assets/web-panel/assets/{Col-azDoyusS.js → Col-Hz86TnLR.js} +1 -1
- package/src/assets/web-panel/assets/{Community-OZdnPWM5.js → Community-HP03ltpD.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-VDMvBN-C.js → Compact-B_N1mqQz.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CPJ_zgQ1.js → Compliance-CVztRpi8.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-iRBwcsOA.js → Cowork-wUVOyZih.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-DrxrspUz.js → Cron-DW5TLJKw.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-D-rkAZXF.js → Crosschain-CrAFGhWH.js} +1 -1
- package/src/assets/web-panel/assets/{DID-5Pp1Xnmr.js → DID-pA-oD8ke.js} +2 -2
- package/src/assets/web-panel/assets/Dashboard-CXrd5gAw.js +3 -0
- package/src/assets/web-panel/assets/{Dropdown-BWj_E0Ie.js → Dropdown-EweJcsek.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BT-wgSEh.js → EmailListRenderer-C9xVLPG4.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-1PzH23pa.js → FamilyGuardDashboard-CDcEEqlu.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BxMIXGC6.js → Federation-DtZda9A_.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CyJobBln.js → FormItemContext-CiYdcVz3.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-YkjFuQTN.js → GenericCardRenderer-DA13uwA0.js} +1 -1
- package/src/assets/web-panel/assets/{Git-C2a98Wp_.js → Git-DzRhZD1O.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DKL3Fl84.js → Governance-D5RMgOSb.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BJ2cQC_3.js → Inference-BgrPfSNk.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DBAsOngt.js → KnowledgeGraph-DzjnD571.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-COt8g9LO.js → Logs-BhWzVDtN.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-3Lfht1Fd.js → MarkdownRenderer-BDape9cx.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-C9Zk9Pb2.js → Marketplace-DJtL5GV7.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DDWDFWPO.js → McpTools-CZcQygI7.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-BRmVye_o.js → Memory-DUWSDUUu.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CppBbWpD.js → MobileBridge-BTwq2WKY.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-NZvvfDME.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-CcWpeGa6.js → Mtc-BiGugEQm.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-BcllEq0K.js → MtcAudit-DY7a6gUe.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BFD1CarL.js → Multisig-BQbDu_w7.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-QNXXYvjz.js → NLProgramming-CM2wXTLv.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-07YwgQVy.js → Notes-DI6gGs1v.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-bOccEInE.js → NotificationSettings-BsZOLWAB.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DlRi29WL.js → OrderTableRenderer-C48mu09U.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CBaezzEr.js → Organization-Cds0_tXr.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Bl5NohFO.js → Overflow-WunYMD87.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CLMal9Aw.js → P2P-Bo6j4DDv.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CGO0NITk.js → PdhVaultBrowser-Bh2XPD5f.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-CPSw48E2.js → Permissions-EMvMMC8N.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-CDM5n134.js → PersonalDataHub-AX3ypUDV.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-BdsqG7WV.js → Pipeline-BOx8HOgL.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-B6L4E-M7.js → Privacy-tBeTVQVM.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-DXPyZKRs.js → ProjectInit-CVYg1W4M.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BrCC3xYT.js → ProjectSettings-Dvt5I7y1.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BYmuHC2q.js → Projects-Cc7FC9-e.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-CbCe2eUl.js → Providers-Ct8xqY-E.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-DkukgCrR.js → QrScannerModal-Cni8Ooja.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-D-htOrV8.js → QuickAsk-BJVLKdxr.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Bm7SIfzu.js → Recommend-DPG8Rbbm.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-C9rP-iMc.js → RemoteSession-DsdR7dCt.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-kGlUgbsl.js → Reputation-Csg1YM-b.js} +1 -1
- package/src/assets/web-panel/assets/{Row-PBupbbUA.js → Row-D9DoFoEf.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-njlwKUGK.js → RssFeed-BsvKrXMS.js} +2 -2
- package/src/assets/web-panel/assets/{Search-DLdEmgBw.js → Search-DFUStfgQ.js} +1 -1
- package/src/assets/web-panel/assets/{Security-SXGPSHdu.js → Security-ILg1zxdK.js} +4 -4
- package/src/assets/web-panel/assets/{Services-CuFGnNsb.js → Services-Dd41PCaY.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CtUC0mDa.js → Skeleton-Bzo1cN80.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-P1qgOVFn.js → Skills-BDHh17P0.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CsppE8YV.js → Sla-jl7UTiRY.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Cq1oG56m.js → SpeechSettings-BePa-RF6.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DdKW6V-C.js → SyncSettings-DiqqDKGZ.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BCc9san5.js → Tasks-DYQ_6lxj.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CcHC1dMA.js → Templates-JiDeI06L.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CA4PqU22.js → Tenant-hhgI6zwS.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-CjTZPa37.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-DHWTSvOy.js → TimelineRenderer-B8uB5Llk.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-Ddz-P_yh.js → Tokens-C3b_6r2z.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-ePmrmLZ1.js → Trigger-tIP7HKVe.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DmuK1CCE.js → Trust-vjoc11vJ.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CqqBuRrT.js → UkeySign-DUPBnGuH.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BGlR3uWM.js → VideoEditing-CBvhUY5T.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Ba_Qx6Ga.js → Wallet-DUaQ0uA5.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-29neXKt2.js → WebAuthn-DllSivjE.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-lD0lR0UQ.js → WorkflowEditor-xc8D3uO6.js} +1 -1
- package/src/assets/web-panel/assets/{chat-B3stH01u.js → chat-BVicU7oA.js} +1 -1
- package/src/assets/web-panel/assets/{colors-Czly56MN.js → colors-DJzLmhLm.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-C0TkbkAJ.js → compact-item-BvYRfThE.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BJmpSlf1.js → createContext-DGXxCBKR.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BT46Y_QI.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-D1q-zw7u.js → hasIn-SBDJB1y4.js} +1 -1
- package/src/assets/web-panel/assets/{index-DV-twjNO.js → index-1SdDS6lR.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-kTvMq7.js → index-9gdI7uUW.js} +1 -1
- package/src/assets/web-panel/assets/index-B7nuIywP.js +1 -0
- package/src/assets/web-panel/assets/{index-Bm_-RKal.js → index-BJZf9DhV.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQftlZn-.js → index-BO1itZaY.js} +3 -3
- package/src/assets/web-panel/assets/{index-Dw3L_smW.js → index-BTrBGBJs.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7sFKQ53.js → index-BYqz4Wrr.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlvsSuBC.js → index-Bf-ctERC.js} +1 -1
- package/src/assets/web-panel/assets/{index-ChESIe5r.js → index-CKyEivf8.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaqEHaCg.js → index-CdGY9P8a.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZeoKL6t.js → index-Cf-O_g_8.js} +1 -1
- package/src/assets/web-panel/assets/{index-XWV8JWMc.js → index-CloCgBUR.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpMIdPJ0.js → index-CoJAO1Lm.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgS8XUBU.js → index-Crk5NTb0.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmUta2lw.js → index-Cs2rmLFt.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dpz_7sf-.js → index-CtwqO5qo.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRcQsPez.js → index-D7HimK0M.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEt2-3x5.js → index-DCdRAgjy.js} +1 -1
- package/src/assets/web-panel/assets/{index-CHvPlzWJ.js → index-DCqRS6da.js} +1 -1
- package/src/assets/web-panel/assets/{index-BDHXx65P.js → index-DHVLJ8q0.js} +1 -1
- package/src/assets/web-panel/assets/{index-K4YaPDOn.js → index-DKrvvWm4.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1pOqU7D.js → index-DMarmfrv.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAhrn9EJ.js → index-DRfiXB_p.js} +1 -1
- package/src/assets/web-panel/assets/{index-cPjWjvmW.js → index-Dm_77jgR.js} +1 -1
- package/src/assets/web-panel/assets/{index-C27TnOoT.js → index-DnjPdvR6.js} +1 -1
- package/src/assets/web-panel/assets/{index-upY9rkGZ.js → index-DonCnfMr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbvNJUwu.js → index-DvUTDYXX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVwJ3jht.js → index-FxZzRyE1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DIF6XHIi.js → index-MjC4G09d.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8KqsomG.js → index-VMfwIH5G.js} +1 -1
- package/src/assets/web-panel/assets/{index-8GKykbS4.js → index-YJkzy8ZF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpGs96FC.js → index-d5BVd-cL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DO8xOwxi.js → index-e4fXH_WO.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cu_4HaUS.js → index-hxTODbM1.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf7Gr3NG.js → index-lpaGoTH3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBqAm8es.js → index-wcCL-miV.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZDUhX41Z.js → index-xfluRkCT.js} +1 -1
- package/src/assets/web-panel/assets/index-ycwAfC-i.js +1 -0
- package/src/assets/web-panel/assets/{index-z8ATo2aQ.js → index-z1ZylsLq.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-QWEXi6-t.js → initDefaultProps-C1zO1KnY.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BfrQwvV1.js → motion-CWLtEGmC.js} +1 -1
- package/src/assets/web-panel/assets/{move-Dn7x0H9t.js → move-DzD_C3Vm.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-F61D_TgE.js → mtc-parser-D880PYJl.js} +1 -1
- package/src/assets/web-panel/assets/{omit-4SQZ39PF.js → omit-CFR_z2ov.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-C7DTe126.js → pickAttrs-srIhgrSC.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-40NeyzDK.js → placementArrow-C1rXpibP.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BiUJ6qWs.js → responsiveObserve-C30gRcSS.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CacJTM3f.js → slide-CvtKiMfV.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-K812HB-k.js → statusUtils-DNHO7ITG.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CKeHA2eM.js → styleChecker-Dt_Sl-g4.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CKl4FqXF.js → useFlexGapSupport-Cjev42Gh.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DPoiJjSZ.js → useFs-Baxglj2V.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-aHwBspmt.js → usePersonalDataHub-B4NkcLaP.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DrA-GuCT.js → vnode-mIRkdT7o.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-G3LMswgy.js → zoom-HzI5DlH_.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 +64 -2
- package/src/commands/agent.js +45 -3
- package/src/commands/background-session.js +103 -0
- package/src/commands/config.js +70 -5
- package/src/commands/context.js +36 -2
- package/src/commands/hub.js +19 -1
- 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/team.js +20 -7
- package/src/commands/update.js +65 -10
- package/src/esm-bridge.js +3 -0
- 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 +92 -4
- package/src/harness/jsonl-session-store.js +13 -6
- package/src/harness/mcp-client.js +200 -1
- package/src/index.js +123 -55
- package/src/lazy-dispatch.js +86 -85
- 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-ipc-bus.js +32 -2
- package/src/lib/agent-sandbox.js +16 -2
- package/src/lib/agent-schedule-store.js +55 -0
- package/src/lib/agent-tool-admission.js +104 -0
- package/src/lib/api-key-helper.js +10 -2
- package/src/lib/async-hook-supervisor.cjs +26 -4
- package/src/lib/background-interaction-resolver.js +71 -0
- package/src/lib/background-session-transport.js +59 -1
- package/src/lib/changelog.js +19 -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/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/crash-reporter.js +6 -0
- package/src/lib/diff-review-follow-up.js +154 -0
- package/src/lib/downloader.js +17 -3
- package/src/lib/ensure-utf8.js +11 -3
- 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 +34 -15
- package/src/lib/hook-runner.cjs +48 -3
- 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 +111 -21
- package/src/lib/ide-context.js +128 -1
- package/src/lib/interaction-adapter.js +39 -0
- package/src/lib/ipc-attach-protocol.js +98 -0
- package/src/lib/json-schema-validate.js +190 -36
- package/src/lib/lan-pairing-preflight.js +13 -2
- package/src/lib/lsp/__tests__/lsp-server-registry.test.js +18 -0
- package/src/lib/lsp/lsp-client.js +18 -1
- package/src/lib/lsp/lsp-manager.js +4 -0
- package/src/lib/lsp/lsp-server-registry.js +11 -0
- package/src/lib/mcp-oauth.js +8 -2
- package/src/lib/npm-invocation.js +29 -0
- package/src/lib/packer/pkg-runner.js +13 -2
- package/src/lib/packer/precheck.js +33 -16
- package/src/lib/packer/web-panel-builder.js +16 -2
- 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 +39 -4
- 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 +2 -1
- 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 +295 -0
- package/src/lib/process-execution-broker/index.js +440 -14
- package/src/lib/process-execution-broker/patch-child-process.js +2 -3
- package/src/lib/process-execution-broker/platform-sandbox.js +351 -0
- package/src/lib/process-manager.js +18 -3
- package/src/lib/provenance-api.js +6 -0
- package/src/lib/proxy-bootstrap.js +19 -0
- package/src/lib/publish-workspace.js +14 -6
- package/src/lib/repl-rewind.js +9 -4
- package/src/lib/secret-store.js +159 -0
- package/src/lib/service-manager.js +64 -29
- package/src/lib/session-hooks.js +328 -473
- package/src/lib/session-telemetry-middleware.js +6 -0
- package/src/lib/settings-hook-events.cjs +61 -1
- package/src/lib/settings-hooks.cjs +4 -0
- package/src/lib/side-effect-ledger.js +22 -0
- package/src/lib/sub-agent-context.js +5 -0
- package/src/lib/sub-agent-profiles.js +4 -0
- package/src/lib/trace-api.js +6 -0
- package/src/lib/turn-context.js +14 -8
- package/src/lib/unattended-action-policy.js +83 -0
- package/src/lib/update-notice.js +9 -45
- package/src/lib/with-file-lock.js +7 -0
- package/src/lib/ws-server.js +1 -0
- package/src/repl/agent-repl.js +71 -13
- package/src/repl/clipboard-copy.js +8 -2
- package/src/repl/pr-comments.js +30 -7
- package/src/runtime/agent-core.js +439 -87
- 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 +63 -0
- package/src/runtime/headless-stream.js +269 -17
- package/src/runtime/mcp-config.js +16 -1
- package/src/workers/background-agent-worker.js +80 -1
- package/src/assets/web-panel/assets/AppLayout-7iSKDmlI.js +0 -9
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DcbUHeGW.js +0 -1
- package/src/assets/web-panel/assets/Dashboard-BAKYNavw.js +0 -3
- package/src/assets/web-panel/assets/MobileProjects-C4GKn1dH.js +0 -1
- package/src/assets/web-panel/assets/Terminal-Fj7ea0In.js +0 -3
- package/src/assets/web-panel/assets/devWarning-CDI8Sbaj.js +0 -1
- package/src/assets/web-panel/assets/index-96LBR96V.js +0 -1
- package/src/assets/web-panel/assets/index-DyQkiW24.js +0 -1
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
const POLL_TIMEOUT_S = 25;
|
|
15
15
|
const ERROR_BACKOFF_MS = 5000;
|
|
16
|
+
import { EventRuntimeProducer } from "../event-runtime-producer.js";
|
|
16
17
|
|
|
17
18
|
export async function startTelegramChannel(options = {}) {
|
|
18
19
|
const {
|
|
@@ -27,7 +28,11 @@ export async function startTelegramChannel(options = {}) {
|
|
|
27
28
|
// failures) can never turn the loop into a microtask chain that starves
|
|
28
29
|
// the event loop (timers, stop()) entirely.
|
|
29
30
|
pollPauseMs = 50,
|
|
31
|
+
eventRuntimeStore = null,
|
|
30
32
|
} = options;
|
|
33
|
+
const runtimeProducer = eventRuntimeStore
|
|
34
|
+
? new EventRuntimeProducer({ store: eventRuntimeStore })
|
|
35
|
+
: null;
|
|
31
36
|
|
|
32
37
|
if (!botToken) {
|
|
33
38
|
throw new Error(
|
|
@@ -65,12 +70,17 @@ export async function startTelegramChannel(options = {}) {
|
|
|
65
70
|
if (!chatId || !text) continue;
|
|
66
71
|
if (!allowed.has(String(chatId))) continue; // fail closed
|
|
67
72
|
try {
|
|
68
|
-
|
|
73
|
+
const event = {
|
|
69
74
|
channel: "telegram",
|
|
70
75
|
sender: String(chatId),
|
|
71
76
|
text,
|
|
72
77
|
meta: { updateId: update.update_id },
|
|
78
|
+
};
|
|
79
|
+
runtimeProducer?.publish(event, {
|
|
80
|
+
origin: "telegram",
|
|
81
|
+
id: `telegram:${update.update_id}`,
|
|
73
82
|
});
|
|
83
|
+
onEvent?.(event);
|
|
74
84
|
} catch {
|
|
75
85
|
/* downstream owns its failures */
|
|
76
86
|
}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServer } from "node:http";
|
|
19
19
|
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
20
|
+
import { EventRuntimeProducer } from "../event-runtime-producer.js";
|
|
20
21
|
|
|
21
22
|
const MAX_BODY_BYTES = 64 * 1024;
|
|
22
23
|
|
|
@@ -34,7 +35,11 @@ export async function startWebhookChannel(options = {}) {
|
|
|
34
35
|
allowlist,
|
|
35
36
|
onEvent,
|
|
36
37
|
log = () => {},
|
|
38
|
+
eventRuntimeStore = null,
|
|
37
39
|
} = options;
|
|
40
|
+
const runtimeProducer = eventRuntimeStore
|
|
41
|
+
? new EventRuntimeProducer({ store: eventRuntimeStore })
|
|
42
|
+
: null;
|
|
38
43
|
|
|
39
44
|
const isLoopback =
|
|
40
45
|
host === "127.0.0.1" || host === "::1" || host === "localhost";
|
|
@@ -92,8 +97,7 @@ export async function startWebhookChannel(options = {}) {
|
|
|
92
97
|
return respond(403, { error: "sender not in allowlist" });
|
|
93
98
|
}
|
|
94
99
|
}
|
|
95
|
-
|
|
96
|
-
onEvent?.({
|
|
100
|
+
const event = {
|
|
97
101
|
channel: "webhook",
|
|
98
102
|
sender,
|
|
99
103
|
text,
|
|
@@ -101,9 +105,17 @@ export async function startWebhookChannel(options = {}) {
|
|
|
101
105
|
payload.meta && typeof payload.meta === "object"
|
|
102
106
|
? payload.meta
|
|
103
107
|
: undefined,
|
|
108
|
+
};
|
|
109
|
+
try {
|
|
110
|
+
runtimeProducer?.publish(event, {
|
|
111
|
+
origin: "webhook",
|
|
112
|
+
id: payload.event_id || payload.eventId || null,
|
|
104
113
|
});
|
|
114
|
+
onEvent?.(event);
|
|
105
115
|
} catch {
|
|
106
|
-
|
|
116
|
+
// A configured durable runtime is the recovery boundary. Refuse the
|
|
117
|
+
// request rather than acknowledging an event that was not persisted.
|
|
118
|
+
if (runtimeProducer) return respond(503, { error: "event persistence unavailable" });
|
|
107
119
|
}
|
|
108
120
|
respond(202, { ok: true });
|
|
109
121
|
});
|
|
@@ -18,9 +18,13 @@
|
|
|
18
18
|
* is. When it is not, callers should fall back / report unavailable.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import { spawnSync } from "node:child_process";
|
|
22
21
|
import { rmSync } from "node:fs";
|
|
23
22
|
import path from "node:path";
|
|
23
|
+
import executionBroker from "./process-execution-broker/index.js";
|
|
24
|
+
|
|
25
|
+
export const _deps = {
|
|
26
|
+
spawnSync: (...args) => executionBroker.spawnSync(...args),
|
|
27
|
+
};
|
|
24
28
|
|
|
25
29
|
const REF_NS = "refs/cc-checkpoints";
|
|
26
30
|
// Deterministic identity for shadow commits so `git commit-tree` never trips on
|
|
@@ -41,7 +45,11 @@ const CHECKPOINT_IDENTITY = Object.freeze({
|
|
|
41
45
|
* @throws {Error} with git's stderr when the command fails
|
|
42
46
|
*/
|
|
43
47
|
function git(args, { cwd, env, input } = {}) {
|
|
44
|
-
const res = spawnSync("git", args, {
|
|
48
|
+
const res = _deps.spawnSync("git", args, {
|
|
49
|
+
origin: "checkpoint:git",
|
|
50
|
+
scope: "checkpoint",
|
|
51
|
+
policy: "allow",
|
|
52
|
+
shell: false,
|
|
45
53
|
cwd,
|
|
46
54
|
input,
|
|
47
55
|
encoding: "utf-8",
|
package/src/lib/cloud/bundle.js
CHANGED
|
@@ -7,13 +7,23 @@
|
|
|
7
7
|
* a repo.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { execFileSync } from "node:child_process";
|
|
11
10
|
import { writeFileSync, mkdtempSync } from "node:fs";
|
|
12
11
|
import { readFileSync, rmSync } from "node:fs";
|
|
13
12
|
import { join } from "node:path";
|
|
14
13
|
import { tmpdir } from "node:os";
|
|
14
|
+
import { executionBroker } from "../process-execution-broker/index.js";
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
function brokerExecFileSync(file, args, options) {
|
|
17
|
+
return executionBroker.execFileSync(file, args, {
|
|
18
|
+
...options,
|
|
19
|
+
origin: "cloud:git",
|
|
20
|
+
policy: "allow",
|
|
21
|
+
scope: "cloud",
|
|
22
|
+
shell: false,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const _deps = { execFileSync: brokerExecFileSync };
|
|
17
27
|
|
|
18
28
|
function git(args, cwd, deps = _deps) {
|
|
19
29
|
return deps
|
package/src/lib/code-review.js
CHANGED
|
@@ -4,8 +4,37 @@
|
|
|
4
4
|
* @module lib/code-review
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { execSync } from "child_process";
|
|
8
7
|
import { logger } from "./logger.js";
|
|
8
|
+
import { executionBroker } from "./process-execution-broker/index.js";
|
|
9
|
+
|
|
10
|
+
export const _deps = {
|
|
11
|
+
execFileSync: (...args) => executionBroker.execFileSync(...args),
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export function buildGitDiffArgs(
|
|
15
|
+
target = "--staged",
|
|
16
|
+
{ nameOnly = false } = {},
|
|
17
|
+
) {
|
|
18
|
+
const args = ["diff"];
|
|
19
|
+
if (nameOnly) args.push("--name-only");
|
|
20
|
+
if (target === "--staged" || target === "--cached") {
|
|
21
|
+
args.push(target);
|
|
22
|
+
} else {
|
|
23
|
+
args.push("--end-of-options", String(target), "--");
|
|
24
|
+
}
|
|
25
|
+
return args;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function gitDiff(target, options = {}) {
|
|
29
|
+
return _deps.execFileSync("git", buildGitDiffArgs(target, options), {
|
|
30
|
+
encoding: "utf8",
|
|
31
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
32
|
+
origin: "review:git-diff",
|
|
33
|
+
policy: "allow",
|
|
34
|
+
scope: "review",
|
|
35
|
+
shell: false,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
9
38
|
|
|
10
39
|
/**
|
|
11
40
|
* Get git diff for review
|
|
@@ -14,10 +43,7 @@ import { logger } from "./logger.js";
|
|
|
14
43
|
*/
|
|
15
44
|
export function getGitDiff(target = "--staged") {
|
|
16
45
|
try {
|
|
17
|
-
return
|
|
18
|
-
encoding: "utf8",
|
|
19
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
20
|
-
});
|
|
46
|
+
return gitDiff(target);
|
|
21
47
|
} catch (err) {
|
|
22
48
|
logger.error(`Failed to get git diff: ${err.message}`);
|
|
23
49
|
return "";
|
|
@@ -31,9 +57,7 @@ export function getGitDiff(target = "--staged") {
|
|
|
31
57
|
*/
|
|
32
58
|
export function getChangedFiles(target = "--staged") {
|
|
33
59
|
try {
|
|
34
|
-
const output =
|
|
35
|
-
encoding: "utf8",
|
|
36
|
-
});
|
|
60
|
+
const output = gitDiff(target, { nameOnly: true });
|
|
37
61
|
return output.trim().split("\n").filter(Boolean);
|
|
38
62
|
} catch (err) {
|
|
39
63
|
logger.error(`Failed to get changed files: ${err.message}`);
|
|
@@ -7,16 +7,27 @@
|
|
|
7
7
|
* project's U-Key/hardware posture.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import
|
|
10
|
+
import executionBroker from "../process-execution-broker/index.js";
|
|
11
11
|
|
|
12
|
-
export const _deps = {
|
|
12
|
+
export const _deps = {
|
|
13
|
+
spawnSync: (...args) => executionBroker.spawnSync(...args),
|
|
14
|
+
platform: () => process.platform,
|
|
15
|
+
};
|
|
13
16
|
|
|
14
17
|
/** Run a PowerShell script, returning { ok, stdout, stderr }. */
|
|
15
18
|
function runPowerShell(script, deps = _deps) {
|
|
16
19
|
const res = deps.spawnSync(
|
|
17
20
|
"powershell.exe",
|
|
18
21
|
["-NoProfile", "-NonInteractive", "-Command", script],
|
|
19
|
-
{
|
|
22
|
+
{
|
|
23
|
+
encoding: "utf-8",
|
|
24
|
+
windowsHide: true,
|
|
25
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
26
|
+
origin: "computer-use:powershell",
|
|
27
|
+
scope: "computer-use",
|
|
28
|
+
policy: "allow",
|
|
29
|
+
shell: false,
|
|
30
|
+
},
|
|
20
31
|
);
|
|
21
32
|
if (res.error) return { ok: false, stdout: "", stderr: res.error.message };
|
|
22
33
|
return {
|
|
@@ -140,6 +151,10 @@ export function createWindowsBackend(deps = _deps) {
|
|
|
140
151
|
windowsHide: false,
|
|
141
152
|
detached: true,
|
|
142
153
|
stdio: "ignore",
|
|
154
|
+
origin: "computer-use:app-launch",
|
|
155
|
+
scope: "computer-use",
|
|
156
|
+
policy: "allow",
|
|
157
|
+
shell: false,
|
|
143
158
|
});
|
|
144
159
|
return res.error
|
|
145
160
|
? { ok: false, error: res.error.message }
|
|
@@ -57,6 +57,41 @@ export function breakdownInstructionSources(files, estimateTokens, cwd) {
|
|
|
57
57
|
return { sources, total };
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
/** Attribute the exact MCP tool schemas admitted to a persisted run. */
|
|
61
|
+
export function breakdownMcpSchemas(definitions, estimateTokens) {
|
|
62
|
+
const est = typeof estimateTokens === "function" ? estimateTokens : () => 0;
|
|
63
|
+
const list = Array.isArray(definitions) ? definitions : [];
|
|
64
|
+
const sources = list
|
|
65
|
+
.map((definition) => {
|
|
66
|
+
const fn = definition?.function || definition || {};
|
|
67
|
+
const name = String(fn.name || definition?.name || "mcp");
|
|
68
|
+
const schema = fn.parameters || definition?.inputSchema || {};
|
|
69
|
+
return {
|
|
70
|
+
source: name.split("__")[1] || name,
|
|
71
|
+
tool: name,
|
|
72
|
+
tokens: est(JSON.stringify({ description: fn.description || "", parameters: schema })),
|
|
73
|
+
};
|
|
74
|
+
})
|
|
75
|
+
.filter((row) => row.tokens > 0);
|
|
76
|
+
return { sources, total: sources.reduce((sum, row) => sum + row.tokens, 0) };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Attribute Skill bodies that were actually injected into the system prompt. */
|
|
80
|
+
export function breakdownSkillSources(skills, estimateTokens) {
|
|
81
|
+
const est = typeof estimateTokens === "function" ? estimateTokens : () => 0;
|
|
82
|
+
const list = Array.isArray(skills) ? skills : [];
|
|
83
|
+
const sources = list
|
|
84
|
+
.map((skill) => ({
|
|
85
|
+
source: skill?.source || "skill",
|
|
86
|
+
skill: String(skill?.id || skill?.displayName || "skill"),
|
|
87
|
+
tokens: est(
|
|
88
|
+
`## Persona: ${skill?.displayName || skill?.id || "skill"}\n${skill?.body || ""}`,
|
|
89
|
+
),
|
|
90
|
+
}))
|
|
91
|
+
.filter((row) => row.tokens > 0);
|
|
92
|
+
return { sources, total: sources.reduce((sum, row) => sum + row.tokens, 0) };
|
|
93
|
+
}
|
|
94
|
+
|
|
60
95
|
// role bucket key → { label, kind } for the ranked source list.
|
|
61
96
|
const MESSAGE_SOURCE_ROWS = [
|
|
62
97
|
["system", "system messages", "message"],
|
|
@@ -84,6 +119,7 @@ export function rankContextSources({
|
|
|
84
119
|
instructionTotal = 0,
|
|
85
120
|
buckets = {},
|
|
86
121
|
counts = {},
|
|
122
|
+
extraSources = [],
|
|
87
123
|
} = {}) {
|
|
88
124
|
const rows = [];
|
|
89
125
|
if (instructionTotal > 0) {
|
|
@@ -105,6 +141,16 @@ export function rankContextSources({
|
|
|
105
141
|
});
|
|
106
142
|
}
|
|
107
143
|
}
|
|
144
|
+
for (const row of Array.isArray(extraSources) ? extraSources : []) {
|
|
145
|
+
if (!row || !(row.tokens > 0)) continue;
|
|
146
|
+
rows.push({
|
|
147
|
+
kind: row.kind || "runtime",
|
|
148
|
+
source: row.source || "runtime",
|
|
149
|
+
tokens: row.tokens,
|
|
150
|
+
count: row.count ?? null,
|
|
151
|
+
tool: row.tool || null,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
108
154
|
const total = rows.reduce((s, x) => s + x.tokens, 0);
|
|
109
155
|
// Stable sort: tokens desc, then source name for deterministic ties.
|
|
110
156
|
rows.sort((a, b) => b.tokens - a.tokens || a.source.localeCompare(b.source));
|
|
@@ -43,6 +43,7 @@ class ContextSourceLedger {
|
|
|
43
43
|
const entryId = entry.entryId || crypto.randomUUID();
|
|
44
44
|
const full = {
|
|
45
45
|
entryId,
|
|
46
|
+
traceId: entry.traceId || null,
|
|
46
47
|
sessionId: entry.sessionId || "unknown",
|
|
47
48
|
turnId: entry.turnId || "unknown",
|
|
48
49
|
sourceType: entry.sourceType || "unknown",
|
|
@@ -69,6 +70,48 @@ class ContextSourceLedger {
|
|
|
69
70
|
return entryId;
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
/** Compatibility adapter for runtime provenance producers. */
|
|
74
|
+
recordRead(entry = {}) {
|
|
75
|
+
return this.record({
|
|
76
|
+
sessionId: entry.sessionId,
|
|
77
|
+
turnId: entry.turnId,
|
|
78
|
+
sourceType: entry.sourceType || entry.source || "unknown",
|
|
79
|
+
sourceId: entry.sourceId || entry.span || "unknown",
|
|
80
|
+
permissionMode: entry.permissionMode || "agent",
|
|
81
|
+
confidence: entry.confidence,
|
|
82
|
+
summary: entry.summary || entry.content,
|
|
83
|
+
metadata: entry.metadata,
|
|
84
|
+
tokenCount: entry.tokenCount ?? entry.tokens ?? 0,
|
|
85
|
+
traceId: entry.traceId,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Return a flat, read-only provenance snapshot for diagnostics/export. */
|
|
90
|
+
getProvenance({ sessionId, turnId } = {}) {
|
|
91
|
+
let entries = Array.from(this._entries.values());
|
|
92
|
+
if (sessionId) entries = entries.filter((e) => e.sessionId === sessionId);
|
|
93
|
+
if (turnId) entries = entries.filter((e) => e.turnId === turnId);
|
|
94
|
+
return entries.map((entry) => ({ ...entry, tags: [...entry.tags] }));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Aggregate token usage by source type. */
|
|
98
|
+
getTokenBreakdown() {
|
|
99
|
+
const bySource = {};
|
|
100
|
+
let total = 0;
|
|
101
|
+
for (const entry of this._entries.values()) {
|
|
102
|
+
total += entry.tokenCount;
|
|
103
|
+
bySource[entry.sourceType] = (bySource[entry.sourceType] || 0) + entry.tokenCount;
|
|
104
|
+
}
|
|
105
|
+
return { total, bySource };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Clear the in-memory ledger (test/runtime lifecycle boundary). */
|
|
109
|
+
clear() {
|
|
110
|
+
this._entries.clear();
|
|
111
|
+
this._byTurn.clear();
|
|
112
|
+
this._bySession.clear();
|
|
113
|
+
}
|
|
114
|
+
|
|
72
115
|
/**
|
|
73
116
|
* Get all context entries for a given turn
|
|
74
117
|
* @param {string} turnId
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Correlate an IDE Diff "Request changes" decision with the next review of the
|
|
3
|
+
* same file. The tracker writes only bounded review metadata into the existing
|
|
4
|
+
* side-effect ledger; model text and file content are never copied.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const MAX_ID = 256;
|
|
8
|
+
const MAX_PATH = 2048;
|
|
9
|
+
const MAX_REASON = 256;
|
|
10
|
+
const VALID_OUTCOMES = new Set(["accepted", "rejected", "changes-requested"]);
|
|
11
|
+
|
|
12
|
+
function bounded(value, max) {
|
|
13
|
+
if (value == null) return null;
|
|
14
|
+
const text = String(value).slice(0, max);
|
|
15
|
+
return text || null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function reviewKey(audit) {
|
|
19
|
+
const path = bounded(audit?.path, MAX_PATH);
|
|
20
|
+
if (!path) return null;
|
|
21
|
+
return `${bounded(audit?.sessionId, MAX_ID) || ""}\0${path}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function pendingFollowUp(audit) {
|
|
25
|
+
return {
|
|
26
|
+
status: "pending",
|
|
27
|
+
requestedAt: bounded(audit?.createdAt, 64),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function reviewedFollowUp(audit) {
|
|
32
|
+
const outcome = VALID_OUTCOMES.has(audit?.outcome)
|
|
33
|
+
? audit.outcome
|
|
34
|
+
: "rejected";
|
|
35
|
+
return {
|
|
36
|
+
status: outcome,
|
|
37
|
+
reviewId: bounded(audit?.reviewId, 64),
|
|
38
|
+
turnId: bounded(audit?.turnId, MAX_ID),
|
|
39
|
+
toolUseId: bounded(audit?.toolUseId, MAX_ID),
|
|
40
|
+
operation: bounded(audit?.operation, 16) || "modify",
|
|
41
|
+
targetPath:
|
|
42
|
+
audit?.operation === "rename"
|
|
43
|
+
? bounded(audit?.targetPath, MAX_PATH)
|
|
44
|
+
: null,
|
|
45
|
+
written: audit?.written === true,
|
|
46
|
+
completedAt: bounded(audit?.createdAt, 64),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function terminalFollowUp(status, { turnId = null, reason = null } = {}) {
|
|
51
|
+
return {
|
|
52
|
+
status,
|
|
53
|
+
turnId: bounded(turnId, MAX_ID),
|
|
54
|
+
reason: bounded(reason, MAX_REASON),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Ledger-facing tracker. `ledger` only needs `list()` and `annotate()` methods,
|
|
60
|
+
* which keeps the correlation logic independently testable.
|
|
61
|
+
*/
|
|
62
|
+
export class DiffReviewFollowUpTracker {
|
|
63
|
+
constructor(ledger = null) {
|
|
64
|
+
this._pending = new Map();
|
|
65
|
+
if (ledger) this.hydrate(ledger);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Restore only explicitly-pending v1 records after a process/session resume. */
|
|
69
|
+
hydrate(ledger) {
|
|
70
|
+
this._pending.clear();
|
|
71
|
+
for (const op of ledger?.list?.() || []) {
|
|
72
|
+
const audit = op?.meta?.diffReview;
|
|
73
|
+
if (
|
|
74
|
+
audit?.schema !== "cc-diff-review/v1" ||
|
|
75
|
+
audit?.outcome !== "changes-requested" ||
|
|
76
|
+
audit?.followUp?.status !== "pending"
|
|
77
|
+
) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const key = reviewKey(audit);
|
|
81
|
+
if (key) this._pending.set(key, { opId: op.opId, audit });
|
|
82
|
+
}
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Attach the current audit and, when applicable, resolve the preceding
|
|
88
|
+
* Request Changes record for the same trusted session/path.
|
|
89
|
+
*/
|
|
90
|
+
observe(ledger, opId, audit) {
|
|
91
|
+
if (!ledger?.annotate || !opId || audit?.schema !== "cc-diff-review/v1") {
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
const updates = [];
|
|
95
|
+
const key = reviewKey(audit);
|
|
96
|
+
const prior = key ? this._pending.get(key) : null;
|
|
97
|
+
let currentAudit = audit;
|
|
98
|
+
if (prior && prior.opId !== opId) {
|
|
99
|
+
const followUp = reviewedFollowUp(audit);
|
|
100
|
+
ledger.annotate(prior.opId, {
|
|
101
|
+
diffReview: { ...prior.audit, followUp },
|
|
102
|
+
});
|
|
103
|
+
this._pending.delete(key);
|
|
104
|
+
currentAudit = {
|
|
105
|
+
...audit,
|
|
106
|
+
followUpOfReviewId: bounded(prior.audit.reviewId, 64),
|
|
107
|
+
};
|
|
108
|
+
updates.push({
|
|
109
|
+
reviewId: prior.audit.reviewId || null,
|
|
110
|
+
followUp,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (audit.outcome === "changes-requested" && key) {
|
|
115
|
+
currentAudit = { ...currentAudit, followUp: pendingFollowUp(audit) };
|
|
116
|
+
this._pending.set(key, { opId, audit: currentAudit });
|
|
117
|
+
}
|
|
118
|
+
ledger.annotate(opId, { diffReview: currentAudit });
|
|
119
|
+
return updates;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Settle every still-pending request when the agent run ends without another
|
|
124
|
+
* Diff proposal. Returns updates so callers can decide whether persistence is
|
|
125
|
+
* necessary.
|
|
126
|
+
*/
|
|
127
|
+
complete(
|
|
128
|
+
ledger,
|
|
129
|
+
{
|
|
130
|
+
status = "completed-without-reproposal",
|
|
131
|
+
turnId = null,
|
|
132
|
+
reason = null,
|
|
133
|
+
} = {},
|
|
134
|
+
) {
|
|
135
|
+
if (!ledger?.annotate || this._pending.size === 0) return [];
|
|
136
|
+
const updates = [];
|
|
137
|
+
for (const pending of this._pending.values()) {
|
|
138
|
+
const followUp = terminalFollowUp(status, { turnId, reason });
|
|
139
|
+
ledger.annotate(pending.opId, {
|
|
140
|
+
diffReview: { ...pending.audit, followUp },
|
|
141
|
+
});
|
|
142
|
+
updates.push({
|
|
143
|
+
reviewId: pending.audit.reviewId || null,
|
|
144
|
+
followUp,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
this._pending.clear();
|
|
148
|
+
return updates;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
get pendingCount() {
|
|
152
|
+
return this._pending.size;
|
|
153
|
+
}
|
|
154
|
+
}
|
package/src/lib/downloader.js
CHANGED
|
@@ -7,12 +7,16 @@ import {
|
|
|
7
7
|
} from "node:fs";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { pipeline } from "node:stream/promises";
|
|
10
|
-
import { execFileSync } from "node:child_process";
|
|
11
10
|
import ora from "ora";
|
|
12
11
|
import { GITHUB_RELEASES_URL } from "../constants.js";
|
|
13
12
|
import { getBinDir, ensureDir } from "./paths.js";
|
|
14
13
|
import { getPlatform, getArch } from "./platform.js";
|
|
15
14
|
import logger from "./logger.js";
|
|
15
|
+
import { executionBroker } from "./process-execution-broker/index.js";
|
|
16
|
+
|
|
17
|
+
function brokerExecFileSync(file, args, options) {
|
|
18
|
+
return executionBroker.execFileSync(file, args, options);
|
|
19
|
+
}
|
|
16
20
|
|
|
17
21
|
// Platform-specific asset matching patterns
|
|
18
22
|
const ASSET_PATTERNS = {
|
|
@@ -211,7 +215,7 @@ async function fetchRelease(url) {
|
|
|
211
215
|
export function extractZip(
|
|
212
216
|
zipPath,
|
|
213
217
|
destDir,
|
|
214
|
-
{ execFileImpl =
|
|
218
|
+
{ execFileImpl = brokerExecFileSync, platform = getPlatform() } = {},
|
|
215
219
|
) {
|
|
216
220
|
// Never interpolate the paths into a shell string — `zipPath`/`destDir` derive
|
|
217
221
|
// from the (remote) release asset name, so a `"`/`$()`/`'` in a path would be a
|
|
@@ -229,10 +233,20 @@ export function extractZip(
|
|
|
229
233
|
{
|
|
230
234
|
stdio: "ignore",
|
|
231
235
|
env: { ...process.env, CC_ZIP_SRC: zipPath, CC_ZIP_DEST: destDir },
|
|
236
|
+
origin: "update:archive-extract",
|
|
237
|
+
policy: "allow",
|
|
238
|
+
scope: "update",
|
|
239
|
+
shell: false,
|
|
232
240
|
},
|
|
233
241
|
);
|
|
234
242
|
} else {
|
|
235
|
-
execFileImpl("unzip", ["-o", zipPath, "-d", destDir], {
|
|
243
|
+
execFileImpl("unzip", ["-o", zipPath, "-d", destDir], {
|
|
244
|
+
stdio: "ignore",
|
|
245
|
+
origin: "update:archive-extract",
|
|
246
|
+
policy: "allow",
|
|
247
|
+
scope: "update",
|
|
248
|
+
shell: false,
|
|
249
|
+
});
|
|
236
250
|
}
|
|
237
251
|
}
|
|
238
252
|
|
package/src/lib/ensure-utf8.js
CHANGED
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
* Node.js streams to use UTF-8 encoding.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { executionBroker } from "./process-execution-broker/index.js";
|
|
11
11
|
|
|
12
12
|
// Injectable so tests can assert whether the (expensive) chcp spawn happened
|
|
13
13
|
// without actually spawning cmd.exe. See cli-dev.md `_deps` pattern.
|
|
14
|
-
export const _deps = {
|
|
14
|
+
export const _deps = {
|
|
15
|
+
execFileSync: (...args) => executionBroker.execFileSync(...args),
|
|
16
|
+
};
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* Call this as early as possible in the process entry point.
|
|
@@ -34,7 +36,13 @@ export function ensureUtf8() {
|
|
|
34
36
|
Boolean(process.stderr && process.stderr.isTTY);
|
|
35
37
|
if (consoleAttached || process.env.CC_FORCE_CHCP === "1") {
|
|
36
38
|
try {
|
|
37
|
-
_deps.
|
|
39
|
+
_deps.execFileSync("cmd.exe", ["/d", "/s", "/c", "chcp 65001"], {
|
|
40
|
+
stdio: "ignore",
|
|
41
|
+
origin: "runtime:utf8-console",
|
|
42
|
+
policy: "allow",
|
|
43
|
+
scope: "runtime",
|
|
44
|
+
shell: false,
|
|
45
|
+
});
|
|
38
46
|
} catch (_err) {
|
|
39
47
|
// Ignore - may fail in non-interactive environments
|
|
40
48
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Canonical producer boundary for durable Event Runtime events. */
|
|
2
|
+
|
|
3
|
+
import { EventEmitter } from "node:events";
|
|
4
|
+
import { eventId } from "./event-runtime-store.js";
|
|
5
|
+
|
|
6
|
+
const ALLOWED_ORIGINS = new Set([
|
|
7
|
+
"agenda",
|
|
8
|
+
"monitor",
|
|
9
|
+
"webhook",
|
|
10
|
+
"telegram",
|
|
11
|
+
"mcp",
|
|
12
|
+
"hook",
|
|
13
|
+
"agent-ipc",
|
|
14
|
+
"system",
|
|
15
|
+
]);
|
|
16
|
+
|
|
17
|
+
function normalizeOrigin(origin) {
|
|
18
|
+
const value = String(origin || "system").trim().toLowerCase();
|
|
19
|
+
if (!ALLOWED_ORIGINS.has(value)) throw new Error(`unsupported event origin: ${value}`);
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Publish an event with an immutable producer envelope. The store remains the
|
|
25
|
+
* source of truth; the optional emitter is only a low-latency notification.
|
|
26
|
+
*/
|
|
27
|
+
export class EventRuntimeProducer extends EventEmitter {
|
|
28
|
+
constructor({ store, emitter = null, now = () => Date.now() } = {}) {
|
|
29
|
+
super();
|
|
30
|
+
if (!store || typeof store.enqueue !== "function") {
|
|
31
|
+
throw new Error("EventRuntimeProducer requires a durable EventRuntimeStore");
|
|
32
|
+
}
|
|
33
|
+
this.store = store;
|
|
34
|
+
this.emitter = emitter;
|
|
35
|
+
this._now = now;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
publish(event, { origin = "system", queue = "inbox", id = null, metadata = null } = {}) {
|
|
39
|
+
if (queue !== "inbox" && queue !== "outbox") throw new Error(`unsupported event queue: ${queue}`);
|
|
40
|
+
const producer = normalizeOrigin(origin);
|
|
41
|
+
const base = {
|
|
42
|
+
...(event && typeof event === "object" ? event : { value: event }),
|
|
43
|
+
origin: producer,
|
|
44
|
+
};
|
|
45
|
+
const payload = { ...base, producedAt: this._now(), authority: "system" };
|
|
46
|
+
const record = this.store.enqueue(queue, payload, {
|
|
47
|
+
id: id || eventId(base),
|
|
48
|
+
metadata: { ...(metadata || {}), producer: producer },
|
|
49
|
+
});
|
|
50
|
+
if (!record.duplicate) {
|
|
51
|
+
this.emit("published", record);
|
|
52
|
+
this.emitter?.emit?.("event-runtime:published", record);
|
|
53
|
+
}
|
|
54
|
+
return record;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { ALLOWED_ORIGINS };
|