chainlesschain 0.162.160 → 0.162.161
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 +1 -1
- package/src/assets/web-panel/assets/{AIOps-CkRHjW8e.js → AIOps-DMn528q-.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BP3MeNi2.js → ActionButton-D9ZcDCJL.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CjbjQsOr.js → Analytics-A_K-8PX0.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-i0adH1M8.js → AppLayout-D4pFW3X6.js} +3 -3
- package/src/assets/web-panel/assets/{Artifacts-CCCG2GOU.js → Artifacts-Dz46COAd.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DrsgvwHC.js → Audit-cbMjbyg0.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DkXNkbZM.js → BackgroundAgents-Dtf88GAj.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DarTWCex.js → Backup-C5KRxn52.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DaDzhcto.js → BaseInput-Dd2UK3BN.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-C4EzGw6V.js → Chat-lptKTFdG.js} +6 -6
- package/src/assets/web-panel/assets/ChatBubbleRenderer-C2KLtwHz.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-gddNgaQi.js → Checkbox-_yspG6rG.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BKldFWf9.js → Codegen-BGq_GAha.js} +1 -1
- package/src/assets/web-panel/assets/{Col-ChR-brDs.js → Col-CePor71g.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DlHtZX86.js → Community-CLOWhIT7.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BAhfcBpC.js → Compact-CivJt2vT.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-gIrKkm6m.js → Compliance-Btmo1GGE.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BYnzLBO3.js → Cowork-Ct35OlG4.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-ByUDIljI.js → Cron-CTc2GmhB.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DOdNbHFp.js → Crosschain-ZtiBETk1.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BJHaNWD2.js → DID-BNqMQQXw.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Drm_tClz.js → Dashboard-BmzZd-9V.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-CA1WLzGN.js → Dropdown-CMVgvP2M.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-Di1SKjNO.js → EmailListRenderer-CcqQFAfT.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-44Ve7ZFe.js → FamilyGuardDashboard-CTqB1_4V.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CubPwv_N.js → Federation-CiKOOzlb.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CsUFe5bU.js → FormItemContext-Wk-OT0gr.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-D7xRjPjZ.js → GenericCardRenderer-DbEQT6ue.js} +1 -1
- package/src/assets/web-panel/assets/{Git-D-Qx9dhO.js → Git-0ZvCPSD9.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-_YMYaU4n.js → Governance-CmVuKkPb.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-J7Yzh-K_.js → Inference-CTWE3Jwg.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-D37iI_Mo.js → KnowledgeGraph-CBEIF00L.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-oMTSYfGY.js → Logs-DLhxDwVG.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-DxywvhTU.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-DKUqYDaF.js → Marketplace-BgsCBrnc.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BEv3Gx61.js → McpTools-ClBUGDS2.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-CtA8XD2y.js → Memory-CnG_ZnYw.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-ug7c1mMj.js → MobileBridge-BUOAbR1Z.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-Dnt_9-WB.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-WJaMs4i2.js → Mtc-CLjt4kCD.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-DXnK_-ru.js → MtcAudit-f24U9Aes.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-C4Ev7726.js → Multisig-GrmGQbSq.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-BMFb9_zk.js → NLProgramming-DADaWn-n.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Bl93nvBX.js → Notes-xtf5RX6C.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-BN2W5cl6.js → NotificationSettings-Cd27Rgtx.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-Dxc9oN4o.js → OrderTableRenderer-fXRxlDjl.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CAs48637.js → Organization-joCFlNB0.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Bhq27Zoc.js → Overflow-B1HoURq0.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-D61-2542.js → P2P-DiwsKbT7.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-C1j4iUxz.js → PdhVaultBrowser-Xe-BsW6S.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-rJ2-fScM.js → Permissions-C23qi8kl.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-DFIlTok6.js → PersonalDataHub-BS1syX2f.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-BjIgEWoZ.js → Pipeline-DRYwwDyh.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BQoH5wcX.js → Privacy-BQKaDHPH.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CYR_-_Ub.js → ProjectInit-BC6F9xiG.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-nkatCq-9.js → ProjectSettings-ClFPc1Nd.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-SS9uZKCl.js → Projects-Dn-f5aYe.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BnKM9fsF.js → Providers-CLWuOUNt.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Cfe82dbz.js → QrScannerModal-DiqULTxb.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-r1RbPufV.js → QuickAsk-9A03P-E_.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CjCbM2WE.js → Recommend-CJZAnbq_.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-BuMGPH6V.js → RemoteSession-C9A1R77h.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-Bmj3NY1F.js → Reputation-BIZc6Rky.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BIsNcE_1.js → Row-DfIPNtuG.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BObmojD2.js → RssFeed-C5znFcQ1.js} +2 -2
- package/src/assets/web-panel/assets/{Search-BRmbkQNS.js → Search-DSs2z3OX.js} +1 -1
- package/src/assets/web-panel/assets/{Security-_rF3DRpY.js → Security-CV6LcrLY.js} +3 -3
- package/src/assets/web-panel/assets/{Services-D0If9ZV4.js → Services-cmhoX0Xj.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-o7zIksUg.js → Skeleton-tCsg2po7.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-oUR7zi9u.js → Skills-BK1KUDiy.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-fqKyGi03.js → Sla-yRgyeA82.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-B1wZ_gxx.js → SpeechSettings-c1mo1mlp.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-B3qJWYXq.js → SyncSettings-koIAfuT3.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BH5_dUfr.js → Tasks-DkkreAaB.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CCIVpjRP.js → Templates-fy5Ctf9M.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-2GZtTGnB.js → Tenant-Bw70Jf6S.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BlMkfs_u.js → Terminal-BKh6Rx-4.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-U6hi5OMc.js → TimelineRenderer-Dg54WP0c.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-C-_BerGJ.js → Tokens-BvvD5SxJ.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DaKzBgN3.js → Trigger-B7Ug9x4e.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CLvcsco3.js → Trust-BjvuMORY.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BFn_Y1zZ.js → UkeySign-CZqhkx8p.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B0V18dLT.js → VideoEditing-ClR50lhX.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BbmP7Imu.js → Wallet-DlfppYjx.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-Dewj_0kt.js → WebAuthn-BirgVr8B.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-DOxz3Lwa.js → WorkflowEditor-B8DP_bax.js} +1 -1
- package/src/assets/web-panel/assets/{chat-B1OIpZnh.js → chat-DA8AUZzL.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CSGNVdri.js → colors-C38pLGp1.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-8S0vcg0u.js → compact-item-81rtr98o.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-vZyc27TN.js → createContext-D34ixq8t.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CHDIEOeN.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DWw3-UhA.js → hasIn-D4bzqTrZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-dxocDVD_.js → index-9qoVpPt6.js} +1 -1
- package/src/assets/web-panel/assets/{index-xx5M5Rbj.js → index-B0QArPQt.js} +1 -1
- package/src/assets/web-panel/assets/{index-DtHWHJnj.js → index-B8mkLM4x.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLgkAhEE.js → index-BIP62a6r.js} +1 -1
- package/src/assets/web-panel/assets/{index-tr1x96W9.js → index-BP-zkXK8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CfEvacz7.js → index-BS3M5H9V.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1i_8oop.js → index-BXd2_LmH.js} +1 -1
- package/src/assets/web-panel/assets/{index-BDHyovnK.js → index-BlxEphl7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CLPr2vC_.js → index-BqIhLAbA.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQssf0EQ.js → index-BtGxuQrO.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuB5P0TR.js → index-BvD7b2IK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeCS12Mh.js → index-BvL_3J_n.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeBv896m.js → index-COe_cOLJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dc40pX3F.js → index-CP5alL4t.js} +1 -1
- package/src/assets/web-panel/assets/index-CY1NURWZ.js +1 -0
- package/src/assets/web-panel/assets/{index-B4pP2ycr.js → index-CbhE3j5j.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKwl1AkQ.js → index-Cd3KuNK5.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZnauCqN.js → index-CoVgZw_b.js} +1 -1
- package/src/assets/web-panel/assets/{index-BwKrTVV0.js → index-CuS-UPoj.js} +1 -1
- package/src/assets/web-panel/assets/{index-Q6oyLnKC.js → index-D0Ih7Hwn.js} +1 -1
- package/src/assets/web-panel/assets/{index-CB2MOS_8.js → index-D3zCCZRS.js} +3 -3
- package/src/assets/web-panel/assets/{index-BdyokEau.js → index-D6GfvEQG.js} +1 -1
- package/src/assets/web-panel/assets/{index-DPgY5GLy.js → index-DBFSo1NF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CFQWZvak.js → index-DFHa1HIg.js} +1 -1
- package/src/assets/web-panel/assets/{index-BjC-TrOb.js → index-DFyWKOBD.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dg0Izipr.js → index-DMgnRwrK.js} +1 -1
- package/src/assets/web-panel/assets/{index-BKEmQQvR.js → index-DUQLXLQM.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLAvUtOH.js → index-D_2VYPr1.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8qXVfoV.js → index-DakfFZ-k.js} +1 -1
- package/src/assets/web-panel/assets/{index-DcfLXAW7.js → index-Ddk0e_Pi.js} +1 -1
- package/src/assets/web-panel/assets/{index-BoIPHP4R.js → index-DkHqMnn3.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJgKP2cm.js → index-Dmo3dFHb.js} +1 -1
- package/src/assets/web-panel/assets/index-DokUYqpq.js +1 -0
- package/src/assets/web-panel/assets/{index-C6r27A-o.js → index-DvfCEJG-.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbZqw7pg.js → index-E1OJRXs4.js} +1 -1
- package/src/assets/web-panel/assets/{index-BkWd6YL7.js → index-F76w1NiL.js} +1 -1
- package/src/assets/web-panel/assets/{index-t-q3rkVm.js → index-ZRJRItm0.js} +1 -1
- package/src/assets/web-panel/assets/{index-CwXBblm-.js → index-fI5sXMLg.js} +1 -1
- package/src/assets/web-panel/assets/{index-CI3slBKI.js → index-tKiC8T-4.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Di5YFId0.js → initDefaultProps-ByyvflIR.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BVSN0aeL.js → motion-B3FQm2By.js} +1 -1
- package/src/assets/web-panel/assets/{move-DHNiaP2l.js → move-BSfns6Ef.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-xJPf3gQD.js → mtc-parser-CTG1Ieri.js} +1 -1
- package/src/assets/web-panel/assets/{omit-C7qzUdkN.js → omit-DObM_2j6.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-pSpjg3Le.js → pickAttrs-DOfelQ1t.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-cs_jL_UC.js → placementArrow-CHZILds_.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DkS_Zs4r.js → responsiveObserve-REbucKSx.js} +1 -1
- package/src/assets/web-panel/assets/{slide-B5O1Kpxo.js → slide-C6EZzD7o.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BX02GnZp.js → statusUtils-BxkWS-g3.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-EmBYRftd.js → styleChecker-Chklyoq6.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-ZGzN1cU8.js → useFlexGapSupport-CRVwKrrI.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CfP7M1m7.js → useFs-DV24ik_J.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CbIPHgNh.js → usePersonalDataHub-C7vIo4Pg.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-7xh0If_O.js → vnode-By-v5GlF.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DmitvTR2.js → zoom-B1w9Am3r.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agenda.js +15 -1
- package/src/commands/agent.js +7 -0
- package/src/commands/background-session.js +16 -2
- package/src/data/changelog.json +7 -2
- package/src/gateways/ws/background-agent-protocol.js +88 -14
- package/src/lib/agent-authority.js +251 -0
- package/src/lib/background-agent-phase.js +100 -0
- package/src/lib/background-agent-supervisor.js +288 -8
- package/src/lib/backpressure-policy.js +105 -0
- package/src/lib/capability-negotiation.js +212 -0
- package/src/lib/credential-guard.js +11 -0
- package/src/lib/credential-proxy.js +182 -0
- package/src/lib/event-seq-replay.js +167 -0
- package/src/lib/goal-condition-engine.js +369 -0
- package/src/lib/headless-manifest.js +13 -0
- package/src/lib/ide-context.js +53 -14
- package/src/lib/project-instructions.js +98 -1
- package/src/lib/remote-path-mapping.js +229 -0
- package/src/lib/schedule-planner.js +136 -0
- package/src/repl/bg-dashboard.js +13 -12
- package/src/runtime/agent-core.js +11 -4
- package/src/runtime/headless-stream.js +195 -11
- package/src/runtime/system-prompt.js +3 -0
- package/src/workers/background-agent-worker.js +37 -2
- package/src/assets/web-panel/assets/ChatBubbleRenderer-lkavIWMS.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-BqaPmC0W.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-BpX5g9It.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DYEZcY55.js +0 -1
- package/src/assets/web-panel/assets/index-DmVFfcNR.js +0 -1
- package/src/assets/web-panel/assets/index-x7YyhMUa.js +0 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote URI ↔ filesystem path mapping for the IDE bridge.
|
|
3
|
+
*
|
|
4
|
+
* A local IDE (VS Code / JetBrains) can report a file in a representation that
|
|
5
|
+
* does not exist on the host `cc` runs on, so inlining it into the prompt makes
|
|
6
|
+
* the agent's read_file/edit_file target a path the CLI host can't see:
|
|
7
|
+
* - a URI: file:///c:/code/my%20proj/文件.ts
|
|
8
|
+
* vscode-remote://wsl+Ubuntu/home/u/x
|
|
9
|
+
* vscode-remote://ssh-remote+host/home/u/x
|
|
10
|
+
* vscode-remote://dev-container+<hex>/workspaces/x
|
|
11
|
+
* - a WSL UNC path from a Windows host: \\wsl.localhost\Ubuntu\home\u\x
|
|
12
|
+
* (older Windows builds: \\wsl$\Ubuntu\home\u\x)
|
|
13
|
+
* - a Windows drive path while cc runs INSIDE WSL: C:\code\x == /mnt/c/code/x
|
|
14
|
+
*
|
|
15
|
+
* normalizeIdePathForCli() folds these foreign forms into the CLI's native fs
|
|
16
|
+
* path; anything already native (or unrecognized) passes through byte-for-byte.
|
|
17
|
+
* cliPathToIdeUri() is the reverse, for surfaces that must hand a URI back to
|
|
18
|
+
* the editor.
|
|
19
|
+
*
|
|
20
|
+
* Pure: string transforms only (no fs / process). Percent-decoding preserves
|
|
21
|
+
* spaces and non-ASCII (中文) exactly, so round-trips are lossless.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** decodeURIComponent that never throws on a malformed % sequence. */
|
|
25
|
+
function decodeSafe(s) {
|
|
26
|
+
if (typeof s !== "string") return s;
|
|
27
|
+
try {
|
|
28
|
+
return decodeURIComponent(s);
|
|
29
|
+
} catch {
|
|
30
|
+
return s; // leave a malformed sequence as-is rather than lose the value
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Has a `scheme://` prefix (a URI, not a bare path). */
|
|
35
|
+
export function looksLikeUri(value) {
|
|
36
|
+
return typeof value === "string" && /^[a-z][a-z0-9.+-]*:\/\//i.test(value);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** `C:\…` or `C:/…` — a Windows drive-absolute path. */
|
|
40
|
+
export function looksLikeWindowsPath(value) {
|
|
41
|
+
return typeof value === "string" && /^[a-zA-Z]:[\\/]/.test(value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** `\\host\…` or `//host/…` — a UNC path. */
|
|
45
|
+
function looksLikeUnc(value) {
|
|
46
|
+
return typeof value === "string" && /^(\\\\|\/\/)[^\\/]/.test(value);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const WSL_UNC_RE =
|
|
50
|
+
/^(?:\\\\|\/\/)(?:wsl\.localhost|wsl\$)[\\/]([^\\/]+)[\\/]?(.*)$/i;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* `\\wsl.localhost\Ubuntu\home\u\x` (or `\\wsl$\…`, forward-slash variants) →
|
|
54
|
+
* `{ distro:"Ubuntu", posix:"/home/u/x" }`, or null when not a WSL UNC path.
|
|
55
|
+
*/
|
|
56
|
+
export function wslUncToPosix(value) {
|
|
57
|
+
if (typeof value !== "string") return null;
|
|
58
|
+
const m = value.match(WSL_UNC_RE);
|
|
59
|
+
if (!m) return null;
|
|
60
|
+
const distro = m[1];
|
|
61
|
+
const rest = (m[2] || "").replace(/\\/g, "/");
|
|
62
|
+
return { distro, posix: "/" + rest.replace(/^\/+/, "") };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** `/home/u/x` + distro → `\\wsl.localhost\Ubuntu\home\u\x` (host overridable). */
|
|
66
|
+
export function posixToWslUnc(posix, distro, { host = "wsl.localhost" } = {}) {
|
|
67
|
+
if (typeof posix !== "string" || !distro) return null;
|
|
68
|
+
const win = posix.replace(/^\/+/, "").replace(/\//g, "\\");
|
|
69
|
+
return `\\\\${host}\\${distro}\\${win}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** `C:\code\x` → `/mnt/c/code/x`, or null when not a drive path. */
|
|
73
|
+
export function winDriveToWslMount(value) {
|
|
74
|
+
if (!looksLikeWindowsPath(value)) return null;
|
|
75
|
+
const drive = value[0].toLowerCase();
|
|
76
|
+
const rest = value.slice(2).replace(/\\/g, "/").replace(/^\/+/, "");
|
|
77
|
+
return `/mnt/${drive}${rest ? "/" + rest : ""}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const WSL_MOUNT_RE = /^\/mnt\/([a-zA-Z])(?:\/(.*))?$/;
|
|
81
|
+
|
|
82
|
+
/** `/mnt/c/code/x` → `C:\code\x`, or null when not a /mnt/<drive> path. */
|
|
83
|
+
export function wslMountToWinDrive(value) {
|
|
84
|
+
if (typeof value !== "string") return null;
|
|
85
|
+
const m = value.match(WSL_MOUNT_RE);
|
|
86
|
+
if (!m) return null;
|
|
87
|
+
const drive = m[1].toUpperCase();
|
|
88
|
+
const rest = (m[2] || "").replace(/\//g, "\\");
|
|
89
|
+
return `${drive}:\\${rest}`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Parse an IDE URI into its parts. Returns null for a non-URI or an unknown
|
|
94
|
+
* scheme (so the caller leaves it untouched).
|
|
95
|
+
* { scheme, remoteKind, remoteParam, fsPath }
|
|
96
|
+
* `fsPath` is the decoded on-host path: a Windows drive path for a `file://`
|
|
97
|
+
* drive URI, else POSIX. `remoteKind`/`remoteParam` are set for vscode-remote.
|
|
98
|
+
*/
|
|
99
|
+
export function parseRemoteUri(uri) {
|
|
100
|
+
if (!looksLikeUri(uri)) return null;
|
|
101
|
+
const m = uri.match(/^([a-z][a-z0-9.+-]*):\/\/([^/]*)((?:\/[^?#]*)?)/i);
|
|
102
|
+
if (!m) return null;
|
|
103
|
+
const scheme = m[1].toLowerCase();
|
|
104
|
+
const authority = m[2] || "";
|
|
105
|
+
const rawPath = m[3] || "";
|
|
106
|
+
|
|
107
|
+
if (scheme === "file") {
|
|
108
|
+
if (authority) {
|
|
109
|
+
// file://server/share/… → UNC \\server\share\…
|
|
110
|
+
const unc = "\\\\" + authority + rawPath.replace(/\//g, "\\");
|
|
111
|
+
return {
|
|
112
|
+
scheme,
|
|
113
|
+
remoteKind: null,
|
|
114
|
+
remoteParam: null,
|
|
115
|
+
fsPath: decodeSafe(unc),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const decoded = decodeSafe(rawPath);
|
|
119
|
+
// /c:/code/x → c:\code\x (Windows drive URI); else a POSIX path.
|
|
120
|
+
if (/^\/[a-zA-Z]:/.test(decoded)) {
|
|
121
|
+
return {
|
|
122
|
+
scheme,
|
|
123
|
+
remoteKind: null,
|
|
124
|
+
remoteParam: null,
|
|
125
|
+
fsPath: decoded.slice(1).replace(/\//g, "\\"),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
scheme,
|
|
130
|
+
remoteKind: null,
|
|
131
|
+
remoteParam: null,
|
|
132
|
+
fsPath: decoded || "/",
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (scheme === "vscode-remote" || scheme === "vscode-vfs") {
|
|
137
|
+
// authority = "<kind>+<param>", where `+` may be percent-encoded (%2B).
|
|
138
|
+
const auth = decodeSafe(authority);
|
|
139
|
+
const plus = auth.indexOf("+");
|
|
140
|
+
const remoteKind = plus >= 0 ? auth.slice(0, plus) : auth;
|
|
141
|
+
const remoteParam = plus >= 0 ? auth.slice(plus + 1) : null;
|
|
142
|
+
return {
|
|
143
|
+
scheme,
|
|
144
|
+
remoteKind: remoteKind || null,
|
|
145
|
+
remoteParam: remoteParam || null,
|
|
146
|
+
fsPath: decodeSafe(rawPath) || "/",
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return null; // unknown scheme — don't guess
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Detect the running CLI's WSL context from env (best-effort). Returns
|
|
155
|
+
* `{ isWsl, distro }`. Injected in tests; ide-context passes process.env.
|
|
156
|
+
*/
|
|
157
|
+
export function detectWsl(env = {}) {
|
|
158
|
+
const distro = env.WSL_DISTRO_NAME || null;
|
|
159
|
+
const isWsl = Boolean(distro || env.WSL_INTEROP);
|
|
160
|
+
return { isWsl, distro };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Fold an IDE-reported file value into the path `cc` can actually open on THIS
|
|
165
|
+
* host. Only recognized foreign forms are rewritten; a native or unrecognized
|
|
166
|
+
* value is returned unchanged (byte-for-byte).
|
|
167
|
+
*
|
|
168
|
+
* @param {string} value URI or path as the IDE reported it
|
|
169
|
+
* @param {object} [opts]
|
|
170
|
+
* @param {string} [opts.platform=process.platform] the CLI host platform
|
|
171
|
+
* @param {{isWsl?:boolean, distro?:string}} [opts.wsl] WSL context (see detectWsl)
|
|
172
|
+
* @returns {string}
|
|
173
|
+
*/
|
|
174
|
+
export function normalizeIdePathForCli(value, opts = {}) {
|
|
175
|
+
if (typeof value !== "string" || value.length === 0) return value;
|
|
176
|
+
const platform = opts.platform || process.platform;
|
|
177
|
+
const wsl = opts.wsl || {};
|
|
178
|
+
const onWindows = platform === "win32";
|
|
179
|
+
|
|
180
|
+
// 1) Resolve a URI down to its on-host fsPath first.
|
|
181
|
+
let base = value;
|
|
182
|
+
let remoteKind = null;
|
|
183
|
+
let remoteParam = null;
|
|
184
|
+
if (looksLikeUri(value)) {
|
|
185
|
+
const parsed = parseRemoteUri(value);
|
|
186
|
+
if (!parsed) return value; // unknown scheme → leave untouched
|
|
187
|
+
base = parsed.fsPath;
|
|
188
|
+
remoteKind = parsed.remoteKind;
|
|
189
|
+
remoteParam = parsed.remoteParam;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (onWindows) {
|
|
193
|
+
// Native form is a Windows path. A POSIX path from a wsl-remote URI is
|
|
194
|
+
// reachable from Windows as a \\wsl.localhost\<distro>\… UNC.
|
|
195
|
+
if (remoteKind === "wsl" && remoteParam && base.startsWith("/")) {
|
|
196
|
+
return posixToWslUnc(base, remoteParam) || base;
|
|
197
|
+
}
|
|
198
|
+
return base;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Native form is POSIX (Linux remote-host or inside WSL).
|
|
202
|
+
const wslUnc = wslUncToPosix(base);
|
|
203
|
+
if (wslUnc) return wslUnc.posix;
|
|
204
|
+
if (looksLikeWindowsPath(base) && wsl.isWsl) {
|
|
205
|
+
return winDriveToWslMount(base) || base;
|
|
206
|
+
}
|
|
207
|
+
return base;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Reverse: a CLI-native fs path → a URI the editor can open. `remoteAuthority`
|
|
212
|
+
* (e.g. "wsl+Ubuntu", "ssh-remote+host") produces a vscode-remote URI; without
|
|
213
|
+
* it, a `file://` URI. Percent-encodes spaces / non-ASCII per component.
|
|
214
|
+
*/
|
|
215
|
+
export function cliPathToIdeUri(fsPath, { remoteAuthority } = {}) {
|
|
216
|
+
if (typeof fsPath !== "string" || fsPath.length === 0) return fsPath;
|
|
217
|
+
const isWinDrive = looksLikeWindowsPath(fsPath);
|
|
218
|
+
const posixish = fsPath.replace(/\\/g, "/");
|
|
219
|
+
const encoded = posixish
|
|
220
|
+
.split("/")
|
|
221
|
+
.map((seg) => (/^[a-zA-Z]:$/.test(seg) ? seg : encodeURIComponent(seg)))
|
|
222
|
+
.join("/");
|
|
223
|
+
if (remoteAuthority) {
|
|
224
|
+
const path = encoded.startsWith("/") ? encoded : "/" + encoded;
|
|
225
|
+
return `vscode-remote://${remoteAuthority}${path}`;
|
|
226
|
+
}
|
|
227
|
+
const path = isWinDrive ? "/" + encoded : encoded;
|
|
228
|
+
return `file://${path.startsWith("/") ? "" : "/"}${path}`;
|
|
229
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure scheduling planner for the agent Scheduler / Monitor (P1 §"统一持久
|
|
3
|
+
* Scheduler、Monitor 和 Channel").
|
|
4
|
+
*
|
|
5
|
+
* The persisted store ([[agent-schedule-store.js]]) already guarantees the
|
|
6
|
+
* catch-up invariant — a cron down for N periods fires ONCE, not N times,
|
|
7
|
+
* because `advanceCron` jumps to `nextCronTime(now)` rather than stepping
|
|
8
|
+
* through every miss. This module adds the pieces a unified daemon event
|
|
9
|
+
* runtime still needs, all as PURE, clock-injected functions (no timers, no
|
|
10
|
+
* RNG, deterministic across restarts):
|
|
11
|
+
*
|
|
12
|
+
* - **deterministic jitter** — spread tasks that share a cron minute (e.g.
|
|
13
|
+
* every `0 * * * *`) by a STABLE per-task offset, so a shared tick is not a
|
|
14
|
+
* thundering herd. The offset is a hash of the task id, so it never moves
|
|
15
|
+
* across a restart (an RNG offset would, defeating the point).
|
|
16
|
+
* - **adaptive next-wakeup** — the earliest future fire time, so a daemon
|
|
17
|
+
* sleeps until then instead of polling.
|
|
18
|
+
* - **expiry** — a task past `expiresAt` retires without a final fire.
|
|
19
|
+
*
|
|
20
|
+
* A daemon uses `partitionSchedule` (retire expired, fire due) then
|
|
21
|
+
* `msUntilNextWakeup` (sleep precisely). `jitterMs = 0` (the default) makes the
|
|
22
|
+
* due set byte-identical to the store's existing `due()`.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// FNV-1a → a stable 32-bit hash. Deterministic and dependency-free, so the same
|
|
26
|
+
// task always draws the same jitter offset (across processes and restarts).
|
|
27
|
+
function hash32(str) {
|
|
28
|
+
let h = 0x811c9dc5;
|
|
29
|
+
const s = String(str ?? "");
|
|
30
|
+
for (let i = 0; i < s.length; i += 1) {
|
|
31
|
+
h ^= s.charCodeAt(i);
|
|
32
|
+
h = Math.imul(h, 0x01000193);
|
|
33
|
+
}
|
|
34
|
+
return h >>> 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A stable jitter offset in `[0, jitterMs)` derived from the task id. Same id +
|
|
39
|
+
* same jitterMs → same offset, every time. `jitterMs <= 0` → no jitter (0).
|
|
40
|
+
*/
|
|
41
|
+
export function jitterOffsetMs(id, jitterMs) {
|
|
42
|
+
const j = Math.floor(Number(jitterMs) || 0);
|
|
43
|
+
if (j <= 0) return 0;
|
|
44
|
+
return hash32(id) % j;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The entry's base fire time: `dueAt` for a wakeup, `nextAt` otherwise. */
|
|
48
|
+
export function baseFireAt(entry) {
|
|
49
|
+
if (!entry) return null;
|
|
50
|
+
const raw = entry.kind === "wakeup" ? entry.dueAt : entry.nextAt;
|
|
51
|
+
const n = Number(raw);
|
|
52
|
+
return Number.isFinite(n) ? n : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Base fire time with the entry's deterministic jitter applied. */
|
|
56
|
+
export function effectiveFireAt(entry, jitterMs = 0) {
|
|
57
|
+
const base = baseFireAt(entry);
|
|
58
|
+
if (base == null) return null;
|
|
59
|
+
return base + jitterOffsetMs(entry?.id, jitterMs);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Is an entry still pending/active (not in a terminal state)? */
|
|
63
|
+
export function isSchedulable(entry) {
|
|
64
|
+
if (!entry) return false;
|
|
65
|
+
if (entry.kind === "wakeup") return entry.status === "pending";
|
|
66
|
+
return entry.status === "active";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Expiry: a task with an `expiresAt` at or before `now` is retired regardless
|
|
71
|
+
* of its schedule. A missing / non-positive `expiresAt` never expires.
|
|
72
|
+
*/
|
|
73
|
+
export function isEntryExpired(entry, now) {
|
|
74
|
+
const exp = Number(entry?.expiresAt);
|
|
75
|
+
return Number.isFinite(exp) && exp > 0 && exp <= Number(now);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Partition schedulable entries at `now` into what a daemon should do:
|
|
80
|
+
* - `expired` — retire (status → expired). Checked BEFORE due so an expired
|
|
81
|
+
* task never gets a final fire.
|
|
82
|
+
* - `due` — fire now (jittered fire time has arrived).
|
|
83
|
+
* - `waiting` — still pending.
|
|
84
|
+
* Terminal entries are skipped entirely.
|
|
85
|
+
*/
|
|
86
|
+
export function partitionSchedule(entries, { now, jitterMs = 0 } = {}) {
|
|
87
|
+
const t = Number(now);
|
|
88
|
+
const expired = [];
|
|
89
|
+
const due = [];
|
|
90
|
+
const waiting = [];
|
|
91
|
+
for (const entry of entries || []) {
|
|
92
|
+
if (!isSchedulable(entry)) continue;
|
|
93
|
+
if (isEntryExpired(entry, t)) {
|
|
94
|
+
expired.push(entry);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const fireAt = effectiveFireAt(entry, jitterMs);
|
|
98
|
+
if (fireAt != null && fireAt <= t) due.push(entry);
|
|
99
|
+
else waiting.push(entry);
|
|
100
|
+
}
|
|
101
|
+
return { expired, due, waiting };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The earliest future jittered fire time among schedulable, non-expired
|
|
106
|
+
* entries — what a daemon sleeps until (adaptive wakeup). An already-due entry
|
|
107
|
+
* contributes `now` (fire immediately). Returns null when nothing is scheduled.
|
|
108
|
+
*/
|
|
109
|
+
export function nextWakeupAt(entries, { now, jitterMs = 0 } = {}) {
|
|
110
|
+
const t = Number(now);
|
|
111
|
+
let min = null;
|
|
112
|
+
for (const entry of entries || []) {
|
|
113
|
+
if (!isSchedulable(entry) || isEntryExpired(entry, t)) continue;
|
|
114
|
+
const fireAt = effectiveFireAt(entry, jitterMs);
|
|
115
|
+
if (fireAt == null) continue;
|
|
116
|
+
const at = fireAt <= t ? t : fireAt;
|
|
117
|
+
if (min == null || at < min) min = at;
|
|
118
|
+
}
|
|
119
|
+
return min;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Milliseconds until the next wakeup, clamped to `[0, maxMs]` (a cap keeps a
|
|
124
|
+
* far-future task from parking the daemon forever — it re-checks by `maxMs`).
|
|
125
|
+
* null when nothing is scheduled.
|
|
126
|
+
*/
|
|
127
|
+
export function msUntilNextWakeup(
|
|
128
|
+
entries,
|
|
129
|
+
{ now, jitterMs = 0, maxMs = null } = {},
|
|
130
|
+
) {
|
|
131
|
+
const at = nextWakeupAt(entries, { now, jitterMs });
|
|
132
|
+
if (at == null) return null;
|
|
133
|
+
let ms = Math.max(0, at - Number(now));
|
|
134
|
+
if (maxMs != null && Number.isFinite(maxMs)) ms = Math.min(ms, Number(maxMs));
|
|
135
|
+
return ms;
|
|
136
|
+
}
|
package/src/repl/bg-dashboard.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Background-agent dashboard — the interactive agent view behind
|
|
3
3
|
* `cc daemon view` (no id). Claude-Code `claude agents` parity: one live panel
|
|
4
|
-
* over every background session with grouping (Needs input / Working /
|
|
4
|
+
* over every background session with grouping (Needs input / Working / Idle /
|
|
5
5
|
* Completed / Failed / Stopped), peek + reply, attach hand-off, stop, rename,
|
|
6
|
-
* pin, filter, and new-task dispatch.
|
|
6
|
+
* pin, filter, and new-task dispatch. Phase→group classification is the shared
|
|
7
|
+
* `background-agent-phase.js` contract, so `idle` (parked, nothing blocking)
|
|
8
|
+
* is kept distinct from a genuine `needs-input` (a human decision blocks it).
|
|
7
9
|
*
|
|
8
10
|
* Design:
|
|
9
11
|
* - Pure model/render layer (`groupKey`, `buildDashboardModel`,
|
|
@@ -17,10 +19,12 @@
|
|
|
17
19
|
*/
|
|
18
20
|
|
|
19
21
|
import chalk from "chalk";
|
|
22
|
+
import { phaseGroupKey } from "../lib/background-agent-phase.js";
|
|
20
23
|
|
|
21
24
|
export const GROUP_ORDER = [
|
|
22
25
|
"needs-input",
|
|
23
26
|
"working",
|
|
27
|
+
"idle",
|
|
24
28
|
"completed",
|
|
25
29
|
"failed",
|
|
26
30
|
"stopped",
|
|
@@ -29,24 +33,21 @@ export const GROUP_ORDER = [
|
|
|
29
33
|
export const GROUP_TITLES = {
|
|
30
34
|
"needs-input": "Needs input",
|
|
31
35
|
working: "Working",
|
|
36
|
+
idle: "Idle",
|
|
32
37
|
completed: "Completed",
|
|
33
38
|
failed: "Failed",
|
|
34
39
|
stopped: "Stopped",
|
|
35
40
|
};
|
|
36
41
|
|
|
37
42
|
/**
|
|
38
|
-
* Group a session
|
|
39
|
-
*
|
|
40
|
-
*
|
|
43
|
+
* Group a session into a dashboard bucket. Delegates to the shared
|
|
44
|
+
* `background-agent-phase.js` contract so the worker/supervisor and this panel
|
|
45
|
+
* agree on phase semantics: running + pending approval / blocking phase →
|
|
46
|
+
* "needs-input"; running + idle (parked, nothing blocking) → "idle"; running +
|
|
47
|
+
* working/turn/starting → "working"; lost/unknown → "failed".
|
|
41
48
|
*/
|
|
42
49
|
export function groupKey(session) {
|
|
43
|
-
|
|
44
|
-
if (status === "running") {
|
|
45
|
-
return session.phase === "idle" ? "needs-input" : "working";
|
|
46
|
-
}
|
|
47
|
-
if (status === "completed") return "completed";
|
|
48
|
-
if (status === "stopped") return "stopped";
|
|
49
|
-
return "failed"; // failed | lost | unknown
|
|
50
|
+
return phaseGroupKey(session);
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
function formatAge(ms) {
|
|
@@ -25,6 +25,7 @@ import sharedSettingsHooks from "../lib/settings-hooks.cjs";
|
|
|
25
25
|
import sharedHookRunner from "../lib/hook-runner.cjs";
|
|
26
26
|
import sharedHookEvents from "../lib/settings-hook-events.cjs";
|
|
27
27
|
import { mergeProviderOptions } from "../lib/provider-options.js";
|
|
28
|
+
import { applyCredentialProxy } from "../lib/credential-proxy.js";
|
|
28
29
|
import { getPlanModeManager } from "../lib/plan-mode.js";
|
|
29
30
|
import { CLISkillLoader } from "../lib/skill-loader.js";
|
|
30
31
|
import { executeHooks, HookEvents } from "../lib/hook-manager.js";
|
|
@@ -2540,7 +2541,10 @@ async function executeToolInner(
|
|
|
2540
2541
|
// Same agent-identity env as the foreground path: CLAUDECODE marks
|
|
2541
2542
|
// "running under the agent"; the session id correlates work to the
|
|
2542
2543
|
// run (CC_SESSION_ID + CLAUDE_CODE_SESSION_ID for Claude-Code parity).
|
|
2543
|
-
|
|
2544
|
+
// Credential proxy (opt-in, CC_CREDENTIAL_PROXY): keeps the agent's
|
|
2545
|
+
// real long-lived secrets out of the spawned command's env — a
|
|
2546
|
+
// no-op (same object) when disabled. See credential-proxy.js.
|
|
2547
|
+
env: applyCredentialProxy({
|
|
2544
2548
|
...process.env,
|
|
2545
2549
|
CLAUDECODE: "1",
|
|
2546
2550
|
...(sessionId
|
|
@@ -2549,7 +2553,7 @@ async function executeToolInner(
|
|
|
2549
2553
|
CLAUDE_CODE_SESSION_ID: String(sessionId),
|
|
2550
2554
|
}
|
|
2551
2555
|
: {}),
|
|
2552
|
-
},
|
|
2556
|
+
}).env,
|
|
2553
2557
|
// POSIX: own process group so check_shell{kill}/teardown can signal
|
|
2554
2558
|
// the whole tree (shell + its grandchild command). No-op on Windows
|
|
2555
2559
|
// where the tree is killed via taskkill /T instead.
|
|
@@ -2715,7 +2719,10 @@ async function executeToolInner(
|
|
|
2715
2719
|
// parity): CLAUDECODE=1 marks "running under the agent"; CC_SESSION_ID
|
|
2716
2720
|
// + its CLAUDE_CODE_SESSION_ID mirror let scripts/hooks correlate work
|
|
2717
2721
|
// to the agent session (the mirror is what CC-targeting tools expect).
|
|
2718
|
-
|
|
2722
|
+
// Credential proxy (opt-in, CC_CREDENTIAL_PROXY): keeps the agent's
|
|
2723
|
+
// real long-lived secrets out of the shell's env — a no-op (same
|
|
2724
|
+
// object) when disabled. See credential-proxy.js.
|
|
2725
|
+
env: applyCredentialProxy({
|
|
2719
2726
|
...process.env,
|
|
2720
2727
|
CLAUDECODE: "1",
|
|
2721
2728
|
...(sessionId
|
|
@@ -2724,7 +2731,7 @@ async function executeToolInner(
|
|
|
2724
2731
|
CLAUDE_CODE_SESSION_ID: String(sessionId),
|
|
2725
2732
|
}
|
|
2726
2733
|
: {}),
|
|
2727
|
-
},
|
|
2734
|
+
}).env,
|
|
2728
2735
|
};
|
|
2729
2736
|
let output;
|
|
2730
2737
|
if (shellInv.useDefaultShell) {
|