chainlesschain 0.162.103 → 0.162.105
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-BpJ5yCcV.js → AIOps-DYaOYjxA.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-B1uBfxnA.js → ActionButton-BRnLVtON.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-0ubw5quf.js → Analytics-Bi5dt6xG.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-go-GyyM_.js → AppLayout-FdAkPhdh.js} +5 -5
- package/src/assets/web-panel/assets/{Audit-CdUfoUnM.js → Audit-huJ-2mSb.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CBn0xtsa.js → Backup-CTAFMoyw.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-a9fqTkvL.js → BaseInput-DNh66xG2.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-D-d_IatD.js → Chat-xLRQDs5G.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-Co9h0SbA.js → ChatBubbleRenderer-BFRpdxeW.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CiKEjtXm.js → Checkbox-BEZRITX8.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-OQxW_9Z2.js → Codegen-BD6xBApN.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BZHXUEnZ.js → Col-B_Xqx3Ul.js} +1 -1
- package/src/assets/web-panel/assets/{Community-D3xno9fj.js → Community-Bu4rj14W.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-D62jpZk_.js → Compact-B17uNB4p.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-D4jFTAcQ.js → Compliance-DjaCMltJ.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BOU_wir4.js → Cowork-BdE44Hek.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-Cr9BlJA7.js → Cron-DZyVpxse.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-L9M--CXb.js → Crosschain-BeSoFHpQ.js} +1 -1
- package/src/assets/web-panel/assets/{DID-xFu3-VWT.js → DID-D8GTLlQ5.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard--ax48T3j.js → Dashboard-vAKXjb1o.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-CTOS8daR.js → Dropdown-BvgPRTyP.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CNLSX81U.js → EmailListRenderer-CtXq_Ttt.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-5EjFynBc.js → FamilyGuardDashboard-oG2LekBb.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CoPyIWIu.js → Federation-C-oMwAUG.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BbzCNbYy.js → FormItemContext-rj-oMGta.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-8_9_uXY0.js → GenericCardRenderer-UeOKM5KJ.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Bz_qlVPg.js → Git-BOjLMgD-.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-7eepNCeD.js → Governance-DVlgF083.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DlBx5l1g.js → Inference-BzpCtSRm.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BPkc--rM.js → KnowledgeGraph-5sFDbZKo.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BQw4nPvS.js → Logs-BagEqu7D.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-Cil3SdgN.js → Marketplace-za352FZT.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-Bnch7KrG.js → McpTools-CEavmaZU.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-assQ3Suc.js → Memory-Dp0d39Y-.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-D5mE8c-z.js → MobileBridge-BljVPikC.js} +2 -2
- package/src/assets/web-panel/assets/{MobileProjects-C4MiDXw1.js → MobileProjects-dR-6L-xU.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CumojeLk.js → Mtc-CO80_dbI.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-3tTBc_fw.js → MtcAudit-ByH4suVc.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-Dl4IJBsl.js → Multisig-CvQ373Kp.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DHN_cV9x.js → NLProgramming-DSugxBwU.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DeyTvwYk.js → Notes-BN_R_-qG.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-BUkj8mTj.js → NotificationSettings-x3Ipb8KF.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-BMpEXTki.js → OrderTableRenderer-CJCW-n1E.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-B6Ogmkpz.js → Organization-CUo9tpab.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-DRUE-2Wz.js → Overflow-Cm1ok3yr.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CnMUkd64.js → P2P-BPXfkljx.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-B3nFxT3b.js → PdhVaultBrowser-bB_pMcWV.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-CyG1FR7v.js → Permissions-bUj1KcNM.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BmN6YMb5.js → PersonalDataHub-DODkpqmo.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-BZcamAnH.js → Pipeline-DEqfqfHT.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-D7_zsaY3.js → Privacy-C5b_6Np-.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-DNa7XQjg.js → ProjectInit-DSnPoDLm.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-KH2Dm09G.js → ProjectSettings-DjDz4FBi.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-T-WqR3D6.js → Projects-9chbQyJR.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-8GtQ6GgR.js → Providers-CrtYhXe4.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BuBM5Zpg.js → QuickAsk-BwBKTclE.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DvH95W1b.js → Recommend-mQMxq3Xc.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-BHCpMEP6.js → Reputation-CL6wmEN-.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BnMPysBm.js → Row-CVXQQg_a.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-C-T8B5VU.js → RssFeed-CfoKWtqq.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CioiZGkX.js → Search-BXBraFwH.js} +1 -1
- package/src/assets/web-panel/assets/{Security-zSApKqdd.js → Security-DuVGdvLC.js} +4 -4
- package/src/assets/web-panel/assets/{Services-CQh0UDXC.js → Services-vfsS-hHM.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-C0dRaEVG.js → Skeleton-UODCxnzg.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BgQRArsa.js → Skills-DVHtahH_.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-BNn7F3jc.js → Sla-DSoODBCc.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-kvVfKfqv.js → SpeechSettings-DiaqTk_e.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BwIkkX1E.js → SyncSettings-BQcVBcLi.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-w5vOQG7_.js +1 -0
- package/src/assets/web-panel/assets/{Templates-COK0o2pL.js → Templates-BpnfhFKX.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DpK87fqo.js → Tenant-l6EIK9VO.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-2wTdm-Qz.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-B4SJqyqf.js → TimelineRenderer-6dWgzU5T.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-C3iSR8fH.js → Tokens-CmTEa0qE.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-D1Oo58Yo.js → Trigger-DrfC7Hb-.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CUhy4DDc.js → Trust-9SSsKJ67.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-r-kTqSw8.js → UkeySign-_4fg9FZz.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B8MyBfCX.js → VideoEditing-XBXv_ieG.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CquTfSv0.js → Wallet-0eP1nq2A.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-BC7TP1H3.js → WebAuthn-BWs4GCCZ.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-CELBSNbP.js → WorkflowEditor-BFSo4kVo.js} +1 -1
- package/src/assets/web-panel/assets/{chat-d66mbO2i.js → chat-DJSs4Z3h.js} +1 -1
- package/src/assets/web-panel/assets/{colors-D0WRCg20.js → colors-DyNgmHM2.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-4__-8TIi.js → compact-item-M3CZ-i2H.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-Dqsf52js.js → createContext-lNMonv_i.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-D7oeO7SY.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-ClTZOS8I.js → hasIn-B91aXEzF.js} +1 -1
- package/src/assets/web-panel/assets/{index-81SaeU6t.js → index-BDOOE70-.js} +1 -1
- package/src/assets/web-panel/assets/index-BIPYc_9M.js +1 -0
- package/src/assets/web-panel/assets/{index-C5l6tSky.js → index-BMG7MAgn.js} +1 -1
- package/src/assets/web-panel/assets/index-BRXyk-mT.js +1 -0
- package/src/assets/web-panel/assets/{index-B1TGSkBt.js → index-BTzUzcRX.js} +1 -1
- package/src/assets/web-panel/assets/{index-PMJ4tBAA.js → index-BVeeHE1i.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGf3oqM0.js → index-Be_FDJks.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbY1lv1z.js → index-BfRRIydd.js} +1 -1
- package/src/assets/web-panel/assets/{index-leuwRsbf.js → index-Bsl-sRNN.js} +1 -1
- package/src/assets/web-panel/assets/{index-CFwkeSun.js → index-BxhgIY1j.js} +1 -1
- package/src/assets/web-panel/assets/{index-D-ya3Ohe.js → index-BzaXBB1A.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCOpbfAH.js → index-C2oG0D9w.js} +1 -1
- package/src/assets/web-panel/assets/{index-e5zJLrJQ.js → index-C4tKStAX.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZZpfHd4J.js → index-C51tOSTU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNKECBZm.js → index-CJsTosBw.js} +1 -1
- package/src/assets/web-panel/assets/{index-fi2ikHoc.js → index-CKiGfsRP.js} +1 -1
- package/src/assets/web-panel/assets/{index-B3vrmn5v.js → index-CVCoAsQq.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4_XhCJS.js → index-CXoioS1t.js} +1 -1
- package/src/assets/web-panel/assets/{index-luisYDBz.js → index-CkpZNnfb.js} +1 -1
- package/src/assets/web-panel/assets/{index-Yi5Lr63I.js → index-CmtXAPQT.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cg8Qw3Jw.js → index-Cvj5N5SK.js} +1 -1
- package/src/assets/web-panel/assets/{index-jAPphbJL.js → index-DAd-oQMK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DORg0Hps.js → index-DMUkAgqR.js} +1 -1
- package/src/assets/web-panel/assets/{index-PAiWA2un.js → index-DQIBwi9k.js} +1 -1
- package/src/assets/web-panel/assets/{index-P4X9zSF2.js → index-DRJ_Lszr.js} +1 -1
- package/src/assets/web-panel/assets/{index-DQaGurrQ.js → index-DV9i6LzE.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dm7CYK3j.js → index-DWuMyZbA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CxoWS8hl.js → index-De6_AYb4.js} +1 -1
- package/src/assets/web-panel/assets/{index-D68tyHYa.js → index-Do3iJlSY.js} +1 -1
- package/src/assets/web-panel/assets/{index-BwozLU75.js → index-DyOBjEUA.js} +1 -1
- package/src/assets/web-panel/assets/{index-we9-1IbF.js → index-Dz-UTFho.js} +1 -1
- package/src/assets/web-panel/assets/{index-b7a5aEX9.js → index-HIF1H3Qi.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9x6i7iV.js → index-HcSrdXIY.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cops66s2.js → index-IHn9LQeI.js} +3 -3
- package/src/assets/web-panel/assets/{index-0Axwx1nN.js → index-KSwJzeqG.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpLhC0nx.js → index-_kFxj8Iv.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJKyF-y8.js → index-dW5CK84B.js} +1 -1
- package/src/assets/web-panel/assets/{index-DDLjwgva.js → index-eLphHYgM.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ct5SJenr.js → index-vb_z80lH.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-zqDf7qWv.js → initDefaultProps-BKCFkUwh.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DRqTooll.js → motion-CuYmQtOE.js} +1 -1
- package/src/assets/web-panel/assets/{move-N8tkRqS4.js → move-DlPzxPAW.js} +1 -1
- package/src/assets/web-panel/assets/{omit-Cy01f2vw.js → omit-Ds3kQlyN.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-C2ycNXNi.js → pickAttrs-RUYRa-vv.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-D60Xb1j9.js → placementArrow-jYZCPIVc.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BF8Y-1HQ.js → responsiveObserve-BsNIdQzh.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DDi6zYZf.js → slide-IDA11Awb.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CWPq6UzA.js → statusUtils-D-dVqEII.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-D4zVyb4w.js → styleChecker-qHsriHs9.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BEMNO3oR.js → useFlexGapSupport-Bf1CATNE.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DBLO8VR7.js → useFs-BaqG_--5.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-C83ZIrPY.js → usePersonalDataHub-DsEBdplG.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Dcfyve-7.js → vnode-AvKcICeL.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Dg6uoWSc.js → zoom-ClicurwO.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/llm.js +89 -28
- package/src/lib/__tests__/pdh-wiring-load-error.test.js +59 -0
- package/src/lib/personal-data-hub-wiring.js +53 -6
- package/src/assets/web-panel/assets/Tasks-BkcvhBZw.js +0 -1
- package/src/assets/web-panel/assets/Terminal-2g2-XPT_.js +0 -3
- package/src/assets/web-panel/assets/devWarning-DUAmX0aE.js +0 -1
- package/src/assets/web-panel/assets/index-BLCwqv8j.js +0 -1
- package/src/assets/web-panel/assets/index-Db5JRQ6E.js +0 -1
package/src/commands/llm.js
CHANGED
|
@@ -7,6 +7,7 @@ import ora from "ora";
|
|
|
7
7
|
import chalk from "chalk";
|
|
8
8
|
import { logger } from "../lib/logger.js";
|
|
9
9
|
import { bootstrap, shutdown } from "../runtime/bootstrap.js";
|
|
10
|
+
import { loadConfig } from "../lib/config-manager.js";
|
|
10
11
|
import {
|
|
11
12
|
BUILT_IN_PROVIDERS,
|
|
12
13
|
LLMProviderRegistry,
|
|
@@ -43,6 +44,58 @@ import {
|
|
|
43
44
|
getLlmProvidersStatsV2,
|
|
44
45
|
} from "../lib/llm-providers.js";
|
|
45
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Resolve the effective `cc llm test` target from CLI flags + persisted config.
|
|
49
|
+
* Pure (no I/O) so the precedence is unit-testable: explicit flag >
|
|
50
|
+
* config.llm.* > provider default. The connectivity probe used to ignore
|
|
51
|
+
* config entirely and hard-default to ollama, so a user on volcengine/openai
|
|
52
|
+
* (and the JetBrains "Configure LLM" wizard) got a spurious fetch-failed
|
|
53
|
+
* against a local ollama they never ran.
|
|
54
|
+
*
|
|
55
|
+
* @param {object} options commander options (provider/model/baseUrl/apiKey)
|
|
56
|
+
* @param {object} config loadConfig() result ({ llm?: {...} })
|
|
57
|
+
* @param {object} builtIns BUILT_IN_PROVIDERS map
|
|
58
|
+
* @param {object} [env] process.env (for apiKeyEnv lookup)
|
|
59
|
+
* @returns {{provider,model,baseUrl,apiKey,isOllama,label}}
|
|
60
|
+
*/
|
|
61
|
+
export function resolveLlmTestTarget(options = {}, config = {}, builtIns = {}, env = {}) {
|
|
62
|
+
const llm = config.llm || {};
|
|
63
|
+
const provider = options.provider || llm.provider || "ollama";
|
|
64
|
+
const isOllama = provider === "ollama";
|
|
65
|
+
const builtIn = builtIns[provider];
|
|
66
|
+
|
|
67
|
+
const model =
|
|
68
|
+
options.model ||
|
|
69
|
+
llm.model ||
|
|
70
|
+
(isOllama ? "qwen2:7b" : builtIn?.models?.[0] || "gpt-4o-mini");
|
|
71
|
+
|
|
72
|
+
let baseUrl;
|
|
73
|
+
if (isOllama) {
|
|
74
|
+
// Only inherit config.baseUrl when the CONFIGURED provider is also ollama —
|
|
75
|
+
// otherwise `--provider ollama` would probe another provider's endpoint.
|
|
76
|
+
const configOllamaBase = llm.provider === "ollama" ? llm.baseUrl : undefined;
|
|
77
|
+
baseUrl = options.baseUrl || configOllamaBase || "http://localhost:11434";
|
|
78
|
+
} else {
|
|
79
|
+
baseUrl =
|
|
80
|
+
options.baseUrl || llm.baseUrl || builtIn?.baseUrl || "https://api.openai.com/v1";
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const apiKey = isOllama
|
|
84
|
+
? undefined
|
|
85
|
+
: options.apiKey ||
|
|
86
|
+
llm.apiKey ||
|
|
87
|
+
(builtIn?.apiKeyEnv ? env[builtIn.apiKeyEnv] : undefined);
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
provider,
|
|
91
|
+
model,
|
|
92
|
+
baseUrl,
|
|
93
|
+
apiKey,
|
|
94
|
+
isOllama,
|
|
95
|
+
label: builtIn?.displayName || (isOllama ? "Ollama" : provider),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
46
99
|
export function registerLlmCommand(program) {
|
|
47
100
|
const llm = program.command("llm").description("LLM provider management");
|
|
48
101
|
|
|
@@ -103,24 +156,39 @@ export function registerLlmCommand(program) {
|
|
|
103
156
|
});
|
|
104
157
|
|
|
105
158
|
// llm test - test connectivity
|
|
159
|
+
//
|
|
160
|
+
// Defaults to the CONFIGURED provider/model/baseUrl/apiKey (config.llm.*),
|
|
161
|
+
// NOT a hard-coded ollama. Previously this always probed ollama unless you
|
|
162
|
+
// passed --provider, so a user on volcengine/openai/etc. (and the JetBrains
|
|
163
|
+
// "Configure LLM" wizard, which calls `cc llm test`) got a spurious
|
|
164
|
+
// "fetch failed" against a local ollama they never ran. Any non-ollama
|
|
165
|
+
// built-in provider is OpenAI-compatible, so they share one /chat/completions
|
|
166
|
+
// probe instead of only special-casing openai.
|
|
106
167
|
llm
|
|
107
168
|
.command("test")
|
|
108
|
-
.description("Test LLM provider connectivity")
|
|
109
|
-
.option("--provider <provider>", "LLM provider
|
|
110
|
-
.option("--model <model>", "Model to test
|
|
111
|
-
.option("--base-url <url>", "API base URL
|
|
112
|
-
.option("--api-key <key>", "API key")
|
|
169
|
+
.description("Test LLM provider connectivity (defaults to configured provider)")
|
|
170
|
+
.option("--provider <provider>", "LLM provider (default: configured)")
|
|
171
|
+
.option("--model <model>", "Model to test (default: configured)")
|
|
172
|
+
.option("--base-url <url>", "API base URL (default: configured/provider)")
|
|
173
|
+
.option("--api-key <key>", "API key (default: configured)")
|
|
113
174
|
.action(async (options) => {
|
|
114
|
-
const
|
|
175
|
+
const config = loadConfig();
|
|
176
|
+
const target = resolveLlmTestTarget(
|
|
177
|
+
options,
|
|
178
|
+
config,
|
|
179
|
+
BUILT_IN_PROVIDERS,
|
|
180
|
+
process.env,
|
|
181
|
+
);
|
|
182
|
+
const spinner = ora(`Testing ${target.provider}...`).start();
|
|
115
183
|
try {
|
|
116
184
|
const start = Date.now();
|
|
117
185
|
|
|
118
|
-
if (
|
|
119
|
-
const response = await fetch(`${
|
|
186
|
+
if (target.isOllama) {
|
|
187
|
+
const response = await fetch(`${target.baseUrl}/api/generate`, {
|
|
120
188
|
method: "POST",
|
|
121
189
|
headers: { "Content-Type": "application/json" },
|
|
122
190
|
body: JSON.stringify({
|
|
123
|
-
model:
|
|
191
|
+
model: target.model,
|
|
124
192
|
prompt: "Say hi in one word.",
|
|
125
193
|
stream: false,
|
|
126
194
|
}),
|
|
@@ -134,28 +202,24 @@ export function registerLlmCommand(program) {
|
|
|
134
202
|
const elapsed = Date.now() - start;
|
|
135
203
|
|
|
136
204
|
spinner.succeed(
|
|
137
|
-
`${chalk.green("Connected")} to Ollama (${
|
|
205
|
+
`${chalk.green("Connected")} to Ollama (${target.model}) in ${elapsed}ms`,
|
|
138
206
|
);
|
|
139
207
|
logger.log(
|
|
140
|
-
` Response: ${chalk.gray(data.response.trim().substring(0, 100))}`,
|
|
208
|
+
` Response: ${chalk.gray((data.response || "").trim().substring(0, 100))}`,
|
|
141
209
|
);
|
|
142
|
-
} else
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const url =
|
|
147
|
-
options.baseUrl !== "http://localhost:11434"
|
|
148
|
-
? options.baseUrl
|
|
149
|
-
: "https://api.openai.com/v1";
|
|
210
|
+
} else {
|
|
211
|
+
// OpenAI-compatible path (openai, volcengine, deepseek, dashscope,
|
|
212
|
+
// kimi, minimax, mistral, …).
|
|
213
|
+
if (!target.apiKey) throw new Error("API key required");
|
|
150
214
|
|
|
151
|
-
const response = await fetch(`${
|
|
215
|
+
const response = await fetch(`${target.baseUrl}/chat/completions`, {
|
|
152
216
|
method: "POST",
|
|
153
217
|
headers: {
|
|
154
218
|
"Content-Type": "application/json",
|
|
155
|
-
Authorization: `Bearer ${apiKey}`,
|
|
219
|
+
Authorization: `Bearer ${target.apiKey}`,
|
|
156
220
|
},
|
|
157
221
|
body: JSON.stringify({
|
|
158
|
-
model:
|
|
222
|
+
model: target.model,
|
|
159
223
|
messages: [{ role: "user", content: "Say hi in one word." }],
|
|
160
224
|
max_tokens: 10,
|
|
161
225
|
}),
|
|
@@ -167,15 +231,12 @@ export function registerLlmCommand(program) {
|
|
|
167
231
|
|
|
168
232
|
const data = await response.json();
|
|
169
233
|
const elapsed = Date.now() - start;
|
|
234
|
+
const reply = data.choices?.[0]?.message?.content?.trim() || "";
|
|
170
235
|
|
|
171
236
|
spinner.succeed(
|
|
172
|
-
`${chalk.green("Connected")} to
|
|
173
|
-
);
|
|
174
|
-
logger.log(
|
|
175
|
-
` Response: ${chalk.gray(data.choices[0].message.content.trim())}`,
|
|
237
|
+
`${chalk.green("Connected")} to ${target.label} (${target.model}) in ${elapsed}ms`,
|
|
176
238
|
);
|
|
177
|
-
|
|
178
|
-
spinner.fail(`Unknown provider: ${options.provider}`);
|
|
239
|
+
logger.log(` Response: ${chalk.gray(reply)}`);
|
|
179
240
|
}
|
|
180
241
|
} catch (err) {
|
|
181
242
|
spinner.fail(`Test failed: ${err.message}`);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* personal-data-hub-wiring — rewritePdhLoadError unit tests.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists: after the lazy-load refactor, a partial/corrupt pdh
|
|
5
|
+
* install (e.g. an interrupted `npm i -g` that left adapter files unwritten)
|
|
6
|
+
* surfaces as a raw ESM `ERR_MODULE_NOT_FOUND` the first time a `cc hub …`
|
|
7
|
+
* command touches the hub. That default error reads like a bug in the
|
|
8
|
+
* package, not a local-install problem, so users can't self-fix. This rewrite
|
|
9
|
+
* turns it into an actionable repair message. We must NOT swallow real bugs
|
|
10
|
+
* inside pdh (a TypeError, or a missing module that isn't pdh) — those pass
|
|
11
|
+
* through untouched. This suite pins both behaviors.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { describe, it, expect } from "vitest";
|
|
15
|
+
import { _rewritePdhLoadError } from "../personal-data-hub-wiring.js";
|
|
16
|
+
|
|
17
|
+
describe("rewritePdhLoadError", () => {
|
|
18
|
+
it("rewrites ERR_MODULE_NOT_FOUND for a missing pdh adapter file", () => {
|
|
19
|
+
const err = new Error(
|
|
20
|
+
"Cannot find module '.../@chainlesschain/personal-data-hub/lib/adapters/wechat/index.js'",
|
|
21
|
+
);
|
|
22
|
+
err.code = "ERR_MODULE_NOT_FOUND";
|
|
23
|
+
err.url =
|
|
24
|
+
"file:///.../@chainlesschain/personal-data-hub/lib/adapters/wechat/index.js";
|
|
25
|
+
const out = _rewritePdhLoadError(err);
|
|
26
|
+
expect(out).not.toBe(err);
|
|
27
|
+
expect(out.code).toBe("PDH_INSTALL_INCOMPLETE");
|
|
28
|
+
expect(out.cause).toBe(err);
|
|
29
|
+
expect(out.message).toMatch(/incomplete/i);
|
|
30
|
+
expect(out.message).toMatch(/npm i -g chainlesschain/);
|
|
31
|
+
// Keep the original error text for debugging.
|
|
32
|
+
expect(out.message).toMatch(/adapters\/wechat\/index\.js/);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("rewrites when the package root itself is missing (message-based, no url)", () => {
|
|
36
|
+
const err = new Error(
|
|
37
|
+
"Cannot find package '@chainlesschain/personal-data-hub' imported from x",
|
|
38
|
+
);
|
|
39
|
+
err.code = "ERR_MODULE_NOT_FOUND";
|
|
40
|
+
const out = _rewritePdhLoadError(err);
|
|
41
|
+
expect(out.code).toBe("PDH_INSTALL_INCOMPLETE");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("passes through a missing module that is NOT pdh (unrelated dep)", () => {
|
|
45
|
+
const err = new Error("Cannot find module './some-other-thing.js'");
|
|
46
|
+
err.code = "ERR_MODULE_NOT_FOUND";
|
|
47
|
+
expect(_rewritePdhLoadError(err)).toBe(err);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("passes through a real pdh runtime bug (not a resolution failure)", () => {
|
|
51
|
+
const err = new TypeError("foo is not a function in personal-data-hub");
|
|
52
|
+
expect(_rewritePdhLoadError(err)).toBe(err);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("is null/undefined safe", () => {
|
|
56
|
+
expect(_rewritePdhLoadError(null)).toBe(null);
|
|
57
|
+
expect(_rewritePdhLoadError(undefined)).toBe(undefined);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -136,6 +136,45 @@ let LocalVault,
|
|
|
136
136
|
ANALYSIS_SKILL_NAMES;
|
|
137
137
|
|
|
138
138
|
let _pdhLoadPromise = null;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Turn a raw ESM module-resolution failure for the personal-data-hub package
|
|
142
|
+
* into an actionable "your install is incomplete — repair it" error.
|
|
143
|
+
*
|
|
144
|
+
* Today this happens when a global `npm i -g chainlesschain` is interrupted
|
|
145
|
+
* mid-extraction (commonly a running `cc` / node process holding a lock on a
|
|
146
|
+
* native .node file → EBUSY/EPERM), leaving the pdh package partially
|
|
147
|
+
* written. The default Node error ("Cannot find module
|
|
148
|
+
* .../personal-data-hub/lib/adapters/wechat/index.js") reads like a bug in
|
|
149
|
+
* the package rather than a local-install problem, so users can't self-fix.
|
|
150
|
+
* Non-resolution errors (a real bug inside pdh) pass through unchanged.
|
|
151
|
+
*/
|
|
152
|
+
function rewritePdhLoadError(err) {
|
|
153
|
+
const isMissingModule =
|
|
154
|
+
err &&
|
|
155
|
+
(err.code === "ERR_MODULE_NOT_FOUND" ||
|
|
156
|
+
/Cannot find (module|package)/.test(err.message || ""));
|
|
157
|
+
const mentionsPdh = /personal-data-hub/.test(
|
|
158
|
+
(err && (err.url || err.message)) || "",
|
|
159
|
+
);
|
|
160
|
+
if (!isMissingModule || !mentionsPdh) return err;
|
|
161
|
+
const wrapped = new Error(
|
|
162
|
+
"Personal Data Hub package is missing files — your install looks " +
|
|
163
|
+
"incomplete.\n" +
|
|
164
|
+
"This usually means a global install was interrupted (often a running " +
|
|
165
|
+
"`cc`/node process locking a native file).\n" +
|
|
166
|
+
"Repair it with: npm i -g chainlesschain@latest\n" +
|
|
167
|
+
"(close any running `cc` sessions first so the install isn't blocked).\n" +
|
|
168
|
+
`Original error: ${err.message}`,
|
|
169
|
+
);
|
|
170
|
+
wrapped.code = "PDH_INSTALL_INCOMPLETE";
|
|
171
|
+
wrapped.cause = err;
|
|
172
|
+
return wrapped;
|
|
173
|
+
}
|
|
174
|
+
// Test seam (mirrors _atomicWriteJson600): unit-test the error rewrite
|
|
175
|
+
// without provoking a real partial-install.
|
|
176
|
+
export { rewritePdhLoadError as _rewritePdhLoadError };
|
|
177
|
+
|
|
139
178
|
/**
|
|
140
179
|
* Lazily import the personal-data-hub package + wechat adapter and populate
|
|
141
180
|
* the module-level binding holders above. Memoized so concurrent
|
|
@@ -145,13 +184,21 @@ let _pdhLoadPromise = null;
|
|
|
145
184
|
function ensurePdhLoaded() {
|
|
146
185
|
if (!_pdhLoadPromise) {
|
|
147
186
|
_pdhLoadPromise = (async () => {
|
|
148
|
-
|
|
187
|
+
let hubMod, waMod;
|
|
188
|
+
try {
|
|
189
|
+
hubMod = await import("@chainlesschain/personal-data-hub");
|
|
190
|
+
// Composed specifier dodges vite/vitest static import-analysis of
|
|
191
|
+
// subpath exports (same trick as loadAIChatHealthChecker below).
|
|
192
|
+
const wechatSpec =
|
|
193
|
+
"@chainlesschain/personal-data-hub" + "/adapters/wechat";
|
|
194
|
+
waMod = await import(wechatSpec);
|
|
195
|
+
} catch (err) {
|
|
196
|
+
// Don't poison the memoized promise — a repaired install (or a retry
|
|
197
|
+
// in a long-lived process) should be able to load.
|
|
198
|
+
_pdhLoadPromise = null;
|
|
199
|
+
throw rewritePdhLoadError(err);
|
|
200
|
+
}
|
|
149
201
|
const hub = hubMod.default || hubMod;
|
|
150
|
-
// Composed specifier dodges vite/vitest static import-analysis of
|
|
151
|
-
// subpath exports (same trick as loadAIChatHealthChecker below).
|
|
152
|
-
const wechatSpec =
|
|
153
|
-
"@chainlesschain/personal-data-hub" + "/adapters/wechat";
|
|
154
|
-
const waMod = await import(wechatSpec);
|
|
155
202
|
const wechatAdapterModule = waMod.default || waMod;
|
|
156
203
|
({ bootstrapWechatAdapter, probeWeChatEnv } = wechatAdapterModule);
|
|
157
204
|
({
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{E as B,b as D,r as R,I as p,J as c,U as _,c as n,K as a,S as C,V as x,o as F,x as I,P as i,Q as k,R as r,F as T,Z as O}from"./vendor-BvqAck49.js";import{u as P,_ as E}from"./index-Cops66s2.js";import{R as U}from"./icons-DP3uiYxy.js";const V=B("tasks",()=>{const y=R([]),l=R(!1);let u=null,t=null,d=null;const b=D(()=>y.value.filter(e=>e.status==="running")),v=D(()=>y.value.filter(e=>e.status==="pending")),w=D(()=>y.value.filter(e=>e.status==="completed"||e.status==="failed"||e.status==="timeout"));async function s(){const e=P();l.value=!0;try{const g=await e.sendRaw({type:"tasks-list"});g&&Array.isArray(g.tasks)&&(y.value=g.tasks)}catch{}finally{l.value=!1}}async function m(e){const g=P();try{await g.sendRaw({type:"tasks-stop",taskId:e})}catch{}finally{await s()}}const f=R(null);function h(e=5e3){N(),s(),u=setInterval(s,e),S()}function N(){u&&(clearInterval(u),u=null),t&&(t(),t=null),d&&(clearTimeout(d),d=null)}function S(){const e=P();if(t)return;const g=z=>{z.type==="task:notification"&&z.payload?.task&&(f.value=z.payload.task,s(),d&&clearTimeout(d),d=setTimeout(()=>{f.value=null,d=null},8e3))};t=e.onRuntimeEvent(g)}function A(e){return!e||e<0?"-":e<1e3?`${e}ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:`${(e/6e4).toFixed(1)}m`}function o(e){switch(e){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:y,loading:l,running:b,pending:v,completed:w,lastNotification:f,fetchTasks:s,stopTask:m,startPolling:h,stopPolling:N,formatDuration:A,getStatusColor:o}}),L={__name:"Tasks",setup(y,{expose:l}){l();const u=V(),t=[{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 d(s){return s.status==="running"&&s.startedAt?u.formatDuration(Date.now()-s.startedAt):s.completedAt&&s.startedAt?u.formatDuration(s.completedAt-s.startedAt):"-"}function b(s){return s?new Date(s).toLocaleString():"-"}function v(s,m){return s?s.length>m?`${s.slice(0,m)}...`:s:""}F(()=>u.startPolling(5e3)),I(()=>u.stopPolling());const w={store:u,columns:t,getDuration:d,formatTime:b,truncate:v,onMounted:F,onUnmounted:I,get ReloadOutlined(){return U},get useTasksStore(){return V}};return Object.defineProperty(w,"__isScriptSetup",{enumerable:!1,value:!0}),w}},j={class:"page-header"},J={key:0,class:"error-text"},K={key:1},M={class:"task-header"},Q={class:"task-desc"},W={class:"task-id"},Z={class:"task-meta"},q=["title"],G={key:0,class:"error-text"},H={key:1,class:"success-text"},X={key:2,class:"muted-text"};function Y(y,l,u,t,d,b){const v=p("a-button"),w=p("a-space"),s=p("a-alert"),m=p("a-statistic"),f=p("a-card"),h=p("a-col"),N=p("a-row"),S=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(w,null,{default:a(()=>[n(v,{ghost:"",loading:t.store.loading,onClick:l[0]||(l[0]=o=>t.store.fetchTasks())},{icon:a(()=>[n(t.ReloadOutlined)]),default:a(()=>[l[2]||(l[2]=k(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),t.store.lastNotification?(i(),C(s,{key:0,type:t.store.lastNotification.status==="completed"?"success":"error","show-icon":"",closable:"",class:"banner",onClose:l[1]||(l[1]=o=>t.store.lastNotification=null)},{message:a(()=>[k(" 任务"+r(t.store.lastNotification.status==="completed"?"完成":"结束")+": "+r(t.store.lastNotification.description||t.store.lastNotification.id.slice(0,16)),1)]),description:a(()=>[t.store.lastNotification.error?(i(),c("span",J,r(t.store.lastNotification.error),1)):t.store.lastNotification.result?(i(),c("span",K,r(t.truncate(String(t.store.lastNotification.result),120)),1)):x("v-if",!0)]),_:1},8,["type"])):x("v-if",!0),n(N,{gutter:[16,16],class:"stats-row"},{default:a(()=>[n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"全部任务",value:t.store.tasks.length},null,8,["value"])]),_:1})]),_:1}),n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"运行中",value:t.store.running.length},null,8,["value"])]),_:1})]),_:1}),n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"等待中",value:t.store.pending.length},null,8,["value"])]),_:1})]),_:1}),n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"已完成",value:t.store.completed.length},null,8,["value"])]),_:1})]),_:1})]),_:1}),t.store.running.length>0?(i(),C(f,{key:1,title:"运行中的任务",class:"panel-card",size:"small"},{default:a(()=>[(i(!0),c(T,null,O(t.store.running,o=>(i(),c("div",{key:o.id,class:"task-item running"},[_("div",M,[n(S,{color:t.store.getStatusColor(o.status)},{default:a(()=>[k(r(o.status.toUpperCase()),1)]),_:2},1032,["color"]),_("span",Q,r(o.description),1),_("span",W,r(o.id.slice(0,16)),1)]),_("div",Z,[_("span",null,"类型: "+r(o.type||"-"),1),_("span",null,"已运行: "+r(t.store.formatDuration(Date.now()-o.startedAt)),1),n(v,{size:"small",danger:"",onClick:e=>t.store.stopTask(o.id)},{default:a(()=>[...l[4]||(l[4]=[k("停止",-1)])]),_:1},8,["onClick"])])]))),128))]),_:1})):x("v-if",!0),n(f,{class:"panel-card"},{default:a(()=>[n(A,{columns:t.columns,"data-source":t.store.tasks,pagination:{pageSize:15,size:"small"},loading:t.store.loading,"row-key":"id",size:"small"},{bodyCell:a(({column:o,record:e})=>[o.key==="status"?(i(),C(S,{key:0,color:t.store.getStatusColor(e.status)},{default:a(()=>[k(r(e.status),1)]),_:2},1032,["color"])):o.key==="description"?(i(),c("span",{key:1,title:e.command},r(e.description),9,q)):o.key==="duration"?(i(),c(T,{key:2},[k(r(t.getDuration(e)),1)],64)):o.key==="createdAt"?(i(),c(T,{key:3},[k(r(t.formatTime(e.createdAt)),1)],64)):o.key==="result"?(i(),c(T,{key:4},[e.error?(i(),c("span",G,r(t.truncate(e.error,60)),1)):e.result?(i(),c("span",H,r(t.truncate(String(e.result),60)),1)):(i(),c("span",X,"-"))],64)):o.key==="action"?(i(),c(T,{key:5},[e.status==="running"?(i(),C(v,{key:0,size:"small",danger:"",onClick:g=>t.store.stopTask(e.id)},{default:a(()=>[...l[5]||(l[5]=[k(" 停止 ",-1)])]),_:1},8,["onClick"])):x("v-if",!0)],64)):x("v-if",!0)]),_:1},8,["data-source","loading"])]),_:1})])}const st=E(L,[["render",Y],["__scopeId","data-v-da5ff6a2"],["__file","/tmp/cc-web-panel-gA2tfF/repo/packages/web-panel/src/views/Tasks.vue"]]);export{st 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-Cops66s2.js";import{I as z,J as x,U as _,Q as D,S as Q,K as T,V as R,c as A,F as Y,Z,R as E,o as G,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,F=new Set,N=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)),F.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)),N.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)}):(F.add(a),()=>F.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)}):(N.add(a),()=>N.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 K of v)m.write(K.data),t.lastSeq=K.seq}catch(v){m.writeln(`\x1B[31m[history fetch failed: ${v?.message||v}]\x1B[0m`)}const J=new ResizeObserver(()=>{try{P.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 X(){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}}G(async()=>{await X()}),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 j={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:X,ref:S,computed:ee,onMounted:G,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(j,"__isScriptSetup",{enumerable:!1,value:!0}),j}},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(),Q(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(),Q(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(Y,null,Z(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(Y,null,Z(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 Ne=me(Se,[["render",Be],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-gA2tfF/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Ne as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{O as r}from"./index-Cops66s2.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-BZHXUEnZ.js";import{U as t}from"./index-Cops66s2.js";import"./vendor-BvqAck49.js";import"./index-DDLjwgva.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-BnMPysBm.js";import{U as t}from"./index-Cops66s2.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-BF8Y-1HQ.js";import"./useFlexGapSupport-BEMNO3oR.js";import"./styleChecker-D4zVyb4w.js";import"./index-DDLjwgva.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};
|