chainlesschain 0.162.92 → 0.162.94

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 (155) hide show
  1. package/package.json +4 -4
  2. package/src/assets/web-panel/assets/{AIOps-6twtwnPW.js → AIOps-CiEoV_Hg.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-BSDNY--F.js → ActionButton-DrrjQMuK.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-Bfn50rrv.js → Analytics-ChlhPe9a.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-B9W4a66_.js → AppLayout-CIkI7d5o.js} +5 -5
  6. package/src/assets/web-panel/assets/{Audit-DDobDwcD.js → Audit-_sY9bNSN.js} +1 -1
  7. package/src/assets/web-panel/assets/{Backup-BsXWp0sT.js → Backup-DvzaThN8.js} +1 -1
  8. package/src/assets/web-panel/assets/{BaseInput-CkWCbOEr.js → BaseInput-DDZW_DU8.js} +1 -1
  9. package/src/assets/web-panel/assets/{Chat-DxStgik4.js → Chat-DqErkog2.js} +6 -6
  10. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CzKI3REx.js → ChatBubbleRenderer-BcnNHS-r.js} +1 -1
  11. package/src/assets/web-panel/assets/{Checkbox-CjZytMW9.js → Checkbox-NWDuyRK6.js} +1 -1
  12. package/src/assets/web-panel/assets/{Codegen-DE8LtQGr.js → Codegen-B_jnSC8a.js} +1 -1
  13. package/src/assets/web-panel/assets/{Col-DyUt1sFI.js → Col-B-uyUy0z.js} +1 -1
  14. package/src/assets/web-panel/assets/{Community-BdvahpIz.js → Community-Dmf1MpG7.js} +1 -1
  15. package/src/assets/web-panel/assets/{Compact-a29mg08X.js → Compact-fGI68M5y.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compliance-UC6JFaSt.js → Compliance-PV9qT-iV.js} +1 -1
  17. package/src/assets/web-panel/assets/{Cowork-Cs5I8Nzy.js → Cowork-BM6BvCgv.js} +3 -3
  18. package/src/assets/web-panel/assets/{Cron-BX79AD11.js → Cron-BsSWwFFo.js} +2 -2
  19. package/src/assets/web-panel/assets/{Crosschain-BvxZT8FE.js → Crosschain-DUdPVYvS.js} +1 -1
  20. package/src/assets/web-panel/assets/{DID-B6Zrl_7C.js → DID-PPLLhrJs.js} +2 -2
  21. package/src/assets/web-panel/assets/{Dashboard-Do6fbQ17.js → Dashboard-Cn_Xjj80.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dropdown-gAXIfJbo.js → Dropdown-DkTXjy5D.js} +1 -1
  23. package/src/assets/web-panel/assets/{EmailListRenderer-B49KXDBh.js → EmailListRenderer-BnA27cjB.js} +1 -1
  24. package/src/assets/web-panel/assets/{FamilyGuardDashboard-3pBN-Pmu.js → FamilyGuardDashboard-jqrv5VCp.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-BfiJ60Oq.js → Federation-DESwXwtR.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-UdCc-bZB.js → FormItemContext-C9gbyY1r.js} +1 -1
  27. package/src/assets/web-panel/assets/{GenericCardRenderer-dD_BaOLA.js → GenericCardRenderer-CkZB9crH.js} +1 -1
  28. package/src/assets/web-panel/assets/{Git-DDE3KmiQ.js → Git-B6niu0W9.js} +2 -2
  29. package/src/assets/web-panel/assets/{Governance-CwhuK23F.js → Governance-BrF28dEi.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-B5Wj9bBy.js → Inference-CZDnV8SN.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-DkOOruKr.js → KnowledgeGraph-eqZ0hP0l.js} +1 -1
  32. package/src/assets/web-panel/assets/{Logs-BLZDOpYT.js → Logs-BlHS7DoS.js} +2 -2
  33. package/src/assets/web-panel/assets/{Marketplace-DVvRgBgV.js → Marketplace-NOp9G83e.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-BOMfVLk1.js → McpTools-B6wMx173.js} +5 -5
  35. package/src/assets/web-panel/assets/{Memory-DgTyfHvz.js → Memory-BKVeTAeT.js} +2 -2
  36. package/src/assets/web-panel/assets/{MobileBridge-B0B5CjIo.js → MobileBridge-Da2y6iYW.js} +2 -2
  37. package/src/assets/web-panel/assets/MobileProjects-CTFPhn4A.js +1 -0
  38. package/src/assets/web-panel/assets/{Mtc-BVDDuvn9.js → Mtc-B7Hy5rAT.js} +4 -4
  39. package/src/assets/web-panel/assets/{MtcAudit-BCMiZcKF.js → MtcAudit-BgBoX0XI.js} +4 -4
  40. package/src/assets/web-panel/assets/{Multisig-D3iDui-6.js → Multisig-Db7bwi5J.js} +3 -3
  41. package/src/assets/web-panel/assets/{NLProgramming-CIOniQmy.js → NLProgramming-f9ca2vst.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-BIp2dwk4.js → Notes-meVqoOMz.js} +3 -3
  43. package/src/assets/web-panel/assets/{NotificationSettings-BUhOSAd7.js → NotificationSettings-BfEhBXNo.js} +1 -1
  44. package/src/assets/web-panel/assets/OrderTableRenderer-e25Q6ALJ.js +1 -0
  45. package/src/assets/web-panel/assets/{Organization-ax8vgKPP.js → Organization-BpgOG9lj.js} +3 -3
  46. package/src/assets/web-panel/assets/{Overflow-DshI7d1Y.js → Overflow-fI3L05Rq.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-CNlUxg1y.js → P2P-wD0wpJJY.js} +2 -2
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-D39VHh_o.js → PdhVaultBrowser-BWV9J4VZ.js} +3 -3
  49. package/src/assets/web-panel/assets/{Permissions-BdRnAHww.js → Permissions-BJH7W2iv.js} +4 -4
  50. package/src/assets/web-panel/assets/{PersonalDataHub-CMWRhLJO.js → PersonalDataHub-CqQ3XpMz.js} +2 -2
  51. package/src/assets/web-panel/assets/{Pipeline-BjNk195c.js → Pipeline-CHyXCU1i.js} +1 -1
  52. package/src/assets/web-panel/assets/{Privacy-HPWrTCjI.js → Privacy-CJtfNlc7.js} +1 -1
  53. package/src/assets/web-panel/assets/{ProjectInit-BOrTZqGv.js → ProjectInit-CKOaHFGR.js} +2 -2
  54. package/src/assets/web-panel/assets/{ProjectSettings-CUQvHkB9.js → ProjectSettings-QD8wp_EM.js} +2 -2
  55. package/src/assets/web-panel/assets/{Projects-DbQSmrB7.js → Projects-Dj33CO-H.js} +1 -1
  56. package/src/assets/web-panel/assets/{Providers-Dooco7el.js → Providers-BPESqCEg.js} +1 -1
  57. package/src/assets/web-panel/assets/{QuickAsk-DeTcGs9R.js → QuickAsk-C5AzvvRo.js} +1 -1
  58. package/src/assets/web-panel/assets/{Recommend-DtroPrGa.js → Recommend-cGpF3tsA.js} +1 -1
  59. package/src/assets/web-panel/assets/{Reputation-BlXGOy-i.js → Reputation-Duaxvbt9.js} +1 -1
  60. package/src/assets/web-panel/assets/{Row-BEX1Dblk.js → Row-xsUwB5Ay.js} +1 -1
  61. package/src/assets/web-panel/assets/{RssFeed-sM0sottB.js → RssFeed-DmUUsqaF.js} +3 -3
  62. package/src/assets/web-panel/assets/{Search-Bfp_glKa.js → Search-Do9YuDbX.js} +1 -1
  63. package/src/assets/web-panel/assets/{Security-BF0xUsBO.js → Security-06BgEn-d.js} +3 -3
  64. package/src/assets/web-panel/assets/{Services-BtJuny5P.js → Services-DyaCes7r.js} +2 -2
  65. package/src/assets/web-panel/assets/{Skeleton-DSknAG8_.js → Skeleton-Cj_VbkFG.js} +1 -1
  66. package/src/assets/web-panel/assets/{Skills-DxYaVxIs.js → Skills-DCOWMJOR.js} +1 -1
  67. package/src/assets/web-panel/assets/{Sla-DebP2eS_.js → Sla-C44_86bu.js} +1 -1
  68. package/src/assets/web-panel/assets/{SpeechSettings-Dg-unWVe.js → SpeechSettings-BXhBJSMB.js} +1 -1
  69. package/src/assets/web-panel/assets/{SyncSettings-D2EY-hwE.js → SyncSettings-BpHsaNWg.js} +2 -2
  70. package/src/assets/web-panel/assets/{Tasks---d5Krbm.js → Tasks-C83eyBn8.js} +1 -1
  71. package/src/assets/web-panel/assets/{Templates-tzsVBBBR.js → Templates-aEWbCOdo.js} +1 -1
  72. package/src/assets/web-panel/assets/{Tenant-jbao2ccf.js → Tenant-DkOLw1Yz.js} +1 -1
  73. package/src/assets/web-panel/assets/Terminal-5Z4paIoh.js +3 -0
  74. package/src/assets/web-panel/assets/{TimelineRenderer-CrzTjuP2.js → TimelineRenderer-CYhublOm.js} +1 -1
  75. package/src/assets/web-panel/assets/{Tokens-BRWBFdFC.js → Tokens-h57dBT4T.js} +1 -1
  76. package/src/assets/web-panel/assets/{Trigger-Cprr32mB.js → Trigger-abE21FpD.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trust-DurON-f6.js → Trust-urB3VZip.js} +1 -1
  78. package/src/assets/web-panel/assets/{UkeySign-CWl0lxFB.js → UkeySign-D6uXV9pp.js} +1 -1
  79. package/src/assets/web-panel/assets/{VideoEditing-DC19li0J.js → VideoEditing-C9MxXAzw.js} +1 -1
  80. package/src/assets/web-panel/assets/{Wallet-P91J4Vm0.js → Wallet-DTn5rW4u.js} +4 -4
  81. package/src/assets/web-panel/assets/{WebAuthn-B0SZWdJZ.js → WebAuthn-BNYEqeqr.js} +5 -5
  82. package/src/assets/web-panel/assets/{WorkflowEditor-B4FjG3m2.js → WorkflowEditor-CsRoOJPT.js} +1 -1
  83. package/src/assets/web-panel/assets/{chat-CxsW4Ke9.js → chat-B5GoUHDS.js} +1 -1
  84. package/src/assets/web-panel/assets/{colors-BvHfC8In.js → colors-BF_Rqaab.js} +1 -1
  85. package/src/assets/web-panel/assets/{compact-item-DCflxzMp.js → compact-item-BNPfqT4P.js} +1 -1
  86. package/src/assets/web-panel/assets/{createContext-Dke_7fby.js → createContext-C3qLKXX-.js} +1 -1
  87. package/src/assets/web-panel/assets/devWarning-D5Rwbl_Y.js +1 -0
  88. package/src/assets/web-panel/assets/{hasIn-BbmdxhX_.js → hasIn-BLpAeFXB.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-WUhnQfgx.js → index-2-7AD4Fq.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-DLzdcWS9.js → index-7Tt41tHa.js} +1 -1
  91. package/src/assets/web-panel/assets/index-7ls1Z3dH.js +1 -0
  92. package/src/assets/web-panel/assets/{index-BZGfOexF.js → index-81hgV6U6.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-BRa8zxOl.js → index-BIpGZeh2.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-DvRMAvUz.js → index-BJsVUj80.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BDf7No_W.js → index-BOoTjHGU.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-wMu52DQD.js → index-BlEDjdTc.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-Cgg9FVBY.js → index-BqjU6Jp9.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DrjWlYim.js → index-BryugSCS.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DiJNuzOB.js → index-BxWEK9FS.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DSZRBxQm.js → index-C2wJowV1.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DkT9o8ua.js → index-C6yRwT6e.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CuwtZOlw.js → index-C8B3rHnr.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DseIJFKK.js → index-CBFekqcY.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CZtRpChp.js → index-CIjPwa7h.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CW6Qw36d.js → index-CMRdeB2r.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-1fhZRJRr.js → index-CaROOJ5Z.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-iRWJlzYS.js → index-CgIrRLBP.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DgodFtjR.js → index-CmBMP52w.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-C0z_cJFv.js → index-Cqb8TXEp.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Bqrzn8h8.js → index-Cv1WRH-j.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Cd-IYAJf.js → index-Cxd2RsZR.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BiFygmHz.js → index-D-PNuV4r.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DTjZEU8T.js → index-DGVf-eOG.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CQPy5Rb0.js → index-DH95hKUN.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CI7B8kzt.js → index-DMKbLaTg.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CZhMMMOi.js → index-DMKiwMJa.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DU0k7Ysd.js → index-DYWExa2Z.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-ChTfizrh.js → index-Dj6rUk3f.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Dkd8hCt6.js → index-DmrPbYXh.js} +3 -3
  120. package/src/assets/web-panel/assets/{index-CrfvJHyV.js → index-Dn95Blhx.js} +1 -1
  121. package/src/assets/web-panel/assets/index-DoldiBPq.js +1 -0
  122. package/src/assets/web-panel/assets/{index-CNUpbwEf.js → index-DudglWTC.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CizldTB_.js → index-Dz7o1Zt6.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CPckRA0n.js → index-KUdyAwqr.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DMC2DRU2.js → index-ixN0R0We.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BIm5F2fe.js → index-o1doEeT3.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DkBLudRn.js → index-vXHPZOmO.js} +1 -1
  128. package/src/assets/web-panel/assets/{initDefaultProps-D4IAc-nN.js → initDefaultProps-Dhfx-jOJ.js} +1 -1
  129. package/src/assets/web-panel/assets/{motion-CApYRlHW.js → motion-DzZPc4Mq.js} +1 -1
  130. package/src/assets/web-panel/assets/{move-DaNa9bnr.js → move-D6R8EIjz.js} +1 -1
  131. package/src/assets/web-panel/assets/{omit-1hODPLMf.js → omit-CPniUUR1.js} +1 -1
  132. package/src/assets/web-panel/assets/{pickAttrs-CGoof33k.js → pickAttrs-DbzxHNNa.js} +1 -1
  133. package/src/assets/web-panel/assets/{placementArrow-DNYKbOwM.js → placementArrow-B_MxmwXz.js} +1 -1
  134. package/src/assets/web-panel/assets/{responsiveObserve-jNLseSbH.js → responsiveObserve-Em-jKJ7U.js} +1 -1
  135. package/src/assets/web-panel/assets/{slide-BSE3l28J.js → slide-B2RV1mQl.js} +1 -1
  136. package/src/assets/web-panel/assets/{statusUtils-BXb-XPpL.js → statusUtils-C9Ps6HQe.js} +1 -1
  137. package/src/assets/web-panel/assets/{styleChecker-BcI1njah.js → styleChecker-DCoehh1S.js} +1 -1
  138. package/src/assets/web-panel/assets/{useFlexGapSupport-gth2MaoX.js → useFlexGapSupport-DZOaLVto.js} +1 -1
  139. package/src/assets/web-panel/assets/{useFs-BV43tE6b.js → useFs-Dk_JA91R.js} +1 -1
  140. package/src/assets/web-panel/assets/{usePersonalDataHub-DoxkcYXB.js → usePersonalDataHub-CJR6Dqtz.js} +1 -1
  141. package/src/assets/web-panel/assets/{vnode-DR3PK0G0.js → vnode-BaFNaDQL.js} +1 -1
  142. package/src/assets/web-panel/assets/{zoom-pAqsaWRe.js → zoom-CxA9IYpM.js} +1 -1
  143. package/src/assets/web-panel/index.html +1 -1
  144. package/src/harness/mock-llm-provider.js +14 -0
  145. package/src/lib/pdh-bridge.js +266 -0
  146. package/src/lib/repl-completer.js +5 -1
  147. package/src/lib/skill-mcp.js +10 -4
  148. package/src/runtime/agent-core.js +25 -0
  149. package/src/runtime/mcp-config.js +104 -3
  150. package/src/assets/web-panel/assets/MobileProjects-PMnBid2r.js +0 -1
  151. package/src/assets/web-panel/assets/OrderTableRenderer-Dkl3Cygy.js +0 -1
  152. package/src/assets/web-panel/assets/Terminal-YOv7bl3H.js +0 -3
  153. package/src/assets/web-panel/assets/devWarning-BHFLT7gP.js +0 -1
  154. package/src/assets/web-panel/assets/index-BqIi56n5.js +0 -1
  155. package/src/assets/web-panel/assets/index-DZOHzIMy.js +0 -1
