chainlesschain 0.162.86 → 0.162.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-BsWi0a9a.js → AIOps-C7p710um.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CgU09_bk.js → ActionButton-BPkTxPrS.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-EAT1K7a2.js → Analytics-ZVxKJQmI.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-scmKwxG-.js → AppLayout-BnAycTFm.js} +3 -3
- package/src/assets/web-panel/assets/{Audit-BjUhZorx.js → Audit-B7ndNORB.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-UZynrFEB.js → Backup-DsghhiwY.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-Dw7VRL38.js → BaseInput-QpM6Sqnh.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-jFpknfRR.js → Chat-BATie-Ql.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-V8GFgU1l.js → ChatBubbleRenderer-3ihYfTKb.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-A6QNjulp.js → Checkbox-CD7zltrP.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-plIAoFPy.js → Codegen-Cjcpbqy9.js} +1 -1
- package/src/assets/web-panel/assets/{Col-p8jds0fN.js → Col-CNaC37C3.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CjdSyAYH.js → Community-CoYZ9qY1.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-D_pwxcOz.js → Compact-CPwcX_f4.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-lKVtLubh.js → Compliance-DwpNy1Vy.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-C1N1klDH.js → Cowork-CHf8f-Dj.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-De82luS5.js → Cron-DfNvIJWO.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-Ye0orjca.js → Crosschain-BLMwA95k.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Ci2zdZFM.js → DID-DPjQKDJA.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-8ttZ4QQ9.js → Dashboard-UkuRfhAR.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BON5tdO8.js → Dropdown-CnXX69X4.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-iPlELXWj.js → EmailListRenderer-CmyZ4JIO.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BNBYL3FW.js → FamilyGuardDashboard-D9pJ7lhj.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Bur4PRzE.js → Federation-BTae63Nm.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BlOvhD7K.js → FormItemContext-XQRGWRGN.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BoVvb2xa.js → GenericCardRenderer-Da27wB3g.js} +1 -1
- package/src/assets/web-panel/assets/{Git-B__nMbw1.js → Git-CqkMNIfH.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DK0Zgh2N.js → Governance-CD3kOLh8.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BddQ7oih.js → Inference-B7lFbXHh.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-CvFX71Ed.js → KnowledgeGraph-BQy_DfuV.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-L2sBQLYZ.js → Logs-Dm7o5SAZ.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-BCWe7HDC.js → Marketplace-BH5XF-eR.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DqKH9JPl.js → McpTools-CpoDVi4m.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-DWWABKsb.js → Memory-CSuFkL3l.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-B2eLD-PB.js → MobileBridge-DWlG1Q_d.js} +2 -2
- package/src/assets/web-panel/assets/MobileProjects-BzYrwU_s.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-Y-5_ueBj.js → Mtc-BtWk1cJe.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-D00-m4zy.js → MtcAudit-CGpZVUOE.js} +6 -6
- package/src/assets/web-panel/assets/{Multisig-2YOBtc_K.js → Multisig-BcUnSjCA.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-kRWZBnaz.js → NLProgramming-DUmrvSP0.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DPRHkyl5.js → Notes-D9FXvxYu.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-vJOg9C4W.js → NotificationSettings-BrmdFdj6.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-CdtRzrha.js +1 -0
- package/src/assets/web-panel/assets/{Organization-BuISwIXd.js → Organization-DOvfmN8O.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BNGHwMDw.js → Overflow-CWG2ShdF.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DHBBs29l.js → P2P-DaWTeBSk.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-D9zGzba7.js → PdhVaultBrowser-DZqxKcZI.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-QLkdu-G_.js → Permissions-DR0b2vOB.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BuQlObqk.js → PersonalDataHub-DCWQVfqV.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-D_ycs0g9.js → Pipeline-BWxeVK9I.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-oN6XDVGm.js → Privacy-DvyfEXua.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BGThFxbb.js → ProjectInit-BkKJTJYI.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BxWieeHC.js → ProjectSettings-Dj-CSqKJ.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-DOd58I-_.js → Projects-DxWA-GFn.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-kREzYT7U.js → Providers-DygrHqSN.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Cw11_JEa.js → QuickAsk-CoRPq_xD.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CDWYEzDP.js → Recommend-DdOIHxul.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-BuDEzBoL.js → Reputation-BunheyMP.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Bxxu4Xtz.js → Row-DQJPE1Hl.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BpEsZmwI.js → RssFeed-Dv5NljB2.js} +3 -3
- package/src/assets/web-panel/assets/{Search-BKDmySFl.js → Search-DETFhGY8.js} +1 -1
- package/src/assets/web-panel/assets/{Security-gJvuDQw2.js → Security-3kETo1JV.js} +3 -3
- package/src/assets/web-panel/assets/{Services-XmNshc8J.js → Services-nci51WA4.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-sGp0pOss.js → Skeleton-CN_zj5Oz.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-O-23QIht.js → Skills-BJW2xEDm.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DVxzPFWL.js → Sla-DWbkkwaH.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CdZV4JqV.js → SpeechSettings-Dw0Eobl1.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CzKwdZHi.js → SyncSettings-D2xzsxVY.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-CXj_bksx.js +1 -0
- package/src/assets/web-panel/assets/{Templates-dKai3F-y.js → Templates-CyNa5Phu.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DGtGH0wG.js → Tenant-BlmHvT2V.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-B4S1SFTD.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-Dq4yqkky.js → TimelineRenderer-CsVx24uf.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-C2qbIdlP.js → Tokens-C8i9sMwm.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-Cqee0r__.js → Trigger-BW0Wr8zU.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-D2qJ8aQY.js → Trust-yeY49AiB.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DVvv_9zC.js → UkeySign-CeX-u78O.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B-34cGbd.js → VideoEditing-DMz6N92G.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-ChvGDsZH.js → Wallet-OzYHmmSs.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-h7kqS8ou.js → WebAuthn-rmzLUB7g.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-AUqprf8Y.js → WorkflowEditor-Dvjfyhrq.js} +1 -1
- package/src/assets/web-panel/assets/{chat-i7hUCh_C.js → chat-B6FXhFv9.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DjtDsEu7.js → colors-Bn9vUneb.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CyoTiRay.js → compact-item-DtwuNWsP.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-byecyZks.js → createContext-DAJtVtdd.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CUtg0_6Z.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CJVaIlUw.js → hasIn-D5c5gdV9.js} +1 -1
- package/src/assets/web-panel/assets/{index-CDf8t-mU.js → index-5UHFrmZR.js} +1 -1
- package/src/assets/web-panel/assets/{index-1SXdlEmZ.js → index-5bFK91OU.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLIQMCBQ.js → index-5d-14CRb.js} +1 -1
- package/src/assets/web-panel/assets/{index-EZd5K5UE.js → index-Al0VKpbw.js} +1 -1
- package/src/assets/web-panel/assets/{index-kOZvf-u5.js → index-BLwrvr7X.js} +1 -1
- package/src/assets/web-panel/assets/{index-K1wX1vnH.js → index-BPkg_k6k.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cr42QNqy.js → index-BcVW04-2.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cme6n3eY.js → index-Bex3miQ0.js} +1 -1
- package/src/assets/web-panel/assets/{index-DznVBVpM.js → index-BfRKcYyV.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRWjzWaM.js → index-BfwJ25Ar.js} +1 -1
- package/src/assets/web-panel/assets/{index-XGSqce94.js → index-Bh7i75eT.js} +1 -1
- package/src/assets/web-panel/assets/{index-BscEBCR0.js → index-Bi714djd.js} +1 -1
- package/src/assets/web-panel/assets/index-Buu4km5l.js +1 -0
- package/src/assets/web-panel/assets/{index-CnjxYq-t.js → index-BwzmekUj.js} +1 -1
- package/src/assets/web-panel/assets/{index-B4gYSyri.js → index-BxvE4tvX.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dc8QTolS.js → index-Byucj_-b.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXgZwbRe.js → index-C1rXkPLH.js} +1 -1
- package/src/assets/web-panel/assets/{index-a6qb2NLc.js → index-C5Ke20j6.js} +1 -1
- package/src/assets/web-panel/assets/{index-DwV8P00A.js → index-CLLjQyNA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtdcStbl.js → index-CVAU-rz-.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3mMDCOE.js → index-CfssgRTF.js} +1 -1
- package/src/assets/web-panel/assets/{index-BxkXcXNs.js → index-Ch9xyBwj.js} +1 -1
- package/src/assets/web-panel/assets/{index-DwI-ZhZq.js → index-CizZpWXl.js} +1 -1
- package/src/assets/web-panel/assets/{index-gWPWksKr.js → index-Ck-Y-zMe.js} +1 -1
- package/src/assets/web-panel/assets/{index-COs_6PQ5.js → index-Ckk1aCu6.js} +1 -1
- package/src/assets/web-panel/assets/{index-RYkcxXFq.js → index-CwaiSvQu.js} +1 -1
- package/src/assets/web-panel/assets/{index-C8beUhKO.js → index-D2pqmzya.js} +1 -1
- package/src/assets/web-panel/assets/{index-sUJ2fbT9.js → index-D5jVrErG.js} +1 -1
- package/src/assets/web-panel/assets/index-DJQBDN4o.js +1 -0
- package/src/assets/web-panel/assets/{index-D3JKjMEY.js → index-DOYO7e-g.js} +1 -1
- package/src/assets/web-panel/assets/{index-KIqcaJ6Q.js → index-DXIYYWVV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKeNd7yb.js → index-DdW7vya3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DH7suqAN.js → index-DueHm10i.js} +3 -3
- package/src/assets/web-panel/assets/{index-jAdTCN4U.js → index-JMQznEKT.js} +1 -1
- package/src/assets/web-panel/assets/{index-Qesr-8RD.js → index-Ra_2K2v3.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2I6a-RA.js → index-bqodI7zJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BLaQNt_7.js → index-dpy2EOcg.js} +1 -1
- package/src/assets/web-panel/assets/{index-DoAiXnUJ.js → index-hTd8zvNU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BD3pqRA9.js → index-rvuBNAZ0.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-C9XZl-TO.js → initDefaultProps-7A7oMj0Q.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DTSNqE6t.js → motion-DW8osXmN.js} +1 -1
- package/src/assets/web-panel/assets/{move-DTmo8xnK.js → move-fFBKeX-1.js} +1 -1
- package/src/assets/web-panel/assets/{omit-Dd9VzuaV.js → omit-BftvxKV7.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CRTbePD_.js → pickAttrs-Bo1b8Ust.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-cPPZNiDG.js → placementArrow-DEz5HJX5.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CWSLBUlY.js → responsiveObserve-Do0AXkGf.js} +1 -1
- package/src/assets/web-panel/assets/{slide-Bu6wM4Vm.js → slide-BJx6VmlY.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BQSVPEW6.js → statusUtils-B3H6UxEU.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CIH0NQmx.js → styleChecker-CQ6edivv.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Cw2z1E4v.js → useFlexGapSupport-1L2Xx-45.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CEf8lFD8.js → useFs-COy3Bo5w.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-C-xuLSv-.js → usePersonalDataHub-D2Hg1YtD.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-D6QpJFSY.js → vnode-BFJqKuGN.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DccRPdcN.js → zoom-Na3JHINV.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/repl/agent-repl.js +4 -1
- package/src/repl/config-summary.js +48 -0
- package/src/runtime/coding-agent-shell-policy.cjs +90 -18
- package/src/runtime/headless-stream.js +26 -10
- package/src/assets/web-panel/assets/MobileProjects-cieCNE_S.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-B0Y6J6Nc.js +0 -1
- package/src/assets/web-panel/assets/Tasks-2QWjs9uX.js +0 -1
- package/src/assets/web-panel/assets/Terminal-DK2OhsAg.js +0 -3
- package/src/assets/web-panel/assets/devWarning-D3_gOwpU.js +0 -1
- package/src/assets/web-panel/assets/index-C4MOtXdA.js +0 -1
- package/src/assets/web-panel/assets/index-nH2eOdD9.js +0 -1
|
@@ -46,6 +46,11 @@ export function parseConfigCommand(argStr) {
|
|
|
46
46
|
const s = (argStr || "").trim();
|
|
47
47
|
if (s === "") return { action: "show" };
|
|
48
48
|
|
|
49
|
+
// `/config --help` | `-h` | `help` | `?` (Claude-Code 2.1.183 parity) — list
|
|
50
|
+
// the common config keys. Checked before `=` / `key value` so `help` isn't
|
|
51
|
+
// mistaken for a key read.
|
|
52
|
+
if (/^(--help|-h|help|\?)$/i.test(s)) return { action: "help" };
|
|
53
|
+
|
|
49
54
|
const eq = s.indexOf("=");
|
|
50
55
|
if (eq !== -1) {
|
|
51
56
|
const key = s.slice(0, eq).trim();
|
|
@@ -62,6 +67,49 @@ export function parseConfigCommand(argStr) {
|
|
|
62
67
|
return { action: "get", key: s };
|
|
63
68
|
}
|
|
64
69
|
|
|
70
|
+
/**
|
|
71
|
+
* The common config keys, surfaced by `/config --help`. cc's `/config` accepts
|
|
72
|
+
* any dotted key (free-form), so this is a curated quick-reference of the keys
|
|
73
|
+
* the CLI actually reads — not an exhaustive schema.
|
|
74
|
+
*/
|
|
75
|
+
export const COMMON_CONFIG_KEYS = Object.freeze([
|
|
76
|
+
[
|
|
77
|
+
"llm.provider",
|
|
78
|
+
"LLM provider (ollama | volcengine | anthropic | openai | …)",
|
|
79
|
+
],
|
|
80
|
+
["llm.model", "default text model id"],
|
|
81
|
+
["llm.visionModel", "model used for image turns (falls back to a default)"],
|
|
82
|
+
["llm.baseUrl", "provider API base URL"],
|
|
83
|
+
["llm.apiKey", "provider API key (stored masked; env *_API_KEY overrides)"],
|
|
84
|
+
[
|
|
85
|
+
"webSearch.provider",
|
|
86
|
+
"web_search backend (auto | tavily | brave | duckduckgo | …)",
|
|
87
|
+
],
|
|
88
|
+
["webSearch.apiKey", "web-search API key"],
|
|
89
|
+
["cli.theme", "REPL color theme (auto | dark | light | mono)"],
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
/** Render `/config --help`: usage + the common config keys. */
|
|
93
|
+
export function renderConfigHelp() {
|
|
94
|
+
const lines = [
|
|
95
|
+
"/config — show or edit configuration:",
|
|
96
|
+
" /config show effective config (secret-safe)",
|
|
97
|
+
" /config <key> read a value (e.g. /config llm.model)",
|
|
98
|
+
" /config <key>=<value> set a value (e.g. /config llm.model=opus)",
|
|
99
|
+
" /config <key> <value> set a value (space form)",
|
|
100
|
+
" /config --help this list",
|
|
101
|
+
"",
|
|
102
|
+
"Common keys:",
|
|
103
|
+
];
|
|
104
|
+
const width = Math.max(...COMMON_CONFIG_KEYS.map(([k]) => k.length));
|
|
105
|
+
for (const [key, desc] of COMMON_CONFIG_KEYS) {
|
|
106
|
+
lines.push(` ${key.padEnd(width)} ${desc}`);
|
|
107
|
+
}
|
|
108
|
+
lines.push("");
|
|
109
|
+
lines.push(" (any dotted key is accepted; keys are stored in config.json)");
|
|
110
|
+
return lines.join("\n");
|
|
111
|
+
}
|
|
112
|
+
|
|
65
113
|
/** Render a single config value for `/config <key>`, masking secrets. */
|
|
66
114
|
export function renderConfigGet(key, value) {
|
|
67
115
|
if (value === undefined) return `${key} = (unset)`;
|
|
@@ -114,6 +114,52 @@ function splitFirstCommandSegment(command) {
|
|
|
114
114
|
.trim();
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Strip the parts of a command segment that hide the real executable from
|
|
119
|
+
* first-token classification: a leading subshell `(`/`{`, and leading env-var
|
|
120
|
+
* assignments (`FOO=bar BAZ=qux cmd …` → `cmd …`). Without this, `x=1 rm -rf …`
|
|
121
|
+
* would be classified by firstToken `x=1` (unclassified → WARN) instead of `rm`.
|
|
122
|
+
*/
|
|
123
|
+
function stripSegmentPrefix(segment) {
|
|
124
|
+
let t = String(segment || "").trim();
|
|
125
|
+
t = t.replace(/^[({]\s*/, ""); // leading subshell / group
|
|
126
|
+
// leading VAR=value assignments (quoted or bare), one or more
|
|
127
|
+
t = t.replace(/^(?:[A-Za-z_]\w*=(?:"[^"]*"|'[^']*'|\S*)\s+)+/, "");
|
|
128
|
+
return t.trim();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Split a (possibly compound) command into the individual command segments the
|
|
133
|
+
* policy must EACH inspect — not just the first — so a destructive command
|
|
134
|
+
* (`rm -rf …`, `git reset --hard`) cannot be smuggled past a benign or
|
|
135
|
+
* allowlisted leading segment.
|
|
136
|
+
*
|
|
137
|
+
* Covers every way a second command can ride along: the shell separators
|
|
138
|
+
* `&& || | ; &` AND newlines, plus commands hidden inside command-substitution
|
|
139
|
+
* `$(…)` / backticks (extracted as their own segments). Leading subshell parens
|
|
140
|
+
* and env-var assignment prefixes are stripped per segment so the real
|
|
141
|
+
* executable is what gets classified.
|
|
142
|
+
*/
|
|
143
|
+
function splitCommandSegments(command) {
|
|
144
|
+
let s = String(command || "");
|
|
145
|
+
const extracted = [];
|
|
146
|
+
// Pull out command-substitution / backtick bodies as additional segments
|
|
147
|
+
// (single level — nested substitutions are an accepted edge case).
|
|
148
|
+
s = s.replace(/\$\(([^()]*)\)/g, (_m, inner) => {
|
|
149
|
+
extracted.push(inner);
|
|
150
|
+
return " ";
|
|
151
|
+
});
|
|
152
|
+
s = s.replace(/`([^`]*)`/g, (_m, inner) => {
|
|
153
|
+
extracted.push(inner);
|
|
154
|
+
return " ";
|
|
155
|
+
});
|
|
156
|
+
// Separators: && || | ; & and any newline.
|
|
157
|
+
const parts = s.split(/(?:\|\||&&|[|;&]|[\r\n]+)/).concat(extracted);
|
|
158
|
+
return parts
|
|
159
|
+
.map((segment) => stripSegmentPrefix(segment))
|
|
160
|
+
.filter(Boolean);
|
|
161
|
+
}
|
|
162
|
+
|
|
117
163
|
function tokenizeShellCommand(command) {
|
|
118
164
|
const tokens = [];
|
|
119
165
|
let current = "";
|
|
@@ -165,34 +211,28 @@ function normalizeShellCommand(command) {
|
|
|
165
211
|
return splitFirstCommandSegment(command).replace(/\s+/g, " ").trim();
|
|
166
212
|
}
|
|
167
213
|
|
|
168
|
-
|
|
169
|
-
|
|
214
|
+
// Severity ordering so the most restrictive segment of a compound command wins.
|
|
215
|
+
const DECISION_SEVERITY = Object.freeze({
|
|
216
|
+
[SHELL_POLICY_DECISIONS.DENY]: 3,
|
|
217
|
+
[SHELL_POLICY_DECISIONS.REROUTE]: 2,
|
|
218
|
+
[SHELL_POLICY_DECISIONS.WARN]: 1,
|
|
219
|
+
[SHELL_POLICY_DECISIONS.ALLOW]: 0,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
/** Classify ONE command segment (no separators). */
|
|
223
|
+
function evaluateSegmentPolicy(segment, overrideRuleIds) {
|
|
224
|
+
const normalized = normalizeShellCommand(segment);
|
|
170
225
|
const tokens = tokenizeShellCommand(normalized);
|
|
171
226
|
const firstToken = (tokens[0] || "").toLowerCase();
|
|
172
227
|
const secondToken = (tokens[1] || "").toLowerCase();
|
|
173
228
|
const context = {
|
|
174
|
-
command: String(
|
|
229
|
+
command: String(segment || ""),
|
|
175
230
|
normalized,
|
|
176
231
|
tokens,
|
|
177
232
|
firstToken,
|
|
178
233
|
secondToken,
|
|
179
234
|
};
|
|
180
235
|
|
|
181
|
-
// Rule IDs that should be downgraded from DENY to WARN (e.g. cowork web-research)
|
|
182
|
-
const overrideRuleIds = Array.isArray(options.overrideRuleIds)
|
|
183
|
-
? new Set(options.overrideRuleIds)
|
|
184
|
-
: new Set();
|
|
185
|
-
|
|
186
|
-
if (!normalized) {
|
|
187
|
-
return {
|
|
188
|
-
allowed: false,
|
|
189
|
-
decision: SHELL_POLICY_DECISIONS.DENY,
|
|
190
|
-
reason: "Shell command is required.",
|
|
191
|
-
ruleId: "empty-command",
|
|
192
|
-
normalizedCommand: normalized,
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
|
|
196
236
|
const blockedRule = BLOCKED_SHELL_RULES.find((rule) => rule.test(context));
|
|
197
237
|
if (blockedRule) {
|
|
198
238
|
// If the rule is overridden, downgrade from DENY to WARN (allowed)
|
|
@@ -237,6 +277,37 @@ function evaluateShellCommandPolicy(command, options = {}) {
|
|
|
237
277
|
};
|
|
238
278
|
}
|
|
239
279
|
|
|
280
|
+
function evaluateShellCommandPolicy(command, options = {}) {
|
|
281
|
+
// Rule IDs that should be downgraded from DENY to WARN (e.g. cowork web-research)
|
|
282
|
+
const overrideRuleIds = Array.isArray(options.overrideRuleIds)
|
|
283
|
+
? new Set(options.overrideRuleIds)
|
|
284
|
+
: new Set();
|
|
285
|
+
|
|
286
|
+
// Inspect EVERY segment of a compound command, not just the first — a
|
|
287
|
+
// dangerous segment after `&&` / `;` / `|` must still be caught. The most
|
|
288
|
+
// restrictive segment decides the whole command (a compound is only ALLOW
|
|
289
|
+
// when every segment is independently allowlisted).
|
|
290
|
+
const segments = splitCommandSegments(command);
|
|
291
|
+
if (!segments.length) {
|
|
292
|
+
return {
|
|
293
|
+
allowed: false,
|
|
294
|
+
decision: SHELL_POLICY_DECISIONS.DENY,
|
|
295
|
+
reason: "Shell command is required.",
|
|
296
|
+
ruleId: "empty-command",
|
|
297
|
+
normalizedCommand: "",
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
let worst = null;
|
|
302
|
+
for (const segment of segments) {
|
|
303
|
+
const result = evaluateSegmentPolicy(segment, overrideRuleIds);
|
|
304
|
+
const sev = DECISION_SEVERITY[result.decision] ?? 1;
|
|
305
|
+
const worstSev = worst ? (DECISION_SEVERITY[worst.decision] ?? 1) : -1;
|
|
306
|
+
if (sev > worstSev) worst = result;
|
|
307
|
+
}
|
|
308
|
+
return worst;
|
|
309
|
+
}
|
|
310
|
+
|
|
240
311
|
module.exports = {
|
|
241
312
|
ALLOWLISTED_SHELL_RULES,
|
|
242
313
|
BLOCKED_SHELL_RULES,
|
|
@@ -244,5 +315,6 @@ module.exports = {
|
|
|
244
315
|
evaluateShellCommandPolicy,
|
|
245
316
|
normalizeShellCommand,
|
|
246
317
|
splitFirstCommandSegment,
|
|
318
|
+
splitCommandSegments,
|
|
247
319
|
tokenizeShellCommand,
|
|
248
320
|
};
|
|
@@ -649,6 +649,12 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
649
649
|
|
|
650
650
|
let turns = 0;
|
|
651
651
|
let sawError = false;
|
|
652
|
+
// Once any turn attaches an image, the image stays in the conversation
|
|
653
|
+
// history — so every later turn (even a text-only follow-up like "what colour
|
|
654
|
+
// is it?") must keep using the vision LLM, otherwise a text-only default model
|
|
655
|
+
// is handed image content it can't read. Claude Code never hits this (one
|
|
656
|
+
// multimodal model); cc splits text/vision models, so we sticky the routing.
|
|
657
|
+
let conversationHasImages = false;
|
|
652
658
|
|
|
653
659
|
// ── Concurrent stdin pump (turn-interrupt support) ────────────────────────
|
|
654
660
|
// Input is consumed AS IT ARRIVES — not between turns — so an
|
|
@@ -879,23 +885,15 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
879
885
|
// On an image turn, also switch THIS turn to the vision LLM (model only —
|
|
880
886
|
// same account/key) so it's read by a vision-capable model.
|
|
881
887
|
let turnContent = userContent;
|
|
882
|
-
let turnVisionLlm = null;
|
|
883
888
|
if (parsed.images && parsed.images.length) {
|
|
884
889
|
try {
|
|
885
|
-
const { resolveImages, buildUserContent
|
|
890
|
+
const { resolveImages, buildUserContent } =
|
|
886
891
|
await import("../lib/image-input.js");
|
|
887
892
|
turnContent = buildUserContent(
|
|
888
893
|
userContent,
|
|
889
894
|
resolveImages(parsed.images),
|
|
890
895
|
);
|
|
891
|
-
|
|
892
|
-
hasImage: true,
|
|
893
|
-
flags: {},
|
|
894
|
-
llm: { provider, baseUrl, apiKey, visionModel },
|
|
895
|
-
});
|
|
896
|
-
writeErr(
|
|
897
|
-
` [image] ${parsed.images.length} attached → vision model ${turnVisionLlm.model}\n`,
|
|
898
|
-
);
|
|
896
|
+
conversationHasImages = true;
|
|
899
897
|
} catch (err) {
|
|
900
898
|
emit({
|
|
901
899
|
type: "result",
|
|
@@ -907,6 +905,24 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
907
905
|
continue; // bad attachment kills the turn, not the session
|
|
908
906
|
}
|
|
909
907
|
}
|
|
908
|
+
// Route to the vision LLM (model only — same provider/account/key/baseUrl)
|
|
909
|
+
// on any turn that carries an image AND on every later turn once the
|
|
910
|
+
// conversation holds an image, so a text-only follow-up about the image
|
|
911
|
+
// isn't sent to a text-only default model that can't read the history.
|
|
912
|
+
let turnVisionLlm = null;
|
|
913
|
+
if (conversationHasImages) {
|
|
914
|
+
const { resolveVisionLlm } = await import("../lib/image-input.js");
|
|
915
|
+
turnVisionLlm = resolveVisionLlm({
|
|
916
|
+
hasImage: true,
|
|
917
|
+
flags: {},
|
|
918
|
+
llm: { provider, baseUrl, apiKey, visionModel },
|
|
919
|
+
});
|
|
920
|
+
if (parsed.images && parsed.images.length) {
|
|
921
|
+
writeErr(
|
|
922
|
+
` [image] ${parsed.images.length} attached → vision model ${turnVisionLlm.model}\n`,
|
|
923
|
+
);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
910
926
|
|
|
911
927
|
messages.push({ role: "user", content: turnContent });
|
|
912
928
|
if (persist) {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as n,J as g,c as l,K as r,N as u,P as h,U as o,R as t,Q as b}from"./vendor-BvqAck49.js";import{_ as v,b as m}from"./index-DH7suqAN.js";import{a7 as y,M}from"./icons-DP3uiYxy.js";const B={__name:"MobileProjects",setup(p,{expose:i}){i();const c=u(),{t:e}=m();function a(){c.push("/projects")}function _(){c.push("/mobile-bridge")}const s={router:c,t:e,goToProjects:a,goToMobileBridge:_,get useRouter(){return u},get useI18n(){return m},get MobileOutlined(){return M},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},x={class:"mobile-projects-placeholder"},O={class:"title"},k={class:"subtitle"},w={class:"explainer"};function T(p,i,c,e,a,_){const s=n("a-alert"),d=n("a-button"),f=n("a-space"),j=n("a-empty"),P=n("a-card");return h(),g("div",x,[l(P,null,{default:r(()=>[l(j,{description:!1},{image:r(()=>[l(e.MobileOutlined,{style:{fontSize:"64px",color:"#bfbfbf"}})]),default:r(()=>[o("h2",O,t(e.t("mobileProjects.title")),1),o("p",k,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",w,[o("h3",null,t(e.t("mobileProjects.currentDirection")),1),o("p",null,t(e.t("mobileProjects.currentDirectionBody")),1),o("ul",null,[o("li",null,t(e.t("mobileProjects.stepPhone")),1),o("li",null,t(e.t("mobileProjects.stepTap")),1),o("li",null,t(e.t("mobileProjects.stepPull")),1)]),o("h3",null,t(e.t("mobileProjects.reverseDirection")),1),o("p",null,t(e.t("mobileProjects.reverseDirectionBody")),1)]),l(f,{class:"actions"},{default:r(()=>[l(d,{type:"primary",onClick:e.goToProjects},{default:r(()=>[l(e.FolderOutlined),b(" "+t(e.t("mobileProjects.viewLocalProjects")),1)]),_:1}),l(d,{onClick:e.goToMobileBridge},{default:r(()=>[l(e.MobileOutlined),b(" "+t(e.t("mobileProjects.checkBridge")),1)]),_:1})]),_:1})]),_:1})]),_:1})])}const N=v(B,[["render",T],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-GijCQY/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{N as default};
|
|
@@ -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 a}from"./vendor-BvqAck49.js";import{_ as S}from"./index-DH7suqAN.js";import"./icons-DP3uiYxy.js";const k={__name:"OrderTableRenderer",props:{event:{type:Object,required:!0}},setup(p,{expose:r}){r();const o=p,e=a(()=>o.event.content||{}),d=a(()=>o.event.extra||{}),m=a(()=>d.value.merchant||e.value.merchant||e.value.counterparty||"—"),c=a(()=>e.value.title||e.value.name||e.value.itemName||e.value.text||"—"),y=a(()=>{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=a(()=>d.value.orderNo||e.value.orderNo||e.value.orderId),f=a(()=>e.value.status||e.value.state),b=a(()=>{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=a(()=>{if(!o.event.occurredAt)return"";const t=new Date(o.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:o,c:e,e:d,merchantText:m,itemText:c,amountText:y,orderNo:T,statusText:f,statusColor:b,formattedTime:h,computed:a};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"},j={class:"row"},B={class:"val"},D={class:"row amount-row"},I={class:"val amount"},A={key:0,class:"row"},F={class:"val mono"},M={key:1,class:"row"};function P(p,r,o,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(o.event.source.adapter),1)]),_:1}),i(c,null,{default:v(()=>[_(n(o.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",j,[r[1]||(r[1]=s("span",{class:"key"},"商品/项目",-1)),s("span",B,n(e.itemText),1)]),s("div",D,[r[2]||(r[2]=s("span",{class:"key"},"金额",-1)),s("span",I,n(e.amountText),1)]),e.orderNo?(l(),u("div",A,[r[3]||(r[3]=s("span",{class:"key"},"单号",-1)),s("span",F,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 G=S(k,[["render",P],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-GijCQY/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{G as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{E as B,b as z,r as D,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-DH7suqAN.js";import{R as E}from"./icons-DP3uiYxy.js";const V=B("tasks",()=>{const k=D([]),l=D(!1);let u=null,e=null;const x=z(()=>k.value.filter(t=>t.status==="running")),b=z(()=>k.value.filter(t=>t.status==="pending")),y=z(()=>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=D(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}},j={class:"page-header"},L={key:0,class:"error-text"},Q={key:1},G={class:"task-header"},J={class:"task-desc"},K={class:"task-id"},M={class:"task-meta"},W=["title"],Y={key:0,class:"error-text"},Z={key:1,class:"success-text"},q={key:2,class:"muted-text"};function H(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",j,[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",L,r(e.store.lastNotification.error),1)):e.store.lastNotification.result?(i(),c("span",Q,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",Y,r(e.truncate(s.error,60)),1)):s.result?(i(),c("span",Z,r(e.truncate(String(s.result),60)),1)):(i(),c("span",q,"-"))],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",H],["__scopeId","data-v-da5ff6a2"],["__file","/tmp/cc-web-panel-GijCQY/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-DH7suqAN.js";import{I as z,J as x,U as _,Q as D,S as G,K as T,V as R,c as A,F as J,Z as K,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(L=>({seq:L.seq,data:ae(L.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 L(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}),P=new p.FitAddon;m.loadAddon(P),m.open(b);try{P.fit()}catch{}t.xterm=m,t.fitAddon=P;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 Y of v)m.write(Y.data),t.lastSeq=Y.seq}catch(v){m.writeln(`\x1B[31m[history fetch failed: ${v?.message||v}]\x1B[0m`)}const X=new ResizeObserver(()=>{try{P.fit(),s.resize(t.id,m.cols,m.rows).catch(()=>{})}catch{}});X.observe(b);const ue=t.offs;t.offs=()=>{try{X.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 j(){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 j()}),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 Q={term:s,sessions:e,activeId:i,newShell:w,creating:u,loadingList:d,error:f,warning:n,xtermContainers:a,shellOptions:r,active:h,shortId:L,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:j,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(Q,"__isScriptSetup",{enumerable:!1,value:!0}),Q}},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"},Le=["data-session-id"],Pe={key:0,class:"xterm-placeholder"},De={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]=D(" 桌面端托管的 PTY 会话;Android 端可远程操控同一通道 ",-1)),e.warning?(y(),G(u,{key:0,color:"orange",style:{"margin-left":"8px"}},{default:T(()=>[D(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]=D(" 新会话 ",-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]=D(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.error?(y(),G(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(J,null,K(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(J,null,K(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,Le)),[[_e,r.id===e.activeId]])),128)),e.sessions.length===0?(y(),x("div",Pe,[...o[6]||(o[6]=[_("span",null,"无活跃会话",-1)])])):R("v-if",!0)])]),e.active?(y(),x("div",De,[_("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-GijCQY/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{O as r}from"./index-DH7suqAN.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-p8jds0fN.js";import{U as t}from"./index-DH7suqAN.js";import"./vendor-BvqAck49.js";import"./index-BLaQNt_7.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-Bxxu4Xtz.js";import{U as t}from"./index-DH7suqAN.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-CWSLBUlY.js";import"./useFlexGapSupport-Cw2z1E4v.js";import"./styleChecker-CIH0NQmx.js";import"./index-BLaQNt_7.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};
|