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.
Files changed (152) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-BpJ5yCcV.js → AIOps-DYaOYjxA.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-B1uBfxnA.js → ActionButton-BRnLVtON.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-0ubw5quf.js → Analytics-Bi5dt6xG.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-go-GyyM_.js → AppLayout-FdAkPhdh.js} +5 -5
  7. package/src/assets/web-panel/assets/{Audit-CdUfoUnM.js → Audit-huJ-2mSb.js} +1 -1
  8. package/src/assets/web-panel/assets/{Backup-CBn0xtsa.js → Backup-CTAFMoyw.js} +1 -1
  9. package/src/assets/web-panel/assets/{BaseInput-a9fqTkvL.js → BaseInput-DNh66xG2.js} +1 -1
  10. package/src/assets/web-panel/assets/{Chat-D-d_IatD.js → Chat-xLRQDs5G.js} +6 -6
  11. package/src/assets/web-panel/assets/{ChatBubbleRenderer-Co9h0SbA.js → ChatBubbleRenderer-BFRpdxeW.js} +1 -1
  12. package/src/assets/web-panel/assets/{Checkbox-CiKEjtXm.js → Checkbox-BEZRITX8.js} +1 -1
  13. package/src/assets/web-panel/assets/{Codegen-OQxW_9Z2.js → Codegen-BD6xBApN.js} +1 -1
  14. package/src/assets/web-panel/assets/{Col-BZHXUEnZ.js → Col-B_Xqx3Ul.js} +1 -1
  15. package/src/assets/web-panel/assets/{Community-D3xno9fj.js → Community-Bu4rj14W.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compact-D62jpZk_.js → Compact-B17uNB4p.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compliance-D4jFTAcQ.js → Compliance-DjaCMltJ.js} +1 -1
  18. package/src/assets/web-panel/assets/{Cowork-BOU_wir4.js → Cowork-BdE44Hek.js} +3 -3
  19. package/src/assets/web-panel/assets/{Cron-Cr9BlJA7.js → Cron-DZyVpxse.js} +2 -2
  20. package/src/assets/web-panel/assets/{Crosschain-L9M--CXb.js → Crosschain-BeSoFHpQ.js} +1 -1
  21. package/src/assets/web-panel/assets/{DID-xFu3-VWT.js → DID-D8GTLlQ5.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dashboard--ax48T3j.js → Dashboard-vAKXjb1o.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dropdown-CTOS8daR.js → Dropdown-BvgPRTyP.js} +1 -1
  24. package/src/assets/web-panel/assets/{EmailListRenderer-CNLSX81U.js → EmailListRenderer-CtXq_Ttt.js} +1 -1
  25. package/src/assets/web-panel/assets/{FamilyGuardDashboard-5EjFynBc.js → FamilyGuardDashboard-oG2LekBb.js} +1 -1
  26. package/src/assets/web-panel/assets/{Federation-CoPyIWIu.js → Federation-C-oMwAUG.js} +1 -1
  27. package/src/assets/web-panel/assets/{FormItemContext-BbzCNbYy.js → FormItemContext-rj-oMGta.js} +1 -1
  28. package/src/assets/web-panel/assets/{GenericCardRenderer-8_9_uXY0.js → GenericCardRenderer-UeOKM5KJ.js} +1 -1
  29. package/src/assets/web-panel/assets/{Git-Bz_qlVPg.js → Git-BOjLMgD-.js} +2 -2
  30. package/src/assets/web-panel/assets/{Governance-7eepNCeD.js → Governance-DVlgF083.js} +1 -1
  31. package/src/assets/web-panel/assets/{Inference-DlBx5l1g.js → Inference-BzpCtSRm.js} +1 -1
  32. package/src/assets/web-panel/assets/{KnowledgeGraph-BPkc--rM.js → KnowledgeGraph-5sFDbZKo.js} +1 -1
  33. package/src/assets/web-panel/assets/{Logs-BQw4nPvS.js → Logs-BagEqu7D.js} +2 -2
  34. package/src/assets/web-panel/assets/{Marketplace-Cil3SdgN.js → Marketplace-za352FZT.js} +1 -1
  35. package/src/assets/web-panel/assets/{McpTools-Bnch7KrG.js → McpTools-CEavmaZU.js} +5 -5
  36. package/src/assets/web-panel/assets/{Memory-assQ3Suc.js → Memory-Dp0d39Y-.js} +2 -2
  37. package/src/assets/web-panel/assets/{MobileBridge-D5mE8c-z.js → MobileBridge-BljVPikC.js} +2 -2
  38. package/src/assets/web-panel/assets/{MobileProjects-C4MiDXw1.js → MobileProjects-dR-6L-xU.js} +1 -1
  39. package/src/assets/web-panel/assets/{Mtc-CumojeLk.js → Mtc-CO80_dbI.js} +4 -4
  40. package/src/assets/web-panel/assets/{MtcAudit-3tTBc_fw.js → MtcAudit-ByH4suVc.js} +2 -2
  41. package/src/assets/web-panel/assets/{Multisig-Dl4IJBsl.js → Multisig-CvQ373Kp.js} +3 -3
  42. package/src/assets/web-panel/assets/{NLProgramming-DHN_cV9x.js → NLProgramming-DSugxBwU.js} +1 -1
  43. package/src/assets/web-panel/assets/{Notes-DeyTvwYk.js → Notes-BN_R_-qG.js} +4 -4
  44. package/src/assets/web-panel/assets/{NotificationSettings-BUkj8mTj.js → NotificationSettings-x3Ipb8KF.js} +1 -1
  45. package/src/assets/web-panel/assets/{OrderTableRenderer-BMpEXTki.js → OrderTableRenderer-CJCW-n1E.js} +1 -1
  46. package/src/assets/web-panel/assets/{Organization-B6Ogmkpz.js → Organization-CUo9tpab.js} +4 -4
  47. package/src/assets/web-panel/assets/{Overflow-DRUE-2Wz.js → Overflow-Cm1ok3yr.js} +1 -1
  48. package/src/assets/web-panel/assets/{P2P-CnMUkd64.js → P2P-BPXfkljx.js} +2 -2
  49. package/src/assets/web-panel/assets/{PdhVaultBrowser-B3nFxT3b.js → PdhVaultBrowser-bB_pMcWV.js} +5 -5
  50. package/src/assets/web-panel/assets/{Permissions-CyG1FR7v.js → Permissions-bUj1KcNM.js} +4 -4
  51. package/src/assets/web-panel/assets/{PersonalDataHub-BmN6YMb5.js → PersonalDataHub-DODkpqmo.js} +4 -4
  52. package/src/assets/web-panel/assets/{Pipeline-BZcamAnH.js → Pipeline-DEqfqfHT.js} +1 -1
  53. package/src/assets/web-panel/assets/{Privacy-D7_zsaY3.js → Privacy-C5b_6Np-.js} +1 -1
  54. package/src/assets/web-panel/assets/{ProjectInit-DNa7XQjg.js → ProjectInit-DSnPoDLm.js} +2 -2
  55. package/src/assets/web-panel/assets/{ProjectSettings-KH2Dm09G.js → ProjectSettings-DjDz4FBi.js} +2 -2
  56. package/src/assets/web-panel/assets/{Projects-T-WqR3D6.js → Projects-9chbQyJR.js} +1 -1
  57. package/src/assets/web-panel/assets/{Providers-8GtQ6GgR.js → Providers-CrtYhXe4.js} +1 -1
  58. package/src/assets/web-panel/assets/{QuickAsk-BuBM5Zpg.js → QuickAsk-BwBKTclE.js} +1 -1
  59. package/src/assets/web-panel/assets/{Recommend-DvH95W1b.js → Recommend-mQMxq3Xc.js} +1 -1
  60. package/src/assets/web-panel/assets/{Reputation-BHCpMEP6.js → Reputation-CL6wmEN-.js} +1 -1
  61. package/src/assets/web-panel/assets/{Row-BnMPysBm.js → Row-CVXQQg_a.js} +1 -1
  62. package/src/assets/web-panel/assets/{RssFeed-C-T8B5VU.js → RssFeed-CfoKWtqq.js} +3 -3
  63. package/src/assets/web-panel/assets/{Search-CioiZGkX.js → Search-BXBraFwH.js} +1 -1
  64. package/src/assets/web-panel/assets/{Security-zSApKqdd.js → Security-DuVGdvLC.js} +4 -4
  65. package/src/assets/web-panel/assets/{Services-CQh0UDXC.js → Services-vfsS-hHM.js} +2 -2
  66. package/src/assets/web-panel/assets/{Skeleton-C0dRaEVG.js → Skeleton-UODCxnzg.js} +1 -1
  67. package/src/assets/web-panel/assets/{Skills-BgQRArsa.js → Skills-DVHtahH_.js} +1 -1
  68. package/src/assets/web-panel/assets/{Sla-BNn7F3jc.js → Sla-DSoODBCc.js} +1 -1
  69. package/src/assets/web-panel/assets/{SpeechSettings-kvVfKfqv.js → SpeechSettings-DiaqTk_e.js} +1 -1
  70. package/src/assets/web-panel/assets/{SyncSettings-BwIkkX1E.js → SyncSettings-BQcVBcLi.js} +2 -2
  71. package/src/assets/web-panel/assets/Tasks-w5vOQG7_.js +1 -0
  72. package/src/assets/web-panel/assets/{Templates-COK0o2pL.js → Templates-BpnfhFKX.js} +1 -1
  73. package/src/assets/web-panel/assets/{Tenant-DpK87fqo.js → Tenant-l6EIK9VO.js} +1 -1
  74. package/src/assets/web-panel/assets/Terminal-2wTdm-Qz.js +3 -0
  75. package/src/assets/web-panel/assets/{TimelineRenderer-B4SJqyqf.js → TimelineRenderer-6dWgzU5T.js} +1 -1
  76. package/src/assets/web-panel/assets/{Tokens-C3iSR8fH.js → Tokens-CmTEa0qE.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trigger-D1Oo58Yo.js → Trigger-DrfC7Hb-.js} +1 -1
  78. package/src/assets/web-panel/assets/{Trust-CUhy4DDc.js → Trust-9SSsKJ67.js} +1 -1
  79. package/src/assets/web-panel/assets/{UkeySign-r-kTqSw8.js → UkeySign-_4fg9FZz.js} +1 -1
  80. package/src/assets/web-panel/assets/{VideoEditing-B8MyBfCX.js → VideoEditing-XBXv_ieG.js} +1 -1
  81. package/src/assets/web-panel/assets/{Wallet-CquTfSv0.js → Wallet-0eP1nq2A.js} +4 -4
  82. package/src/assets/web-panel/assets/{WebAuthn-BC7TP1H3.js → WebAuthn-BWs4GCCZ.js} +5 -5
  83. package/src/assets/web-panel/assets/{WorkflowEditor-CELBSNbP.js → WorkflowEditor-BFSo4kVo.js} +1 -1
  84. package/src/assets/web-panel/assets/{chat-d66mbO2i.js → chat-DJSs4Z3h.js} +1 -1
  85. package/src/assets/web-panel/assets/{colors-D0WRCg20.js → colors-DyNgmHM2.js} +1 -1
  86. package/src/assets/web-panel/assets/{compact-item-4__-8TIi.js → compact-item-M3CZ-i2H.js} +1 -1
  87. package/src/assets/web-panel/assets/{createContext-Dqsf52js.js → createContext-lNMonv_i.js} +1 -1
  88. package/src/assets/web-panel/assets/devWarning-D7oeO7SY.js +1 -0
  89. package/src/assets/web-panel/assets/{hasIn-ClTZOS8I.js → hasIn-B91aXEzF.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-81SaeU6t.js → index-BDOOE70-.js} +1 -1
  91. package/src/assets/web-panel/assets/index-BIPYc_9M.js +1 -0
  92. package/src/assets/web-panel/assets/{index-C5l6tSky.js → index-BMG7MAgn.js} +1 -1
  93. package/src/assets/web-panel/assets/index-BRXyk-mT.js +1 -0
  94. package/src/assets/web-panel/assets/{index-B1TGSkBt.js → index-BTzUzcRX.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-PMJ4tBAA.js → index-BVeeHE1i.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-CGf3oqM0.js → index-Be_FDJks.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DbY1lv1z.js → index-BfRRIydd.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-leuwRsbf.js → index-Bsl-sRNN.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CFwkeSun.js → index-BxhgIY1j.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-D-ya3Ohe.js → index-BzaXBB1A.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BCOpbfAH.js → index-C2oG0D9w.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-e5zJLrJQ.js → index-C4tKStAX.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-ZZpfHd4J.js → index-C51tOSTU.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BNKECBZm.js → index-CJsTosBw.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-fi2ikHoc.js → index-CKiGfsRP.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-B3vrmn5v.js → index-CVCoAsQq.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-C4_XhCJS.js → index-CXoioS1t.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-luisYDBz.js → index-CkpZNnfb.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Yi5Lr63I.js → index-CmtXAPQT.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Cg8Qw3Jw.js → index-Cvj5N5SK.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-jAPphbJL.js → index-DAd-oQMK.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DORg0Hps.js → index-DMUkAgqR.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-PAiWA2un.js → index-DQIBwi9k.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-P4X9zSF2.js → index-DRJ_Lszr.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DQaGurrQ.js → index-DV9i6LzE.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Dm7CYK3j.js → index-DWuMyZbA.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CxoWS8hl.js → index-De6_AYb4.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-D68tyHYa.js → index-Do3iJlSY.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BwozLU75.js → index-DyOBjEUA.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-we9-1IbF.js → index-Dz-UTFho.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-b7a5aEX9.js → index-HIF1H3Qi.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-D9x6i7iV.js → index-HcSrdXIY.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-Cops66s2.js → index-IHn9LQeI.js} +3 -3
  124. package/src/assets/web-panel/assets/{index-0Axwx1nN.js → index-KSwJzeqG.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DpLhC0nx.js → index-_kFxj8Iv.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CJKyF-y8.js → index-dW5CK84B.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DDLjwgva.js → index-eLphHYgM.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Ct5SJenr.js → index-vb_z80lH.js} +1 -1
  129. package/src/assets/web-panel/assets/{initDefaultProps-zqDf7qWv.js → initDefaultProps-BKCFkUwh.js} +1 -1
  130. package/src/assets/web-panel/assets/{motion-DRqTooll.js → motion-CuYmQtOE.js} +1 -1
  131. package/src/assets/web-panel/assets/{move-N8tkRqS4.js → move-DlPzxPAW.js} +1 -1
  132. package/src/assets/web-panel/assets/{omit-Cy01f2vw.js → omit-Ds3kQlyN.js} +1 -1
  133. package/src/assets/web-panel/assets/{pickAttrs-C2ycNXNi.js → pickAttrs-RUYRa-vv.js} +1 -1
  134. package/src/assets/web-panel/assets/{placementArrow-D60Xb1j9.js → placementArrow-jYZCPIVc.js} +1 -1
  135. package/src/assets/web-panel/assets/{responsiveObserve-BF8Y-1HQ.js → responsiveObserve-BsNIdQzh.js} +1 -1
  136. package/src/assets/web-panel/assets/{slide-DDi6zYZf.js → slide-IDA11Awb.js} +1 -1
  137. package/src/assets/web-panel/assets/{statusUtils-CWPq6UzA.js → statusUtils-D-dVqEII.js} +1 -1
  138. package/src/assets/web-panel/assets/{styleChecker-D4zVyb4w.js → styleChecker-qHsriHs9.js} +1 -1
  139. package/src/assets/web-panel/assets/{useFlexGapSupport-BEMNO3oR.js → useFlexGapSupport-Bf1CATNE.js} +1 -1
  140. package/src/assets/web-panel/assets/{useFs-DBLO8VR7.js → useFs-BaqG_--5.js} +1 -1
  141. package/src/assets/web-panel/assets/{usePersonalDataHub-C83ZIrPY.js → usePersonalDataHub-DsEBdplG.js} +1 -1
  142. package/src/assets/web-panel/assets/{vnode-Dcfyve-7.js → vnode-AvKcICeL.js} +1 -1
  143. package/src/assets/web-panel/assets/{zoom-Dg6uoWSc.js → zoom-ClicurwO.js} +1 -1
  144. package/src/assets/web-panel/index.html +1 -1
  145. package/src/commands/llm.js +89 -28
  146. package/src/lib/__tests__/pdh-wiring-load-error.test.js +59 -0
  147. package/src/lib/personal-data-hub-wiring.js +53 -6
  148. package/src/assets/web-panel/assets/Tasks-BkcvhBZw.js +0 -1
  149. package/src/assets/web-panel/assets/Terminal-2g2-XPT_.js +0 -3
  150. package/src/assets/web-panel/assets/devWarning-DUAmX0aE.js +0 -1
  151. package/src/assets/web-panel/assets/index-BLCwqv8j.js +0 -1
  152. package/src/assets/web-panel/assets/index-Db5JRQ6E.js +0 -1
@@ -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", "ollama")
110
- .option("--model <model>", "Model to test", "qwen2:7b")
111
- .option("--base-url <url>", "API base URL", "http://localhost:11434")
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 spinner = ora(`Testing ${options.provider}...`).start();
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 (options.provider === "ollama") {
119
- const response = await fetch(`${options.baseUrl}/api/generate`, {
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: options.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 (${options.model}) in ${elapsed}ms`,
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 if (options.provider === "openai") {
143
- const apiKey = options.apiKey || process.env.OPENAI_API_KEY;
144
- if (!apiKey) throw new Error("API key required");
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(`${url}/chat/completions`, {
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: options.model || "gpt-4o-mini",
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 OpenAI (${options.model || "gpt-4o-mini"}) in ${elapsed}ms`,
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
- } else {
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
- const hubMod = await import("@chainlesschain/personal-data-hub");
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};