chainlesschain 0.162.71 → 0.162.73
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 +3 -2
- package/src/assets/web-panel/assets/{AIOps-pes7_jGr.js → AIOps-DTI_-iZ_.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DiHWdeH1.js → ActionButton-CtpbGicW.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-C51UX-V_.js → Analytics-C1HwMd7E.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BE6LJLw9.js → AppLayout-Db953rqB.js} +5 -5
- package/src/assets/web-panel/assets/{Audit-CtTkLTe2.js → Audit-CuIi9Vup.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-lmpVwPxc.js → Backup-DwR7Wlve.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-Dr7DR1E1.js → BaseInput-B5wNMp7S.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DXph6klA.js → Chat-DivalHgk.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-RefrXxqp.js → ChatBubbleRenderer-BwPSr02C.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-BF0aS5R9.js → Checkbox-CJrXPCJH.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B-oHWNTV.js → Codegen-BieZvOkC.js} +1 -1
- package/src/assets/web-panel/assets/{Col-B6KdyRTE.js → Col-BzvPsQgb.js} +1 -1
- package/src/assets/web-panel/assets/{Community-D5ac0KyO.js → Community-CWcAMlpQ.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-Dc61O2eQ.js → Compact-Bj_BLBpw.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-a48qvNmd.js → Compliance-DKvo0WAi.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CIF9lSRj.js → Cowork-DRajk8JO.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-C_gkf4xd.js → Cron-DPz9MoUo.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CJt15PzW.js → Crosschain-BpSuvmns.js} +1 -1
- package/src/assets/web-panel/assets/{DID-D8I_okEj.js → DID-Co98G00H.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-O4q-qCF2.js → Dashboard-8TSG0W7f.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-flRziiaw.js → Dropdown-CKViu7w3.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CnnkfGPw.js → EmailListRenderer-BqfdADvJ.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-CYAJpGqd.js → FamilyGuardDashboard-aWu1imGZ.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Dm3WqzQ_.js → Federation-w4YpT8EN.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CpAIter6.js → FormItemContext-CAk4CXid.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-ChzXcyuN.js → GenericCardRenderer-MoJw4J2L.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DElmMsL4.js → Git-HNU_a9Jz.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-EWmgn9io.js → Governance-BkIXWYUS.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-VtOR_sef.js → Inference-CnquB88h.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-OMqlGkMR.js → KnowledgeGraph-PGSMF-uq.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CTgYDsTZ.js → Logs-DCc-nYzu.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-DZIUTbn8.js → Marketplace-CyGX8XEt.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DWeOErCA.js → McpTools-DBkZ5yUL.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-DwFBp-ev.js → Memory-DmYLRCwo.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-D42xBfE3.js → MobileBridge-CszJjeNc.js} +2 -2
- package/src/assets/web-panel/assets/{MobileProjects-BHCHauUl.js → MobileProjects-DWgtDsta.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CabnNsyS.js → Mtc-Bmt_Pmg4.js} +3 -3
- package/src/assets/web-panel/assets/{MtcAudit-Ddx9Awu5.js → MtcAudit-BmG0ys0l.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-CJpYBZ8f.js → Multisig-DNd5iMmD.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-BvPJskVG.js → NLProgramming-yxbNl09B.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-92ELvJM2.js → Notes-CQ0qAzI4.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-CXz0SUzP.js → NotificationSettings-CIzkE4ao.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-4iWRkMr-.js → OrderTableRenderer-e1VMUxTi.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-DblqJPeY.js → Organization-BNBIlf_R.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CHfS3HwD.js → Overflow-C5GzzJTq.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DIg0pLIG.js → P2P-DjL2jIED.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BhD3DGjk.js → PdhVaultBrowser-C2EYDmpW.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-Ct7bwrz8.js → Permissions-BVGCXxDp.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DG9c1eas.js → PersonalDataHub-B1xBro16.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-BwQnEqG0.js → Pipeline-DIYWiDnt.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BvWaf-Ba.js → Privacy--Qx3QdO1.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BFzMHtiW.js → ProjectInit-DYOEcV04.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DDpokSpH.js → ProjectSettings-BcOx5-KS.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-3IL8lyPl.js → Projects-CO69txk4.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-C6BsEzSR.js → Providers-Bj8pCgzo.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Mh6690Ey.js → QuickAsk-Cukpq-4s.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CJbZ6wgA.js → Recommend-DJB5wUfM.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-GDcyl6iQ.js → Reputation-B9t0-nT0.js} +1 -1
- package/src/assets/web-panel/assets/{Row-6p4DKFSi.js → Row-4cniRgxC.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BLhrkoDq.js → RssFeed-Y4db_T9t.js} +3 -3
- package/src/assets/web-panel/assets/{Search-Ckiyt35t.js → Search-DggZDzlc.js} +1 -1
- package/src/assets/web-panel/assets/{Security-qhh-B5Qt.js → Security-C67A6kED.js} +4 -4
- package/src/assets/web-panel/assets/{Services-D7a2OwKm.js → Services-BocBjvaa.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CSMxupKd.js → Skeleton-C9jI-iOy.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CGpMng8w.js → Skills-2baFHKOW.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CYtaU3Ar.js → Sla-CnowXeRb.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BTCsu1uM.js → SpeechSettings-DWGBkmUt.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Cnzx2L5I.js → SyncSettings-B89qwCgX.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-C1_WvNc0.js +1 -0
- package/src/assets/web-panel/assets/{Templates-Ccdx_C3w.js → Templates-P8dBhbxa.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-ZN8c86j3.js → Tenant-DHo0pxrm.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-Dr-HvjH-.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-CjgirE9d.js → TimelineRenderer-DM7dOaUR.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-QoRpi6Wf.js → Tokens-DnJxqOPM.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CEQKJkhs.js → Trigger-C-FLgMzr.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-UTuAzV1q.js → Trust-CIT_RVqA.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-JDs9I7fl.js → UkeySign-Cg9VS6y6.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BACYQQSd.js → VideoEditing-BzoxE8mA.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-C-SKluhH.js → Wallet-ZkmCII8R.js} +3 -3
- package/src/assets/web-panel/assets/{WebAuthn-9chizTFy.js → WebAuthn-CptQdp3u.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-0mF-LAUo.js → WorkflowEditor-Vkz28khO.js} +1 -1
- package/src/assets/web-panel/assets/{chat-Di7QINiP.js → chat-DXdmvvEA.js} +1 -1
- package/src/assets/web-panel/assets/{colors-SBmhHMM9.js → colors-De7FCj5l.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BmbETbNj.js → compact-item-DnT3XzME.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-C7hFnsJ7.js → createContext-ECZfCCqd.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-gaA8VqZf.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CFtthKDD.js → hasIn-Uodg6pAt.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRBc1Ewn.js → index-1dWvOqru.js} +1 -1
- package/src/assets/web-panel/assets/{index-WjZVyLn7.js → index-BC8SOuGi.js} +1 -1
- package/src/assets/web-panel/assets/{index-CovTrPpI.js → index-BUMNJRCl.js} +1 -1
- package/src/assets/web-panel/assets/{index-CSnTUPQx.js → index-Bg1RsfAJ.js} +3 -3
- package/src/assets/web-panel/assets/{index-NxxQTlPJ.js → index-Blo85ZKd.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClIp4Vin.js → index-BtJ8BHU0.js} +1 -1
- package/src/assets/web-panel/assets/{index-B4etIqbf.js → index-C01WM7Pk.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWfObC0n.js → index-C4KhsGXo.js} +1 -1
- package/src/assets/web-panel/assets/{index-sz0w-D-C.js → index-C6JgjkY7.js} +1 -1
- package/src/assets/web-panel/assets/{index-lRVjtXeH.js → index-C9_Cnvha.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCcCs7LJ.js → index-CCguvASR.js} +1 -1
- package/src/assets/web-panel/assets/{index-C6tZzsb9.js → index-CLzPxAp4.js} +1 -1
- package/src/assets/web-panel/assets/{index-D0yO3vWh.js → index-CMuqxCVw.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcawAm_i.js → index-COTabJQd.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cib-RTws.js → index-CPjI3AGE.js} +1 -1
- package/src/assets/web-panel/assets/{index-C07kpleB.js → index-CaDZ-LMg.js} +1 -1
- package/src/assets/web-panel/assets/{index-DEYnWiq1.js → index-CbbfcGeJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgXQwqXr.js → index-CcLDjTgI.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2CN7coN.js → index-CffZBdA1.js} +1 -1
- package/src/assets/web-panel/assets/{index-PN02VlUB.js → index-CwXP0KcT.js} +1 -1
- package/src/assets/web-panel/assets/{index-_hO8-EnW.js → index-D2YOclGO.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dk4ez5rf.js → index-DBsl2SuZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-D6vNUp6c.js → index-DCvmjxu9.js} +1 -1
- package/src/assets/web-panel/assets/{index-sA4vr5WV.js → index-DGwgEqwl.js} +1 -1
- package/src/assets/web-panel/assets/{index-DI2xH1fU.js → index-DOIeo8Qs.js} +1 -1
- package/src/assets/web-panel/assets/{index-_a2NG3iP.js → index-DPcpxSQt.js} +1 -1
- package/src/assets/web-panel/assets/index-DTpmiTGK.js +1 -0
- package/src/assets/web-panel/assets/{index-CWDk3nDZ.js → index-Db33l8Ix.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNpb8m5a.js → index-Dbfj4QL5.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dww6gCzI.js → index-Dd9Bx3tJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bpo7UVJe.js → index-Dkvf5upf.js} +1 -1
- package/src/assets/web-panel/assets/index-DwpvMYUU.js +1 -0
- package/src/assets/web-panel/assets/{index-BT2uOwmA.js → index-Dy0AT-uc.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2fhXmhW.js → index-FU8Zo5cp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcRTX_WO.js → index-JVwNC4yP.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dps9xdE8.js → index-JqSxr1A7.js} +1 -1
- package/src/assets/web-panel/assets/{index-D134XFWR.js → index-KV6dXwKC.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8CeUlN0.js → index-LwNszM-5.js} +1 -1
- package/src/assets/web-panel/assets/{index-CcBhsVYn.js → index-cHnmjGqB.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-B1zCwkvT.js → initDefaultProps-B3H1sf95.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BDGIV9KA.js → motion-DreYO5eb.js} +1 -1
- package/src/assets/web-panel/assets/{move-BITqgluK.js → move-B0OVU04M.js} +1 -1
- package/src/assets/web-panel/assets/{omit-uD97QKBF.js → omit-PcEEXHLZ.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CZpXhSIE.js → pickAttrs-DH6-hDkF.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-ByUvT_08.js → placementArrow-DFamUSEw.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BQG9LlBs.js → responsiveObserve-DT1grAyh.js} +1 -1
- package/src/assets/web-panel/assets/{slide-Bx9TyeEE.js → slide-41lCsY6d.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-XWaMqYM8.js → statusUtils-FzJ7j2T7.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BZ-nMyDB.js → styleChecker-D0Zvn50h.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-D_iwA3vx.js → useFlexGapSupport-BTxsJE5n.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DuvW_aRX.js → useFs-DRVttEr3.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BO7orS0d.js → usePersonalDataHub-BSe7NVv0.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Cc_fqAL4.js → vnode-D8O7tUXh.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BGkBp90M.js → zoom-CMQc1RZ4.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +12 -0
- package/src/commands/cowork.js +8 -0
- package/src/commands/crosschain.js +32 -4
- package/src/commands/init.js +10 -10
- package/src/commands/loop.js +9 -3
- package/src/commands/memory.js +6 -4
- package/src/commands/orchestrate.js +5 -2
- package/src/commands/video.js +5 -1
- package/src/lib/agents.js +16 -5
- package/src/lib/cowork-workflow.js +357 -136
- package/src/lib/micro-compact.js +52 -0
- package/src/lib/output-styles.js +41 -7
- package/src/lib/permission-rules.cjs +39 -0
- package/src/lib/project-root.cjs +87 -0
- package/src/lib/settings-hooks.cjs +18 -6
- package/src/lib/settings-loader.cjs +12 -5
- package/src/lib/skill-loader.js +62 -43
- package/src/lib/slash-commands.js +18 -2
- package/src/repl/agent-repl.js +228 -20
- package/src/repl/chat-repl.js +4 -2
- package/src/repl/permission-tier.js +60 -0
- package/src/repl/stream-decision.js +16 -0
- package/src/repl/think-command.js +36 -0
- package/src/runtime/agent-core.js +67 -10
- package/src/runtime/file-ref-expander.js +209 -18
- package/src/runtime/headless-runner.js +3 -3
- package/src/runtime/headless-stream.js +16 -3
- package/src/runtime/mcp-config.js +78 -1
- package/src/assets/web-panel/assets/Tasks-BhnGtqaZ.js +0 -1
- package/src/assets/web-panel/assets/Terminal-BfgM0oyN.js +0 -3
- package/src/assets/web-panel/assets/devWarning-gNvbyy4j.js +0 -1
- package/src/assets/web-panel/assets/index-BNXpMnIY.js +0 -1
- package/src/assets/web-panel/assets/index-gfHxqT1Q.js +0 -1
|
@@ -38,11 +38,51 @@ function looksPathLike(raw) {
|
|
|
38
38
|
return /[\\/]/.test(raw) || /\.[A-Za-z0-9]+$/.test(raw);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/** Whether a resolved path is a PDF (text extraction is async, opt-in). */
|
|
42
|
+
function isPdf(p) {
|
|
43
|
+
return /\.pdf$/i.test(String(p || ""));
|
|
44
|
+
}
|
|
45
|
+
|
|
41
46
|
/** Strip trailing sentence punctuation that is unlikely to be part of a path. */
|
|
42
47
|
function trimTrailingPunct(raw) {
|
|
43
48
|
return raw.replace(/[),;:!?'".]+$/g, "");
|
|
44
49
|
}
|
|
45
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Split a token into its path and an optional trailing line range — Claude-Code
|
|
53
|
+
* `@file#L5-10` parity. Accepts `#L5-10`, `#5-10`, `#L5`, `#5` (1-based,
|
|
54
|
+
* inclusive). Returns `{ path, start, end }`, or null when there is no valid
|
|
55
|
+
* range suffix (so plain `@path` falls through to whole-file expansion).
|
|
56
|
+
*/
|
|
57
|
+
export function parseLineRange(raw) {
|
|
58
|
+
const m = /^(.+?)#[Ll]?(\d+)(?:-(\d+))?$/.exec(String(raw || ""));
|
|
59
|
+
if (!m) return null;
|
|
60
|
+
const start = parseInt(m[2], 10);
|
|
61
|
+
if (!Number.isFinite(start) || start < 1) return null;
|
|
62
|
+
let end = m[3] != null ? parseInt(m[3], 10) : start;
|
|
63
|
+
if (!Number.isFinite(end) || end < start) end = start;
|
|
64
|
+
return { path: m[1], start, end };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Take lines [start, end] (1-based, inclusive) from `content`, clamped to the
|
|
69
|
+
* file, then cap the slice at `maxBytes`. Returns the text plus the actual
|
|
70
|
+
* (clamped) line bounds and whether the byte cap truncated it.
|
|
71
|
+
*/
|
|
72
|
+
function sliceLines(content, start, end, maxBytes) {
|
|
73
|
+
const lines = content.split("\n");
|
|
74
|
+
const total = lines.length;
|
|
75
|
+
const s = Math.max(1, Math.min(start, total));
|
|
76
|
+
const e = Math.min(Math.max(end, s), total);
|
|
77
|
+
let text = lines.slice(s - 1, e).join("\n");
|
|
78
|
+
let truncated = false;
|
|
79
|
+
if (Buffer.byteLength(text, "utf-8") > maxBytes) {
|
|
80
|
+
text = text.slice(0, maxBytes);
|
|
81
|
+
truncated = true;
|
|
82
|
+
}
|
|
83
|
+
return { text, start: s, end: e, truncated };
|
|
84
|
+
}
|
|
85
|
+
|
|
46
86
|
/**
|
|
47
87
|
* Find unique `@path` candidates in the text, in first-seen order.
|
|
48
88
|
* @returns {Array<{raw:string}>}
|
|
@@ -81,7 +121,10 @@ function resolveRef(raw, { cwd, fs, path, maxBytes, maxDirEntries }) {
|
|
|
81
121
|
if (trimmed && trimmed !== raw) candidates.push(trimmed);
|
|
82
122
|
|
|
83
123
|
for (const cand of candidates) {
|
|
84
|
-
|
|
124
|
+
// `@path#L5-10` → resolve the bare path, slice the lines below.
|
|
125
|
+
const range = parseLineRange(cand);
|
|
126
|
+
const fsPath = range ? range.path : cand;
|
|
127
|
+
const abs = path.resolve(cwd, fsPath);
|
|
85
128
|
let stat;
|
|
86
129
|
try {
|
|
87
130
|
stat = fs.statSync(abs);
|
|
@@ -89,6 +132,7 @@ function resolveRef(raw, { cwd, fs, path, maxBytes, maxDirEntries }) {
|
|
|
89
132
|
continue; // not this candidate
|
|
90
133
|
}
|
|
91
134
|
if (stat.isDirectory()) {
|
|
135
|
+
// A line range on a directory is meaningless — ignore it and list the dir.
|
|
92
136
|
let entries;
|
|
93
137
|
try {
|
|
94
138
|
entries = fs.readdirSync(abs, { withFileTypes: true });
|
|
@@ -96,7 +140,7 @@ function resolveRef(raw, { cwd, fs, path, maxBytes, maxDirEntries }) {
|
|
|
96
140
|
return {
|
|
97
141
|
kind: "error",
|
|
98
142
|
raw: cand,
|
|
99
|
-
rel:
|
|
143
|
+
rel: fsPath,
|
|
100
144
|
message: `cannot read directory: ${err.message}`,
|
|
101
145
|
};
|
|
102
146
|
}
|
|
@@ -108,7 +152,7 @@ function resolveRef(raw, { cwd, fs, path, maxBytes, maxDirEntries }) {
|
|
|
108
152
|
return {
|
|
109
153
|
kind: "dir",
|
|
110
154
|
raw: cand,
|
|
111
|
-
rel:
|
|
155
|
+
rel: fsPath,
|
|
112
156
|
entries: names,
|
|
113
157
|
total: entries.length,
|
|
114
158
|
truncated,
|
|
@@ -122,18 +166,46 @@ function resolveRef(raw, { cwd, fs, path, maxBytes, maxDirEntries }) {
|
|
|
122
166
|
return {
|
|
123
167
|
kind: "error",
|
|
124
168
|
raw: cand,
|
|
125
|
-
rel:
|
|
169
|
+
rel: fsPath,
|
|
126
170
|
message: `cannot read file: ${err.message}`,
|
|
127
171
|
};
|
|
128
172
|
}
|
|
173
|
+
if (isPdf(fsPath)) {
|
|
174
|
+
// PDF text extraction is async (pdf-parse). Return a deferred marker
|
|
175
|
+
// carrying the bytes + requested page range; expandFileRefsAsync fills
|
|
176
|
+
// in `content`. The sync path renders it as a note (no extraction).
|
|
177
|
+
return {
|
|
178
|
+
kind: "pdf",
|
|
179
|
+
raw: cand,
|
|
180
|
+
rel: fsPath,
|
|
181
|
+
buf,
|
|
182
|
+
bytes: stat.size,
|
|
183
|
+
pageStart: range ? range.start : null,
|
|
184
|
+
pageEnd: range ? range.end : null,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
129
187
|
if (looksBinary(buf)) {
|
|
130
188
|
return {
|
|
131
189
|
kind: "binary",
|
|
132
190
|
raw: cand,
|
|
133
|
-
rel:
|
|
191
|
+
rel: fsPath,
|
|
134
192
|
bytes: stat.size,
|
|
135
193
|
};
|
|
136
194
|
}
|
|
195
|
+
if (range) {
|
|
196
|
+
// Slice the requested lines (clamped to the file), then byte-cap them.
|
|
197
|
+
const sl = sliceLines(buf.toString("utf-8"), range.start, range.end, maxBytes);
|
|
198
|
+
return {
|
|
199
|
+
kind: "file",
|
|
200
|
+
raw: cand,
|
|
201
|
+
rel: fsPath,
|
|
202
|
+
bytes: stat.size,
|
|
203
|
+
content: sl.text,
|
|
204
|
+
truncated: sl.truncated,
|
|
205
|
+
lineStart: sl.start,
|
|
206
|
+
lineEnd: sl.end,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
137
209
|
const truncated = buf.length > maxBytes;
|
|
138
210
|
const content = (truncated ? buf.slice(0, maxBytes) : buf).toString(
|
|
139
211
|
"utf-8",
|
|
@@ -141,7 +213,7 @@ function resolveRef(raw, { cwd, fs, path, maxBytes, maxDirEntries }) {
|
|
|
141
213
|
return {
|
|
142
214
|
kind: "file",
|
|
143
215
|
raw: cand,
|
|
144
|
-
rel:
|
|
216
|
+
rel: fsPath,
|
|
145
217
|
bytes: stat.size,
|
|
146
218
|
content,
|
|
147
219
|
truncated,
|
|
@@ -164,15 +236,23 @@ function renderBlock(refs) {
|
|
|
164
236
|
];
|
|
165
237
|
for (const ref of refs) {
|
|
166
238
|
if (ref.kind === "file") {
|
|
239
|
+
const lineAttr = ref.lineStart
|
|
240
|
+
? ` lines="${ref.lineStart}-${ref.lineEnd}"`
|
|
241
|
+
: "";
|
|
167
242
|
const attrs =
|
|
168
243
|
`path="${escapeAttr(ref.rel)}" bytes="${ref.bytes}"` +
|
|
244
|
+
lineAttr +
|
|
169
245
|
(ref.truncated
|
|
170
246
|
? ` truncated="true" shown-bytes="${DEFAULT_MAX_BYTES}"`
|
|
171
247
|
: "");
|
|
172
248
|
parts.push(`<file ${attrs}>`);
|
|
173
249
|
parts.push(ref.content);
|
|
174
250
|
if (ref.truncated) {
|
|
175
|
-
parts.push(
|
|
251
|
+
parts.push(
|
|
252
|
+
ref.lineStart
|
|
253
|
+
? `\n… [truncated — line range exceeds ${DEFAULT_MAX_BYTES} bytes]`
|
|
254
|
+
: `\n… [truncated — file is ${ref.bytes} bytes]`,
|
|
255
|
+
);
|
|
176
256
|
}
|
|
177
257
|
parts.push("</file>");
|
|
178
258
|
} else if (ref.kind === "dir") {
|
|
@@ -185,6 +265,30 @@ function renderBlock(refs) {
|
|
|
185
265
|
parts.push(`… [truncated — ${ref.total} entries total]`);
|
|
186
266
|
}
|
|
187
267
|
parts.push("</dir>");
|
|
268
|
+
} else if (ref.kind === "pdf") {
|
|
269
|
+
if (typeof ref.content === "string") {
|
|
270
|
+
const pageAttr =
|
|
271
|
+
ref.pageStart != null ? ` pages="${ref.pageStart}-${ref.pageEnd}"` : "";
|
|
272
|
+
const attrs =
|
|
273
|
+
`path="${escapeAttr(ref.rel)}" bytes="${ref.bytes}" type="pdf"` +
|
|
274
|
+
pageAttr +
|
|
275
|
+
(ref.truncated
|
|
276
|
+
? ` truncated="true" shown-bytes="${DEFAULT_MAX_BYTES}"`
|
|
277
|
+
: "");
|
|
278
|
+
parts.push(`<file ${attrs}>`);
|
|
279
|
+
parts.push(ref.content);
|
|
280
|
+
if (ref.truncated) {
|
|
281
|
+
parts.push(`\n… [truncated — PDF text exceeds ${DEFAULT_MAX_BYTES} bytes]`);
|
|
282
|
+
}
|
|
283
|
+
parts.push("</file>");
|
|
284
|
+
} else {
|
|
285
|
+
// Sync context (or extraction failed): no page text inlined.
|
|
286
|
+
const note =
|
|
287
|
+
ref.pdfNote || "PDF — page text not extracted in this context";
|
|
288
|
+
parts.push(
|
|
289
|
+
`<file path="${escapeAttr(ref.rel)}" bytes="${ref.bytes}" type="pdf" note="${escapeAttr(note)}" />`,
|
|
290
|
+
);
|
|
291
|
+
}
|
|
188
292
|
} else if (ref.kind === "binary") {
|
|
189
293
|
parts.push(
|
|
190
294
|
`<file path="${escapeAttr(ref.rel)}" bytes="${ref.bytes}" binary="true" note="binary file — contents omitted" />`,
|
|
@@ -208,11 +312,8 @@ function renderBlock(refs) {
|
|
|
208
312
|
* `prompt` is unchanged when nothing resolved; otherwise it is the
|
|
209
313
|
* original text + a trailing `<referenced-files>` block.
|
|
210
314
|
*/
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (!text || !text.includes("@")) {
|
|
214
|
-
return { prompt: text, refs: [], warnings: [] };
|
|
215
|
-
}
|
|
315
|
+
/** Resolve every @token to a ref (no rendering). Shared by sync + async. */
|
|
316
|
+
function _resolveAllRefs(text, opts) {
|
|
216
317
|
const fs = opts.deps?.fs || fsDefault;
|
|
217
318
|
const path = opts.deps?.path || pathDefault;
|
|
218
319
|
const cwd = opts.cwd || process.cwd();
|
|
@@ -242,17 +343,107 @@ export function expandFileRefs(prompt, opts = {}) {
|
|
|
242
343
|
}
|
|
243
344
|
refs.push(ref);
|
|
244
345
|
}
|
|
346
|
+
return { refs, warnings, maxBytes };
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export function expandFileRefs(prompt, opts = {}) {
|
|
350
|
+
const text = typeof prompt === "string" ? prompt : "";
|
|
351
|
+
if (!text || !text.includes("@")) {
|
|
352
|
+
return { prompt: text, refs: [], warnings: [] };
|
|
353
|
+
}
|
|
354
|
+
const { refs, warnings } = _resolveAllRefs(text, opts);
|
|
355
|
+
if (refs.length === 0) {
|
|
356
|
+
return { prompt: text, refs: [], warnings };
|
|
357
|
+
}
|
|
358
|
+
return { prompt: `${text}\n\n${renderBlock(refs)}`, refs, warnings };
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Async superset of {@link expandFileRefs} that ALSO extracts text from
|
|
363
|
+
* `@file.pdf` (optionally a page range, e.g. `@doc.pdf#1-3`). Needs the optional
|
|
364
|
+
* `pdf-parse` dependency; when it's absent each PDF ref degrades to a note and a
|
|
365
|
+
* warning (never throws). Used by the agent / REPL paths; the sync expandFileRefs
|
|
366
|
+
* leaves PDFs un-extracted.
|
|
367
|
+
*/
|
|
368
|
+
export async function expandFileRefsAsync(prompt, opts = {}) {
|
|
369
|
+
const text = typeof prompt === "string" ? prompt : "";
|
|
370
|
+
if (!text || !text.includes("@")) {
|
|
371
|
+
return { prompt: text, refs: [], warnings: [] };
|
|
372
|
+
}
|
|
373
|
+
const { refs, warnings, maxBytes } = _resolveAllRefs(text, opts);
|
|
374
|
+
const extractPdf = opts.deps?.extractPdfPages || _extractPdfPages;
|
|
375
|
+
|
|
376
|
+
for (const ref of refs) {
|
|
377
|
+
if (ref.kind !== "pdf" || !ref.buf) continue;
|
|
378
|
+
try {
|
|
379
|
+
const out = await extractPdf(ref.buf, {
|
|
380
|
+
firstPage: ref.pageStart,
|
|
381
|
+
lastPage: ref.pageEnd,
|
|
382
|
+
maxBytes,
|
|
383
|
+
});
|
|
384
|
+
ref.content = String(out?.text || "");
|
|
385
|
+
ref.truncated = !!out?.truncated;
|
|
386
|
+
} catch (err) {
|
|
387
|
+
if (err && err.code === "PDF_LIB_MISSING") {
|
|
388
|
+
ref.pdfNote =
|
|
389
|
+
"PDF — install the optional `pdf-parse` dependency to extract page text";
|
|
390
|
+
warnings.push(
|
|
391
|
+
`@${ref.raw} — PDF extraction needs the optional \`pdf-parse\` dep (left as a reference)`,
|
|
392
|
+
);
|
|
393
|
+
} else {
|
|
394
|
+
ref.pdfNote = `PDF — could not extract text (${err?.message || "error"})`;
|
|
395
|
+
warnings.push(
|
|
396
|
+
`@${ref.raw} — PDF extraction failed: ${err?.message || "error"} (left as a reference)`,
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
delete ref.buf; // don't keep the raw bytes around once consumed
|
|
401
|
+
}
|
|
245
402
|
|
|
246
403
|
if (refs.length === 0) {
|
|
247
404
|
return { prompt: text, refs: [], warnings };
|
|
248
405
|
}
|
|
406
|
+
return { prompt: `${text}\n\n${renderBlock(refs)}`, refs, warnings };
|
|
407
|
+
}
|
|
249
408
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
409
|
+
/**
|
|
410
|
+
* Default PDF text extractor (optional `pdf-parse`). Returns
|
|
411
|
+
* `{ text, numpages, truncated }` for pages [firstPage, lastPage] (all pages
|
|
412
|
+
* when those are null), byte-capped at maxBytes. Throws code `PDF_LIB_MISSING`
|
|
413
|
+
* when the optional dependency is not installed.
|
|
414
|
+
*/
|
|
415
|
+
async function _extractPdfPages(buffer, { firstPage, lastPage, maxBytes } = {}) {
|
|
416
|
+
let pdfParse;
|
|
417
|
+
try {
|
|
418
|
+
// pdf-parse's index.js runs debug code under ESM (no module.parent), so
|
|
419
|
+
// import the lib entry directly to avoid it.
|
|
420
|
+
const mod = await import("pdf-parse/lib/pdf-parse.js");
|
|
421
|
+
pdfParse = mod.default || mod;
|
|
422
|
+
} catch {
|
|
423
|
+
const e = new Error("pdf-parse not installed");
|
|
424
|
+
e.code = "PDF_LIB_MISSING";
|
|
425
|
+
throw e;
|
|
426
|
+
}
|
|
427
|
+
const data = await pdfParse(buffer, {
|
|
428
|
+
pagerender: (pageData) => {
|
|
429
|
+
const n = pageData && pageData.pageNumber;
|
|
430
|
+
if (typeof n === "number") {
|
|
431
|
+
if (firstPage && n < firstPage) return "";
|
|
432
|
+
if (lastPage && n > lastPage) return "";
|
|
433
|
+
}
|
|
434
|
+
return pageData.getTextContent().then((tc) =>
|
|
435
|
+
(tc.items || []).map((it) => it.str).join(" "),
|
|
436
|
+
);
|
|
437
|
+
},
|
|
438
|
+
});
|
|
439
|
+
let out = String(data?.text || "").trim();
|
|
440
|
+
let truncated = false;
|
|
441
|
+
const cap = Number.isFinite(maxBytes) ? maxBytes : DEFAULT_MAX_BYTES;
|
|
442
|
+
if (Buffer.byteLength(out, "utf-8") > cap) {
|
|
443
|
+
out = out.slice(0, cap);
|
|
444
|
+
truncated = true;
|
|
445
|
+
}
|
|
446
|
+
return { text: out, numpages: data?.numpages || 0, truncated };
|
|
256
447
|
}
|
|
257
448
|
|
|
258
449
|
export const _deps = { fs: fsDefault, path: pathDefault };
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
sessionExists as jsonlSessionExists,
|
|
44
44
|
getLastSessionId as jsonlGetLastSessionId,
|
|
45
45
|
} from "../harness/jsonl-session-store.js";
|
|
46
|
-
import {
|
|
46
|
+
import { expandFileRefsAsync } from "./file-ref-expander.js";
|
|
47
47
|
import { composeSystemPrompt } from "./system-prompt.js";
|
|
48
48
|
import { buildUserContent } from "../lib/image-input.js";
|
|
49
49
|
import { withQuietStdout } from "./quiet-stdout.js";
|
|
@@ -330,8 +330,8 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
330
330
|
// cat-pipe. Opt out with `--no-file-refs` (options.expandFileRefs === false).
|
|
331
331
|
let userContent = prompt;
|
|
332
332
|
if (options.expandFileRefs !== false) {
|
|
333
|
-
const doExpand = deps.expandFileRefs ||
|
|
334
|
-
const expanded = doExpand(prompt, { cwd });
|
|
333
|
+
const doExpand = deps.expandFileRefs || expandFileRefsAsync;
|
|
334
|
+
const expanded = await doExpand(prompt, { cwd });
|
|
335
335
|
userContent = expanded.prompt;
|
|
336
336
|
// Warnings (typo'd paths, unreadable files) go to stderr in every output
|
|
337
337
|
// format so stdout stays a clean machine payload.
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import { bootstrap } from "./bootstrap.js";
|
|
20
20
|
import { buildSystemPrompt, agentLoop as coreAgentLoop } from "./agent-core.js";
|
|
21
21
|
import { composeSystemPrompt } from "./system-prompt.js";
|
|
22
|
-
import {
|
|
22
|
+
import { expandFileRefsAsync } from "./file-ref-expander.js";
|
|
23
23
|
import {
|
|
24
24
|
resolveAgentMcp,
|
|
25
25
|
resolvePermissionPromptTool,
|
|
@@ -260,7 +260,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
260
260
|
const input = deps.input || process.stdin;
|
|
261
261
|
const runLoop = deps.agentLoop || coreAgentLoop;
|
|
262
262
|
const doBootstrap = deps.bootstrap || bootstrap;
|
|
263
|
-
const doExpand = deps.expandFileRefs ||
|
|
263
|
+
const doExpand = deps.expandFileRefs || expandFileRefsAsync;
|
|
264
264
|
const writeOut = deps.writeOut || ((s) => process.stdout.write(s));
|
|
265
265
|
const writeErr = deps.writeErr || ((s) => process.stderr.write(s));
|
|
266
266
|
const emit = (obj) => writeOut(JSON.stringify(obj) + "\n");
|
|
@@ -578,6 +578,19 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
578
578
|
},
|
|
579
579
|
})
|
|
580
580
|
: undefined,
|
|
581
|
+
// Extended-thinking reasoning deltas (Anthropic; only when thinking is on).
|
|
582
|
+
// Surfaced as a thinking_delta so consumers can render a dimmed/collapsed
|
|
583
|
+
// reasoning block — the visible half of the /think toggle.
|
|
584
|
+
onThinking: options.includePartialMessages
|
|
585
|
+
? (thinking) =>
|
|
586
|
+
emit({
|
|
587
|
+
type: "stream_event",
|
|
588
|
+
event: {
|
|
589
|
+
type: "content_block_delta",
|
|
590
|
+
delta: { type: "thinking_delta", thinking },
|
|
591
|
+
},
|
|
592
|
+
})
|
|
593
|
+
: undefined,
|
|
581
594
|
};
|
|
582
595
|
|
|
583
596
|
// --max-budget-usd: a SESSION-WIDE USD spend cap across all turns. Folded
|
|
@@ -745,7 +758,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
745
758
|
// @file expansion per user event (parity with single-turn headless).
|
|
746
759
|
let userContent = parsed.text;
|
|
747
760
|
if (options.expandFileRefs !== false) {
|
|
748
|
-
const expanded = doExpand(parsed.text, { cwd });
|
|
761
|
+
const expanded = await doExpand(parsed.text, { cwd });
|
|
749
762
|
userContent = expanded.prompt;
|
|
750
763
|
for (const w of expanded.warnings) writeErr(` @ref: ${w}\n`);
|
|
751
764
|
}
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import fs from "fs";
|
|
18
|
+
import path from "path";
|
|
18
19
|
import { MCPClient } from "../harness/mcp-client.js";
|
|
20
|
+
import { projectRootBase } from "../lib/project-root.cjs";
|
|
19
21
|
import {
|
|
20
22
|
discoverIdeServer,
|
|
21
23
|
ideServerToMcpConfig,
|
|
@@ -375,10 +377,73 @@ export async function loadIdeMcp(opts = {}, deps = {}) {
|
|
|
375
377
|
return out;
|
|
376
378
|
}
|
|
377
379
|
|
|
380
|
+
/**
|
|
381
|
+
* Discover + connect a project-scoped `.mcp.json` (Claude-Code parity). Reads a
|
|
382
|
+
* `.mcp.json` from the git project root (walked up from cwd, same as the
|
|
383
|
+
* `.claude` config layers) and from cwd itself, merging their `mcpServers`
|
|
384
|
+
* (cwd wins on a name clash — closest wins). Best-effort: a missing / empty /
|
|
385
|
+
* malformed file contributes nothing and never throws.
|
|
386
|
+
*
|
|
387
|
+
* SECURITY: a checked-in `.mcp.json` can spawn arbitrary commands, so this layer
|
|
388
|
+
* is OPT-IN (default-off) — it only runs when explicitly enabled with
|
|
389
|
+
* `--project-mcp` / `CC_PROJECT_MCP=1` (truthy). When enabled, the servers it
|
|
390
|
+
* loads are announced via writeErr. Connected into `deps.into`, so an explicit
|
|
391
|
+
* `--mcp-config` server or a registered (`cc mcp add`) server WINS on a name
|
|
392
|
+
* clash (the first batch wins in setupMcpFromConfig).
|
|
393
|
+
*
|
|
394
|
+
* @param {object} opts { cwd?, env? }
|
|
395
|
+
* @param {object} [deps] { writeErr, into, readFile, fileExists, createClient }
|
|
396
|
+
*/
|
|
397
|
+
export async function loadProjectMcp(opts = {}, deps = {}) {
|
|
398
|
+
const env = opts.env || process.env;
|
|
399
|
+
// Opt-in gate (default-off): only load a project `.mcp.json` when explicitly
|
|
400
|
+
// enabled — a checked-in file spawning commands in any cloned repo is a
|
|
401
|
+
// supply-chain risk, so the user must turn it on per run / per shell.
|
|
402
|
+
const flag = String(env.CC_PROJECT_MCP || "").toLowerCase();
|
|
403
|
+
if (flag !== "1" && flag !== "true") return deps.into || null;
|
|
404
|
+
const cwd = opts.cwd || process.cwd();
|
|
405
|
+
const readFile = deps.readFile || ((p) => fs.readFileSync(p, "utf-8"));
|
|
406
|
+
const fileExists = deps.fileExists || ((p) => fs.existsSync(p));
|
|
407
|
+
const writeErr = deps.writeErr || (() => {});
|
|
408
|
+
|
|
409
|
+
// Project-root `.mcp.json` (below cwd's), then cwd's own — so a cwd-local file
|
|
410
|
+
// overrides the root on a name clash. projectRootBase() is null when cwd IS
|
|
411
|
+
// the root (its own file already covers it) or there is no git project.
|
|
412
|
+
const files = [];
|
|
413
|
+
const root = projectRootBase(cwd, { fs, path });
|
|
414
|
+
if (root) files.push(path.join(root, ".mcp.json"));
|
|
415
|
+
files.push(path.join(cwd, ".mcp.json"));
|
|
416
|
+
|
|
417
|
+
const servers = {};
|
|
418
|
+
const seenFiles = [];
|
|
419
|
+
for (const file of files) {
|
|
420
|
+
if (!fileExists(file)) continue;
|
|
421
|
+
let raw;
|
|
422
|
+
try {
|
|
423
|
+
raw = JSON.parse(readFile(file));
|
|
424
|
+
} catch (err) {
|
|
425
|
+
writeErr(` mcp: ignoring malformed ${file} (${err.message})\n`);
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
const parsed = parseMcpServers(raw);
|
|
429
|
+
if (Object.keys(parsed).length > 0) {
|
|
430
|
+
Object.assign(servers, parsed); // later file (cwd) overrides earlier (root)
|
|
431
|
+
seenFiles.push(file);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (Object.keys(servers).length === 0) return deps.into || null;
|
|
435
|
+
writeErr(
|
|
436
|
+
` mcp: ${Object.keys(servers).length} server(s) from project .mcp.json ` +
|
|
437
|
+
`(${seenFiles.join(", ")}) — loaded via --project-mcp\n`,
|
|
438
|
+
);
|
|
439
|
+
return setupMcpFromConfig(servers, deps);
|
|
440
|
+
}
|
|
441
|
+
|
|
378
442
|
/**
|
|
379
443
|
* Resolve the full MCP tool surface for one agent run: the ad-hoc
|
|
380
444
|
* `--mcp-config` file (if any) PLUS registered auto-connect servers (unless
|
|
381
|
-
* disabled) PLUS
|
|
445
|
+
* disabled) PLUS a project-scoped `.mcp.json` (opt-in, `--project-mcp`) PLUS an
|
|
446
|
+
* auto-discovered IDE bridge, connected into a single client.
|
|
382
447
|
* Returns the combined `{mcpClient, extraToolDefinitions, ...}` or null when
|
|
383
448
|
* there's nothing. Throws only on a bad `--mcp-config` file (explicit request).
|
|
384
449
|
*
|
|
@@ -391,6 +456,7 @@ export async function loadIdeMcp(opts = {}, deps = {}) {
|
|
|
391
456
|
export async function resolveAgentMcp(args = {}, deps = {}) {
|
|
392
457
|
const doFile = deps.loadMcpConfig || loadMcpConfig;
|
|
393
458
|
const doReg = deps.loadRegisteredMcp || loadRegisteredMcp;
|
|
459
|
+
const doProject = deps.loadProjectMcp || loadProjectMcp;
|
|
394
460
|
const doIde = deps.loadIdeMcp || loadIdeMcp;
|
|
395
461
|
// Thread the agent session id down to setupMcpFromConfig so spawned stdio MCP
|
|
396
462
|
// servers get CC_SESSION_ID / CLAUDE_CODE_SESSION_ID (Claude-Code parity).
|
|
@@ -413,6 +479,17 @@ export async function resolveAgentMcp(args = {}, deps = {}) {
|
|
|
413
479
|
into: result || undefined,
|
|
414
480
|
});
|
|
415
481
|
}
|
|
482
|
+
// Project-scoped `.mcp.json` (Claude-Code parity). After --mcp-config +
|
|
483
|
+
// registered (those win on a name clash), before IDE auto-discovery. Skipped
|
|
484
|
+
// under --strict-mcp-config (returned above). OPT-IN: loadProjectMcp is a
|
|
485
|
+
// no-op unless --project-mcp / CC_PROJECT_MCP=1 is set (default-off — a
|
|
486
|
+
// checked-in .mcp.json can spawn commands). `projectMcp:false` hard-skips it.
|
|
487
|
+
if (args.projectMcp !== false) {
|
|
488
|
+
result = await doProject(
|
|
489
|
+
{ cwd: args.cwd, env: args.env || process.env },
|
|
490
|
+
{ ...fwd, into: result || undefined },
|
|
491
|
+
);
|
|
492
|
+
}
|
|
416
493
|
if (args.ide !== false) {
|
|
417
494
|
const env = args.env || process.env;
|
|
418
495
|
const inIde = (deps.isInIdeTerminal || isInIdeTerminal)(env);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{E as B,b as D,r as z,I as p,J as c,U as _,c as n,K as a,S,V as w,o as P,x as I,P as i,Q as g,R as r,F as h,Z as F}from"./vendor-BvqAck49.js";import{u as R,_ as O}from"./index-CSnTUPQx.js";import{R as E}from"./icons-DP3uiYxy.js";const V=B("tasks",()=>{const k=z([]),l=z(!1);let u=null,e=null;const x=D(()=>k.value.filter(t=>t.status==="running")),b=D(()=>k.value.filter(t=>t.status==="pending")),y=D(()=>k.value.filter(t=>t.status==="completed"||t.status==="failed"||t.status==="timeout"));async function f(){const t=R();l.value=!0;try{const s=await t.sendRaw({type:"tasks-list"});s&&Array.isArray(s.tasks)&&(k.value=s.tasks)}catch{}finally{l.value=!1}}async function o(t){const s=R();try{await s.sendRaw({type:"tasks-stop",taskId:t})}catch{}finally{await f()}}const d=z(null);function m(t=5e3){v(),f(),u=setInterval(f,t),T()}function v(){u&&(clearInterval(u),u=null),e&&(e(),e=null)}function T(){const t=R();if(e)return;const s=C=>{C.type==="task:notification"&&C.payload?.task&&(d.value=C.payload.task,f(),setTimeout(()=>{d.value=null},8e3))};e=t.onRuntimeEvent(s)}function N(t){return!t||t<0?"-":t<1e3?`${t}ms`:t<6e4?`${(t/1e3).toFixed(1)}s`:`${(t/6e4).toFixed(1)}m`}function A(t){switch(t){case"running":return"processing";case"pending":return"default";case"completed":return"success";case"failed":return"error";case"timeout":return"warning";default:return"default"}}return{tasks:k,loading:l,running:x,pending:b,completed:y,lastNotification:d,fetchTasks:f,stopTask:o,startPolling:m,stopPolling:v,formatDuration:N,getStatusColor:A}}),U={__name:"Tasks",setup(k,{expose:l}){l();const u=V(),e=[{title:"状态",key:"status",width:90},{title:"描述",key:"description",ellipsis:!0},{title:"类型",dataIndex:"type",width:100},{title:"耗时",key:"duration",width:90},{title:"创建时间",key:"createdAt",width:180},{title:"结果",key:"result",ellipsis:!0},{title:"操作",key:"action",width:80}];function x(o){return o.status==="running"&&o.startedAt?u.formatDuration(Date.now()-o.startedAt):o.completedAt&&o.startedAt?u.formatDuration(o.completedAt-o.startedAt):"-"}function b(o){return o?new Date(o).toLocaleString():"-"}function y(o,d){return o?o.length>d?`${o.slice(0,d)}...`:o:""}P(()=>u.startPolling(5e3)),I(()=>u.stopPolling());const f={store:u,columns:e,getDuration:x,formatTime:b,truncate:y,onMounted:P,onUnmounted:I,get ReloadOutlined(){return E},get useTasksStore(){return V}};return Object.defineProperty(f,"__isScriptSetup",{enumerable:!1,value:!0}),f}},L={class:"page-header"},Q={key:0,class:"error-text"},j={key:1},G={class:"task-header"},J={class:"task-desc"},K={class:"task-id"},M={class:"task-meta"},W=["title"],Z={key:0,class:"error-text"},q={key:1,class:"success-text"},H={key:2,class:"muted-text"};function X(k,l,u,e,x,b){const y=p("a-button"),f=p("a-space"),o=p("a-alert"),d=p("a-statistic"),m=p("a-card"),v=p("a-col"),T=p("a-row"),N=p("a-tag"),A=p("a-table");return i(),c("div",null,[_("div",L,[l[3]||(l[3]=_("div",null,[_("h2",{class:"page-title"},"后台任务"),_("p",{class:"page-sub"},"查看后台任务队列、实时通知和任务执行结果。")],-1)),n(f,null,{default:a(()=>[n(y,{ghost:"",loading:e.store.loading,onClick:l[0]||(l[0]=t=>e.store.fetchTasks())},{icon:a(()=>[n(e.ReloadOutlined)]),default:a(()=>[l[2]||(l[2]=g(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.store.lastNotification?(i(),S(o,{key:0,type:e.store.lastNotification.status==="completed"?"success":"error","show-icon":"",closable:"",class:"banner",onClose:l[1]||(l[1]=t=>e.store.lastNotification=null)},{message:a(()=>[g(" 任务"+r(e.store.lastNotification.status==="completed"?"完成":"结束")+": "+r(e.store.lastNotification.description||e.store.lastNotification.id.slice(0,16)),1)]),description:a(()=>[e.store.lastNotification.error?(i(),c("span",Q,r(e.store.lastNotification.error),1)):e.store.lastNotification.result?(i(),c("span",j,r(e.truncate(String(e.store.lastNotification.result),120)),1)):w("v-if",!0)]),_:1},8,["type"])):w("v-if",!0),n(T,{gutter:[16,16],class:"stats-row"},{default:a(()=>[n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"全部任务",value:e.store.tasks.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"运行中",value:e.store.running.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"等待中",value:e.store.pending.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"已完成",value:e.store.completed.length},null,8,["value"])]),_:1})]),_:1})]),_:1}),e.store.running.length>0?(i(),S(m,{key:1,title:"运行中的任务",class:"panel-card",size:"small"},{default:a(()=>[(i(!0),c(h,null,F(e.store.running,t=>(i(),c("div",{key:t.id,class:"task-item running"},[_("div",G,[n(N,{color:e.store.getStatusColor(t.status)},{default:a(()=>[g(r(t.status.toUpperCase()),1)]),_:2},1032,["color"]),_("span",J,r(t.description),1),_("span",K,r(t.id.slice(0,16)),1)]),_("div",M,[_("span",null,"类型: "+r(t.type||"-"),1),_("span",null,"已运行: "+r(e.store.formatDuration(Date.now()-t.startedAt)),1),n(y,{size:"small",danger:"",onClick:s=>e.store.stopTask(t.id)},{default:a(()=>[...l[4]||(l[4]=[g("停止",-1)])]),_:1},8,["onClick"])])]))),128))]),_:1})):w("v-if",!0),n(m,{class:"panel-card"},{default:a(()=>[n(A,{columns:e.columns,"data-source":e.store.tasks,pagination:{pageSize:15,size:"small"},loading:e.store.loading,"row-key":"id",size:"small"},{bodyCell:a(({column:t,record:s})=>[t.key==="status"?(i(),S(N,{key:0,color:e.store.getStatusColor(s.status)},{default:a(()=>[g(r(s.status),1)]),_:2},1032,["color"])):t.key==="description"?(i(),c("span",{key:1,title:s.command},r(s.description),9,W)):t.key==="duration"?(i(),c(h,{key:2},[g(r(e.getDuration(s)),1)],64)):t.key==="createdAt"?(i(),c(h,{key:3},[g(r(e.formatTime(s.createdAt)),1)],64)):t.key==="result"?(i(),c(h,{key:4},[s.error?(i(),c("span",Z,r(e.truncate(s.error,60)),1)):s.result?(i(),c("span",q,r(e.truncate(String(s.result),60)),1)):(i(),c("span",H,"-"))],64)):t.key==="action"?(i(),c(h,{key:5},[s.status==="running"?(i(),S(y,{key:0,size:"small",danger:"",onClick:C=>e.store.stopTask(s.id)},{default:a(()=>[...l[5]||(l[5]=[g(" 停止 ",-1)])]),_:1},8,["onClick"])):w("v-if",!0)],64)):w("v-if",!0)]),_:1},8,["data-source","loading"])]),_:1})])}const et=O(U,[["render",X],["__scopeId","data-v-da5ff6a2"],["__file","/tmp/cc-web-panel-wQGCAD/repo/packages/web-panel/src/views/Tasks.vue"]]);export{et as default};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./xterm-BZcWGsqw.js","./markdown-CsiA8-E5.js","./markdown-Dfs9RUU9.css","./addon-fit-CK6X9sAG.js","./xterm-DFuMZ0ql.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{u as fe,_ as me,d as V,e as U}from"./index-CSnTUPQx.js";import{I as z,J as x,U as _,Q as P,S as J,K as T,V as R,c as A,F as K,Z as Y,R as E,o as Z,f as H,w as $,n as q,b as ee,r as S,P as y,_ as ve,a2 as we,a3 as he,a4 as _e}from"./vendor-BvqAck49.js";import{R as ye,b as pe,as as ge}from"./icons-DP3uiYxy.js";const k=new Map,C=new Map,N=new Set,F=new Set;let te=!1;function xe(c){te||(te=!0,c.onMessage(o=>{if(!(!o||typeof o.type!="string")){if(o.type==="terminal.stdout"){const{sessionId:s,data:e,seq:i}=o.payload||{};if(!s)return;let w;try{const d=atob(e||""),f=new Uint8Array(d.length);for(let n=0;n<d.length;n++)f[n]=d.charCodeAt(n);w=new TextDecoder("utf-8").decode(f)}catch{w=""}const u={sessionId:s,data:w,seq:i};k.get(s)?.forEach(d=>d(u)),N.forEach(d=>d(u))}else if(o.type==="terminal.exit"){const{sessionId:s,exitCode:e,signal:i}=o.payload||{};if(!s)return;const w={sessionId:s,exitCode:e,signal:i};C.get(s)?.forEach(u=>u(w)),F.forEach(u=>u(w))}}}))}function ne(c){const o=new TextEncoder().encode(c);let s="";for(let e=0;e<o.length;e++)s+=String.fromCharCode(o[e]);return btoa(s)}function ae(c){const o=atob(c||""),s=new Uint8Array(o.length);for(let e=0;e<o.length;e++)s[e]=o.charCodeAt(e);return new TextDecoder("utf-8").decode(s)}function oe(){const c=fe();xe(c);async function o(n={}){const a=await c.sendRaw({type:"terminal.create",payload:{shell:n.shell,cwd:n.cwd,env:n.env,cols:n.cols,rows:n.rows}});if(a.ok===!1)throw new Error(a.error||"terminal_create_failed");return a.result??a}async function s(){const n=await c.sendRaw({type:"terminal.list",payload:{}});if(n.ok===!1)throw new Error(n.error||"terminal_list_failed");const a=n.result??n;return Array.isArray(a.sessions)?a.sessions:[]}async function e(n,a){const r=await c.sendRaw({type:"terminal.stdin",payload:{sessionId:n,data:ne(String(a))}});if(r.ok===!1)throw new Error(r.error||"terminal_stdin_failed");return r.result??r}async function i(n,a,r){const h=await c.sendRaw({type:"terminal.resize",payload:{sessionId:n,cols:a,rows:r}});if(h.ok===!1)throw new Error(h.error||"terminal_resize_failed");return h.result??h}async function w(n){const a=await c.sendRaw({type:"terminal.close",payload:{sessionId:n}});if(a.ok===!1)throw new Error(a.error||"terminal_close_failed");return a.result??a}async function u(n,a=0){const r=await c.sendRaw({type:"terminal.history",payload:{sessionId:n,fromSeq:a}});if(r.ok===!1)throw new Error(r.error||"terminal_history_failed");const h=r.result??r;return{truncated:!!h.truncated,chunks:(h.chunks||[]).map(D=>({seq:D.seq,data:ae(D.data)}))}}function d(n,a){return n?(k.has(n)||k.set(n,new Set),k.get(n).add(a),()=>{k.get(n)?.delete(a),k.get(n)?.size===0&&k.delete(n)}):(N.add(a),()=>N.delete(a))}function f(n,a){return n?(C.has(n)||C.set(n,new Set),C.get(n).add(a),()=>{C.get(n)?.delete(a),C.get(n)?.size===0&&C.delete(n)}):(F.add(a),()=>F.delete(a))}return{create:o,list:s,stdin:e,resize:i,close:w,history:u,onStdout:d,onExit:f,_internal:{stdoutSubs:k,exitSubs:C,toBase64Utf8:ne,fromBase64Utf8:ae}}}const Se={__name:"Terminal",setup(c,{expose:o}){o();const s=oe(),e=S([]),i=S(null),w=S("pwsh"),u=S(!1),d=S(!1),f=S(""),n=S(""),a=S([]),r=[{value:"pwsh",label:"PowerShell"},{value:"cmd",label:"CMD"},{value:"bash",label:"Bash"},{value:"wsl",label:"WSL"}],h=ee(()=>e.value.find(t=>t.id===i.value));function D(t){return t?t.slice(0,8):""}let O=null,M=null;async function I(){if(O)return{xtermMod:O,fitAddonMod:M};try{O=await U(()=>import("./xterm-BZcWGsqw.js").then(t=>t.x),__vite__mapDeps([0,1,2]),import.meta.url),M=await U(()=>import("./addon-fit-CK6X9sAG.js").then(t=>t.a),__vite__mapDeps([3,1,2]),import.meta.url),await U(()=>Promise.resolve({}),__vite__mapDeps([4]),import.meta.url)}catch(t){throw n.value="xterm 资源加载失败:"+(t?.message||"未知错误"),t}return{xtermMod:O,fitAddonMod:M}}async function B(t){await q();const{xtermMod:l,fitAddonMod:p}=await I(),b=a.value.find(v=>v?.dataset?.sessionId===t.id);if(!b)return;const m=new l.Terminal({cursorBlink:!0,fontFamily:'Consolas, "Courier New", monospace',fontSize:13,theme:{background:"#1e1e1e",foreground:"#d4d4d4"},convertEol:!1}),L=new p.FitAddon;m.loadAddon(L),m.open(b);try{L.fit()}catch{}t.xterm=m,t.fitAddon=L;const ie=m.onData(v=>{s.stdin(t.id,v).catch(g=>{String(g?.message||"").includes("dangerous_keyword_blocked")?V.warning("该命令被桌面端拦截(高危关键字)"):V.error("stdin 失败: "+(g?.message||g))})}),ce=s.onStdout(t.id,({data:v,seq:g})=>{t.lastSeq=g,m.write(v)}),de=s.onExit(t.id,({exitCode:v,signal:g})=>{t.alive=!1,t.exitCode=v,t.signal=g,m.writeln(`\r
|
|
3
|
-
\x1B[33m[session exited, code=${v}, signal=${g??"-"}]\x1B[0m`)});t.offs=()=>{try{ie.dispose?.()}catch{}ce(),de()};try{const{chunks:v,truncated:g}=await s.history(t.id,0);g&&m.writeln("\x1B[2m[history truncated — earlier output was evicted]\x1B[0m");for(const G of v)m.write(G.data),t.lastSeq=G.seq}catch(v){m.writeln(`\x1B[31m[history fetch failed: ${v?.message||v}]\x1B[0m`)}const j=new ResizeObserver(()=>{try{L.fit(),s.resize(t.id,m.cols,m.rows).catch(()=>{})}catch{}});j.observe(b);const ue=t.offs;t.offs=()=>{try{j.disconnect()}catch{}ue()}}async function re(){u.value=!0,f.value="";try{const t=await s.create({shell:w.value,cols:80,rows:24}),l={id:t.sessionId,shell:t.shell,cwd:"",alive:!0,lastSeq:0,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(l),i.value=l.id,await B(l)}catch(t){f.value=t?.message||String(t)}finally{u.value=!1}}async function se(t){try{await s.close(t)}catch(l){f.value=l?.message||String(l)}setTimeout(()=>W(t),500)}function W(t){const l=e.value.findIndex(b=>b.id===t);if(l===-1)return;const p=e.value[l];try{p.offs?.()}catch{}try{p.xterm?.dispose?.()}catch{}e.value.splice(l,1),i.value===t&&(i.value=e.value[0]?.id||null)}function le(t){i.value=t,q(()=>{const l=e.value.find(p=>p.id===t);try{l?.fitAddon?.fit()}catch{}})}async function Q(){d.value=!0,f.value="";try{const t=await s.list();for(const l of t){const p=e.value.find(m=>m.id===l.id);if(p){p.alive=l.alive,p.lastSeq=l.lastSeq;continue}const b={id:l.id,shell:l.shell,cwd:l.cwd,alive:l.alive,lastSeq:l.lastSeq,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(b),await B(b)}!i.value&&e.value.length>0&&(i.value=e.value[0].id)}catch(t){f.value=t?.message||String(t)}finally{d.value=!1}}Z(async()=>{await Q()}),H(()=>{for(const t of e.value){try{t.offs?.()}catch{}try{t.xterm?.dispose?.()}catch{}}}),$(i,()=>{q(()=>{const t=h.value;try{t?.fitAddon?.fit()}catch{}})});const X={term:s,sessions:e,activeId:i,newShell:w,creating:u,loadingList:d,error:f,warning:n,xtermContainers:a,shellOptions:r,active:h,shortId:D,get xtermMod(){return O},set xtermMod(t){O=t},get fitAddonMod(){return M},set fitAddonMod(t){M=t},loadXterm:I,mountXterm:B,onCreate:re,onClose:se,removeSession:W,activate:le,refreshList:Q,ref:S,computed:ee,onMounted:Z,onBeforeUnmount:H,nextTick:q,watch:$,get message(){return V},get PlusOutlined(){return ge},get CloseOutlined(){return pe},get ReloadOutlined(){return ye},get useTerminal(){return oe}};return Object.defineProperty(X,"__isScriptSetup",{enumerable:!1,value:!0}),X}},be={class:"terminal-page"},ke={class:"terminal-header"},Ce={class:"page-sub"},Ae={class:"terminal-body"},Ee={class:"session-tabs"},Oe=["onClick"],Te={class:"session-shell"},Re={class:"session-id"},Me={key:0,class:"session-empty"},ze={class:"xterm-host"},De=["data-session-id"],Le={key:0,class:"xterm-placeholder"},Pe={key:1,class:"terminal-footer"},qe={key:0,class:"footer-exit"};function Be(c,o,s,e,i,w){const u=z("a-tag"),d=z("a-select"),f=z("a-button"),n=z("a-space"),a=z("a-alert");return y(),x("div",be,[_("div",ke,[_("div",null,[o[3]||(o[3]=_("h2",{class:"page-title"},"远程终端",-1)),_("p",Ce,[o[2]||(o[2]=P(" 桌面端托管的 PTY 会话;Android 端可远程操控同一通道 ",-1)),e.warning?(y(),J(u,{key:0,color:"orange",style:{"margin-left":"8px"}},{default:T(()=>[P(E(e.warning),1)]),_:1})):R("v-if",!0)])]),A(n,null,{default:T(()=>[A(d,{value:e.newShell,"onUpdate:value":o[0]||(o[0]=r=>e.newShell=r),style:{width:"130px"},size:"small",options:e.shellOptions},null,8,["value"]),A(f,{type:"primary",size:"small",loading:e.creating,onClick:e.onCreate},{icon:T(()=>[A(e.PlusOutlined)]),default:T(()=>[o[4]||(o[4]=P(" 新会话 ",-1))]),_:1},8,["loading"]),A(f,{size:"small",loading:e.loadingList,onClick:e.refreshList},{icon:T(()=>[A(e.ReloadOutlined)]),default:T(()=>[o[5]||(o[5]=P(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.error?(y(),J(a,{key:0,message:e.error,type:"error","show-icon":"",closable:"",style:{"margin-bottom":"12px"},onClose:o[1]||(o[1]=r=>e.error="")},null,8,["message"])):R("v-if",!0),_("div",Ae,[_("div",Ee,[(y(!0),x(K,null,Y(e.sessions,r=>(y(),x("div",{key:r.id,class:ve(["session-tab",{active:r.id===e.activeId,dead:!r.alive}]),onClick:h=>e.activate(r.id)},[_("span",Te,E(r.shell),1),_("span",Re,E(e.shortId(r.id)),1),A(e.CloseOutlined,{class:"session-close",onClick:we(h=>e.onClose(r.id),["stop"])},null,8,["onClick"])],10,Oe))),128)),e.sessions.length===0?(y(),x("div",Me,' 点击 "新会话" 创建第一个终端 ')):R("v-if",!0)]),_("div",ze,[(y(!0),x(K,null,Y(e.sessions,r=>he((y(),x("div",{key:r.id,ref_for:!0,ref:"xtermContainers","data-session-id":r.id,class:"xterm-container"},null,8,De)),[[_e,r.id===e.activeId]])),128)),e.sessions.length===0?(y(),x("div",Le,[...o[6]||(o[6]=[_("span",null,"无活跃会话",-1)])])):R("v-if",!0)])]),e.active?(y(),x("div",Pe,[_("span",null,E(e.active.shell)+" · "+E(e.active.cwd||"(默认 cwd)")+" · seq "+E(e.active.lastSeq),1),e.active.alive?R("v-if",!0):(y(),x("span",qe,"已退出 (code="+E(e.active.exitCode??"-")+")",1))])):R("v-if",!0)])}const Fe=me(Se,[["render",Be],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-wQGCAD/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{O as r}from"./index-CSnTUPQx.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-B6KdyRTE.js";import{U as t}from"./index-CSnTUPQx.js";import"./vendor-BvqAck49.js";import"./index-C2CN7coN.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-6p4DKFSi.js";import{U as t}from"./index-CSnTUPQx.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-BQG9LlBs.js";import"./useFlexGapSupport-D_iwA3vx.js";import"./styleChecker-BZ-nMyDB.js";import"./index-C2CN7coN.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};
|