chainlesschain 0.162.159 → 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/README.md +1 -1
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-ByIiF5bT.js → AIOps-DMn528q-.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-NlgSFZq5.js → ActionButton-D9ZcDCJL.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D17cOUcb.js → Analytics-A_K-8PX0.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-B4mEZcbl.js → AppLayout-D4pFW3X6.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CASsmyQw.js → Artifacts-Dz46COAd.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DYAia2e2.js → Audit-cbMjbyg0.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-C1lvYUSu.js → BackgroundAgents-Dtf88GAj.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-B6agK6bA.js → Backup-C5KRxn52.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DM43R2vy.js → BaseInput-Dd2UK3BN.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-Dtdp3eXp.js → Chat-lptKTFdG.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-BL5c_OQ1.js → ChatBubbleRenderer-C2KLtwHz.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-D2xf7uZt.js → Checkbox-_yspG6rG.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-D3j45jJL.js → Codegen-BGq_GAha.js} +1 -1
- package/src/assets/web-panel/assets/{Col-voPJ9fUZ.js → Col-CePor71g.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DEsyTESF.js → Community-CLOWhIT7.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-OHV_QXLD.js → Compact-CivJt2vT.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-eDTJWC-J.js → Compliance-Btmo1GGE.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BBvy-6d1.js → Cowork-Ct35OlG4.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-Dw2eoJxu.js → Cron-CTc2GmhB.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DQHms_Bh.js → Crosschain-ZtiBETk1.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Cyu7Id1c.js → DID-BNqMQQXw.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-sIDzkG92.js → Dashboard-BmzZd-9V.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DUW3T2ey.js → Dropdown-CMVgvP2M.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CECELXW8.js → EmailListRenderer-CcqQFAfT.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BIZR37ov.js → FamilyGuardDashboard-CTqB1_4V.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BEZIQX84.js → Federation-CiKOOzlb.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BcdUMznL.js → FormItemContext-Wk-OT0gr.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DsN_fr5H.js → GenericCardRenderer-DbEQT6ue.js} +1 -1
- package/src/assets/web-panel/assets/{Git-63LhjBx2.js → Git-0ZvCPSD9.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CYtQtIcH.js → Governance-CmVuKkPb.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BwR6UUox.js → Inference-CTWE3Jwg.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-D9lVNTUA.js → KnowledgeGraph-CBEIF00L.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-C4q5h7Ut.js → Logs-DLhxDwVG.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-DxywvhTU.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Plksliuw.js → Marketplace-BgsCBrnc.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DZUFfeuG.js → McpTools-ClBUGDS2.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-NoDYt29V.js → Memory-CnG_ZnYw.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CEXGTkdh.js → MobileBridge-BUOAbR1Z.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-DnbJkbZo.js → MobileProjects-Dnt_9-WB.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DTAa0cwy.js → Mtc-CLjt4kCD.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-CVV7LnNS.js → MtcAudit-f24U9Aes.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-BqqGrjt_.js → Multisig-GrmGQbSq.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-C4WP8DRp.js → NLProgramming-DADaWn-n.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Zo4DJUVI.js → Notes-xtf5RX6C.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DBcjRaz2.js → NotificationSettings-Cd27Rgtx.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-fXRxlDjl.js +1 -0
- package/src/assets/web-panel/assets/{Organization-BT9WPBOX.js → Organization-joCFlNB0.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-D6b4bZ3q.js → Overflow-B1HoURq0.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Cw3OsYx-.js → P2P-DiwsKbT7.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-C0nyiK2b.js → PdhVaultBrowser-Xe-BsW6S.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-zVBZEB_C.js → Permissions-C23qi8kl.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-BOspsFew.js → PersonalDataHub-BS1syX2f.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-CQWfZ4XH.js → Pipeline-DRYwwDyh.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-C2oGJ_WL.js → Privacy-BQKaDHPH.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BZMR4qY1.js → ProjectInit-BC6F9xiG.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DAujoP63.js → ProjectSettings-ClFPc1Nd.js} +2 -2
- package/src/assets/web-panel/assets/Projects-Dn-f5aYe.js +1 -0
- package/src/assets/web-panel/assets/{Providers-D_RGHM-v.js → Providers-CLWuOUNt.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Mf6KfL2J.js → QrScannerModal-DiqULTxb.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-5D8URoI_.js → QuickAsk-9A03P-E_.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Df4kC8Gy.js → Recommend-CJZAnbq_.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DGi3f3vO.js → RemoteSession-C9A1R77h.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-jmkGFNWb.js → Reputation-BIZc6Rky.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DP6Pcu3m.js → Row-DfIPNtuG.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-D60hSuPO.js → RssFeed-C5znFcQ1.js} +3 -3
- package/src/assets/web-panel/assets/{Search-0mf1BQUK.js → Search-DSs2z3OX.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CfZtLFYV.js → Security-CV6LcrLY.js} +4 -4
- package/src/assets/web-panel/assets/{Services-D9zpZLWz.js → Services-cmhoX0Xj.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-D1_44eMD.js → Skeleton-tCsg2po7.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-cVFa8zkz.js → Skills-BK1KUDiy.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Cinpzc3L.js → Sla-yRgyeA82.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-bqdiJE_P.js → SpeechSettings-c1mo1mlp.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Dgl_SLgj.js → SyncSettings-koIAfuT3.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DawWAEhy.js → Tasks-DkkreAaB.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-Ca0nY651.js → Templates-fy5Ctf9M.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CgaGEhLm.js → Tenant-Bw70Jf6S.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-D-9EnpRx.js → Terminal-BKh6Rx-4.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-CSOxDHZ6.js → TimelineRenderer-Dg54WP0c.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BpwLZpL3.js → Tokens-BvvD5SxJ.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DgowwBK5.js → Trigger-B7Ug9x4e.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BZutapjE.js → Trust-BjvuMORY.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-QZPt8_Sp.js → UkeySign-CZqhkx8p.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DlQx5UDJ.js → VideoEditing-ClR50lhX.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-ZfdTgtWA.js → Wallet-DlfppYjx.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-CAp0y_Cr.js → WebAuthn-BirgVr8B.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-BVITZEmr.js → WorkflowEditor-B8DP_bax.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CC2tPaNg.js → chat-DA8AUZzL.js} +1 -1
- package/src/assets/web-panel/assets/{colors-31brc9CA.js → colors-C38pLGp1.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DLMkC9C-.js → compact-item-81rtr98o.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BMtveI6F.js → createContext-D34ixq8t.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CHDIEOeN.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DbD6WHW2.js → hasIn-D4bzqTrZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BoO4WEJB.js → index-9qoVpPt6.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJhREOlG.js → index-B0QArPQt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnFLzejT.js → index-B8mkLM4x.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bbc2JeQG.js → index-BIP62a6r.js} +1 -1
- package/src/assets/web-panel/assets/{index-CFXKbOek.js → index-BP-zkXK8.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-cGlCDW.js → index-BS3M5H9V.js} +1 -1
- package/src/assets/web-panel/assets/{index-AaIKG60c.js → index-BXd2_LmH.js} +1 -1
- package/src/assets/web-panel/assets/{index-CEXa-4zd.js → index-BlxEphl7.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZl-UXB6.js → index-BqIhLAbA.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOM-VFlv.js → index-BtGxuQrO.js} +1 -1
- package/src/assets/web-panel/assets/{index-CcVszn2b.js → index-BvD7b2IK.js} +1 -1
- package/src/assets/web-panel/assets/{index-C21pdBqs.js → index-BvL_3J_n.js} +1 -1
- package/src/assets/web-panel/assets/{index-DJvxFyIz.js → index-COe_cOLJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-ALvoNTRF.js → index-CP5alL4t.js} +1 -1
- package/src/assets/web-panel/assets/index-CY1NURWZ.js +1 -0
- package/src/assets/web-panel/assets/{index-Dm0byjm1.js → index-CbhE3j5j.js} +1 -1
- package/src/assets/web-panel/assets/{index-WQUO2vvK.js → index-Cd3KuNK5.js} +1 -1
- package/src/assets/web-panel/assets/{index-bdaJwTXJ.js → index-CoVgZw_b.js} +1 -1
- package/src/assets/web-panel/assets/{index-COHHQ9cU.js → index-CuS-UPoj.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7LHNw_N.js → index-D0Ih7Hwn.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cod97Urs.js → index-D3zCCZRS.js} +3 -3
- package/src/assets/web-panel/assets/{index-Cwbqh0KZ.js → index-D6GfvEQG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BKAB6-6V.js → index-DBFSo1NF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CEwjBA9q.js → index-DFHa1HIg.js} +1 -1
- package/src/assets/web-panel/assets/{index-DndNnYc0.js → index-DFyWKOBD.js} +1 -1
- package/src/assets/web-panel/assets/{index-3oBsXZmF.js → index-DMgnRwrK.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_eUKGYP.js → index-DUQLXLQM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUmLMFsy.js → index-D_2VYPr1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPpS-lGb.js → index-DakfFZ-k.js} +1 -1
- package/src/assets/web-panel/assets/{index-ep6JchNG.js → index-Ddk0e_Pi.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7cV0tu0.js → index-DkHqMnn3.js} +1 -1
- package/src/assets/web-panel/assets/{index-jG6h22Qg.js → index-Dmo3dFHb.js} +1 -1
- package/src/assets/web-panel/assets/index-DokUYqpq.js +1 -0
- package/src/assets/web-panel/assets/{index-C1PfeI88.js → index-DvfCEJG-.js} +1 -1
- package/src/assets/web-panel/assets/{index-ntVQqSML.js → index-E1OJRXs4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWgfipcC.js → index-F76w1NiL.js} +1 -1
- package/src/assets/web-panel/assets/{index-BiRQUoyE.js → index-ZRJRItm0.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFRLmCR3.js → index-fI5sXMLg.js} +1 -1
- package/src/assets/web-panel/assets/{index-D67kIagl.js → index-tKiC8T-4.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-D5UoBRhN.js → initDefaultProps-ByyvflIR.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DltOw0CR.js → motion-B3FQm2By.js} +1 -1
- package/src/assets/web-panel/assets/{move-_oPkk5zj.js → move-BSfns6Ef.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-EES8ROCS.js → mtc-parser-CTG1Ieri.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B-_39x_M.js → omit-DObM_2j6.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-l6D0yJHz.js → pickAttrs-DOfelQ1t.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DIeUK31L.js → placementArrow-CHZILds_.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-dG4EzUQo.js → responsiveObserve-REbucKSx.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DWFzYGdH.js → slide-C6EZzD7o.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CECdTA5H.js → statusUtils-BxkWS-g3.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-D6kP-mMK.js → styleChecker-Chklyoq6.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BWfna_rd.js → useFlexGapSupport-CRVwKrrI.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Bb-j6rzo.js → useFs-DV24ik_J.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-D5OIsYM4.js → usePersonalDataHub-C7vIo4Pg.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DNpwzFTM.js → vnode-By-v5GlF.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-vNLpFQBW.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 +72 -6
- package/src/commands/background-session.js +46 -2
- package/src/commands/mcp.js +46 -0
- package/src/commands/session.js +70 -0
- package/src/data/changelog.json +12 -2
- package/src/gateways/ws/background-agent-protocol.js +88 -14
- package/src/harness/jsonl-session-store.js +70 -1
- package/src/harness/mcp-client.js +50 -0
- package/src/lib/agent-authority.js +251 -0
- package/src/lib/agent-sandbox.js +68 -0
- package/src/lib/agents.js +12 -4
- package/src/lib/api-key-helper.js +62 -0
- package/src/lib/background-agent-phase.js +100 -0
- package/src/lib/background-agent-supervisor.js +320 -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/dependency-install-policy.js +130 -0
- package/src/lib/event-seq-replay.js +167 -0
- package/src/lib/exit-codes.cjs +77 -0
- package/src/lib/goal-condition-engine.js +369 -0
- package/src/lib/headless-manifest.js +188 -0
- package/src/lib/hook-runner.cjs +70 -4
- package/src/lib/ide-context-redaction.js +130 -0
- package/src/lib/ide-context.js +128 -13
- package/src/lib/jsonl-session-store.js +2 -0
- package/src/lib/llm-config-defaults.js +24 -8
- package/src/lib/project-instructions.js +98 -1
- package/src/lib/project-mcp-trust.js +87 -0
- package/src/lib/remote-path-mapping.js +229 -0
- package/src/lib/schedule-planner.js +136 -0
- package/src/lib/sensitive-file-guard.js +51 -0
- package/src/lib/sub-agent-context.js +7 -3
- package/src/repl/bg-dashboard.js +13 -12
- package/src/runtime/agent-core.js +113 -10
- package/src/runtime/coding-agent-contract-shared.cjs +19 -2
- package/src/runtime/headless-runner.js +66 -7
- package/src/runtime/headless-stream.js +224 -12
- package/src/runtime/mcp-config.js +32 -1
- package/src/runtime/system-prompt.js +3 -0
- package/src/workers/background-agent-worker.js +37 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-DexLlXfN.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-BCQel9bD.js +0 -1
- package/src/assets/web-panel/assets/Projects-DvH_P2Uq.js +0 -1
- package/src/assets/web-panel/assets/devWarning-CB8pPOtd.js +0 -1
- package/src/assets/web-panel/assets/index-BhXiaiev.js +0 -1
- package/src/assets/web-panel/assets/index-WpaYaE3D.js +0 -1
|
@@ -16,6 +16,11 @@
|
|
|
16
16
|
* not duplicate (or fork) `runAgentHeadless`'s internals.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
import { randomUUID } from "node:crypto";
|
|
20
|
+
import {
|
|
21
|
+
approvalBindingDigest,
|
|
22
|
+
verifyApprovalBinding,
|
|
23
|
+
} from "../lib/agent-authority.js";
|
|
19
24
|
import { bootstrap } from "./bootstrap.js";
|
|
20
25
|
import { buildSystemPrompt, agentLoop as coreAgentLoop } from "./agent-core.js";
|
|
21
26
|
import { composeSystemPrompt } from "./system-prompt.js";
|
|
@@ -43,6 +48,18 @@ import {
|
|
|
43
48
|
makePermissionPromptConfirmer,
|
|
44
49
|
} from "./mcp-config.js";
|
|
45
50
|
import { maybeApplyToolSearch } from "./mcp-tool-search.js";
|
|
51
|
+
import {
|
|
52
|
+
STREAM_PROTOCOL_VERSION,
|
|
53
|
+
computePolicyDigest,
|
|
54
|
+
computeToolsHash,
|
|
55
|
+
buildLoadedSources,
|
|
56
|
+
buildAgentCapabilities,
|
|
57
|
+
} from "../lib/headless-manifest.js";
|
|
58
|
+
import {
|
|
59
|
+
negotiateProtocol,
|
|
60
|
+
buildServerOffer,
|
|
61
|
+
applyNegotiationToGate,
|
|
62
|
+
} from "../lib/capability-negotiation.js";
|
|
46
63
|
import { IterationBudget } from "../lib/iteration-budget.js";
|
|
47
64
|
import { CostBudget } from "../lib/cost-budget.js";
|
|
48
65
|
import {
|
|
@@ -80,6 +97,30 @@ export function resolveStreamCoalesceMs(options = {}, env = {}) {
|
|
|
80
97
|
return n;
|
|
81
98
|
}
|
|
82
99
|
|
|
100
|
+
/** Basic wire-safe trace-id sanitizer: keep only id-friendly chars, cap length
|
|
101
|
+
* (so an injected id can't smuggle whitespace/newlines into NDJSON or blow up
|
|
102
|
+
* a log line). Non-string / empty after trimming → falsy so a fresh one mints. */
|
|
103
|
+
function sanitizeTraceId(value) {
|
|
104
|
+
if (typeof value !== "string") return null;
|
|
105
|
+
const cleaned = value.trim().replace(/[^A-Za-z0-9._:-]/g, "");
|
|
106
|
+
return cleaned ? cleaned.slice(0, 128) : null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Resolve the run's cross-event trace id (additive protocol-v1, §1.2.1).
|
|
111
|
+
* Precedence: explicit `options.traceId` > `CC_TRACE_ID` env > a freshly
|
|
112
|
+
* minted per-process id. Callers may inject `deps.genTraceId` for
|
|
113
|
+
* deterministic tests. The result is sanitized so an externally supplied id
|
|
114
|
+
* stays a safe single NDJSON token.
|
|
115
|
+
*/
|
|
116
|
+
export function resolveTraceId(options = {}, env = {}, deps = {}) {
|
|
117
|
+
const supplied =
|
|
118
|
+
sanitizeTraceId(options.traceId) || sanitizeTraceId(env.CC_TRACE_ID);
|
|
119
|
+
if (supplied) return supplied;
|
|
120
|
+
const gen = deps.genTraceId || (() => `tr-${randomUUID()}`);
|
|
121
|
+
return gen();
|
|
122
|
+
}
|
|
123
|
+
|
|
83
124
|
/**
|
|
84
125
|
* Coalescer for the NDJSON output stream. Every line still flows through `emit`,
|
|
85
126
|
* but consecutive partial-message text/thinking deltas are buffered and flushed
|
|
@@ -91,14 +132,41 @@ export function resolveStreamCoalesceMs(options = {}, env = {}) {
|
|
|
91
132
|
*
|
|
92
133
|
* The flush timer is `unref()`d so it never holds the process open. Pure aside
|
|
93
134
|
* from the injected `writeOut`/timer seams, so it unit-tests deterministically.
|
|
135
|
+
*
|
|
136
|
+
* Every emitted NDJSON line is stamped with a monotonic 1-based `seq`
|
|
137
|
+
* (additive protocol-v1 field, agent-sdk docs/PROTOCOL.md §1.2.1) — the
|
|
138
|
+
* coalescer is the single output choke point, so numbering here covers every
|
|
139
|
+
* line including batched delta runs (one seq per LINE, not per token).
|
|
140
|
+
* `stampSeq:false` restores the unstamped legacy output.
|
|
141
|
+
*
|
|
142
|
+
* When a `traceId` is provided, every line is ALSO stamped with `trace_id` —
|
|
143
|
+
* a run-scoped cross-event correlation id (additive protocol-v1, §1.2.1). It
|
|
144
|
+
* is opt-in (default: absent, legacy shape) so the IDE bridge can thread its
|
|
145
|
+
* own id end-to-end (CC_TRACE_ID / --trace-id) while unstamped callers stay
|
|
146
|
+
* byte-identical.
|
|
94
147
|
*/
|
|
95
148
|
export function createStreamCoalescer({
|
|
96
149
|
writeOut,
|
|
97
150
|
coalesceMs = 50,
|
|
98
151
|
setTimer,
|
|
99
152
|
clearTimer,
|
|
153
|
+
stampSeq = true,
|
|
154
|
+
traceId = null,
|
|
155
|
+
fieldGate = null,
|
|
100
156
|
} = {}) {
|
|
101
|
-
|
|
157
|
+
let seq = 0;
|
|
158
|
+
// `fieldGate` (if provided) is read LIVE per line so a capability
|
|
159
|
+
// negotiation arriving mid-stream (client `hello`) can suppress an additive
|
|
160
|
+
// field the client said it can't parse. Absent / undefined key = stamp (so
|
|
161
|
+
// the default path is byte-for-byte unchanged); only an explicit `false`
|
|
162
|
+
// suppresses. See lib/capability-negotiation.js applyNegotiationToGate.
|
|
163
|
+
const gateOn = (field) => !fieldGate || fieldGate[field] !== false;
|
|
164
|
+
const rawEmit = (obj) => {
|
|
165
|
+
let line = obj;
|
|
166
|
+
if (traceId && gateOn("trace_id")) line = { ...line, trace_id: traceId };
|
|
167
|
+
if (stampSeq && gateOn("seq")) line = { ...line, seq: ++seq };
|
|
168
|
+
writeOut(JSON.stringify(line) + "\n");
|
|
169
|
+
};
|
|
102
170
|
const startTimer =
|
|
103
171
|
setTimer ||
|
|
104
172
|
((fn, ms) => {
|
|
@@ -236,6 +304,19 @@ export function parseInputEvent(line) {
|
|
|
236
304
|
} catch {
|
|
237
305
|
return { error: `invalid JSON line: ${trimmed.slice(0, 80)}` };
|
|
238
306
|
}
|
|
307
|
+
// Capability handshake (agent-sdk docs/PROTOCOL.md §1.3): an optional first
|
|
308
|
+
// line by which the client announces the protocol range + wire features it
|
|
309
|
+
// understands, so the CLI can negotiate a common level and step down on
|
|
310
|
+
// disagreement. {"type":"hello","protocol_version":2,"features":[...]}
|
|
311
|
+
if (obj && typeof obj === "object" && obj.type === "hello") {
|
|
312
|
+
const offer = {};
|
|
313
|
+
if (obj.protocol_version !== undefined)
|
|
314
|
+
offer.protocolVersion = obj.protocol_version;
|
|
315
|
+
if (obj.min_protocol_version !== undefined)
|
|
316
|
+
offer.minProtocolVersion = obj.min_protocol_version;
|
|
317
|
+
if (obj.features !== undefined) offer.features = obj.features;
|
|
318
|
+
return { hello: offer };
|
|
319
|
+
}
|
|
239
320
|
// Plan-mode control events (chat-panel plan UI):
|
|
240
321
|
// {"type":"plan","action":"enter"|"approve"|"reject"}
|
|
241
322
|
if (obj && typeof obj === "object" && obj.type === "plan") {
|
|
@@ -258,7 +339,17 @@ export function parseInputEvent(line) {
|
|
|
258
339
|
// {"type":"approval","id":"appr-1","approve":true|false}
|
|
259
340
|
if (obj && typeof obj === "object" && obj.type === "approval") {
|
|
260
341
|
if (!obj.id) return null;
|
|
261
|
-
return {
|
|
342
|
+
return {
|
|
343
|
+
approval: {
|
|
344
|
+
id: String(obj.id),
|
|
345
|
+
approve: obj.approve === true,
|
|
346
|
+
// Optional approval binding (authority §"权限来源与跨 Agent 授权边界"):
|
|
347
|
+
// when present it must match the digest the matching approval_request
|
|
348
|
+
// advertised, so a stale/mis-routed/param-substituted verdict can't
|
|
349
|
+
// green-light a different tool call. Absent → legacy behavior.
|
|
350
|
+
binding: typeof obj.binding === "string" ? obj.binding : null,
|
|
351
|
+
},
|
|
352
|
+
};
|
|
262
353
|
}
|
|
263
354
|
// Answer to an ask_user_question (panel QuickPick for interactive questions):
|
|
264
355
|
// {"type":"answer","id":"q-1","answer":<string|string[]|null>}
|
|
@@ -440,7 +531,11 @@ export async function* readJsonLines(input, opts = {}) {
|
|
|
440
531
|
* Run a single turn through the core agent loop, emitting NDJSON events.
|
|
441
532
|
* Returns the turn outcome so the caller can grow history + the result line.
|
|
442
533
|
*/
|
|
443
|
-
async function runTurn(
|
|
534
|
+
async function runTurn(
|
|
535
|
+
messages,
|
|
536
|
+
loopOptions,
|
|
537
|
+
{ runLoop, emit, costBudget, nextToolUseId },
|
|
538
|
+
) {
|
|
444
539
|
const usage = {
|
|
445
540
|
input_tokens: 0,
|
|
446
541
|
output_tokens: 0,
|
|
@@ -476,16 +571,31 @@ async function runTurn(messages, loopOptions, { runLoop, emit, costBudget }) {
|
|
|
476
571
|
}
|
|
477
572
|
for await (const event of runLoop(messages, loopOptions)) {
|
|
478
573
|
switch (event.type) {
|
|
479
|
-
case "tool-executing":
|
|
480
|
-
|
|
481
|
-
|
|
574
|
+
case "tool-executing": {
|
|
575
|
+
// Additive protocol-v1 correlation id ("tu-<n>", session-scoped —
|
|
576
|
+
// agent-sdk docs/PROTOCOL.md §1.2.1): the matching tool_result below
|
|
577
|
+
// echoes the same id so UIs can pair calls without adjacency.
|
|
578
|
+
const toolUseId = nextToolUseId ? nextToolUseId() : undefined;
|
|
579
|
+
toolCalls.push({ id: toolUseId, tool: event.tool, args: event.args });
|
|
580
|
+
emit({
|
|
581
|
+
type: "tool_use",
|
|
582
|
+
...(toolUseId ? { id: toolUseId } : {}),
|
|
583
|
+
tool: event.tool,
|
|
584
|
+
args: event.args,
|
|
585
|
+
});
|
|
482
586
|
break;
|
|
587
|
+
}
|
|
483
588
|
case "tool-result": {
|
|
484
589
|
const err = event.error || event.result?.error || null;
|
|
485
|
-
|
|
486
|
-
|
|
590
|
+
// The loop runs tools serially, so this result settles the most
|
|
591
|
+
// recent tool_use (same adjacency rule the is_error attribution
|
|
592
|
+
// below has always used).
|
|
593
|
+
const lastCall =
|
|
594
|
+
toolCalls.length > 0 ? toolCalls[toolCalls.length - 1] : null;
|
|
595
|
+
if (lastCall) lastCall.is_error = Boolean(err);
|
|
487
596
|
emit({
|
|
488
597
|
type: "tool_result",
|
|
598
|
+
...(lastCall?.id ? { id: lastCall.id } : {}),
|
|
489
599
|
tool: event.tool,
|
|
490
600
|
is_error: Boolean(err),
|
|
491
601
|
error: err,
|
|
@@ -661,6 +771,18 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
661
771
|
if (!deps.writeOut && !deps.writeErr) {
|
|
662
772
|
installPipeSafety();
|
|
663
773
|
}
|
|
774
|
+
// Run-scoped cross-event trace id (additive protocol-v1, docs/PROTOCOL.md
|
|
775
|
+
// §1.2.1): one id stamped on EVERY stdout line so a consumer can correlate
|
|
776
|
+
// the whole run across Webview → Bridge → CLI logs, transcripts and
|
|
777
|
+
// diagnostic bundles. The IDE bridge may thread its own id through
|
|
778
|
+
// `--trace-id` / options.traceId / CC_TRACE_ID; otherwise a per-process id
|
|
779
|
+
// is minted (unique even when two runs resume the same session_id).
|
|
780
|
+
const traceId = resolveTraceId(options, process.env, deps);
|
|
781
|
+
// Live field-gate for the capability handshake (docs/PROTOCOL.md §1.3): a
|
|
782
|
+
// client `hello` narrowing the wire features flips these to suppress the
|
|
783
|
+
// additive fields it can't parse. All true by default = current behavior
|
|
784
|
+
// byte-for-byte; the coalescer reads it per line.
|
|
785
|
+
const fieldGate = { seq: true, trace_id: true, tool_use_id: true };
|
|
664
786
|
// Batch consecutive partial-message text/thinking deltas into one stream_event
|
|
665
787
|
// line (Claude-Code 2.1.191 streaming-CPU optimization). `emit` flushes any
|
|
666
788
|
// pending deltas before writing a non-delta line, so ordering is preserved;
|
|
@@ -670,6 +792,8 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
670
792
|
createStreamCoalescer({
|
|
671
793
|
writeOut,
|
|
672
794
|
coalesceMs: resolveStreamCoalesceMs(options, process.env),
|
|
795
|
+
traceId,
|
|
796
|
+
fieldGate,
|
|
673
797
|
});
|
|
674
798
|
const emit = streamCoalescer.emit;
|
|
675
799
|
|
|
@@ -718,7 +842,9 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
718
842
|
deps.appendAssistantMessage || jsonlAppendAssistantMessage,
|
|
719
843
|
rebuildMessages: deps.rebuildMessages || jsonlRebuildMessages,
|
|
720
844
|
};
|
|
721
|
-
|
|
845
|
+
// --ephemeral forces persistence OFF even with an explicit session id (the
|
|
846
|
+
// id is kept for event correlation only; nothing is written or replayed).
|
|
847
|
+
const persist = Boolean(options.sessionId) && options.ephemeral !== true;
|
|
722
848
|
|
|
723
849
|
// ── Interactive approvals (--interactive-approvals; chat-panel UX) ────────
|
|
724
850
|
// CONFIRM-tier decisions (risky shell via the ApprovalGate, settings/hook
|
|
@@ -735,9 +861,32 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
735
861
|
Number(process.env.CC_APPROVAL_TIMEOUT_MS) > 0
|
|
736
862
|
? Number(process.env.CC_APPROVAL_TIMEOUT_MS)
|
|
737
863
|
: 120000;
|
|
738
|
-
const settleApproval = (id, approve, via) => {
|
|
864
|
+
const settleApproval = (id, approve, via, incomingBinding = null) => {
|
|
739
865
|
const p = pendingApprovals.get(id);
|
|
740
866
|
if (!p) return;
|
|
867
|
+
// Approval binding (authority §"权限来源与跨 Agent 授权边界"): an *approve*
|
|
868
|
+
// verdict that carries a binding which does NOT match the one the request
|
|
869
|
+
// advertised is stale / mis-routed / argument-tampered — reject it (deny,
|
|
870
|
+
// fail closed) instead of green-lighting a different or changed tool call.
|
|
871
|
+
// A verdict with no binding stays backward-compatible; a deny always wins.
|
|
872
|
+
if (
|
|
873
|
+
approve === true &&
|
|
874
|
+
incomingBinding &&
|
|
875
|
+
p.binding &&
|
|
876
|
+
!verifyApprovalBinding(p.binding, incomingBinding)
|
|
877
|
+
) {
|
|
878
|
+
pendingApprovals.delete(id);
|
|
879
|
+
clearTimeout(p.timer);
|
|
880
|
+
emit({
|
|
881
|
+
type: "approval_resolved",
|
|
882
|
+
id,
|
|
883
|
+
approved: false,
|
|
884
|
+
via: "binding-mismatch",
|
|
885
|
+
session_id: sessionId,
|
|
886
|
+
});
|
|
887
|
+
p.resolve(false);
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
741
890
|
pendingApprovals.delete(id);
|
|
742
891
|
clearTimeout(p.timer);
|
|
743
892
|
emit({
|
|
@@ -752,12 +901,22 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
752
901
|
const interactiveConfirm = (ctx = {}) =>
|
|
753
902
|
new Promise((resolve) => {
|
|
754
903
|
const id = `appr-${++approvalSeq}`;
|
|
904
|
+
// Bind this approval request to the exact call it authorizes: the request
|
|
905
|
+
// id, its normalized arguments, and the policy/rule in force. The digest
|
|
906
|
+
// rides on `approval_request` so a UI/relay can echo it back on approve,
|
|
907
|
+
// letting settleApproval reject a verdict meant for a different call.
|
|
908
|
+
const binding = approvalBindingDigest({
|
|
909
|
+
toolCallId: id,
|
|
910
|
+
args:
|
|
911
|
+
ctx.args ?? (ctx.command != null ? { command: ctx.command } : null),
|
|
912
|
+
policyDigest: ctx.rule || ctx.riskLevel || ctx.risk || null,
|
|
913
|
+
});
|
|
755
914
|
const timer = setTimeout(
|
|
756
915
|
() => settleApproval(id, false, "timeout"),
|
|
757
916
|
approvalTimeoutMs,
|
|
758
917
|
);
|
|
759
918
|
timer.unref?.();
|
|
760
|
-
pendingApprovals.set(id, { resolve, timer });
|
|
919
|
+
pendingApprovals.set(id, { resolve, timer, binding });
|
|
761
920
|
emit({
|
|
762
921
|
type: "approval_request",
|
|
763
922
|
id,
|
|
@@ -767,6 +926,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
767
926
|
risk: ctx.riskLevel || ctx.risk || null,
|
|
768
927
|
rule: ctx.rule || null,
|
|
769
928
|
reason: ctx.reason || null,
|
|
929
|
+
binding,
|
|
770
930
|
});
|
|
771
931
|
});
|
|
772
932
|
|
|
@@ -961,11 +1121,31 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
961
1121
|
emit({
|
|
962
1122
|
type: "system",
|
|
963
1123
|
subtype: "init",
|
|
1124
|
+
// Deterministic-headless manifest (gap-analysis 2026-07-11): protocol
|
|
1125
|
+
// version + persistence + live sources + policy/tool digests. The init
|
|
1126
|
+
// event fires BEFORE MCP resolution here (stream consumers expect it
|
|
1127
|
+
// promptly), so `mcp` in loaded_sources reflects the run's MCP intent
|
|
1128
|
+
// (config file / registry auto-connect enabled), not connection outcome.
|
|
1129
|
+
protocol_version: STREAM_PROTOCOL_VERSION,
|
|
964
1130
|
session_id: sessionId,
|
|
1131
|
+
session_persistence: persist,
|
|
965
1132
|
model,
|
|
966
1133
|
provider,
|
|
967
1134
|
permission_mode: options.permissionMode || "default",
|
|
968
1135
|
tools: enabledToolNames,
|
|
1136
|
+
tools_hash: computeToolsHash(enabledToolNames),
|
|
1137
|
+
policy_digest: computePolicyDigest({
|
|
1138
|
+
permissionMode: options.permissionMode,
|
|
1139
|
+
allowedTools: options.allowedTools,
|
|
1140
|
+
disallowedTools: disabledTools,
|
|
1141
|
+
permissionRules,
|
|
1142
|
+
}),
|
|
1143
|
+
loaded_sources: buildLoadedSources({
|
|
1144
|
+
permissionRules,
|
|
1145
|
+
settingsHooks,
|
|
1146
|
+
mcp: Boolean(options.mcpConfig) || options.useRegisteredMcp !== false,
|
|
1147
|
+
enabledToolNames,
|
|
1148
|
+
}),
|
|
969
1149
|
input_format: "stream-json",
|
|
970
1150
|
additional_directories: additionalDirectories,
|
|
971
1151
|
resumed_messages: resumedMessages,
|
|
@@ -1207,6 +1387,13 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
1207
1387
|
|
|
1208
1388
|
let turns = 0;
|
|
1209
1389
|
let sawError = false;
|
|
1390
|
+
// Session-scoped tool-call correlation ids ("tu-<n>", additive protocol-v1
|
|
1391
|
+
// field): one counter across ALL turns so ids never repeat within a session.
|
|
1392
|
+
// Gated by the capability handshake (docs/PROTOCOL.md §1.3): a client that
|
|
1393
|
+
// negotiated tool_use_id off gets undefined (no `id` field emitted).
|
|
1394
|
+
let toolUseCounter = 0;
|
|
1395
|
+
const nextToolUseId = () =>
|
|
1396
|
+
fieldGate.tool_use_id === false ? undefined : `tu-${++toolUseCounter}`;
|
|
1210
1397
|
// Version-skew notice (friendly reminder): a chat-panel agent process is
|
|
1211
1398
|
// long-lived, so if cc was updated on disk while it kept running, it's still
|
|
1212
1399
|
// executing stale in-memory code (a fixed bug then looks "not fixed"). Checked
|
|
@@ -1235,6 +1422,30 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
1235
1422
|
for await (const line of readJsonLines(input)) {
|
|
1236
1423
|
const parsed = parseInputEvent(line);
|
|
1237
1424
|
if (parsed == null) continue;
|
|
1425
|
+
if (parsed.hello) {
|
|
1426
|
+
// Capability handshake (docs/PROTOCOL.md §1.3): negotiate the client's
|
|
1427
|
+
// offer against this CLI's, apply the agreed feature set to the live
|
|
1428
|
+
// field-gate, and echo the result. Never queued (it's out-of-band
|
|
1429
|
+
// control, like interrupt/approval). Incompatible (ok:false) leaves
|
|
1430
|
+
// the gate untouched — the CLI keeps its safe baseline.
|
|
1431
|
+
const negotiated = negotiateProtocol(
|
|
1432
|
+
buildServerOffer(buildAgentCapabilities()),
|
|
1433
|
+
parsed.hello,
|
|
1434
|
+
);
|
|
1435
|
+
applyNegotiationToGate(negotiated, fieldGate);
|
|
1436
|
+
emit({
|
|
1437
|
+
type: "system",
|
|
1438
|
+
subtype: "negotiated",
|
|
1439
|
+
session_id: sessionId,
|
|
1440
|
+
protocol_version: negotiated.agreedVersion,
|
|
1441
|
+
features: negotiated.features,
|
|
1442
|
+
downgraded: negotiated.downgraded,
|
|
1443
|
+
disabled_features: negotiated.disabledFeatures,
|
|
1444
|
+
ok: negotiated.ok,
|
|
1445
|
+
reason: negotiated.reason,
|
|
1446
|
+
});
|
|
1447
|
+
continue;
|
|
1448
|
+
}
|
|
1238
1449
|
if (parsed.interrupt) {
|
|
1239
1450
|
currentAbort?.abort();
|
|
1240
1451
|
continue;
|
|
@@ -1245,6 +1456,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
1245
1456
|
parsed.approval.id,
|
|
1246
1457
|
parsed.approval.approve,
|
|
1247
1458
|
parsed.approval.approve ? "user-approve" : "user-deny",
|
|
1459
|
+
parsed.approval.binding,
|
|
1248
1460
|
);
|
|
1249
1461
|
continue;
|
|
1250
1462
|
}
|
|
@@ -1707,7 +1919,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
1707
1919
|
// Resume-degenerate role merge for the first live model call only.
|
|
1708
1920
|
mergeRoles: mergeRolesThisTurn,
|
|
1709
1921
|
},
|
|
1710
|
-
{ runLoop, emit, costBudget },
|
|
1922
|
+
{ runLoop, emit, costBudget, nextToolUseId },
|
|
1711
1923
|
);
|
|
1712
1924
|
} catch (err) {
|
|
1713
1925
|
currentAbort = null;
|
|
@@ -631,17 +631,48 @@ export async function loadProjectMcp(opts = {}, deps = {}) {
|
|
|
631
631
|
if (root) files.push(path.join(root, ".mcp.json"));
|
|
632
632
|
files.push(path.join(cwd, ".mcp.json"));
|
|
633
633
|
|
|
634
|
+
// Fingerprint trust (gap 2026-07-11): the --project-mcp opt-in covers the
|
|
635
|
+
// file as last seen. First use records a sha256; a CHANGED file is refused
|
|
636
|
+
// (fail-closed) until re-trusted via CC_PROJECT_MCP_TRUST=1 or
|
|
637
|
+
// `cc mcp trust-project`. Injectable for tests.
|
|
638
|
+
const trust =
|
|
639
|
+
deps.projectMcpTrust ||
|
|
640
|
+
(await import("../lib/project-mcp-trust.js").catch(() => null));
|
|
641
|
+
|
|
634
642
|
const servers = {};
|
|
635
643
|
const seenFiles = [];
|
|
636
644
|
for (const file of files) {
|
|
637
645
|
if (!fileExists(file)) continue;
|
|
646
|
+
let content;
|
|
638
647
|
let raw;
|
|
639
648
|
try {
|
|
640
|
-
|
|
649
|
+
content = readFile(file);
|
|
650
|
+
raw = JSON.parse(content);
|
|
641
651
|
} catch (err) {
|
|
642
652
|
writeErr(` mcp: ignoring malformed ${file} (${err.message})\n`);
|
|
643
653
|
continue;
|
|
644
654
|
}
|
|
655
|
+
if (trust) {
|
|
656
|
+
try {
|
|
657
|
+
const check = trust.checkProjectMcpTrust(file, content);
|
|
658
|
+
if (check.status === "changed") {
|
|
659
|
+
if (trust.projectMcpRetrustRequested(env)) {
|
|
660
|
+
trust.recordProjectMcpTrust(file, content);
|
|
661
|
+
writeErr(` mcp: ${file} re-trusted (CC_PROJECT_MCP_TRUST).\n`);
|
|
662
|
+
} else {
|
|
663
|
+
writeErr(
|
|
664
|
+
` mcp: SKIPPING ${file} — its content changed since it was last trusted. ` +
|
|
665
|
+
`Review the diff, then re-trust with CC_PROJECT_MCP_TRUST=1 or \`cc mcp trust-project\`.\n`,
|
|
666
|
+
);
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
} else if (check.status === "first-use") {
|
|
670
|
+
trust.recordProjectMcpTrust(file, content);
|
|
671
|
+
}
|
|
672
|
+
} catch {
|
|
673
|
+
/* trust bookkeeping is best-effort; the opt-in gate above still holds */
|
|
674
|
+
}
|
|
675
|
+
}
|
|
645
676
|
const parsed = parseMcpServers(raw);
|
|
646
677
|
if (Object.keys(parsed).length > 0) {
|
|
647
678
|
Object.assign(servers, parsed); // later file (cwd) overrides earlier (root)
|
|
@@ -70,6 +70,9 @@ export function composeSystemPrompt(base, opts = {}) {
|
|
|
70
70
|
cwd,
|
|
71
71
|
home: opts.projectMemoryHome,
|
|
72
72
|
deps: opts.projectMemoryDeps,
|
|
73
|
+
// Large-monorepo reduction lever: subtrees whose instruction/rule/@import
|
|
74
|
+
// files never load (config `instructionExcludes`, forwarded by the caller).
|
|
75
|
+
instructionExcludes: opts.instructionExcludes,
|
|
73
76
|
});
|
|
74
77
|
if (block) result = result ? `${result}\n\n${block}` : block;
|
|
75
78
|
}
|
|
@@ -38,6 +38,12 @@ let lastExit = { code: 0, signal: null };
|
|
|
38
38
|
let transportState = null;
|
|
39
39
|
const promptQueue = [];
|
|
40
40
|
|
|
41
|
+
// Backpressure (Gap 4): an attached client can push prompts faster than
|
|
42
|
+
// turns drain — an unbounded queue grows without limit and every entry is a
|
|
43
|
+
// future agent turn. Past the cap the prompt is REJECTED (the transport
|
|
44
|
+
// relays the throw as {type:"error", message}) instead of silently queued.
|
|
45
|
+
const MAX_PROMPT_QUEUE = 100;
|
|
46
|
+
|
|
41
47
|
function mergeState(patch) {
|
|
42
48
|
const current = readBackgroundAgentState(job.id) || { id: job.id };
|
|
43
49
|
const next = { ...current, id: job.id, ...patch };
|
|
@@ -109,12 +115,20 @@ function startTurn(argv, promptText) {
|
|
|
109
115
|
env: { ...process.env, CC_BACKGROUND_AGENT_ID: job.id },
|
|
110
116
|
stdio: ["ignore", log.fd, log.fd],
|
|
111
117
|
windowsHide: true,
|
|
118
|
+
// POSIX: give the agent child its own process group so an orphan reclaim
|
|
119
|
+
// (worker crashed → supervisor kills the recorded agentPid) or /stop can
|
|
120
|
+
// signal the WHOLE agent tree via -pid. Windows reaps via taskkill /T.
|
|
121
|
+
detached: process.platform !== "win32",
|
|
112
122
|
});
|
|
113
123
|
mergeState({
|
|
114
124
|
status: "running",
|
|
115
125
|
phase,
|
|
116
126
|
turnCount,
|
|
117
127
|
agentPid: child.pid,
|
|
128
|
+
// Identity anchor for the supervisor's orphan reclaim (Gap 2): pairs
|
|
129
|
+
// with agentPid the way startedAt pairs with the worker pid, so a
|
|
130
|
+
// pid-reusing stranger is never killed in the worker's name.
|
|
131
|
+
agentStartedAt: Date.now(),
|
|
118
132
|
heartbeatAt: Date.now(),
|
|
119
133
|
});
|
|
120
134
|
server?.broadcast({
|
|
@@ -150,7 +164,12 @@ function maybeContinue() {
|
|
|
150
164
|
}
|
|
151
165
|
if (server && server.clientCount() > 0) {
|
|
152
166
|
phase = "idle";
|
|
153
|
-
mergeState({
|
|
167
|
+
mergeState({
|
|
168
|
+
phase,
|
|
169
|
+
agentPid: null,
|
|
170
|
+
agentStartedAt: null,
|
|
171
|
+
heartbeatAt: Date.now(),
|
|
172
|
+
});
|
|
154
173
|
server.broadcast({ type: "idle", turn: turnCount });
|
|
155
174
|
return;
|
|
156
175
|
}
|
|
@@ -188,13 +207,29 @@ async function main() {
|
|
|
188
207
|
"this session was launched without follow-up support — start a new one with cc agent --bg",
|
|
189
208
|
);
|
|
190
209
|
}
|
|
210
|
+
if (promptQueue.length >= MAX_PROMPT_QUEUE) {
|
|
211
|
+
throw new Error(
|
|
212
|
+
`prompt queue full (${MAX_PROMPT_QUEUE} pending) — wait for queued turns to drain before sending more`,
|
|
213
|
+
);
|
|
214
|
+
}
|
|
191
215
|
promptQueue.push(text);
|
|
192
216
|
const queued = promptQueue.length;
|
|
193
217
|
if (!child) maybeContinue();
|
|
194
218
|
return { queued };
|
|
195
219
|
},
|
|
196
220
|
onStop: () => {
|
|
197
|
-
child
|
|
221
|
+
if (!child) return;
|
|
222
|
+
if (process.platform !== "win32") {
|
|
223
|
+
// The agent child is detached into its own group — signal the
|
|
224
|
+
// whole tree, not just the top-level CLI process.
|
|
225
|
+
try {
|
|
226
|
+
process.kill(-child.pid, "SIGTERM");
|
|
227
|
+
} catch {
|
|
228
|
+
child.kill("SIGTERM");
|
|
229
|
+
}
|
|
230
|
+
} else {
|
|
231
|
+
child.kill("SIGTERM");
|
|
232
|
+
}
|
|
198
233
|
},
|
|
199
234
|
onClientChange: (count) => {
|
|
200
235
|
// Last client detached while the session is idle → nothing left to
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as c,J as p,b as s}from"./vendor-Bn1JzzAn.js";import{r as a}from"./markdown-Yo_c6Krv.js";import{_ as d}from"./index-Cod97Urs.js";const _={__name:"MarkdownRenderer",props:{content:{type:String,default:""}},setup(t,{expose:o}){o();const e=t,r=s(()=>a(e.content||"")),n={props:e,rendered:r,computed:s,get renderMarkdown(){return a}};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}},i=["innerHTML"];function m(t,o,e,r,n,u){return c(),p("div",{class:"markdown-content",innerHTML:r.rendered},null,8,i)}const w=d(_,[["render",m],["__scopeId","data-v-0b0b9f63"],["__file","/tmp/cc-web-panel-o6vTWF/repo/packages/web-panel/src/components/MarkdownRenderer.vue"]]);export{w as M};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as w,P as l,J as u,U as s,R as n,c as i,K as v,Q as _,V as g,b as o}from"./vendor-Bn1JzzAn.js";import{_ as S}from"./index-Cod97Urs.js";import"./icons-DG5UD-6K.js";const k={__name:"OrderTableRenderer",props:{event:{type:Object,required:!0}},setup(p,{expose:r}){r();const a=p,e=o(()=>a.event.content||{}),d=o(()=>a.event.extra||{}),m=o(()=>d.value.merchant||e.value.merchant||e.value.counterparty||"—"),c=o(()=>e.value.title||e.value.name||e.value.itemName||e.value.text||"—"),y=o(()=>{const t=e.value.amount??e.value.price??e.value.total;return t==null?"—":`${e.value.currency||"¥"} ${typeof t=="number"?t.toFixed(2):t}`}),T=o(()=>d.value.orderNo||e.value.orderNo||e.value.orderId),f=o(()=>e.value.status||e.value.state),b=o(()=>{const t=(f.value||"").toLowerCase();return t.includes("成功")||t.includes("succe")||t.includes("paid")?"green":t.includes("退")||t.includes("refund")?"orange":t.includes("失败")||t.includes("fail")?"red":"default"}),h=o(()=>{if(!a.event.occurredAt)return"";const t=new Date(a.event.occurredAt);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}),x={props:a,c:e,e:d,merchantText:m,itemText:c,amountText:y,orderNo:T,statusText:f,statusColor:b,formattedTime:h,computed:o};return Object.defineProperty(x,"__isScriptSetup",{enumerable:!1,value:!0}),x}},N={class:"order-card"},C={class:"head"},O={class:"time"},V={class:"row"},R={class:"val"},B={class:"row"},D={class:"val"},F={class:"row amount-row"},I={class:"val amount"},j={key:0,class:"row"},A={class:"val mono"},M={key:1,class:"row"};function P(p,r,a,e,d,m){const c=w("a-tag");return l(),u("div",N,[s("div",C,[s("span",O,n(e.formattedTime),1),i(c,{color:"gold"},{default:v(()=>[_(n(a.event.source.adapter),1)]),_:1}),i(c,null,{default:v(()=>[_(n(a.event.subtype),1)]),_:1})]),s("div",V,[r[0]||(r[0]=s("span",{class:"key"},"商户",-1)),s("span",R,n(e.merchantText),1)]),s("div",B,[r[1]||(r[1]=s("span",{class:"key"},"商品/项目",-1)),s("span",D,n(e.itemText),1)]),s("div",F,[r[2]||(r[2]=s("span",{class:"key"},"金额",-1)),s("span",I,n(e.amountText),1)]),e.orderNo?(l(),u("div",j,[r[3]||(r[3]=s("span",{class:"key"},"单号",-1)),s("span",A,n(e.orderNo),1)])):g("v-if",!0),e.statusText?(l(),u("div",M,[r[4]||(r[4]=s("span",{class:"key"},"状态",-1)),i(c,{color:e.statusColor},{default:v(()=>[_(n(e.statusText),1)]),_:1},8,["color"])])):g("v-if",!0)])}const K=S(k,[["render",P],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-o6vTWF/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{K as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as i,J as I,U,R as s,Q as r,c as t,K as a,V as _,S as x,o as oe,b as ee,r as u,P as p,F as ne,a2 as ge}from"./vendor-Bn1JzzAn.js";import{_ as we,b as re,u as ie,d}from"./index-Cod97Urs.js";import{u as de}from"./useShellMode-CgR0wCYM.js";import{aN as ke,aO as Fe,aP as be,f as je,a5 as Ce,a8 as xe,at as Oe,R as Se}from"./icons-DG5UD-6K.js";const Pe={__name:"Projects",setup(se,{expose:l}){l();const{t:te}=re(),e=ie(),{isEmbedded:W}=de();async function w(o,f,ye,ae=8e3){if(W){const Z=await e.sendRaw({...f,type:o},ae);if(!Z?.ok){const $=Z?.error;throw new Error(typeof $=="string"?$:$?.message||`${o} failed`)}return Z.result}return e.executeJson(ye,ae)}const B=u(!1),y=u([]),O=u(""),S=u(""),P=u(!1),v=u(null),h=u([]),k=u(!1),E=u(!1),L=u(!1),F=u({name:"",description:"",type:"document",rootPath:""}),z=[{title:"ID",key:"id",width:110},{title:"名称",key:"name"},{title:"类型",key:"project_type",width:120},{title:"状态",key:"status",width:100},{title:"同步",key:"sync_status",width:100},{title:"更新",key:"updated_at",width:160},{title:"操作",key:"actions",width:180,fixed:"right"}],V=ee(()=>{const o={active:0,draft:0,completed:0,archived:0};for(const f of y.value)o[f.status]!==void 0&&(o[f.status]+=1);return o}),J=ee(()=>y.value.filter(o=>!(O.value&&o.status!==O.value||S.value&&!o.name.toLowerCase().includes(S.value.toLowerCase()))));function g(o){switch(o){case"active":return"green";case"draft":return"default";case"completed":return"cyan";case"archived":return"gold";default:return"default"}}function K(o){switch(o){case"synced":return"green";case"pending":return"orange";case"conflict":return"red";case"error":return"red";default:return"default"}}function Q(o){return!o&&o!==0?"-":new Date(typeof o=="number"?o:parseInt(o,10)).toLocaleString("zh-CN",{hour12:!1})}async function C(){B.value=!0;try{const o=await w("project.list",{limit:500},"project list --limit 500 --json",1e4);y.value=Array.isArray(o?.projects)?o.projects:Array.isArray(o)?o:[]}catch(o){d.error("加载失败: "+(o.message||o)),y.value=[]}finally{B.value=!1}}function G(o){return{onClick:()=>M(o)}}async function M(o){v.value=o,P.value=!0,k.value=!0,h.value=[];try{const f=await w("project.listFiles",{projectId:o.id,limit:200},`project list-files ${o.id} --json`,8e3);h.value=Array.isArray(f?.files)?f.files:[]}catch{h.value=[]}finally{k.value=!1}}async function H(o){try{(await w("project.delete",{id:o.id},`project delete ${o.id} --json`,8e3))?.ok?(d.success(`已删除项目 '${o.name}'`),P.value=!1,await C()):d.error("删除失败")}catch(f){d.error(f.message||String(f))}}function X(){F.value={name:"",description:"",type:"document",rootPath:""},E.value=!0}async function T(){if(!F.value.name.trim()){d.warning("请输入项目名称");return}L.value=!0;try{const o=await w("project.init",{name:F.value.name.trim(),description:F.value.description||null,projectType:F.value.type,rootPath:F.value.rootPath||null},`project init "${F.value.name.trim()}" --type ${F.value.type} --json`,8e3);o?.id?(d.success(`已创建项目 '${o.name}'`),E.value=!1,await C()):d.error("创建失败")}catch(o){d.error(o.message||String(o))}finally{L.value=!1}}const b=u(!1),D=u(!1),j=u({path:"",content:""}),A=u(!1),m=u(!1),R=u({path:""}),n=u(!1),c=u(null),q=u(""),Y=u(!1);function ue(){j.value={path:"",content:""},b.value=!0}function ce(){R.value={path:""},A.value=!0}async function N(){if(v.value){k.value=!0;try{const o=await w("project.listFiles",{projectId:v.value.id,limit:200},`project list-files ${v.value.id} --json`,8e3);h.value=Array.isArray(o?.files)?o.files:[]}catch(o){d.error("刷新文件失败: "+(o.message||o))}finally{k.value=!1}}}async function fe(){if(!j.value.path.trim()){d.warning("请输入文件路径");return}if(v.value){D.value=!0;try{const o=await w("project.createFile",{projectId:v.value.id,filePath:j.value.path.trim(),content:j.value.content||""},`project create-file ${v.value.id} "${j.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件 '${o.file_name}'`),b.value=!1,await N(),await C()):d.error("创建文件失败")}catch(o){d.error(o.message||String(o))}finally{D.value=!1}}}async function pe(){if(!R.value.path.trim()){d.warning("请输入文件夹路径");return}if(v.value){m.value=!0;try{const o=await w("project.createFolder",{projectId:v.value.id,folderPath:R.value.path.trim()},`project create-folder ${v.value.id} "${R.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件夹 '${o.file_name}'`),A.value=!1,await N(),await C()):d.error("创建文件夹失败")}catch(o){d.error(o.message||String(o))}finally{m.value=!1}}}async function ve(o){try{(await w("project.deleteFile",{fileId:o.id},`project delete-file ${o.id} --json`,8e3))?.deleted?(d.success(`已删除 '${o.file_name}'`),await N(),await C()):d.error("删除失败")}catch(f){d.error(f.message||String(f))}}async function me(o){if(o.is_folder){d.info("文件夹无内容可编辑");return}try{const f=await w("project.getFile",{fileId:o.id},`project get-file ${o.id} --json`,8e3);c.value=o,q.value=f?.content||"",n.value=!0}catch(f){d.error("读取文件失败: "+(f.message||f))}}async function _e(){if(c.value){Y.value=!0;try{(await w("project.writeFile",{fileId:c.value.id,content:q.value},`project write-file ${c.value.id} --json`,8e3))?.id?(d.success("已保存"),n.value=!1,await N()):d.error("保存失败")}catch(o){d.error(o.message||String(o))}finally{Y.value=!1}}}oe(()=>{C()});const le={t:te,ws:e,isEmbedded:W,callProjectTopic:w,loading:B,projects:y,statusFilter:O,nameFilter:S,detailOpen:P,detail:v,files:h,filesLoading:k,createOpen:E,creating:L,newProject:F,columns:z,countByStatus:V,filteredProjects:J,statusColor:g,syncColor:K,formatTime:Q,loadAll:C,onRowClick:G,openDetail:M,onDelete:H,onShowCreate:X,onCreate:T,createFileOpen:b,creatingFile:D,newFile:j,createFolderOpen:A,creatingFolder:m,newFolder:R,editFileOpen:n,editingFile:c,editFileContent:q,savingFile:Y,openCreateFile:ue,openCreateFolder:ce,refreshFiles:N,onCreateFile:fe,onCreateFolder:pe,onDeleteFile:ve,openEditFile:me,onSaveFile:_e,ref:u,computed:ee,onMounted:oe,get ReloadOutlined(){return Se},get PlusOutlined(){return Oe},get FolderOutlined(){return xe},get FileTextOutlined(){return Ce},get CheckCircleOutlined(){return je},get CheckSquareOutlined(){return be},get FileAddOutlined(){return Fe},get FolderAddOutlined(){return ke},get message(){return d},get useI18n(){return re},get useWsStore(){return ie},get useShellMode(){return de}};return Object.defineProperty(le,"__isScriptSetup",{enumerable:!1,value:!0}),le}},ze={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},Ae={class:"page-title"},Ie={class:"page-sub"},Ue={class:"filter-bar",style:{"margin-bottom":"12px",display:"flex",gap:"12px","align-items":"center"}},he={key:0,style:{"font-size":"12px",color:"#888"}},De={key:0,style:{color:"#888","font-size":"12px"}},Re={key:0},Te={key:1,style:{color:"#888"}},Be=["onClick"],Ee={key:0,style:{color:"#888","font-size":"12px"}};function Le(se,l,te,e,W,w){const B=i("router-link"),y=i("a-button"),O=i("a-space"),S=i("a-statistic"),P=i("a-card"),v=i("a-col"),h=i("a-row"),k=i("a-radio-button"),E=i("a-radio-group"),L=i("a-input-search"),F=i("a-alert"),z=i("a-tag"),V=i("a-popconfirm"),J=i("a-table"),g=i("a-descriptions-item"),K=i("a-descriptions"),Q=i("a-divider"),C=i("a-empty"),G=i("a-list-item"),M=i("a-list"),H=i("a-spin"),X=i("a-drawer"),T=i("a-input"),b=i("a-form-item"),D=i("a-textarea"),j=i("a-form"),A=i("a-modal"),m=i("a-select-option"),R=i("a-select");return p(),I("div",null,[U("div",ze,[U("div",null,[U("h2",Ae,s(e.t("projects.title")),1),U("p",Ie,[l[17]||(l[17]=r("桌面 / CLI / 手机 三端共享同一份项目数据,Phase 3d sync 自动同步 (",-1)),t(B,{to:"/project-init"},{default:a(()=>[...l[16]||(l[16]=[r("项目初始化 / 环境设置",-1)])]),_:1}),l[18]||(l[18]=r(")",-1))])]),t(O,null,{default:a(()=>[t(y,{loading:e.loading,onClick:e.loadAll},{icon:a(()=>[t(e.ReloadOutlined)]),default:a(()=>[l[19]||(l[19]=r(" 刷新 ",-1))]),_:1},8,["loading"]),t(y,{type:"primary",onClick:e.onShowCreate},{icon:a(()=>[t(e.PlusOutlined)]),default:a(()=>[l[20]||(l[20]=r(" 新建项目 ",-1))]),_:1})]),_:1})]),_(" Stats "),t(h,{gutter:[16,16],style:{"margin-bottom":"20px"}},{default:a(()=>[t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"总项目",value:e.projects.length,"value-style":{color:"#1677ff",fontSize:"20px"}},{prefix:a(()=>[t(e.FolderOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"活跃",value:e.countByStatus.active,"value-style":{color:"#52c41a",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckCircleOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"草稿",value:e.countByStatus.draft,"value-style":{color:"#8c8c8c",fontSize:"20px"}},{prefix:a(()=>[t(e.FileTextOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"已完成",value:e.countByStatus.completed,"value-style":{color:"#13c2c2",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckSquareOutlined)]),_:1},8,["value"])]),_:1})]),_:1})]),_:1}),_(" Filter "),U("div",Ue,[t(E,{value:e.statusFilter,"onUpdate:value":l[0]||(l[0]=n=>e.statusFilter=n),size:"small","button-style":"solid"},{default:a(()=>[t(k,{value:""},{default:a(()=>[...l[21]||(l[21]=[r("全部",-1)])]),_:1}),t(k,{value:"active"},{default:a(()=>[...l[22]||(l[22]=[r("活跃",-1)])]),_:1}),t(k,{value:"draft"},{default:a(()=>[...l[23]||(l[23]=[r("草稿",-1)])]),_:1}),t(k,{value:"completed"},{default:a(()=>[...l[24]||(l[24]=[r("已完成",-1)])]),_:1}),t(k,{value:"archived"},{default:a(()=>[...l[25]||(l[25]=[r("已归档",-1)])]),_:1})]),_:1},8,["value"]),t(L,{value:e.nameFilter,"onUpdate:value":l[1]||(l[1]=n=>e.nameFilter=n),placeholder:"按名称过滤",style:{"max-width":"260px"},"allow-clear":""},null,8,["value"])]),!e.projects.length&&!e.loading?(p(),x(F,{key:0,type:"info",message:"还没有项目",description:'运行 `cc project init <name>` 或点击右上角"新建项目"按钮创建。桌面 / CLI / 手机三端共享同一份数据。',"show-icon":"",style:{"margin-bottom":"16px"}})):_("v-if",!0),e.projects.length||e.loading?(p(),x(J,{key:1,columns:e.columns,"data-source":e.filteredProjects,loading:e.loading,pagination:{pageSize:20,showSizeChanger:!0},"row-key":"id","custom-row":e.onRowClick},{bodyCell:a(({column:n,record:c})=>[n.key==="id"?(p(),I("code",he,s(c.id.slice(0,8))+"…",1)):n.key==="name"?(p(),I(ne,{key:1},[U("strong",null,s(c.name),1),c.description?(p(),I("div",De,s(c.description),1)):_("v-if",!0)],64)):n.key==="project_type"?(p(),x(z,{key:2},{default:a(()=>[r(s(c.project_type),1)]),_:2},1024)):n.key==="status"?(p(),x(z,{key:3,color:e.statusColor(c.status)},{default:a(()=>[r(s(c.status),1)]),_:2},1032,["color"])):n.key==="sync_status"?(p(),x(z,{key:4,color:e.syncColor(c.sync_status)},{default:a(()=>[r(s(c.sync_status||"unknown"),1)]),_:2},1032,["color"])):n.key==="updated_at"?(p(),I(ne,{key:5},[r(s(e.formatTime(c.updated_at)),1)],64)):n.key==="actions"?(p(),x(O,{key:6,onClick:l[2]||(l[2]=ge(()=>{},["stop"]))},{default:a(()=>[t(y,{size:"small",onClick:q=>e.openDetail(c)},{default:a(()=>[...l[26]||(l[26]=[r("详情",-1)])]),_:1},8,["onClick"]),t(V,{title:`删除项目 '${c.name}' ?`,"ok-text":"删除","ok-type":"danger","cancel-text":"取消",onConfirm:q=>e.onDelete(c)},{default:a(()=>[t(y,{size:"small",danger:""},{default:a(()=>[...l[27]||(l[27]=[r("删除",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)):_("v-if",!0)]),_:1},8,["data-source","loading"])):_("v-if",!0),_(" Detail drawer "),t(X,{open:e.detailOpen,"onUpdate:open":l[3]||(l[3]=n=>e.detailOpen=n),title:e.detail?.name||"项目详情",width:"640",placement:"right"},{default:a(()=>[e.detail?(p(),x(K,{key:0,column:1,bordered:"",size:"small"},{default:a(()=>[t(g,{label:"ID"},{default:a(()=>[U("code",null,s(e.detail.id),1)]),_:1}),t(g,{label:"名称"},{default:a(()=>[r(s(e.detail.name),1)]),_:1}),t(g,{label:"描述"},{default:a(()=>[r(s(e.detail.description||"-"),1)]),_:1}),t(g,{label:"类型"},{default:a(()=>[t(z,null,{default:a(()=>[r(s(e.detail.project_type),1)]),_:1})]),_:1}),t(g,{label:"状态"},{default:a(()=>[t(z,{color:e.statusColor(e.detail.status)},{default:a(()=>[r(s(e.detail.status),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"同步状态"},{default:a(()=>[t(z,{color:e.syncColor(e.detail.sync_status)},{default:a(()=>[r(s(e.detail.sync_status||"unknown"),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"用户"},{default:a(()=>[r(s(e.detail.user_id),1)]),_:1}),t(g,{label:"根路径"},{default:a(()=>[e.detail.root_path?(p(),I("code",Re,s(e.detail.root_path),1)):(p(),I("span",Te,"(无)"))]),_:1}),t(g,{label:"文件数"},{default:a(()=>[r(s(e.detail.file_count||0),1)]),_:1}),t(g,{label:"创建"},{default:a(()=>[r(s(e.formatTime(e.detail.created_at)),1)]),_:1}),t(g,{label:"更新"},{default:a(()=>[r(s(e.formatTime(e.detail.updated_at)),1)]),_:1})]),_:1})):_("v-if",!0),t(Q,null,{default:a(()=>[...l[28]||(l[28]=[r("文件",-1)])]),_:1}),_(" Sub-phase 7.3 (2026-05-17): 文件 CRUD toolbar "),t(O,{style:{"margin-bottom":"12px"}},{default:a(()=>[t(y,{size:"small",type:"primary",disabled:!e.detail,onClick:e.openCreateFile},{default:a(()=>[t(e.FileAddOutlined),l[29]||(l[29]=r(" 新建文件 ",-1))]),_:1},8,["disabled"]),t(y,{size:"small",disabled:!e.detail,onClick:e.openCreateFolder},{default:a(()=>[t(e.FolderAddOutlined),l[30]||(l[30]=r(" 新建文件夹 ",-1))]),_:1},8,["disabled"])]),_:1}),t(H,{spinning:e.filesLoading},{default:a(()=>[!e.files.length&&!e.filesLoading?(p(),x(C,{key:0,description:"无文件 (点上方按钮新建)"})):(p(),x(M,{key:1,size:"small","data-source":e.files},{renderItem:a(({item:n})=>[t(G,null,{extra:a(()=>[t(O,null,{default:a(()=>[n.file_size?(p(),I("span",Ee,s(n.file_size)+" B",1)):_("v-if",!0),t(V,{title:`删除 ${n.is_folder?"文件夹":"文件"} '${n.file_name}' ?`,"ok-text":"删除","ok-type":"danger","cancel-text":"取消",onConfirm:c=>e.onDeleteFile(n)},{default:a(()=>[t(y,{size:"small",danger:""},{default:a(()=>[...l[31]||(l[31]=[r("×",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)]),default:a(()=>[U("span",{style:{cursor:"pointer"},onClick:c=>e.openEditFile(n)},s(n.is_folder?"📁":"📄")+" "+s(n.file_path),9,Be)]),_:2},1024)]),_:1},8,["data-source"]))]),_:1},8,["spinning"])]),_:1},8,["open","title"]),_(" Sub-phase 7.3: Create file modal "),t(A,{open:e.createFileOpen,"onUpdate:open":l[6]||(l[6]=n=>e.createFileOpen=n),title:"新建文件","confirm-loading":e.creatingFile,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreateFile},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"文件路径(项目内)",required:""},{default:a(()=>[t(T,{value:e.newFile.path,"onUpdate:value":l[4]||(l[4]=n=>e.newFile.path=n),placeholder:"例如 README.md 或 src/main.kt"},null,8,["value"])]),_:1}),t(b,{label:"初始内容(可选)"},{default:a(()=>[t(D,{value:e.newFile.content,"onUpdate:value":l[5]||(l[5]=n=>e.newFile.content=n),rows:6,placeholder:"留空创建空文件"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"]),_(" Sub-phase 7.3: Create folder modal "),t(A,{open:e.createFolderOpen,"onUpdate:open":l[8]||(l[8]=n=>e.createFolderOpen=n),title:"新建文件夹","confirm-loading":e.creatingFolder,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreateFolder},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"文件夹路径(项目内)",required:""},{default:a(()=>[t(T,{value:e.newFolder.path,"onUpdate:value":l[7]||(l[7]=n=>e.newFolder.path=n),placeholder:"例如 src/utils"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"]),_(" Sub-phase 7.3: Edit file content modal "),t(A,{open:e.editFileOpen,"onUpdate:open":l[10]||(l[10]=n=>e.editFileOpen=n),title:`编辑 ${e.editingFile?.file_name||""}`,"confirm-loading":e.savingFile,"ok-text":"保存","cancel-text":"取消",onOk:e.onSaveFile,width:"720"},{default:a(()=>[t(D,{value:e.editFileContent,"onUpdate:value":l[9]||(l[9]=n=>e.editFileContent=n),rows:18,"auto-size":{minRows:12,maxRows:24},style:{"font-family":"monospace"}},null,8,["value"])]),_:1},8,["open","title","confirm-loading"]),_(" Create modal "),t(A,{open:e.createOpen,"onUpdate:open":l[15]||(l[15]=n=>e.createOpen=n),title:"新建项目","confirm-loading":e.creating,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreate},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"项目名称",required:""},{default:a(()=>[t(T,{value:e.newProject.name,"onUpdate:value":l[11]||(l[11]=n=>e.newProject.name=n),placeholder:"例如:旅行计划-上海"},null,8,["value"])]),_:1}),t(b,{label:"描述"},{default:a(()=>[t(D,{value:e.newProject.description,"onUpdate:value":l[12]||(l[12]=n=>e.newProject.description=n),rows:2},null,8,["value"])]),_:1}),t(b,{label:"类型"},{default:a(()=>[t(R,{value:e.newProject.type,"onUpdate:value":l[13]||(l[13]=n=>e.newProject.type=n)},{default:a(()=>[t(m,{value:"document"},{default:a(()=>[...l[32]||(l[32]=[r("文档 (document)",-1)])]),_:1}),t(m,{value:"data"},{default:a(()=>[...l[33]||(l[33]=[r("数据 (data)",-1)])]),_:1}),t(m,{value:"web"},{default:a(()=>[...l[34]||(l[34]=[r("Web",-1)])]),_:1}),t(m,{value:"app"},{default:a(()=>[...l[35]||(l[35]=[r("应用 (app)",-1)])]),_:1}),t(m,{value:"presentation"},{default:a(()=>[...l[36]||(l[36]=[r("演示文稿",-1)])]),_:1}),t(m,{value:"spreadsheet"},{default:a(()=>[...l[37]||(l[37]=[r("表格",-1)])]),_:1}),t(m,{value:"design"},{default:a(()=>[...l[38]||(l[38]=[r("设计",-1)])]),_:1}),t(m,{value:"code"},{default:a(()=>[...l[39]||(l[39]=[r("代码",-1)])]),_:1}),t(m,{value:"workflow"},{default:a(()=>[...l[40]||(l[40]=[r("工作流",-1)])]),_:1}),t(m,{value:"knowledge"},{default:a(()=>[...l[41]||(l[41]=[r("知识库",-1)])]),_:1})]),_:1},8,["value"])]),_:1}),t(b,{label:"根路径 (可选)"},{default:a(()=>[t(T,{value:e.newProject.rootPath,"onUpdate:value":l[14]||(l[14]=n=>e.newProject.rootPath=n),placeholder:"留空则仅元数据"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"])])}const We=we(Pe,[["render",Le],["__scopeId","data-v-019ac5aa"],["__file","/tmp/cc-web-panel-o6vTWF/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Q as r}from"./index-Cod97Urs.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-DP6Pcu3m.js";import{a0 as t}from"./index-Cod97Urs.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-dG4EzUQo.js";import"./useFlexGapSupport-BWfna_rd.js";import"./styleChecker-D6kP-mMK.js";import"./index-Bbc2JeQG.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-voPJ9fUZ.js";import{a0 as t}from"./index-Cod97Urs.js";import"./vendor-Bn1JzzAn.js";import"./index-Bbc2JeQG.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};
|