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
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small OS-backed secret store used by plugin options and other user-scoped
|
|
3
|
+
* credentials. Secrets never fall back to plaintext JSON:
|
|
4
|
+
* - Windows: DPAPI (CurrentUser) encrypted blobs in the user data dir
|
|
5
|
+
* - macOS: Keychain via `security`
|
|
6
|
+
* - Linux: Secret Service via `secret-tool`
|
|
7
|
+
*
|
|
8
|
+
* The command runner is injectable so the protocol is deterministic in unit
|
|
9
|
+
* tests and so callers can route it through ProcessExecutionBroker.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import crypto from "node:crypto";
|
|
13
|
+
import fs from "node:fs";
|
|
14
|
+
import os from "node:os";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import { getElectronUserDataDir } from "./paths.js";
|
|
17
|
+
import { executionBroker } from "./process-execution-broker/index.js";
|
|
18
|
+
|
|
19
|
+
const DPAPI_SCRIPT = [
|
|
20
|
+
"$ErrorActionPreference='Stop'",
|
|
21
|
+
"Add-Type -AssemblyName System.Security",
|
|
22
|
+
"$raw=[Console]::In.ReadToEnd()",
|
|
23
|
+
"$b=[Convert]::FromBase64String($raw)",
|
|
24
|
+
"$p=[Security.Cryptography.ProtectedData]::Protect($b,$null,[Security.Cryptography.DataProtectionScope]::CurrentUser)",
|
|
25
|
+
"[Console]::Write([Convert]::ToBase64String($p))",
|
|
26
|
+
].join("; ");
|
|
27
|
+
|
|
28
|
+
const DPAPI_UNPROTECT_SCRIPT = [
|
|
29
|
+
"$ErrorActionPreference='Stop'",
|
|
30
|
+
"Add-Type -AssemblyName System.Security",
|
|
31
|
+
"$raw=[Console]::In.ReadToEnd()",
|
|
32
|
+
"$b=[Convert]::FromBase64String($raw)",
|
|
33
|
+
"$p=[Security.Cryptography.ProtectedData]::Unprotect($b,$null,[Security.Cryptography.DataProtectionScope]::CurrentUser)",
|
|
34
|
+
"[Console]::Write([Convert]::ToBase64String($p))",
|
|
35
|
+
].join("; ");
|
|
36
|
+
|
|
37
|
+
function defaultRunner(file, args, input = undefined) {
|
|
38
|
+
const result = executionBroker.spawnSync(file, args, {
|
|
39
|
+
origin: "secret-store",
|
|
40
|
+
policy: "allow",
|
|
41
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
42
|
+
encoding: "utf8",
|
|
43
|
+
windowsHide: true,
|
|
44
|
+
...(input !== undefined ? { input } : {}),
|
|
45
|
+
});
|
|
46
|
+
if (result.status !== 0) {
|
|
47
|
+
throw new Error(String(result.stderr || "secret store command failed").trim());
|
|
48
|
+
}
|
|
49
|
+
return String(result.stdout || "").trim();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function safeToken(value) {
|
|
53
|
+
return crypto
|
|
54
|
+
.createHash("sha256")
|
|
55
|
+
.update(String(value || ""))
|
|
56
|
+
.digest("hex")
|
|
57
|
+
.slice(0, 32);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function chooseBackend(platform = process.platform) {
|
|
61
|
+
if (platform === "win32") return "dpapi";
|
|
62
|
+
if (platform === "darwin") return "keychain";
|
|
63
|
+
if (platform === "linux" || platform === "freebsd") return "secret-service";
|
|
64
|
+
return "unavailable";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function readJson(file, readFile = fs.readFileSync) {
|
|
68
|
+
try {
|
|
69
|
+
const value = JSON.parse(readFile(file, "utf8"));
|
|
70
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
71
|
+
? value
|
|
72
|
+
: {};
|
|
73
|
+
} catch {
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function writeJson(file, value, deps = {}) {
|
|
79
|
+
const mkdirSync = deps.mkdirSync || fs.mkdirSync;
|
|
80
|
+
const writeFileSync = deps.writeFileSync || fs.writeFileSync;
|
|
81
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
82
|
+
writeFileSync(file, JSON.stringify(value, null, 2), { encoding: "utf8", mode: 0o600 });
|
|
83
|
+
try { fs.chmodSync(file, 0o600); } catch {}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function createDpapiBackend({ file, runner, readFile, writeFile, mkdirSync } = {}) {
|
|
87
|
+
const storeFile = file || path.join(getElectronUserDataDir(), "plugin-secrets.dpapi.json");
|
|
88
|
+
const load = () => readJson(storeFile, readFile);
|
|
89
|
+
const save = (v) => writeJson(storeFile, v, { writeFileSync: writeFile, mkdirSync });
|
|
90
|
+
return {
|
|
91
|
+
name: "dpapi",
|
|
92
|
+
set(key, value) {
|
|
93
|
+
const payload = Buffer.from(String(value), "utf8").toString("base64");
|
|
94
|
+
const encoded = runner("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", DPAPI_SCRIPT], payload);
|
|
95
|
+
const data = load(); data[key] = encoded; save(data);
|
|
96
|
+
},
|
|
97
|
+
get(key) {
|
|
98
|
+
const encoded = load()[key];
|
|
99
|
+
if (!encoded) return null;
|
|
100
|
+
const plain = runner("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", DPAPI_UNPROTECT_SCRIPT], encoded);
|
|
101
|
+
return Buffer.from(plain, "base64").toString("utf8");
|
|
102
|
+
},
|
|
103
|
+
delete(key) {
|
|
104
|
+
const data = load();
|
|
105
|
+
if (!Object.prototype.hasOwnProperty.call(data, key)) return false;
|
|
106
|
+
delete data[key]; save(data); return true;
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function createKeychainBackend({ service, runner } = {}) {
|
|
112
|
+
const name = service || "com.chainlesschain.plugin";
|
|
113
|
+
return {
|
|
114
|
+
name: "keychain",
|
|
115
|
+
set(key, value) {
|
|
116
|
+
runner("security", ["add-generic-password", "-a", key, "-s", name, "-w", String(value), "-U"]);
|
|
117
|
+
},
|
|
118
|
+
get(key) {
|
|
119
|
+
try { return runner("security", ["find-generic-password", "-a", key, "-s", name, "-w"]) || null; } catch { return null; }
|
|
120
|
+
},
|
|
121
|
+
delete(key) {
|
|
122
|
+
try { runner("security", ["delete-generic-password", "-a", key, "-s", name]); return true; } catch { return false; }
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function createSecretServiceBackend({ service, runner } = {}) {
|
|
128
|
+
const name = service || "chainlesschain-plugin";
|
|
129
|
+
return {
|
|
130
|
+
name: "secret-service",
|
|
131
|
+
set(key, value) {
|
|
132
|
+
runner("secret-tool", ["store", "--label", `${name}:${key}`, "service", name, "account", key], String(value));
|
|
133
|
+
},
|
|
134
|
+
get(key) {
|
|
135
|
+
try { return runner("secret-tool", ["lookup", "service", name, "account", key]) || null; } catch { return null; }
|
|
136
|
+
},
|
|
137
|
+
delete(key) {
|
|
138
|
+
try { runner("secret-tool", ["clear", "service", name, "account", key]); return true; } catch { return false; }
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Create a fail-closed secret store. `memory` is intended for tests only. */
|
|
144
|
+
export function createSecretStore(options = {}) {
|
|
145
|
+
const backend = options.backend || chooseBackend(options.platform);
|
|
146
|
+
const runner = options.runner || defaultRunner;
|
|
147
|
+
if (backend === "memory") {
|
|
148
|
+
const values = options.values || new Map();
|
|
149
|
+
return { name: "memory", set: (k, v) => values.set(k, String(v)), get: (k) => values.get(k) ?? null, delete: (k) => values.delete(k) };
|
|
150
|
+
}
|
|
151
|
+
if (backend === "dpapi") return createDpapiBackend({ ...options, runner });
|
|
152
|
+
if (backend === "keychain") return createKeychainBackend({ ...options, runner });
|
|
153
|
+
if (backend === "secret-service") return createSecretServiceBackend({ ...options, runner });
|
|
154
|
+
throw new Error(`No OS secret store available for platform ${options.platform || process.platform}`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function secretRef(key) { return { __cc_secret_ref: String(key) }; }
|
|
158
|
+
export function isSecretRef(value) { return Boolean(value && typeof value === "object" && value.__cc_secret_ref); }
|
|
159
|
+
export { chooseBackend };
|
|
@@ -1,11 +1,26 @@
|
|
|
1
|
-
import { execSync, spawn } from "node:child_process";
|
|
2
1
|
import { existsSync } from "node:fs";
|
|
3
2
|
import { join } from "node:path";
|
|
4
3
|
import logger from "./logger.js";
|
|
4
|
+
import { executionBroker } from "./process-execution-broker/index.js";
|
|
5
|
+
|
|
6
|
+
export const _deps = {
|
|
7
|
+
execFileSync: (...args) => executionBroker.execFileSync(...args),
|
|
8
|
+
spawn: (...args) => executionBroker.spawn(...args),
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function syncDocker(command, args, options = {}, origin = "service:docker") {
|
|
12
|
+
return _deps.execFileSync(command, args, {
|
|
13
|
+
...options,
|
|
14
|
+
origin,
|
|
15
|
+
policy: "allow",
|
|
16
|
+
scope: "service",
|
|
17
|
+
shell: false,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
5
20
|
|
|
6
21
|
export function isDockerAvailable() {
|
|
7
22
|
try {
|
|
8
|
-
|
|
23
|
+
syncDocker("docker", ["--version"], { stdio: "ignore" });
|
|
9
24
|
return true;
|
|
10
25
|
} catch {
|
|
11
26
|
return false;
|
|
@@ -14,11 +29,11 @@ export function isDockerAvailable() {
|
|
|
14
29
|
|
|
15
30
|
export function isDockerComposeAvailable() {
|
|
16
31
|
try {
|
|
17
|
-
|
|
32
|
+
syncDocker("docker", ["compose", "version"], { stdio: "ignore" });
|
|
18
33
|
return true;
|
|
19
34
|
} catch {
|
|
20
35
|
try {
|
|
21
|
-
|
|
36
|
+
syncDocker("docker-compose", ["--version"], { stdio: "ignore" });
|
|
22
37
|
return true;
|
|
23
38
|
} catch {
|
|
24
39
|
return false;
|
|
@@ -26,12 +41,12 @@ export function isDockerComposeAvailable() {
|
|
|
26
41
|
}
|
|
27
42
|
}
|
|
28
43
|
|
|
29
|
-
function
|
|
44
|
+
export function getComposeInvocation() {
|
|
30
45
|
try {
|
|
31
|
-
|
|
32
|
-
return "docker compose";
|
|
46
|
+
syncDocker("docker", ["compose", "version"], { stdio: "ignore" });
|
|
47
|
+
return { command: "docker", prefixArgs: ["compose"] };
|
|
33
48
|
} catch {
|
|
34
|
-
return "docker-compose";
|
|
49
|
+
return { command: "docker-compose", prefixArgs: [] };
|
|
35
50
|
}
|
|
36
51
|
}
|
|
37
52
|
|
|
@@ -54,30 +69,37 @@ export function findComposeFile(searchPaths) {
|
|
|
54
69
|
}
|
|
55
70
|
|
|
56
71
|
export function servicesUp(composePath, options = {}) {
|
|
57
|
-
const
|
|
72
|
+
const invocation = getComposeInvocation();
|
|
58
73
|
const args = ["-f", composePath, "up", "-d"];
|
|
59
74
|
if (options.services) {
|
|
60
75
|
args.push(...options.services);
|
|
61
76
|
}
|
|
62
|
-
return runCompose(
|
|
77
|
+
return runCompose(invocation, args);
|
|
63
78
|
}
|
|
64
79
|
|
|
65
80
|
export function servicesDown(composePath) {
|
|
66
|
-
const
|
|
67
|
-
return runCompose(
|
|
81
|
+
const invocation = getComposeInvocation();
|
|
82
|
+
return runCompose(invocation, ["-f", composePath, "down"]);
|
|
68
83
|
}
|
|
69
84
|
|
|
70
85
|
export function servicesLogs(composePath, options = {}) {
|
|
71
|
-
const
|
|
86
|
+
const invocation = getComposeInvocation();
|
|
72
87
|
const args = ["-f", composePath, "logs"];
|
|
73
88
|
if (options.follow) args.push("-f");
|
|
74
89
|
if (options.tail) args.push("--tail", String(options.tail));
|
|
75
90
|
if (options.services) args.push(...options.services);
|
|
76
91
|
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
92
|
+
const child = _deps.spawn(
|
|
93
|
+
invocation.command,
|
|
94
|
+
[...invocation.prefixArgs, ...args],
|
|
95
|
+
{
|
|
96
|
+
stdio: "inherit",
|
|
97
|
+
origin: "service:compose-logs",
|
|
98
|
+
policy: "allow",
|
|
99
|
+
scope: "service",
|
|
100
|
+
shell: false,
|
|
101
|
+
},
|
|
102
|
+
);
|
|
81
103
|
|
|
82
104
|
return new Promise((resolve, reject) => {
|
|
83
105
|
child.on("close", (code) => {
|
|
@@ -89,17 +111,22 @@ export function servicesLogs(composePath, options = {}) {
|
|
|
89
111
|
}
|
|
90
112
|
|
|
91
113
|
export function servicesPull(composePath) {
|
|
92
|
-
const
|
|
93
|
-
return runCompose(
|
|
114
|
+
const invocation = getComposeInvocation();
|
|
115
|
+
return runCompose(invocation, ["-f", composePath, "pull"]);
|
|
94
116
|
}
|
|
95
117
|
|
|
96
118
|
export function getServiceStatus(composePath) {
|
|
97
|
-
const
|
|
119
|
+
const invocation = getComposeInvocation();
|
|
98
120
|
try {
|
|
99
|
-
const output =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
121
|
+
const output = syncDocker(
|
|
122
|
+
invocation.command,
|
|
123
|
+
[...invocation.prefixArgs, "-f", composePath, "ps", "--format", "json"],
|
|
124
|
+
{
|
|
125
|
+
encoding: "utf-8",
|
|
126
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
127
|
+
},
|
|
128
|
+
"service:compose-status",
|
|
129
|
+
);
|
|
103
130
|
try {
|
|
104
131
|
return JSON.parse(`[${output.trim().split("\n").join(",")}]`);
|
|
105
132
|
} catch {
|
|
@@ -110,14 +137,22 @@ export function getServiceStatus(composePath) {
|
|
|
110
137
|
}
|
|
111
138
|
}
|
|
112
139
|
|
|
113
|
-
function runCompose(
|
|
114
|
-
const
|
|
115
|
-
|
|
140
|
+
function runCompose(invocation, args) {
|
|
141
|
+
const fullArgs = [...invocation.prefixArgs, ...args];
|
|
142
|
+
const display = [invocation.command, ...fullArgs]
|
|
143
|
+
.map((part) => JSON.stringify(String(part)))
|
|
144
|
+
.join(" ");
|
|
145
|
+
logger.verbose(`Running: ${display}`);
|
|
116
146
|
try {
|
|
117
|
-
|
|
147
|
+
syncDocker(
|
|
148
|
+
invocation.command,
|
|
149
|
+
fullArgs,
|
|
150
|
+
{ stdio: "inherit" },
|
|
151
|
+
"service:compose",
|
|
152
|
+
);
|
|
118
153
|
return true;
|
|
119
154
|
} catch (err) {
|
|
120
|
-
logger.error(`Command failed: ${
|
|
155
|
+
logger.error(`Command failed: ${display}`);
|
|
121
156
|
throw err;
|
|
122
157
|
}
|
|
123
158
|
}
|
|
@@ -17,10 +17,31 @@
|
|
|
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
|
|
|
25
|
+
/**
|
|
26
|
+
* Publish lifecycle events to Hooks v2 without making the legacy settings hook
|
|
27
|
+
* path depend on the ESM runtime. Payloads are deliberately reduced before
|
|
28
|
+
* publication: prompt text and file contents must never become durable hook
|
|
29
|
+
* context merely because a lifecycle producer fired.
|
|
30
|
+
*/
|
|
31
|
+
function publishHooksV2Event(event, payload = {}) {
|
|
32
|
+
const safe = { ...payload };
|
|
33
|
+
delete safe.prompt;
|
|
34
|
+
delete safe.content;
|
|
35
|
+
delete safe.files;
|
|
36
|
+
void import("./hooks-v2-producers.js")
|
|
37
|
+
.then(({ emitHooksV2Event }) => {
|
|
38
|
+
emitHooksV2Event(event, safe);
|
|
39
|
+
})
|
|
40
|
+
.catch(() => {
|
|
41
|
+
// Optional producer bridge; legacy settings hooks remain authoritative.
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
24
45
|
/**
|
|
25
46
|
* Stamp a unified-bus delivery id (event_id) onto a hook payload (P2 event bus).
|
|
26
47
|
* Additive — a hook that ignores it is unaffected; a hook that reads it gets a
|
|
@@ -104,6 +125,10 @@ function runUserPromptSubmitHooks(
|
|
|
104
125
|
settingsHooks,
|
|
105
126
|
{ prompt, cwd, sessionId } = {},
|
|
106
127
|
) {
|
|
128
|
+
publishHooksV2Event("UserPromptSubmit", {
|
|
129
|
+
cwd: cwd || null,
|
|
130
|
+
session_id: sessionId || null,
|
|
131
|
+
});
|
|
107
132
|
if (!settingsHooks) return { blocked: false, additionalContext: null };
|
|
108
133
|
const matched = collectHooks(settingsHooks, "UserPromptSubmit", "");
|
|
109
134
|
if (matched.length === 0) return { blocked: false, additionalContext: null };
|
|
@@ -119,7 +144,7 @@ function runUserPromptSubmitHooks(
|
|
|
119
144
|
},
|
|
120
145
|
{ sessionId },
|
|
121
146
|
);
|
|
122
|
-
const outcome = runHooks(sync, payload, {
|
|
147
|
+
const outcome = _deps.runHooks(sync, payload, {
|
|
123
148
|
cwd,
|
|
124
149
|
event: "UserPromptSubmit",
|
|
125
150
|
});
|
|
@@ -159,7 +184,7 @@ function dispatchAsyncHooks(settingsHooks, event, payload = {}, opts = {}) {
|
|
|
159
184
|
return supervisor.dispatch(
|
|
160
185
|
asyncHooks,
|
|
161
186
|
{ hook_event_name: event, cwd: opts.cwd, ...payload },
|
|
162
|
-
{ cwd: opts.cwd },
|
|
187
|
+
{ cwd: opts.cwd, broker: opts.broker },
|
|
163
188
|
);
|
|
164
189
|
}
|
|
165
190
|
|
|
@@ -169,6 +194,11 @@ function dispatchAsyncHooks(settingsHooks, event, payload = {}, opts = {}) {
|
|
|
169
194
|
* @returns {{ additionalContext:string|null }}
|
|
170
195
|
*/
|
|
171
196
|
function runSessionStartHooks(settingsHooks, { source, cwd, sessionId } = {}) {
|
|
197
|
+
publishHooksV2Event("SessionStart", {
|
|
198
|
+
source: source || "startup",
|
|
199
|
+
cwd: cwd || null,
|
|
200
|
+
session_id: sessionId || null,
|
|
201
|
+
});
|
|
172
202
|
if (!settingsHooks) return { additionalContext: null };
|
|
173
203
|
const matched = collectHooks(settingsHooks, "SessionStart", source || "");
|
|
174
204
|
if (matched.length === 0) return { additionalContext: null };
|
|
@@ -182,7 +212,10 @@ function runSessionStartHooks(settingsHooks, { source, cwd, sessionId } = {}) {
|
|
|
182
212
|
},
|
|
183
213
|
{ sessionId },
|
|
184
214
|
);
|
|
185
|
-
const outcome = runHooks(matched, payload, {
|
|
215
|
+
const outcome = _deps.runHooks(matched, payload, {
|
|
216
|
+
cwd,
|
|
217
|
+
event: "SessionStart",
|
|
218
|
+
});
|
|
186
219
|
return { additionalContext: aggregateContext(outcome.results) };
|
|
187
220
|
}
|
|
188
221
|
|
|
@@ -199,6 +232,11 @@ function runCwdChangedHooks(
|
|
|
199
232
|
settingsHooks,
|
|
200
233
|
{ oldCwd, newCwd, cwd, sessionId } = {},
|
|
201
234
|
) {
|
|
235
|
+
publishHooksV2Event("CwdChanged", {
|
|
236
|
+
old_cwd: oldCwd || null,
|
|
237
|
+
cwd: newCwd || cwd || null,
|
|
238
|
+
session_id: sessionId || null,
|
|
239
|
+
});
|
|
202
240
|
if (!settingsHooks) return { additionalContext: null };
|
|
203
241
|
const matched = collectHooks(settingsHooks, "CwdChanged", newCwd || "");
|
|
204
242
|
const { sync } = partitionAsyncHooks(matched);
|
|
@@ -213,7 +251,7 @@ function runCwdChangedHooks(
|
|
|
213
251
|
},
|
|
214
252
|
{ sessionId },
|
|
215
253
|
);
|
|
216
|
-
const outcome = runHooks(sync, payload, {
|
|
254
|
+
const outcome = _deps.runHooks(sync, payload, {
|
|
217
255
|
cwd: newCwd || cwd,
|
|
218
256
|
event: "CwdChanged",
|
|
219
257
|
});
|
|
@@ -234,6 +272,13 @@ function runWorktreeCreateHooks(
|
|
|
234
272
|
settingsHooks,
|
|
235
273
|
{ worktreePath, branch, baseSha, cwd, sessionId } = {},
|
|
236
274
|
) {
|
|
275
|
+
publishHooksV2Event("WorktreeCreate", {
|
|
276
|
+
worktree_path: worktreePath || null,
|
|
277
|
+
branch: branch || null,
|
|
278
|
+
base_sha: baseSha || null,
|
|
279
|
+
cwd: cwd || worktreePath || null,
|
|
280
|
+
session_id: sessionId || null,
|
|
281
|
+
});
|
|
237
282
|
if (!settingsHooks) return { additionalContext: null };
|
|
238
283
|
const matched = collectHooks(settingsHooks, "WorktreeCreate", branch || "");
|
|
239
284
|
const { sync } = partitionAsyncHooks(matched);
|
|
@@ -250,7 +295,7 @@ function runWorktreeCreateHooks(
|
|
|
250
295
|
},
|
|
251
296
|
{ sessionId },
|
|
252
297
|
);
|
|
253
|
-
const outcome = runHooks(sync, payload, {
|
|
298
|
+
const outcome = _deps.runHooks(sync, payload, {
|
|
254
299
|
cwd: cwd || worktreePath,
|
|
255
300
|
event: "WorktreeCreate",
|
|
256
301
|
});
|
|
@@ -271,6 +316,14 @@ function runWorktreeRemoveHooks(
|
|
|
271
316
|
settingsHooks,
|
|
272
317
|
{ worktreePath, branch, removed, reason, cwd, sessionId } = {},
|
|
273
318
|
) {
|
|
319
|
+
publishHooksV2Event("WorktreeRemove", {
|
|
320
|
+
worktree_path: worktreePath || null,
|
|
321
|
+
branch: branch || null,
|
|
322
|
+
removed: removed === true,
|
|
323
|
+
reason: reason || null,
|
|
324
|
+
cwd: cwd || worktreePath || null,
|
|
325
|
+
session_id: sessionId || null,
|
|
326
|
+
});
|
|
274
327
|
if (!settingsHooks) return { additionalContext: null };
|
|
275
328
|
const matched = collectHooks(settingsHooks, "WorktreeRemove", branch || "");
|
|
276
329
|
const { sync } = partitionAsyncHooks(matched);
|
|
@@ -288,7 +341,7 @@ function runWorktreeRemoveHooks(
|
|
|
288
341
|
},
|
|
289
342
|
{ sessionId },
|
|
290
343
|
);
|
|
291
|
-
const outcome = runHooks(sync, payload, {
|
|
344
|
+
const outcome = _deps.runHooks(sync, payload, {
|
|
292
345
|
cwd: cwd || worktreePath,
|
|
293
346
|
event: "WorktreeRemove",
|
|
294
347
|
});
|
|
@@ -312,6 +365,11 @@ function runInstructionsLoadedHooks(
|
|
|
312
365
|
settingsHooks,
|
|
313
366
|
{ files, cwd, sessionId } = {},
|
|
314
367
|
) {
|
|
368
|
+
publishHooksV2Event("InstructionsLoaded", {
|
|
369
|
+
count: Array.isArray(files) ? files.length : 0,
|
|
370
|
+
cwd: cwd || null,
|
|
371
|
+
session_id: sessionId || null,
|
|
372
|
+
});
|
|
315
373
|
if (!settingsHooks) return { additionalContext: null };
|
|
316
374
|
const matched = collectHooks(settingsHooks, "InstructionsLoaded", "");
|
|
317
375
|
const { sync } = partitionAsyncHooks(matched);
|
|
@@ -332,7 +390,7 @@ function runInstructionsLoadedHooks(
|
|
|
332
390
|
},
|
|
333
391
|
{ sessionId },
|
|
334
392
|
);
|
|
335
|
-
const outcome = runHooks(sync, payload, {
|
|
393
|
+
const outcome = _deps.runHooks(sync, payload, {
|
|
336
394
|
cwd,
|
|
337
395
|
event: "InstructionsLoaded",
|
|
338
396
|
});
|
|
@@ -353,11 +411,17 @@ function runObserveHooks(
|
|
|
353
411
|
payload = {},
|
|
354
412
|
{ cwd, matchTarget, traceId, parentId } = {},
|
|
355
413
|
) {
|
|
414
|
+
publishHooksV2Event(event, {
|
|
415
|
+
...payload,
|
|
416
|
+
cwd: cwd || payload.cwd || null,
|
|
417
|
+
trace_id: traceId || payload.trace_id || null,
|
|
418
|
+
parent_id: parentId || payload.parent_id || null,
|
|
419
|
+
});
|
|
356
420
|
if (!settingsHooks) return { decision: "continue", results: [] };
|
|
357
421
|
const matched = collectHooks(settingsHooks, event, matchTarget || "");
|
|
358
422
|
const { sync } = partitionAsyncHooks(matched);
|
|
359
423
|
if (sync.length === 0) return { decision: "continue", results: [] };
|
|
360
|
-
return runHooks(
|
|
424
|
+
return _deps.runHooks(
|
|
361
425
|
sync,
|
|
362
426
|
withDeliveryId(
|
|
363
427
|
event,
|
|
@@ -380,4 +444,5 @@ module.exports = {
|
|
|
380
444
|
aggregateContext,
|
|
381
445
|
partitionAsyncHooks,
|
|
382
446
|
dispatchAsyncHooks,
|
|
447
|
+
_deps,
|
|
383
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;
|
|
@@ -252,6 +252,10 @@ function collectHooks(hooksBlock, event, toolName) {
|
|
|
252
252
|
event,
|
|
253
253
|
async: h.async === true,
|
|
254
254
|
asyncRewake: h.asyncRewake === true,
|
|
255
|
+
origin: h.origin || "hook",
|
|
256
|
+
pluginId: h.pluginId || null,
|
|
257
|
+
pluginVersion: h.pluginVersion || null,
|
|
258
|
+
pluginSource: h.pluginSource || null,
|
|
255
259
|
});
|
|
256
260
|
}
|
|
257
261
|
}
|
|
@@ -56,6 +56,8 @@ const KIND_IDEMPOTENT = new Map([
|
|
|
56
56
|
["network-mutation", false],
|
|
57
57
|
["payment", false],
|
|
58
58
|
["file-write", false],
|
|
59
|
+
["file-delete", false],
|
|
60
|
+
["file-move", false],
|
|
59
61
|
["file-write-checkpointed", true],
|
|
60
62
|
["read", true],
|
|
61
63
|
["compute", true],
|
|
@@ -99,6 +101,18 @@ export function classifyToolSideEffect(toolName, args = {}) {
|
|
|
99
101
|
kind: "file-write",
|
|
100
102
|
key: shortKey(a.path || a.file || a.notebook_path),
|
|
101
103
|
};
|
|
104
|
+
case "delete_file":
|
|
105
|
+
return {
|
|
106
|
+
kind: "file-delete",
|
|
107
|
+
key: shortKey(a.path || a.file),
|
|
108
|
+
};
|
|
109
|
+
case "move_file":
|
|
110
|
+
return {
|
|
111
|
+
kind: "file-move",
|
|
112
|
+
key: shortKey(
|
|
113
|
+
`${a.path || a.file || ""} -> ${a.target_path || a.targetPath || ""}`,
|
|
114
|
+
),
|
|
115
|
+
};
|
|
102
116
|
case "edit_file_hashed":
|
|
103
117
|
// Hash-guarded: re-applying over an already-changed tree fails safely, so
|
|
104
118
|
// a replay cannot silently double-apply — idempotent-by-construction.
|
|
@@ -201,6 +215,14 @@ export class SideEffectLedger {
|
|
|
201
215
|
]);
|
|
202
216
|
}
|
|
203
217
|
|
|
218
|
+
/** Merge bounded correlation metadata discovered after an effect started. */
|
|
219
|
+
annotate(opId, metadata = {}) {
|
|
220
|
+
const rec = this._rec(opId);
|
|
221
|
+
if (!rec || !metadata || typeof metadata !== "object") return this;
|
|
222
|
+
rec.meta = { ...rec.meta, ...metadata };
|
|
223
|
+
return this;
|
|
224
|
+
}
|
|
225
|
+
|
|
204
226
|
/** Confirm the effect applied. Only from `started`. */
|
|
205
227
|
commit(opId) {
|
|
206
228
|
return this._advance(
|
|
@@ -115,6 +115,7 @@ cli-version-hash: "${hash}"
|
|
|
115
115
|
tags: [${allTags}]
|
|
116
116
|
user-invocable: true
|
|
117
117
|
handler: handler.js
|
|
118
|
+
capabilities: [shell-exec]
|
|
118
119
|
---
|
|
119
120
|
|
|
120
121
|
# ${domainDef.displayName}
|
|
@@ -176,7 +177,6 @@ export function generateDirectHandler(domainKey, domainDef) {
|
|
|
176
177
|
* 自动生成 — 请勿手动修改,运行 \`chainlesschain skill sync-cli\` 重新生成
|
|
177
178
|
*/
|
|
178
179
|
|
|
179
|
-
const { spawnSync } = require("child_process");
|
|
180
180
|
|
|
181
181
|
/** 解析输入字符串为指令+参数数组 */
|
|
182
182
|
function parseInput(input) {
|
|
@@ -241,7 +241,7 @@ ${commandGuide}
|
|
|
241
241
|
const useJson = JSON_SUPPORTED_COMMANDS.has(command) && !cliArgs.includes("--json");
|
|
242
242
|
if (useJson) cliArgs.push("--json");
|
|
243
243
|
|
|
244
|
-
// Security:
|
|
244
|
+
// Security: Broker execution uses shell:true (needed to run the chainlesschain.cmd
|
|
245
245
|
// shim on Windows), which joins cliArgs into a shell command. Reject shell
|
|
246
246
|
// metacharacters so a crafted skill input can't inject commands.
|
|
247
247
|
const unsafeArg = cliArgs.find((a) => /[;&|\`$<>()\\n\\r]/.test(a));
|
|
@@ -252,11 +252,16 @@ ${commandGuide}
|
|
|
252
252
|
};
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
|
|
256
|
-
|
|
255
|
+
const processBroker = context?.processBroker;
|
|
256
|
+
if (!processBroker || typeof processBroker.runSync !== "function") {
|
|
257
|
+
return { success: false, error: "Process Broker unavailable for skill execution." };
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Execute via the host-scoped Process Broker facade.
|
|
261
|
+
const result = processBroker.runSync("chainlesschain", cliArgs, {
|
|
257
262
|
encoding: "utf-8",
|
|
258
263
|
shell: true,
|
|
259
|
-
cwd: context
|
|
264
|
+
cwd: context?.projectRoot || process.cwd(),
|
|
260
265
|
timeout: 30000,
|
|
261
266
|
env: { ...process.env },
|
|
262
267
|
});
|
|
@@ -407,7 +412,6 @@ export function generateHybridHandler(domainKey, domainDef) {
|
|
|
407
412
|
* 自动生成 — 请勿手动修改,运行 \`chainlesschain skill sync-cli\` 重新生成
|
|
408
413
|
*/
|
|
409
414
|
|
|
410
|
-
const { spawnSync } = require("child_process");
|
|
411
415
|
|
|
412
416
|
const AGENT_ONLY_COMMANDS = new Set([${agentCmds}]);
|
|
413
417
|
const VALID_COMMANDS = new Set(["${commandList}"]);
|
|
@@ -470,7 +474,7 @@ const handler = {
|
|
|
470
474
|
// Direct execution for other commands
|
|
471
475
|
const cliArgs = [...args, "--quiet"];
|
|
472
476
|
|
|
473
|
-
// Security:
|
|
477
|
+
// Security: Broker execution uses shell:true (needed to run the chainlesschain.cmd
|
|
474
478
|
// shim on Windows), which joins cliArgs into a shell command. Reject shell
|
|
475
479
|
// metacharacters so a crafted skill input can't inject commands.
|
|
476
480
|
const unsafeArg = cliArgs.find((a) => /[;&|\`$<>()\\n\\r]/.test(a));
|
|
@@ -481,10 +485,15 @@ const handler = {
|
|
|
481
485
|
};
|
|
482
486
|
}
|
|
483
487
|
|
|
484
|
-
const
|
|
488
|
+
const processBroker = context?.processBroker;
|
|
489
|
+
if (!processBroker || typeof processBroker.runSync !== "function") {
|
|
490
|
+
return { success: false, error: "Process Broker unavailable for skill execution." };
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
const result = processBroker.runSync("chainlesschain", cliArgs, {
|
|
485
494
|
encoding: "utf-8",
|
|
486
495
|
shell: true,
|
|
487
|
-
cwd: context
|
|
496
|
+
cwd: context?.projectRoot || process.cwd(),
|
|
488
497
|
timeout: 30000,
|
|
489
498
|
env: { ...process.env },
|
|
490
499
|
});
|