@@ -128,8 +128,12 @@ export function makeAtCompleter(opts = {}) {
128
128
  });
129
129
  };
130
130
 
131
+ // De-duplicate before sorting so a drifted/aliased entry in the hand-
132
+ // maintained command list never shows twice in the autocomplete (mirrors the
133
+ // @-path's `new Set` merge below; Claude-Code 2.1.183 fixed the same class of
134
+ // duplicate-in-slash-autocomplete bug).
131
135
  const slashCommands = Array.isArray(opts.slashCommands)
132
- ? [...opts.slashCommands].sort()
136
+ ? [...new Set(opts.slashCommands)].sort()
133
137
  : [];
134
138
 
135
139
  const completer = (line) => {
@@ -118,10 +118,16 @@ export async function mountSkillMcpServers(mcpClient, skill, opts = {}) {
118
118
  for (const server of declared) {
119
119
  const normalized = validateMcpServerConfig(server);
120
120
  if (!normalized) {
121
- skipped.push({
122
- name: server?.name || "(invalid)",
123
- error: "invalid config",
124
- });
121
+ const name = server?.name || "(invalid)";
122
+ skipped.push({ name, error: "invalid config" });
123
+ // Surface invalid configs too — previously only connect FAILURES warned,
124
+ // so a malformed server config was dropped silently and the skill author
125
+ // never learned why their MCP server didn't mount.
126
+ if (typeof opts.onWarn === "function") {
127
+ opts.onWarn(
128
+ `[skill-mcp] Skipped "${name}" for skill "${skill?.id || skill?.name}": invalid config`,
129
+ );
130
+ }
125
131
  continue;
126
132
  }
127
133
  try {
@@ -3838,6 +3838,11 @@ export async function* agentLoop(messages, options) {
3838
3838
  // True once a Stop hook has forced a continuation — passed to the next Stop
3839
3839
  // hook as `stop_hook_active` so a well-behaved hook won't block forever.
3840
3840
  let stopHookActive = false;
3841
+ // True once we have already re-prompted a thinking-only turn (a turn that
3842
+ // produced extended-thinking but no visible text and no tool calls). The
3843
+ // one-shot guard means a model that keeps returning empty turns completes
3844
+ // rather than looping forever (the iteration budget is the hard backstop).
3845
+ let emptyThinkingReprompted = false;
3841
3846
 
3842
3847
  while (budget.hasRemaining()) {
3843
3848
  budget.consume();
@@ -4036,6 +4041,26 @@ export async function* agentLoop(messages, options) {
4036
4041
  .join("")
4037
4042
  .trim()
4038
4043
  : "";
4044
+ // Claude Code 2.1.183 parity: a turn that produced ONLY extended-thinking
4045
+ // (no visible text, no tool calls) would otherwise complete silently with
4046
+ // an empty answer — the user sees nothing. Re-prompt the model ONCE to
4047
+ // surface its actual response. Mirrors the Stop-hook continuation path
4048
+ // below (push assistant turn + a user nudge, then continue). Scoped to the
4049
+ // thinking-only case so a genuinely empty completion (no thinking) still
4050
+ // ends instead of looping.
4051
+ const _contentEmpty = !String(msg.content || "").trim();
4052
+ if (_contentEmpty && _thinking && !emptyThinkingReprompted) {
4053
+ emptyThinkingReprompted = true;
4054
+ messages.push({ role: "assistant", content: "" });
4055
+ messages.push({
4056
+ role: "user",
4057
+ content:
4058
+ "You ended your turn with only internal reasoning and no visible " +
4059
+ "response. Please provide your actual answer now.",
4060
+ });
4061
+ yield { type: "empty-thinking-reprompt", runId };
4062
+ continue;
4063
+ }
4039
4064
  yield {
4040
4065
  type: "response-complete",
4041
4066
  content: msg.content || "",
@@ -23,6 +23,11 @@ import {
23
23
  ideServerToMcpConfig,
24
24
  isInIdeTerminal,
25
25
  } from "../lib/ide-bridge.js";
26
+ import {
27
+ discoverPdhServer,
28
+ pdhServerToMcpConfig,
29
+ isInPdhTerminal,
30
+ } from "../lib/pdh-bridge.js";
26
31
 
27
32
  /**
28
33
  * Normalize a parsed config object into a `{ name: serverConfig }` map.
@@ -55,6 +60,31 @@ export function mcpToolName(server, tool) {
55
60
  return `mcp__${server}__${tool}`;
56
61
  }
57
62
 
63
+ /**
64
+ * When an MCP connect fails with an authentication error (HTTP 401/403, or an
65
+ * explicit Unauthorized/Forbidden) on a URL-based server, return an actionable
66
+ * one-line hint pointing the user at `cc mcp login`. Returns null for non-auth
67
+ * errors or stdio servers (no url). cc's mcp-client throws `HTTP 401: …` /
68
+ * `HTTP 403: …` from its transport on these — the common path for an MCP server
69
+ * that requires OAuth but has no stored token (Claude-Code 2.1.183 surfaced the
70
+ * same auth-required class; cc already exposes no tools from such a server, so
71
+ * the residual gap was the missing actionable guidance).
72
+ *
73
+ * @param {string|undefined} url the server's `url` (stdio servers pass none)
74
+ * @param {string} errMessage the thrown connect error message
75
+ * @returns {string|null}
76
+ */
77
+ export function mcpAuthHint(url, errMessage) {
78
+ if (!url) return null;
79
+ const m = String(errMessage || "");
80
+ const isAuth =
81
+ /\bHTTP\s*40[13]\b/i.test(m) ||
82
+ /\bunauthor/i.test(m) ||
83
+ /\bforbidden\b/i.test(m);
84
+ if (!isAuth) return null;
85
+ return ` → "${url}" requires authentication; run: cc mcp login ${url}\n`;
86
+ }
87
+
58
88
  /**
59
89
  * Connect the given servers and build the agent-loop wiring. Connection
60
90
  * failures are reported (writeErr) but never abort the run — a broken server
@@ -126,12 +156,26 @@ export async function setupMcpFromConfig(servers, deps = {}) {
126
156
  try {
127
157
  res = await mcpClient.connect(name, connectCfg);
128
158
  } catch (err) {
129
- writeErr(` mcp: failed to connect "${name}": ${err.message}\n`);
159
+ let line = ` mcp: failed to connect "${name}": ${err.message}\n`;
160
+ const hint = mcpAuthHint(cfg.url, err.message);
161
+ if (hint) line += hint;
162
+ writeErr(line);
130
163
  continue;
131
164
  }
132
165
  const tools = Array.isArray(res?.tools) ? res.tools : [];
133
166
  const resources = Array.isArray(res?.resources) ? res.resources : [];
134
167
  const prompts = Array.isArray(res?.prompts) ? res.prompts : [];
168
+ // A server can connect (initialize OK) yet have its tools/list fail — the
169
+ // mcp-client surfaces that as `res.toolsError` (Claude-Code 2.1.181
170
+ // "Connected · tools fetch failed"). Don't let it pass as a silent
171
+ // "0 tools": report it, and if the fetch failed on auth (401/403), reuse the
172
+ // same actionable `cc mcp login` hint as the connect-failure path.
173
+ if (res?.toolsError) {
174
+ let line = ` mcp: "${name}" connected but tools fetch failed: ${res.toolsError}\n`;
175
+ const hint = mcpAuthHint(cfg.url, res.toolsError);
176
+ if (hint) line += hint;
177
+ writeErr(line);
178
+ }
135
179
  connected.push({
136
180
  server: name,
137
181
  tools: tools.length,
@@ -377,6 +421,48 @@ export async function loadIdeMcp(opts = {}, deps = {}) {
377
421
  return out;
378
422
  }
379
423
 
424
+ /**
425
+ * Discover a running PDH bridge (the Android app's device-capability MCP server)
426
+ * and connect it as the reserved server `pdh`. Best-effort: returns `deps.into`
427
+ * (or null) on nothing found / bad config, never throws. An explicit user
428
+ * registration of a server named `pdh` wins — PDH auto-discovery yields with a
429
+ * one-line warning. Reserved name `pdh` → tools `mcp__pdh__*`.
430
+ *
431
+ * Mirrors loadIdeMcp, but PDH has no workspace concept (a device has one
432
+ * server): env CHAINLESSCHAIN_PDH_PORT fast-path, else the newest live lock.
433
+ *
434
+ * @param {object} opts { env?, force? }
435
+ * @param {object} [deps] { writeErr, into, discoverPdhServer, pdhServerToMcpConfig }
436
+ */
437
+ export async function loadPdhMcp(opts = {}, deps = {}) {
438
+ const discover = deps.discoverPdhServer || discoverPdhServer;
439
+ const toCfg = deps.pdhServerToMcpConfig || pdhServerToMcpConfig;
440
+ const lock = discover({ env: opts.env, force: opts.force === true });
441
+ if (!lock) return deps.into || null;
442
+ if (deps.into?.mcpClient?.servers?.has?.("pdh")) {
443
+ (deps.writeErr || (() => {}))(
444
+ ` pdh: server "pdh" already registered explicitly — ` +
445
+ `skipping PDH auto-discovery\n`,
446
+ );
447
+ return deps.into;
448
+ }
449
+ const cfg = toCfg(lock);
450
+ if (!cfg) return deps.into || null;
451
+ const out = await setupMcpFromConfig({ pdh: cfg }, deps);
452
+ // Hot reconnect: the app restarts its bridge on a NEW port + token (process
453
+ // restart / sentinel re-extract). Register a reconnector so a failed
454
+ // mcp__pdh__* call re-scans the lockfiles mid-session and retries — the stale
455
+ // CHAINLESSCHAIN_PDH_PORT no longer matches a live lock, so discovery falls
456
+ // through to the newest live lock (exactly the restarted instance).
457
+ if (out?.mcpClient?.setReconnector) {
458
+ out.mcpClient.setReconnector("pdh", () => {
459
+ const fresh = discover({ env: opts.env, force: opts.force === true });
460
+ return fresh ? toCfg(fresh) : null;
461
+ });
462
+ }
463
+ return out;
464
+ }
465
+
380
466
  /**
381
467
  * Discover + connect a project-scoped `.mcp.json` (Claude-Code parity). Reads a
382
468
  * `.mcp.json` from the git project root (walked up from cwd, same as the
@@ -450,14 +536,15 @@ export async function loadProjectMcp(opts = {}, deps = {}) {
450
536
  * IDE discovery: default ON only inside an IDE integrated terminal; `ide:true`
451
537
  * (`--ide`) forces it; `ide:false` (`--no-ide`) disables it.
452
538
  *
453
- * @param {object} args { mcpConfigPath?, db?, includeRegistered=true, allRegistered=false, ide?, cwd?, env? }
454
- * @param {object} [deps] { writeErr, loadMcpConfig, loadRegisteredMcp, loadIdeMcp, isInIdeTerminal }
539
+ * @param {object} args { mcpConfigPath?, db?, includeRegistered=true, allRegistered=false, ide?, pdh?, cwd?, env? }
540
+ * @param {object} [deps] { writeErr, loadMcpConfig, loadRegisteredMcp, loadIdeMcp, loadPdhMcp, isInIdeTerminal, isInPdhTerminal }
455
541
  */
456
542
  export async function resolveAgentMcp(args = {}, deps = {}) {
457
543
  const doFile = deps.loadMcpConfig || loadMcpConfig;
458
544
  const doReg = deps.loadRegisteredMcp || loadRegisteredMcp;
459
545
  const doProject = deps.loadProjectMcp || loadProjectMcp;
460
546
  const doIde = deps.loadIdeMcp || loadIdeMcp;
547
+ const doPdh = deps.loadPdhMcp || loadPdhMcp;
461
548
  // Thread the agent session id down to setupMcpFromConfig so spawned stdio MCP
462
549
  // servers get CC_SESSION_ID / CLAUDE_CODE_SESSION_ID (Claude-Code parity).
463
550
  const fwd =
@@ -500,6 +587,20 @@ export async function resolveAgentMcp(args = {}, deps = {}) {
500
587
  );
501
588
  }
502
589
  }
590
+ // PDH bridge auto-discovery (the Android app's device-capability MCP server).
591
+ // Same gating shape as IDE: default ON only when env-wired (app-spawned cc),
592
+ // `pdh:true` (--pdh) forces it, `pdh:false` (--no-pdh) disables it. Reserved
593
+ // name `pdh` → mcp__pdh__*. Skipped under --strict-mcp-config (returned above).
594
+ if (args.pdh !== false) {
595
+ const env = args.env || process.env;
596
+ const inPdh = (deps.isInPdhTerminal || isInPdhTerminal)(env);
597
+ if (args.pdh === true || inPdh) {
598
+ result = await doPdh(
599
+ { env, force: args.pdh === true },
600
+ { ...fwd, into: result || undefined },
601
+ );
602
+ }
603
+ }
503
604
  return result;
504
605
  }
505
606
 
@@ -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-Dkd8hCt6.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"),P=n("a-empty"),j=n("a-card");return h(),g("div",x,[l(j,null,{default:r(()=>[l(P,{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-GoHooA/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 o}from"./vendor-BvqAck49.js";import{_ as S}from"./index-Dkd8hCt6.js";import"./icons-DP3uiYxy.js";const k={__name:"OrderTableRenderer",props:{event:{type:Object,required:!0}},setup(p,{expose:r}){r();const a=p,e=o(()=>a.event.content||{}),d=o(()=>a.event.extra||{}),m=o(()=>d.value.merchant||e.value.merchant||e.value.counterparty||"—"),c=o(()=>e.value.title||e.value.name||e.value.itemName||e.value.text||"—"),y=o(()=>{const t=e.value.amount??e.value.price??e.value.total;return t==null?"—":`${e.value.currency||"¥"} ${typeof t=="number"?t.toFixed(2):t}`}),T=o(()=>d.value.orderNo||e.value.orderNo||e.value.orderId),f=o(()=>e.value.status||e.value.state),b=o(()=>{const t=(f.value||"").toLowerCase();return t.includes("成功")||t.includes("succe")||t.includes("paid")?"green":t.includes("退")||t.includes("refund")?"orange":t.includes("失败")||t.includes("fail")?"red":"default"}),h=o(()=>{if(!a.event.occurredAt)return"";const t=new Date(a.event.occurredAt);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}),x={props:a,c:e,e:d,merchantText:m,itemText:c,amountText:y,orderNo:T,statusText:f,statusColor:b,formattedTime:h,computed:o};return Object.defineProperty(x,"__isScriptSetup",{enumerable:!1,value:!0}),x}},N={class:"order-card"},C={class:"head"},O={class:"time"},V={class:"row"},R={class:"val"},A={class:"row"},B={class:"val"},D={class:"row amount-row"},I={class:"val amount"},j={key:0,class:"row"},F={class:"val mono"},H={key:1,class:"row"};function M(p,r,a,e,d,m){const c=w("a-tag");return l(),u("div",N,[s("div",C,[s("span",O,n(e.formattedTime),1),i(c,{color:"gold"},{default:v(()=>[_(n(a.event.source.adapter),1)]),_:1}),i(c,null,{default:v(()=>[_(n(a.event.subtype),1)]),_:1})]),s("div",V,[r[0]||(r[0]=s("span",{class:"key"},"商户",-1)),s("span",R,n(e.merchantText),1)]),s("div",A,[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",j,[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",H,[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 J=S(k,[["render",M],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-GoHooA/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{J 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-Dkd8hCt6.js";import{I as z,J as x,U as _,Q as D,S as J,K as T,V as R,c as A,F as K,Z as Q,R as E,o as Y,f as Z,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 H of v)m.write(H.data),t.lastSeq=H.seq}catch(v){m.writeln(`\x1B[31m[history fetch failed: ${v?.message||v}]\x1B[0m`)}const G=new ResizeObserver(()=>{try{P.fit(),s.resize(t.id,m.cols,m.rows).catch(()=>{})}catch{}});G.observe(b);const ue=t.offs;t.offs=()=>{try{G.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}}Y(async()=>{await X()}),Z(()=>{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:Y,onBeforeUnmount:Z,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(),J(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(),J(a,{key:0,message:e.error,type:"error","show-icon":"",closable:"",style:{"margin-bottom":"12px"},onClose:o[1]||(o[1]=r=>e.error="")},null,8,["message"])):R("v-if",!0),_("div",Ae,[_("div",Ee,[(y(!0),x(K,null,Q(e.sessions,r=>(y(),x("div",{key:r.id,class:ve(["session-tab",{active:r.id===e.activeId,dead:!r.alive}]),onClick:h=>e.activate(r.id)},[_("span",Te,E(r.shell),1),_("span",Re,E(e.shortId(r.id)),1),A(e.CloseOutlined,{class:"session-close",onClick:we(h=>e.onClose(r.id),["stop"])},null,8,["onClick"])],10,Oe))),128)),e.sessions.length===0?(y(),x("div",Me,' 点击 "新会话" 创建第一个终端 ')):R("v-if",!0)]),_("div",ze,[(y(!0),x(K,null,Q(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-GoHooA/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
@@ -1 +0,0 @@
1
- import{O as r}from"./index-Dkd8hCt6.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
@@ -1 +0,0 @@
1
- import{A as o}from"./Row-BEX1Dblk.js";import{U as t}from"./index-Dkd8hCt6.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-jNLseSbH.js";import"./useFlexGapSupport-gth2MaoX.js";import"./styleChecker-BcI1njah.js";import"./index-ChTfizrh.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-DyUt1sFI.js";import{U as t}from"./index-Dkd8hCt6.js";import"./vendor-BvqAck49.js";import"./index-ChTfizrh.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};