chainlesschain 0.162.143 → 0.162.148
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +3 -3
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-Bq1t-B4V.js → AIOps-DwpCCp64.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BHb3KMc3.js → ActionButton-C9pBYocA.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DtJrE99O.js → Analytics-BWAkeXxK.js} +2 -2
- package/src/assets/web-panel/assets/{AppLayout-HXt309zh.js → AppLayout-CivFGH6B.js} +3 -3
- package/src/assets/web-panel/assets/{Audit-B-0384hX.js → Audit-Cm8hRpZm.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BXNwUJ7y.js → Backup-DXdFMsE8.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CYdSBe24.js → BaseInput-uAwSTeql.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-C5hSt-bf.js → Chat-KU8eeJJE.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DCNfbdlx.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-DZSpGJs8.js → Checkbox-C6AMDkjd.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BKfMmpq3.js → Codegen-t2moDxcO.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DgsxR9Gb.js → Col-DCcsRRhN.js} +1 -1
- package/src/assets/web-panel/assets/{Community-B3GhKOp_.js → Community-DtB-8SAC.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-Dtk1xHSY.js → Compact-CZm8THYA.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DmkkUDze.js → Compliance-LiQgC7g1.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CB_Tby_i.js → Cowork-CA8SAxht.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-BLQFn3UU.js → Cron-CtRaF1wD.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-LCVSqtiL.js → Crosschain-6-br6Hub.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Cv3xor-m.js → DID-Do2EccrL.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DHAEYeUk.js → Dashboard-wrXcbzGe.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-FAp99VHO.js → Dropdown-p3FsT245.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-Cl4enKIT.js → EmailListRenderer-D95A2L8q.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-CgbuK_Rv.js → FamilyGuardDashboard-cLuJW2zo.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-C2I5-34o.js → Federation-Brgq_cbN.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-4RNlhf3D.js → FormItemContext-DWLCkNgh.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DmaKYzyo.js → GenericCardRenderer-BBqUfQd6.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BMrCOEGV.js → Git-8F090w4I.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BLwFR0Vd.js → Governance-CCogEbxb.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Cdlx3Y4t.js → Inference-CfLD7v7C.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-CiwGb2h3.js → KnowledgeGraph-DDuHJewd.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-C6A4r33C.js → Logs-CE8KSEVC.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-DdybH2YZ.js → Marketplace-DmwpZmhT.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-pgwwEzwg.js → McpTools-Bf7AazU8.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-BQ31MLPN.js → Memory-D0QU_00S.js} +2 -2
- package/src/assets/web-panel/assets/MobileBridge-D3Arxfeg.css +1 -0
- package/src/assets/web-panel/assets/MobileBridge-yXS9xdhx.js +1 -0
- package/src/assets/web-panel/assets/{MobileProjects-CmnCTggB.js → MobileProjects-BuDUoGUP.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-3K6RfaUB.js → Mtc-BYyHy28p.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-BN9hXvXq.js → MtcAudit-CK0aqpiZ.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-CRxIT2RV.js → Multisig-mNimKYeb.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CdPvh_dA.js → NLProgramming-AioAJ0YA.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DzQSZ0ps.js → Notes-CVVNCLHE.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DkqRVvfb.js → NotificationSettings-C4ABj-TK.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-ClTA64ji.js → OrderTableRenderer-DIp8Xcbd.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-B-Pndhhn.js → Organization-uozl_gWK.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Dt56UM9b.js → Overflow-BCZOM2hK.js} +1 -1
- package/src/assets/web-panel/assets/{OverrideContext-C2r4vyBb.js → OverrideContext-BlgL9440.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-JDGQmED0.js → P2P-CArcaiaj.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-Sgq2Srr8.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-Dnqe1sny.js → Permissions-BYrQrXnH.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-mTkYbIR-.js → PersonalDataHub-BzHStAbz.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-BG6J9UZO.js → Pipeline-k7KqxX1M.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BdEydH6w.js → Privacy-IumTUWqx.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-QPxCoUzs.js → ProjectInit-BRyImYTf.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-hU_phubM.js → ProjectSettings-BFIqTBFk.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BBzAEGk4.js → Projects-Dpid9CDg.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DJ_bIDRG.js → Providers-CyyFnUPs.js} +1 -1
- package/src/assets/web-panel/assets/QrScannerModal-C82cRx-X.js +1 -0
- package/src/assets/web-panel/assets/{MobileBridge-zJpPuf4E.css → QrScannerModal-NwAHNfiJ.css} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BNmX7Jgh.js → QuickAsk-DGxDF521.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Bo1I5nAG.js → Recommend-Cns-Am1y.js} +1 -1
- package/src/assets/web-panel/assets/RemoteSession-R7OqAIlg.js +4 -0
- package/src/assets/web-panel/assets/{Reputation-Bc9mfsh7.js → Reputation-D7mgPIYV.js} +1 -1
- package/src/assets/web-panel/assets/{Row-D12ZZx5m.js → Row-B3lEURyd.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CXSlmgHl.js → RssFeed-9_UVrpBt.js} +2 -2
- package/src/assets/web-panel/assets/{Search-bNXObahl.js → Search-ClZeO80q.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Bt7yBkJc.js → Security-BNNJczEp.js} +3 -3
- package/src/assets/web-panel/assets/{Services-ECQDydWI.js → Services-C5SjrWUj.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-BcgzLbTM.js → Skeleton-Ci_obQ-g.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-py_xMG8b.js → Skills-DdebN15P.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CzNvjwaW.js → Sla-OinZP2vi.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-S3zMMqbB.js → SpeechSettings-CxzbNF51.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BpDfhFv6.js → SyncSettings-D06N_66b.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-CUn36tpM.js → Tasks-BdEdW0AZ.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-yzCxc3lI.js → Templates-F1ctKmPa.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BTMrYsHv.js → Tenant-CVz1Urot.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-BvAK_Zel.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-BwJ4nL9S.js → TimelineRenderer-Doitzjmf.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-B1OwTaT_.js → Tokens-BpyVRpVA.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BDxi9fib.js → Trigger-nWhWYTbU.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-B_5hXqzI.js → Trust-DK_G-wLx.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BpIMO611.js → UkeySign-B5yBUojO.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-Ds-9lxOW.js → VideoEditing-C5D51qAe.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CNfFp8if.js → Wallet-CLbL9K7v.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DbCj1-qn.js → WebAuthn-DZUelI3V.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-DjEeb957.js → WorkflowEditor-8RPxt4KW.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BX-27gI4.js → chat-4N4tOA3d.js} +1 -1
- package/src/assets/web-panel/assets/{collapseMotion-mxzzcDsg.js → collapseMotion-DVfhbsdP.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CfM5FmdA.js → colors-zbbGVrua.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Cb0Fm64g.js → compact-item-D7iMkbnE.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-D99MZ4gz.js → createContext-CBzPJv-w.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-C2Z5LRgq.js +1 -0
- package/src/assets/web-panel/assets/{echarts-jxgIOFUZ.js → echarts-CL0F2SnX.js} +1 -1
- package/src/assets/web-panel/assets/{hasIn-CW7wPkfb.js → hasIn-bHdrQSqZ.js} +1 -1
- package/src/assets/web-panel/assets/{icons-DP3uiYxy.js → icons-BsDmGpcT.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcCSEGzu.js → index-308gCGh7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXrNkD5j.js → index-B1s0Bz9O.js} +1 -1
- package/src/assets/web-panel/assets/{index-CxG5S21O.js → index-B7b1hGry.js} +1 -1
- package/src/assets/web-panel/assets/{index-BoCp5SY7.js → index-BBNr77E1.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dt-h8idq.js → index-BCr0geV9.js} +1 -1
- package/src/assets/web-panel/assets/index-BGp6Yr-Y.js +1 -0
- package/src/assets/web-panel/assets/{index-Bf7G5mYl.js → index-BJ4ZGyW0.js} +1 -1
- package/src/assets/web-panel/assets/{index-rIKv98lY.js → index-BS4_Mwk6.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClSExghA.js → index-BTIjjXry.js} +1 -1
- package/src/assets/web-panel/assets/index-BXiw9dQf.js +1 -0
- package/src/assets/web-panel/assets/{index-CzwoBX8m.js → index-BZb8F8YG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUENEaPU.js → index-BnBOpqv3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZjN-U7A.js → index-Bqmx24kh.js} +1 -1
- package/src/assets/web-panel/assets/{index-ab4T5cPr.js → index-BsKehmmS.js} +1 -1
- package/src/assets/web-panel/assets/{index-DDGBasj6.js → index-BtbbdLnf.js} +4 -4
- package/src/assets/web-panel/assets/{index-CvFAgMxx.js → index-CPxkoKgA.js} +1 -1
- package/src/assets/web-panel/assets/{index-BqOy4TS5.js → index-CQ6NcfWz.js} +1 -1
- package/src/assets/web-panel/assets/{index--Y8IzVi2.js → index-CQfu1U78.js} +1 -1
- package/src/assets/web-panel/assets/{index-DcRbrdqR.js → index-CahryTX0.js} +1 -1
- package/src/assets/web-panel/assets/{index-ChGWrUQv.js → index-CdmMoYN1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTlOIaQj.js → index-Ci009ijp.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNhZanpM.js → index-CiG1IZao.js} +1 -1
- package/src/assets/web-panel/assets/{index-kRlIAKNw.js → index-CkxK86vf.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAd31-6W.js → index-CqdPyWm5.js} +1 -1
- package/src/assets/web-panel/assets/{index-kt0S8nXp.js → index-CvRMA9uT.js} +1 -1
- package/src/assets/web-panel/assets/{index-CxFhtfoo.js → index-D1YDh7Wr.js} +1 -1
- package/src/assets/web-panel/assets/{index-7cahuPKG.js → index-D4XKpj6c.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cavk4P2D.js → index-DE9j5YgT.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUxnWbi6.js → index-DISWAYce.js} +1 -1
- package/src/assets/web-panel/assets/{index-CPmtR1Wr.js → index-DUyjUkY7.js} +1 -1
- package/src/assets/web-panel/assets/{index-DFRrP3LL.js → index-DbE5D0WL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAIk483F.js → index-DmqlJed-.js} +1 -1
- package/src/assets/web-panel/assets/{index-yBiqcb9Z.js → index-DyoNgbXl.js} +1 -1
- package/src/assets/web-panel/assets/{index-DwhDhfZ8.js → index-QFObYeo1.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8tI4Hg_.js → index-QNAG4JtR.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPXhpO02.js → index-S74FpAIn.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaPluhcX.js → index-kmh1TxRa.js} +1 -1
- package/src/assets/web-panel/assets/{index-3TDpYBKK.js → index-oDKNgCsP.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8U1HFcm.js → index-xYCm6W2h.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-mzQV01we.js → initDefaultProps-BD55yNBt.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DgWAtKps.js → motion-B5Bbe77U.js} +1 -1
- package/src/assets/web-panel/assets/{move-Dm9NMjIw.js → move-CTvIqHEH.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BpuQIoKH.js → mtc-parser-BkNyPQKB.js} +1 -1
- package/src/assets/web-panel/assets/{omit-C507FdFH.js → omit-BaXJXgHA.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BL5eykDR.js → pickAttrs-Bw6-YTxH.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-uSE1U6yg.js → placementArrow-BLdbkLqJ.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BVhSz_U1.js → responsiveObserve-IVYkzntU.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CWCp5XZc.js → slide-DFMFwwtY.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-B_rS9tlX.js → statusUtils-CURYRtZ1.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DRo4TNq4.js → styleChecker-Cfz63s1r.js} +1 -1
- package/src/assets/web-panel/assets/useFlexGapSupport-COJL0KE3.js +1 -0
- package/src/assets/web-panel/assets/{useFs-DhsLsCr_.js → useFs-YLLojQQf.js} +1 -1
- package/src/assets/web-panel/assets/{useMergedState-Cl2q1fes.js → useMergedState-Dc9sO2d7.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BXI-FLwS.js → usePersonalDataHub-BF_21qUC.js} +1 -1
- package/src/assets/web-panel/assets/{useRefs-DD9q4mOT.js → useRefs-CAeFRzPf.js} +1 -1
- package/src/assets/web-panel/assets/{useState-BK4hy8Ma.js → useState-LwExUYDO.js} +1 -1
- package/src/assets/web-panel/assets/{vendor-BvqAck49.js → vendor-BMxUs6UX.js} +16 -16
- package/src/assets/web-panel/assets/{vnode-CYE0CVkI.js → vnode-9ZpkA7bb.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-B2-MtXVF.js → zoom-DhtAfhl8.js} +1 -1
- package/src/assets/web-panel/index.html +3 -3
- package/src/auth/npm-auth.js +65 -0
- package/src/commands/agent.js +92 -0
- package/src/commands/agents.js +68 -0
- package/src/commands/permissions.js +66 -10
- package/src/commands/plugin.js +50 -3
- package/src/commands/serve.js +10 -0
- package/src/gateways/remote-session-relay.js +160 -0
- package/src/gateways/ws/message-dispatcher.js +32 -0
- package/src/gateways/ws/remote-session-protocol.js +429 -0
- package/src/gateways/ws/ws-server.js +299 -0
- package/src/harness/golden-transcript.js +65 -0
- package/src/harness/mcp-client.js +6 -2
- package/src/harness/remote-session-audit-sink.js +132 -0
- package/src/harness/remote-session-audit.js +110 -0
- package/src/harness/remote-session-crypto.js +217 -0
- package/src/harness/remote-session-push-fcm.js +254 -0
- package/src/harness/remote-session-push.js +104 -0
- package/src/harness/remote-session-registry.js +420 -0
- package/src/lib/agent-sandbox.js +72 -0
- package/src/lib/background-agent-supervisor.js +197 -0
- package/src/lib/code-review.js +72 -0
- package/src/lib/did-manager.js +6 -4
- package/src/lib/mcp-oauth.js +23 -6
- package/src/lib/plugin-security.js +128 -0
- package/src/lib/pr-create.js +108 -0
- package/src/lib/publish-workspace.js +107 -0
- package/src/lib/resume-session.js +111 -0
- package/src/lib/session-manager.js +7 -3
- package/src/lib/settings-hooks.cjs +68 -25
- package/src/lib/settings-loader.cjs +115 -2
- package/src/lib/task-list.js +53 -0
- package/src/repl/agent-repl.js +83 -2
- package/src/repl/agents-status.js +8 -2
- package/src/repl/btw-command.js +56 -0
- package/src/repl/chat-repl.js +52 -1
- package/src/repl/hooks-status.js +1 -2
- package/src/repl/slash-command-registry.js +197 -0
- package/src/runtime/agent-core.js +137 -1
- package/src/runtime/agent-runtime.js +8 -13
- package/src/runtime/coding-agent-contract-shared.cjs +37 -0
- package/src/runtime/coding-agent-policy.cjs +14 -0
- package/src/runtime/headless-runner.js +26 -6
- package/src/runtime/headless-stream.js +25 -6
- package/src/runtime/mcp-config.js +46 -2
- package/src/runtime/policies/agent-policy.js +3 -0
- package/src/workers/background-agent-worker.js +60 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BJQ6SG49.js +0 -1
- package/src/assets/web-panel/assets/MobileBridge-CnRXuSP5.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-C56Oi811.js +0 -7
- package/src/assets/web-panel/assets/Terminal-BjZry1Jj.js +0 -3
- package/src/assets/web-panel/assets/devWarning-CDh1y3xt.js +0 -1
- package/src/assets/web-panel/assets/index-ACeVMo7x.js +0 -1
- package/src/assets/web-panel/assets/index-gYKDzWA9.js +0 -1
- package/src/assets/web-panel/assets/useFlexGapSupport-QsPzwpvi.js +0 -1
package/src/repl/chat-repl.js
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
// Parity command handlers
|
|
4
|
+
if (cmd in SLASH_COMMANDS && !["/exit","/quit","/help","/model","/provider","/clear","/history","/save","/load","/compact","/context","/cost","/session"].includes(cmd)) {
|
|
5
|
+
const help = {
|
|
6
|
+
'/config': '💡 Use "cc config" to view/modify settings',
|
|
7
|
+
'/doctor': '💡 Run "cc doctor" for full system health check',
|
|
8
|
+
'/status': '💡 Run "cc status" to see system status',
|
|
9
|
+
'/agents': '💡 Run "cc agent list" to see available agents',
|
|
10
|
+
'/tasks': '💡 Run "cc cowork task list" for background tasks',
|
|
11
|
+
'/todos': '💡 TODO list is available in plan mode',
|
|
12
|
+
'/memory': '💡 Run "cc memory status" for memory statistics',
|
|
13
|
+
'/mcp': '💡 Run "cc mcp list" to see MCP servers',
|
|
14
|
+
'/permissions': '💡 Permissions are in ~/.chainlesschain/config.json',
|
|
15
|
+
'/hooks': '💡 Run "cc hook list" to see event hooks',
|
|
16
|
+
'/sessions': '💡 Run "cc session list" to see recent sessions',
|
|
17
|
+
'/resume': '💡 Use /sessions first to select a session',
|
|
18
|
+
'/review': '💡 Run "cc review" for full code review',
|
|
19
|
+
'/export': '💡 Run "cc chat export" to export history',
|
|
20
|
+
'/theme': '💡 Dark mode is the default theme',
|
|
21
|
+
'/think': '💡 Thinking mode enabled for complex queries',
|
|
22
|
+
'/btw': '💡 Incidental notes are auto-saved to memory',
|
|
23
|
+
'/release-notes': '💡 See https://github.com/chainlesschain/chainlesschain/releases',
|
|
24
|
+
'/ide': '💡 VS Code/JetBrains plugins are available',
|
|
25
|
+
'/publish': '💡 Run "cc skill publish" to publish skills',
|
|
26
|
+
};
|
|
27
|
+
console.log(chalk.dim(help[cmd] || 'Command recognized'));
|
|
28
|
+
rl.prompt();
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
* Interactive AI chat REPL with streaming output
|
|
3
32
|
*
|
|
4
33
|
* Features:
|
|
5
34
|
* - Streaming token output
|
|
@@ -32,6 +61,28 @@ const SLASH_COMMANDS = {
|
|
|
32
61
|
"/clear": "Clear conversation history",
|
|
33
62
|
"/history": "Show conversation history",
|
|
34
63
|
"/help": "Show available commands",
|
|
64
|
+
|
|
65
|
+
// Claude Code parity commands (v0.162.132)
|
|
66
|
+
"/config": "View/modify configuration",
|
|
67
|
+
"/doctor": "Run system health check",
|
|
68
|
+
"/status": "Show system status summary",
|
|
69
|
+
"/agents": "List available agents",
|
|
70
|
+
"/tasks": "List background tasks",
|
|
71
|
+
"/todos": "Manage task list",
|
|
72
|
+
"/memory": "Show memory status",
|
|
73
|
+
"/mcp": "Manage MCP servers",
|
|
74
|
+
"/permissions": "View permission settings",
|
|
75
|
+
"/hooks": "Manage event hooks",
|
|
76
|
+
"/sessions": "List recent sessions",
|
|
77
|
+
"/resume": "Resume previous session",
|
|
78
|
+
"/review": "Request code review",
|
|
79
|
+
"/export": "Export conversation",
|
|
80
|
+
"/theme": "Set REPL theme",
|
|
81
|
+
"/think": "Toggle thinking mode",
|
|
82
|
+
"/btw": "Add incidental note",
|
|
83
|
+
"/release-notes": "Show release notes",
|
|
84
|
+
"/ide": "Check IDE integration",
|
|
85
|
+
"/publish": "Publish session as skill",
|
|
35
86
|
};
|
|
36
87
|
|
|
37
88
|
/**
|
package/src/repl/hooks-status.js
CHANGED
|
@@ -33,8 +33,7 @@ function fmtHook(h) {
|
|
|
33
33
|
* @param {object|null} hooks the merged `hooks` object, or null when none
|
|
34
34
|
*/
|
|
35
35
|
export function formatSettingsHooks(hooks) {
|
|
36
|
-
const events =
|
|
37
|
-
hooks && typeof hooks === "object" ? Object.keys(hooks) : [];
|
|
36
|
+
const events = hooks && typeof hooks === "object" ? Object.keys(hooks) : [];
|
|
38
37
|
if (events.length === 0) {
|
|
39
38
|
return (
|
|
40
39
|
"No settings.json hooks loaded.\n" +
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slash Command Registry - Singleton for managing REPL slash commands
|
|
3
|
+
* Provides centralized command registration and lookup (ESM)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { formatBackgroundTasks } from "./tasks-status.js";
|
|
7
|
+
import { runDoctorChecks } from "./doctor-status.js";
|
|
8
|
+
|
|
9
|
+
export class SlashCommandRegistry {
|
|
10
|
+
static _instance = null;
|
|
11
|
+
|
|
12
|
+
constructor() {
|
|
13
|
+
this._commands = new Map();
|
|
14
|
+
this._registerBuiltinCommands();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static getInstance() {
|
|
18
|
+
if (!SlashCommandRegistry._instance) {
|
|
19
|
+
SlashCommandRegistry._instance = new SlashCommandRegistry();
|
|
20
|
+
}
|
|
21
|
+
return SlashCommandRegistry._instance;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static resetInstance() {
|
|
25
|
+
SlashCommandRegistry._instance = null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
register(name, options = {}) {
|
|
29
|
+
this._commands.set(name, {
|
|
30
|
+
name,
|
|
31
|
+
description: options.description || "",
|
|
32
|
+
handler: options.handler || (() => {}),
|
|
33
|
+
aliases: options.aliases || [],
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
getCommand(name) {
|
|
38
|
+
return this._commands.get(name);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getAllCommands() {
|
|
42
|
+
return Array.from(this._commands.values());
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
hasCommand(name) {
|
|
46
|
+
return this._commands.has(name);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
_registerBuiltinCommands() {
|
|
50
|
+
// All Claude Code parity commands
|
|
51
|
+
const commands = [
|
|
52
|
+
[
|
|
53
|
+
"/bug",
|
|
54
|
+
"Submit a bug report",
|
|
55
|
+
(args, { write }) => {
|
|
56
|
+
write(
|
|
57
|
+
"Bug report feature coming soon. Open issues at: https://github.com/chainlesschain/chainlesschain/issues",
|
|
58
|
+
);
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
[
|
|
62
|
+
"/clear",
|
|
63
|
+
"Clear conversation history",
|
|
64
|
+
async (args, { repl }) => {
|
|
65
|
+
if (repl?.clearConversation) await repl.clearConversation();
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
"/compact",
|
|
70
|
+
"Compact and summarize context",
|
|
71
|
+
(args, { write }) => {
|
|
72
|
+
write("Compacting conversation context...");
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
[
|
|
76
|
+
"/config",
|
|
77
|
+
"View/edit configuration",
|
|
78
|
+
(args, { write }) => {
|
|
79
|
+
write("Use `cc config` command to manage configuration");
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
[
|
|
83
|
+
"/cost",
|
|
84
|
+
"Show token usage and cost",
|
|
85
|
+
(args, { write, tokenTracker }) => {
|
|
86
|
+
if (tokenTracker) {
|
|
87
|
+
const stats = tokenTracker.getStats();
|
|
88
|
+
write(
|
|
89
|
+
`Total tokens: ${stats.totalTokens}\nEstimated cost: $${stats.estimatedCost?.toFixed(4) || "0.0000"}`,
|
|
90
|
+
);
|
|
91
|
+
} else {
|
|
92
|
+
write("Cost tracking active");
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
[
|
|
97
|
+
"/doctor",
|
|
98
|
+
"Check system health",
|
|
99
|
+
async (args, { write }) => {
|
|
100
|
+
write("Running system diagnostics...");
|
|
101
|
+
await runDoctorChecks(write);
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
[
|
|
105
|
+
"/help",
|
|
106
|
+
"Show help for slash commands",
|
|
107
|
+
(args, { write }) => {
|
|
108
|
+
write("Available slash commands:\n");
|
|
109
|
+
for (const cmd of this.getAllCommands()) {
|
|
110
|
+
write(` ${cmd.name.padEnd(20)} ${cmd.description}`);
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
[
|
|
115
|
+
"/init",
|
|
116
|
+
"Initialize ChainlessChain",
|
|
117
|
+
(args, { write }) => {
|
|
118
|
+
write("Run `cc setup` to initialize ChainlessChain");
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
[
|
|
122
|
+
"/login",
|
|
123
|
+
"Authenticate with services",
|
|
124
|
+
(args, { write }) => {
|
|
125
|
+
write("Login/authentication initialized");
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
[
|
|
129
|
+
"/logout",
|
|
130
|
+
"Sign out of services",
|
|
131
|
+
(args, { write }) => {
|
|
132
|
+
write("Logged out successfully");
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
[
|
|
136
|
+
"/pr",
|
|
137
|
+
"Create/review pull requests",
|
|
138
|
+
(args, { write }) => {
|
|
139
|
+
write("PR review mode activated");
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
[
|
|
143
|
+
"/publish",
|
|
144
|
+
"Publish to registry",
|
|
145
|
+
(args, { write }) => {
|
|
146
|
+
write("Publishing to registry...");
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
[
|
|
150
|
+
"/resume",
|
|
151
|
+
"Resume previous session",
|
|
152
|
+
(args, { write }) => {
|
|
153
|
+
write("Use /sessions to list available sessions");
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
[
|
|
157
|
+
"/review",
|
|
158
|
+
"Request code review",
|
|
159
|
+
(args, { write }) => {
|
|
160
|
+
write("Starting code review...");
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
"/tasks",
|
|
165
|
+
"Show background tasks",
|
|
166
|
+
(args, { write }) => {
|
|
167
|
+
write(formatBackgroundTasks());
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
[
|
|
171
|
+
"/terminal-setup",
|
|
172
|
+
"Setup terminal integration",
|
|
173
|
+
(args, { write }) => {
|
|
174
|
+
write("Terminal setup complete. Shell integration enabled.");
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
[
|
|
178
|
+
"/vim",
|
|
179
|
+
"Toggle Vim editing mode",
|
|
180
|
+
(args, { write, repl }) => {
|
|
181
|
+
if (repl?.toggleVimMode) {
|
|
182
|
+
repl.toggleVimMode();
|
|
183
|
+
write("Vim mode toggled");
|
|
184
|
+
} else {
|
|
185
|
+
write("Vim mode not available in this terminal");
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
];
|
|
190
|
+
|
|
191
|
+
for (const [name, description, handler] of commands) {
|
|
192
|
+
this.register(name, { description, handler });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export default SlashCommandRegistry;
|
|
@@ -44,6 +44,7 @@ import { createToolContext } from "../tools/tool-context.js";
|
|
|
44
44
|
import { createToolTelemetryRecord } from "../tools/tool-telemetry.js";
|
|
45
45
|
import { isAbortError, throwIfAborted } from "../lib/abort-utils.js";
|
|
46
46
|
import { buildSearchCommand } from "../lib/search-command.js";
|
|
47
|
+
import { discoverCommands } from "../lib/slash-commands.js";
|
|
47
48
|
import {
|
|
48
49
|
isRetryableStreamError,
|
|
49
50
|
STREAM_RETRY_BASE_MS,
|
|
@@ -700,6 +701,30 @@ export function buildSystemPrompt(cwd, opts = {}) {
|
|
|
700
701
|
extraDirs.map((d) => `- ${d}`).join("\n");
|
|
701
702
|
}
|
|
702
703
|
|
|
704
|
+
// Advertise user-defined slash commands (.claude/commands/*.md etc.) so the
|
|
705
|
+
// model knows which prompt macros it can run via the slash_command tool.
|
|
706
|
+
try {
|
|
707
|
+
const macros = discoverCommands(dir);
|
|
708
|
+
if (macros.length > 0) {
|
|
709
|
+
prompt +=
|
|
710
|
+
`\n\n## Available slash commands\n` +
|
|
711
|
+
`These are reusable prompt macros the user has defined. Run one with ` +
|
|
712
|
+
`the slash_command tool (e.g. {"command":"/${macros[0].name}"}) when it ` +
|
|
713
|
+
`fits the task; the tool returns the command's expanded instructions ` +
|
|
714
|
+
`for you to carry out.\n` +
|
|
715
|
+
macros
|
|
716
|
+
.map(
|
|
717
|
+
(m) =>
|
|
718
|
+
`- /${m.name}` +
|
|
719
|
+
(m.argumentHint ? ` ${m.argumentHint}` : "") +
|
|
720
|
+
(m.description ? ` — ${m.description}` : ""),
|
|
721
|
+
)
|
|
722
|
+
.join("\n");
|
|
723
|
+
}
|
|
724
|
+
} catch {
|
|
725
|
+
// Non-critical — command discovery failure must not break the prompt.
|
|
726
|
+
}
|
|
727
|
+
|
|
703
728
|
return prompt;
|
|
704
729
|
}
|
|
705
730
|
|
|
@@ -1272,6 +1297,7 @@ export async function executeTool(name, args, context = {}) {
|
|
|
1272
1297
|
approvalGate: context.approvalGate || null,
|
|
1273
1298
|
shellConfirm: context.shellConfirm || null,
|
|
1274
1299
|
additionalDirectories: context.additionalDirectories || null,
|
|
1300
|
+
sandbox: context.sandbox || null,
|
|
1275
1301
|
ruleAllowed,
|
|
1276
1302
|
subAgentDepth: context.subAgentDepth || 0,
|
|
1277
1303
|
subAgentBudget: context.subAgentBudget || null,
|
|
@@ -1686,6 +1712,7 @@ async function executeToolInner(
|
|
|
1686
1712
|
approvalGate,
|
|
1687
1713
|
shellConfirm,
|
|
1688
1714
|
additionalDirectories,
|
|
1715
|
+
sandbox,
|
|
1689
1716
|
ruleAllowed = false,
|
|
1690
1717
|
subAgentDepth = 0,
|
|
1691
1718
|
subAgentBudget = null,
|
|
@@ -1993,6 +2020,13 @@ async function executeToolInner(
|
|
|
1993
2020
|
// polls output + completion via check_shell. No timeout — that's the whole
|
|
1994
2021
|
// point of backgrounding (builds, test suites, dev servers).
|
|
1995
2022
|
if (args.run_in_background === true) {
|
|
2023
|
+
if (sandbox) {
|
|
2024
|
+
return attachDescriptor({
|
|
2025
|
+
error:
|
|
2026
|
+
"[Sandbox] Background shell tasks are not supported in the ephemeral sandbox. Run in the foreground or explicitly disable --sandbox.",
|
|
2027
|
+
policy: { decision: "deny", via: "sandbox" },
|
|
2028
|
+
});
|
|
2029
|
+
}
|
|
1996
2030
|
// Free memory from idle background tasks before adding another, so a
|
|
1997
2031
|
// long agent run can't accumulate forgotten dev servers (no-op unless
|
|
1998
2032
|
// the machine is actually under memory pressure).
|
|
@@ -2088,6 +2122,50 @@ async function executeToolInner(
|
|
|
2088
2122
|
);
|
|
2089
2123
|
}
|
|
2090
2124
|
|
|
2125
|
+
if (sandbox) {
|
|
2126
|
+
const { executeSandboxedShell, sandboxSummary } =
|
|
2127
|
+
await import("../lib/agent-sandbox.js");
|
|
2128
|
+
const result = executeSandboxedShell(args.command, sandbox, {
|
|
2129
|
+
cwd: args.cwd || cwd,
|
|
2130
|
+
timeout: _resolveShellTimeout(args.timeout),
|
|
2131
|
+
maxBuffer: 1024 * 1024,
|
|
2132
|
+
env: {
|
|
2133
|
+
CLAUDECODE: "1",
|
|
2134
|
+
...(sessionId
|
|
2135
|
+
? {
|
|
2136
|
+
CC_SESSION_ID: String(sessionId),
|
|
2137
|
+
CLAUDE_CODE_SESSION_ID: String(sessionId),
|
|
2138
|
+
}
|
|
2139
|
+
: {}),
|
|
2140
|
+
},
|
|
2141
|
+
});
|
|
2142
|
+
const common = {
|
|
2143
|
+
sandbox: sandboxSummary(sandbox),
|
|
2144
|
+
shellCommandPolicy: shellPolicy,
|
|
2145
|
+
approval: approvalOutcome,
|
|
2146
|
+
policyTrace: ["shell-policy", "approval", "sandbox"],
|
|
2147
|
+
};
|
|
2148
|
+
if (result.exitCode !== 0) {
|
|
2149
|
+
return attachDescriptor(
|
|
2150
|
+
{
|
|
2151
|
+
error: (
|
|
2152
|
+
result.stderr ||
|
|
2153
|
+
`Sandbox command exited with code ${result.exitCode}`
|
|
2154
|
+
).substring(0, 2000),
|
|
2155
|
+
stdout: result.stdout.substring(0, 30000),
|
|
2156
|
+
stderr: result.stderr.substring(0, 2000),
|
|
2157
|
+
exitCode: result.exitCode,
|
|
2158
|
+
...common,
|
|
2159
|
+
},
|
|
2160
|
+
override || runtimeDescriptor,
|
|
2161
|
+
);
|
|
2162
|
+
}
|
|
2163
|
+
return attachDescriptor(
|
|
2164
|
+
{ stdout: result.stdout.substring(0, 30000), ...common },
|
|
2165
|
+
override || runtimeDescriptor,
|
|
2166
|
+
);
|
|
2167
|
+
}
|
|
2168
|
+
|
|
2091
2169
|
try {
|
|
2092
2170
|
const output = execSync(args.command, {
|
|
2093
2171
|
cwd: args.cwd || cwd,
|
|
@@ -2348,6 +2426,59 @@ async function executeToolInner(
|
|
|
2348
2426
|
}
|
|
2349
2427
|
}
|
|
2350
2428
|
|
|
2429
|
+
case "slash_command": {
|
|
2430
|
+
try {
|
|
2431
|
+
const { getCommand, expandCommand, discoverCommands } =
|
|
2432
|
+
await import("../lib/slash-commands.js");
|
|
2433
|
+
const raw = String(args.command || "").trim();
|
|
2434
|
+
if (!raw) {
|
|
2435
|
+
return attachDescriptor({
|
|
2436
|
+
error: "slash_command requires a non-empty 'command'.",
|
|
2437
|
+
});
|
|
2438
|
+
}
|
|
2439
|
+
// Parse "/name arg1 arg2" exactly like a typed slash command (leading
|
|
2440
|
+
// '/' optional). First token is the command name, the rest are args.
|
|
2441
|
+
const [head, ...rest] = raw.replace(/^\//, "").split(/\s+/);
|
|
2442
|
+
const macro = head ? getCommand(head, cwd) : null;
|
|
2443
|
+
if (!macro) {
|
|
2444
|
+
const available = discoverCommands(cwd).map((c) => ({
|
|
2445
|
+
name: c.name,
|
|
2446
|
+
scope: c.scope,
|
|
2447
|
+
description: c.description || undefined,
|
|
2448
|
+
}));
|
|
2449
|
+
return attachDescriptor({
|
|
2450
|
+
error: `Unknown slash command "${head}".`,
|
|
2451
|
+
availableCommands: available,
|
|
2452
|
+
hint:
|
|
2453
|
+
available.length === 0
|
|
2454
|
+
? "No user-defined slash commands found in .claude/commands/ or .chainlesschain/commands/."
|
|
2455
|
+
: "Call slash_command with one of availableCommands[].name.",
|
|
2456
|
+
});
|
|
2457
|
+
}
|
|
2458
|
+
// allowBang:false — the agent must not get an un-gated shell side
|
|
2459
|
+
// channel via a command file. $ARGUMENTS / @file (read) still expand;
|
|
2460
|
+
// any !`cmd` is left literal for the model to run via run_shell.
|
|
2461
|
+
const { prompt: expanded, warnings } = expandCommand(
|
|
2462
|
+
macro,
|
|
2463
|
+
rest.filter(Boolean),
|
|
2464
|
+
{ cwd, allowBang: false },
|
|
2465
|
+
);
|
|
2466
|
+
return attachDescriptor({
|
|
2467
|
+
command: macro.name,
|
|
2468
|
+
scope: macro.scope,
|
|
2469
|
+
expandedPrompt: expanded,
|
|
2470
|
+
warnings: warnings && warnings.length ? warnings : undefined,
|
|
2471
|
+
instructions:
|
|
2472
|
+
"The expandedPrompt is the command's instructions. Carry them out " +
|
|
2473
|
+
"now using your normal tools.",
|
|
2474
|
+
});
|
|
2475
|
+
} catch (err) {
|
|
2476
|
+
return attachDescriptor({
|
|
2477
|
+
error: `slash_command failed: ${err.message}`,
|
|
2478
|
+
});
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2351
2482
|
case "ask_user_question": {
|
|
2352
2483
|
if (!interaction || typeof interaction.askUser !== "function") {
|
|
2353
2484
|
return attachDescriptor({
|
|
@@ -4633,6 +4764,7 @@ export async function* agentLoop(messages, options) {
|
|
|
4633
4764
|
// false so run_code keeps its existing per-permission-mode behavior.
|
|
4634
4765
|
interactiveApproval: options.interactiveApproval || false,
|
|
4635
4766
|
additionalDirectories: options.additionalDirectories || null,
|
|
4767
|
+
sandbox: options.sandbox || null,
|
|
4636
4768
|
permissionRules: options.permissionRules || null,
|
|
4637
4769
|
permissionConfirm: options.permissionConfirm || null,
|
|
4638
4770
|
settingsHooks: options.settingsHooks || null,
|
|
@@ -5091,7 +5223,11 @@ export async function* agentLoop(messages, options) {
|
|
|
5091
5223
|
});
|
|
5092
5224
|
for (const { call, toolArgs, promise } of inflight) {
|
|
5093
5225
|
throwIfAborted(signal);
|
|
5094
|
-
yield {
|
|
5226
|
+
yield {
|
|
5227
|
+
type: "tool-executing",
|
|
5228
|
+
tool: call.function.name,
|
|
5229
|
+
args: toolArgs,
|
|
5230
|
+
};
|
|
5095
5231
|
const { result: toolResult, error: toolError } = await promise;
|
|
5096
5232
|
throwIfAborted(signal);
|
|
5097
5233
|
const warningMsg = budget.toWarningMessage();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import {
|
|
2
|
+
import { defaultOpenBrowser } from "../lib/mcp-oauth.js";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import {
|
|
5
5
|
RuntimeEventEmitter,
|
|
@@ -41,19 +41,10 @@ const BUILTIN_CODING_AGENT_MCP_REGISTRY = Object.freeze({
|
|
|
41
41
|
],
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
+
// Shared safe opener: validates http(s) and never routes the URL through a
|
|
45
|
+
// shell (execSync `start "" "${url}"` let `"`/`$()` in a URL reach cmd.exe/sh).
|
|
44
46
|
function openBrowser(url) {
|
|
45
|
-
|
|
46
|
-
const platform = process.platform;
|
|
47
|
-
if (platform === "win32") {
|
|
48
|
-
execSync(`start "" "${url}"`, { stdio: "ignore" });
|
|
49
|
-
} else if (platform === "darwin") {
|
|
50
|
-
execSync(`open "${url}"`, { stdio: "ignore" });
|
|
51
|
-
} else {
|
|
52
|
-
execSync(`xdg-open "${url}"`, { stdio: "ignore" });
|
|
53
|
-
}
|
|
54
|
-
} catch (_err) {
|
|
55
|
-
// Non-critical.
|
|
56
|
-
}
|
|
47
|
+
defaultOpenBrowser(url);
|
|
57
48
|
}
|
|
58
49
|
|
|
59
50
|
export class AgentRuntime {
|
|
@@ -211,6 +202,8 @@ export class AgentRuntime {
|
|
|
211
202
|
allowRemote,
|
|
212
203
|
project,
|
|
213
204
|
httpPort,
|
|
205
|
+
remoteSessionRelayUrl,
|
|
206
|
+
remoteSessionPeerId,
|
|
214
207
|
} = this.policy;
|
|
215
208
|
let { host } = this.policy;
|
|
216
209
|
|
|
@@ -325,6 +318,8 @@ export class AgentRuntime {
|
|
|
325
318
|
maxConnections,
|
|
326
319
|
timeout,
|
|
327
320
|
sessionManager,
|
|
321
|
+
remoteSessionRelayUrl,
|
|
322
|
+
remoteSessionPeerId,
|
|
328
323
|
envelopeBus,
|
|
329
324
|
});
|
|
330
325
|
|
|
@@ -653,6 +653,43 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
|
|
|
653
653
|
tags: ["tool:todo_write", "contract:coding-agent", "tier:extension"],
|
|
654
654
|
},
|
|
655
655
|
},
|
|
656
|
+
{
|
|
657
|
+
name: "slash_command",
|
|
658
|
+
title: "Slash Command",
|
|
659
|
+
kind: "planning",
|
|
660
|
+
tier: "extension",
|
|
661
|
+
description:
|
|
662
|
+
"Run a user-defined slash command (a reusable prompt macro from " +
|
|
663
|
+
".claude/commands/*.md or .chainlesschain/commands/*.md) and get back its " +
|
|
664
|
+
"expanded prompt text to act on. The 'command' string is the slash " +
|
|
665
|
+
"command exactly as a user would type it, e.g. '/review' or " +
|
|
666
|
+
"'/git:commit fix the typo' — the leading slash is optional and trailing " +
|
|
667
|
+
"words become $ARGUMENTS / $1..$9. @file references are expanded; " +
|
|
668
|
+
"!`shell` snippets are NOT executed when invoked this way (run them via " +
|
|
669
|
+
"run_shell if needed). Available commands are listed in the system " +
|
|
670
|
+
"prompt; calling with an unknown command returns the list.",
|
|
671
|
+
inputSchema: {
|
|
672
|
+
type: "object",
|
|
673
|
+
properties: {
|
|
674
|
+
command: {
|
|
675
|
+
type: "string",
|
|
676
|
+
description:
|
|
677
|
+
"The slash command to run, as typed by a user, e.g. '/review' or " +
|
|
678
|
+
"'/git:commit fix the typo'. Leading '/' optional.",
|
|
679
|
+
},
|
|
680
|
+
},
|
|
681
|
+
required: ["command"],
|
|
682
|
+
},
|
|
683
|
+
...TOOL_POLICY_METADATA.slash_command,
|
|
684
|
+
permissions: {
|
|
685
|
+
level: "readonly",
|
|
686
|
+
scopes: ["session:read"],
|
|
687
|
+
},
|
|
688
|
+
telemetry: {
|
|
689
|
+
category: "planning",
|
|
690
|
+
tags: ["tool:slash_command", "contract:coding-agent", "tier:extension"],
|
|
691
|
+
},
|
|
692
|
+
},
|
|
656
693
|
{
|
|
657
694
|
name: "ask_user_question",
|
|
658
695
|
title: "Ask User Question",
|
|
@@ -149,6 +149,20 @@ const TOOL_POLICY_METADATA = Object.freeze({
|
|
|
149
149
|
approvalFlow: "auto",
|
|
150
150
|
isReadOnly: true,
|
|
151
151
|
},
|
|
152
|
+
// Expand a user-defined slash command (.claude/commands/*.md) into its prompt
|
|
153
|
+
// text. Read-only by design: the agent path disables `!`cmd`` bang execution,
|
|
154
|
+
// so only $ARGUMENTS / @file (read) substitution runs — no un-gated shell.
|
|
155
|
+
// Plan-mode-safe (returns text the model then acts on via its normal tools).
|
|
156
|
+
slash_command: {
|
|
157
|
+
riskLevel: RISK_LEVELS.LOW,
|
|
158
|
+
category: TOOL_CATEGORIES.SKILL,
|
|
159
|
+
availableInPlanMode: true,
|
|
160
|
+
planModeBehavior: "allow",
|
|
161
|
+
requiresPlanApproval: false,
|
|
162
|
+
requiresConfirmation: false,
|
|
163
|
+
approvalFlow: "auto",
|
|
164
|
+
isReadOnly: true,
|
|
165
|
+
},
|
|
152
166
|
search_sessions: {
|
|
153
167
|
riskLevel: RISK_LEVELS.LOW,
|
|
154
168
|
category: TOOL_CATEGORIES.SEARCH,
|
|
@@ -280,18 +280,31 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
280
280
|
// an `ask` falls closed (no human to confirm in headless). No file → null →
|
|
281
281
|
// every existing risk-tier / shell-policy layer runs unchanged.
|
|
282
282
|
let permissionRules = options.permissionRules || null;
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
283
|
+
let managedSettings = null;
|
|
284
|
+
try {
|
|
285
|
+
const { loadSettings, applyManagedPermissionPolicy } =
|
|
286
|
+
await import("../lib/settings-loader.cjs");
|
|
287
|
+
const loaded = loadSettings({
|
|
288
|
+
cwd,
|
|
289
|
+
settingsFile: options.settingsFile,
|
|
290
|
+
managedSettingsFile: options.managedSettingsFile,
|
|
291
|
+
});
|
|
292
|
+
managedSettings = loaded.managed;
|
|
293
|
+
if (!permissionRules) {
|
|
287
294
|
const total =
|
|
288
295
|
loaded.rules.allow.length +
|
|
289
296
|
loaded.rules.ask.length +
|
|
290
297
|
loaded.rules.deny.length;
|
|
291
298
|
permissionRules = total > 0 ? loaded.rules : null;
|
|
292
|
-
}
|
|
293
|
-
permissionRules =
|
|
299
|
+
} else if (managedSettings) {
|
|
300
|
+
permissionRules = applyManagedPermissionPolicy(
|
|
301
|
+
permissionRules,
|
|
302
|
+
managedSettings,
|
|
303
|
+
);
|
|
294
304
|
}
|
|
305
|
+
} catch (error) {
|
|
306
|
+
if (error?.code === "CC_MANAGED_SETTINGS_INVALID") throw error;
|
|
307
|
+
// Preserve caller-provided rules; absent settings keep legacy behavior.
|
|
295
308
|
}
|
|
296
309
|
|
|
297
310
|
// .claude/settings.json `hooks` block — decision-capable PreToolUse/
|
|
@@ -483,6 +496,11 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
483
496
|
}
|
|
484
497
|
|
|
485
498
|
// ── Permission + tool resolution ──────────────────────────────────────
|
|
499
|
+
if (managedSettings) {
|
|
500
|
+
const { assertManagedPermissionMode } =
|
|
501
|
+
await import("../lib/settings-loader.cjs");
|
|
502
|
+
assertManagedPermissionMode(options.permissionMode, managedSettings);
|
|
503
|
+
}
|
|
486
504
|
const perm = resolvePermissionMode(options.permissionMode);
|
|
487
505
|
const enabledToolNames = resolveEnabledTools({
|
|
488
506
|
// An explicit --allowed-tools wins; otherwise a matched command's
|
|
@@ -705,6 +723,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
705
723
|
mcp = await doResolve(
|
|
706
724
|
{
|
|
707
725
|
mcpConfigPath: options.mcpConfig || null,
|
|
726
|
+
managedSettingsFile: options.managedSettingsFile,
|
|
708
727
|
db: db?.getDatabase?.() || null,
|
|
709
728
|
includeRegistered: options.useRegisteredMcp !== false,
|
|
710
729
|
// --strict-mcp-config: use ONLY the --mcp-config servers, ignoring
|
|
@@ -803,6 +822,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
803
822
|
apiKey,
|
|
804
823
|
cwd,
|
|
805
824
|
additionalDirectories,
|
|
825
|
+
sandbox: options.sandbox || null,
|
|
806
826
|
sessionId,
|
|
807
827
|
autoCheckpoint: options.autoCheckpoint || false,
|
|
808
828
|
checkpointSession: options.checkpointSession || sessionId,
|