chainlesschain 0.162.70 → 0.162.71

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 (154) hide show
  1. package/package.json +2 -2
  2. package/src/assets/web-panel/assets/{AIOps-CnHIXe2L.js → AIOps-pes7_jGr.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-CzDyhTAp.js → ActionButton-DiHWdeH1.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-rwvDMCd-.js → Analytics-C51UX-V_.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-D-Q1M-5V.js → AppLayout-BE6LJLw9.js} +5 -5
  6. package/src/assets/web-panel/assets/{Audit-BIFSGnAE.js → Audit-CtTkLTe2.js} +1 -1
  7. package/src/assets/web-panel/assets/{Backup-CbUdiVeS.js → Backup-lmpVwPxc.js} +1 -1
  8. package/src/assets/web-panel/assets/{BaseInput-D3P_pICH.js → BaseInput-Dr7DR1E1.js} +1 -1
  9. package/src/assets/web-panel/assets/{Chat-DRrX7vVB.js → Chat-DXph6klA.js} +6 -6
  10. package/src/assets/web-panel/assets/{ChatBubbleRenderer-DTC1ElV-.js → ChatBubbleRenderer-RefrXxqp.js} +1 -1
  11. package/src/assets/web-panel/assets/{Checkbox-Dpq9X8Xd.js → Checkbox-BF0aS5R9.js} +1 -1
  12. package/src/assets/web-panel/assets/{Codegen-yQQOSuHA.js → Codegen-B-oHWNTV.js} +1 -1
  13. package/src/assets/web-panel/assets/{Col-DLFLDxar.js → Col-B6KdyRTE.js} +1 -1
  14. package/src/assets/web-panel/assets/{Community-DYbdX-GB.js → Community-D5ac0KyO.js} +1 -1
  15. package/src/assets/web-panel/assets/{Compact-Dclrp1HE.js → Compact-Dc61O2eQ.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compliance-C9EQMgoP.js → Compliance-a48qvNmd.js} +1 -1
  17. package/src/assets/web-panel/assets/{Cowork-B9IMFsMk.js → Cowork-CIF9lSRj.js} +3 -3
  18. package/src/assets/web-panel/assets/{Cron-V6TlbDey.js → Cron-C_gkf4xd.js} +2 -2
  19. package/src/assets/web-panel/assets/{Crosschain-Cl_vG8R_.js → Crosschain-CJt15PzW.js} +1 -1
  20. package/src/assets/web-panel/assets/{DID-DoUUF9cz.js → DID-D8I_okEj.js} +2 -2
  21. package/src/assets/web-panel/assets/{Dashboard-DcA8WmrS.js → Dashboard-O4q-qCF2.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dropdown-wyGMYzw9.js → Dropdown-flRziiaw.js} +1 -1
  23. package/src/assets/web-panel/assets/{EmailListRenderer-B1T3ziIH.js → EmailListRenderer-CnnkfGPw.js} +1 -1
  24. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CW4CwYbZ.js → FamilyGuardDashboard-CYAJpGqd.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-9tEiw0KA.js → Federation-Dm3WqzQ_.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-DbocfnNQ.js → FormItemContext-CpAIter6.js} +1 -1
  27. package/src/assets/web-panel/assets/{GenericCardRenderer-CGNsG2qI.js → GenericCardRenderer-ChzXcyuN.js} +1 -1
  28. package/src/assets/web-panel/assets/{Git-BxA3dgT8.js → Git-DElmMsL4.js} +2 -2
  29. package/src/assets/web-panel/assets/{Governance-DqnhaC7n.js → Governance-EWmgn9io.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-D6Ll4t9c.js → Inference-VtOR_sef.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-Bb8IXGl7.js → KnowledgeGraph-OMqlGkMR.js} +1 -1
  32. package/src/assets/web-panel/assets/Logs-CTgYDsTZ.js +2 -0
  33. package/src/assets/web-panel/assets/{Marketplace-BYRM186w.js → Marketplace-DZIUTbn8.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-DLbh7uS8.js → McpTools-DWeOErCA.js} +3 -3
  35. package/src/assets/web-panel/assets/{Memory-D2_uZEOI.js → Memory-DwFBp-ev.js} +2 -2
  36. package/src/assets/web-panel/assets/{MobileBridge-CXVJoMKk.js → MobileBridge-D42xBfE3.js} +2 -2
  37. package/src/assets/web-panel/assets/{MobileProjects-QRZYgIME.js → MobileProjects-BHCHauUl.js} +1 -1
  38. package/src/assets/web-panel/assets/{Mtc-D3mv30gW.js → Mtc-CabnNsyS.js} +4 -4
  39. package/src/assets/web-panel/assets/{MtcAudit-__QPus22.js → MtcAudit-Ddx9Awu5.js} +2 -2
  40. package/src/assets/web-panel/assets/{Multisig-Bu5gaTn6.js → Multisig-CJpYBZ8f.js} +3 -3
  41. package/src/assets/web-panel/assets/{NLProgramming-SjaViyfR.js → NLProgramming-BvPJskVG.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-feXsl0dN.js → Notes-92ELvJM2.js} +3 -3
  43. package/src/assets/web-panel/assets/{NotificationSettings-BtVFokbM.js → NotificationSettings-CXz0SUzP.js} +1 -1
  44. package/src/assets/web-panel/assets/OrderTableRenderer-4iWRkMr-.js +1 -0
  45. package/src/assets/web-panel/assets/{Organization-CewL60Rd.js → Organization-DblqJPeY.js} +4 -4
  46. package/src/assets/web-panel/assets/{Overflow-2ZRChJ7E.js → Overflow-CHfS3HwD.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-DuMr6G9y.js → P2P-DIg0pLIG.js} +2 -2
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-BMOcHCWd.js → PdhVaultBrowser-BhD3DGjk.js} +3 -3
  49. package/src/assets/web-panel/assets/{Permissions-Cj94ql75.js → Permissions-Ct7bwrz8.js} +4 -4
  50. package/src/assets/web-panel/assets/{PersonalDataHub-BYK4mlk7.js → PersonalDataHub-DG9c1eas.js} +4 -4
  51. package/src/assets/web-panel/assets/{Pipeline-maRvdrbO.js → Pipeline-BwQnEqG0.js} +1 -1
  52. package/src/assets/web-panel/assets/{Privacy-CKb2zZJz.js → Privacy-BvWaf-Ba.js} +1 -1
  53. package/src/assets/web-panel/assets/{ProjectInit-C2pfXv4l.js → ProjectInit-BFzMHtiW.js} +2 -2
  54. package/src/assets/web-panel/assets/{ProjectSettings-DGeNwq0h.js → ProjectSettings-DDpokSpH.js} +2 -2
  55. package/src/assets/web-panel/assets/{Projects-BRypTQUV.js → Projects-3IL8lyPl.js} +1 -1
  56. package/src/assets/web-panel/assets/{Providers-DYwMPXEO.js → Providers-C6BsEzSR.js} +1 -1
  57. package/src/assets/web-panel/assets/{QuickAsk-DE6isYZV.js → QuickAsk-Mh6690Ey.js} +1 -1
  58. package/src/assets/web-panel/assets/{Recommend-Rc-AE6y9.js → Recommend-CJbZ6wgA.js} +1 -1
  59. package/src/assets/web-panel/assets/{Reputation-DDQ8_kmM.js → Reputation-GDcyl6iQ.js} +1 -1
  60. package/src/assets/web-panel/assets/{Row-Do5iQUFj.js → Row-6p4DKFSi.js} +1 -1
  61. package/src/assets/web-panel/assets/{RssFeed-cxG0ulSw.js → RssFeed-BLhrkoDq.js} +3 -3
  62. package/src/assets/web-panel/assets/{Search-D3-8EdNk.js → Search-Ckiyt35t.js} +1 -1
  63. package/src/assets/web-panel/assets/{Security-DtBfws1D.js → Security-qhh-B5Qt.js} +4 -4
  64. package/src/assets/web-panel/assets/{Services-DzeN8HsG.js → Services-D7a2OwKm.js} +2 -2
  65. package/src/assets/web-panel/assets/{Skeleton-BQCVeTUf.js → Skeleton-CSMxupKd.js} +1 -1
  66. package/src/assets/web-panel/assets/Skills-CGpMng8w.js +1 -0
  67. package/src/assets/web-panel/assets/{Sla-d2IOd-AA.js → Sla-CYtaU3Ar.js} +1 -1
  68. package/src/assets/web-panel/assets/{SpeechSettings-BjfopwT6.js → SpeechSettings-BTCsu1uM.js} +1 -1
  69. package/src/assets/web-panel/assets/{SyncSettings-D5_c1_rI.js → SyncSettings-Cnzx2L5I.js} +2 -2
  70. package/src/assets/web-panel/assets/Tasks-BhnGtqaZ.js +1 -0
  71. package/src/assets/web-panel/assets/{Templates-CCXFgNy3.js → Templates-Ccdx_C3w.js} +1 -1
  72. package/src/assets/web-panel/assets/{Tenant-Duz6eEK3.js → Tenant-ZN8c86j3.js} +1 -1
  73. package/src/assets/web-panel/assets/Terminal-BfgM0oyN.js +3 -0
  74. package/src/assets/web-panel/assets/{TimelineRenderer-Du5jKHJz.js → TimelineRenderer-CjgirE9d.js} +1 -1
  75. package/src/assets/web-panel/assets/{Tokens-B12vLtQm.js → Tokens-QoRpi6Wf.js} +1 -1
  76. package/src/assets/web-panel/assets/{Trigger-s_pHOerx.js → Trigger-CEQKJkhs.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trust-4sDhbAls.js → Trust-UTuAzV1q.js} +1 -1
  78. package/src/assets/web-panel/assets/{UkeySign-UeyFknip.js → UkeySign-JDs9I7fl.js} +1 -1
  79. package/src/assets/web-panel/assets/{VideoEditing-DsopM2S5.js → VideoEditing-BACYQQSd.js} +1 -1
  80. package/src/assets/web-panel/assets/{Wallet-CreLjC5U.js → Wallet-C-SKluhH.js} +4 -4
  81. package/src/assets/web-panel/assets/{WebAuthn-CBuMMZbK.js → WebAuthn-9chizTFy.js} +5 -5
  82. package/src/assets/web-panel/assets/{WorkflowEditor-DWhHHSFW.js → WorkflowEditor-0mF-LAUo.js} +1 -1
  83. package/src/assets/web-panel/assets/{chat-Iurq_BMY.js → chat-Di7QINiP.js} +1 -1
  84. package/src/assets/web-panel/assets/{colors-BIOTIa89.js → colors-SBmhHMM9.js} +1 -1
  85. package/src/assets/web-panel/assets/{compact-item-B7lPu9pO.js → compact-item-BmbETbNj.js} +1 -1
  86. package/src/assets/web-panel/assets/{createContext-Bzzk7mrh.js → createContext-C7hFnsJ7.js} +1 -1
  87. package/src/assets/web-panel/assets/devWarning-gNvbyy4j.js +1 -0
  88. package/src/assets/web-panel/assets/{hasIn-B11xqp5O.js → hasIn-CFtthKDD.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-CA-GPOd9.js → index-B4etIqbf.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-DwGVPCZb.js → index-BCcCs7LJ.js} +1 -1
  91. package/src/assets/web-panel/assets/index-BNXpMnIY.js +1 -0
  92. package/src/assets/web-panel/assets/{index-htxy7qDG.js → index-BT2uOwmA.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-DX7HGwP_.js → index-BcRTX_WO.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-B4rXFIOG.js → index-BcawAm_i.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DsoyfOzW.js → index-Bpo7UVJe.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-D8tm9JnQ.js → index-C07kpleB.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DEKeoJ6I.js → index-C2CN7coN.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Dn_Ht3v2.js → index-C2fhXmhW.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-C-lwsB2F.js → index-C6tZzsb9.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-R-YSpvg4.js → index-CNpb8m5a.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-6QGNBg3m.js → index-CSnTUPQx.js} +3 -3
  102. package/src/assets/web-panel/assets/{index-DMrzHgE6.js → index-CWDk3nDZ.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CzY2mdiR.js → index-CcBhsVYn.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-tub9w6us.js → index-CgXQwqXr.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CxDOX4g6.js → index-Cib-RTws.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CLhpFnSR.js → index-ClIp4Vin.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CCxGEK8b.js → index-CovTrPpI.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-B93pM-xx.js → index-D0yO3vWh.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BlR8YVlt.js → index-D134XFWR.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-vZCGFSJN.js → index-D6vNUp6c.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-5BkUKVyj.js → index-D8CeUlN0.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CS2UWrIt.js → index-DEYnWiq1.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BgmBZgU9.js → index-DI2xH1fU.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CEKRqrI-.js → index-DRBc1Ewn.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-D25-u3Q2.js → index-DWfObC0n.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BVIXYV1R.js → index-Dk4ez5rf.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BLREN4NE.js → index-Dps9xdE8.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-3LgeP4ij.js → index-Dww6gCzI.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BIFscFlm.js → index-NxxQTlPJ.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Y4gmywZo.js → index-PN02VlUB.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-AmHa_sOB.js → index-WjZVyLn7.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DyV9331f.js → index-_a2NG3iP.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CULCwI_H.js → index-_hO8-EnW.js} +1 -1
  124. package/src/assets/web-panel/assets/index-gfHxqT1Q.js +1 -0
  125. package/src/assets/web-panel/assets/{index-D6q-fkXs.js → index-lRVjtXeH.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CiXNVmcx.js → index-sA4vr5WV.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-C4wV32Dn.js → index-sz0w-D-C.js} +1 -1
  128. package/src/assets/web-panel/assets/{initDefaultProps-Bl6klCzd.js → initDefaultProps-B1zCwkvT.js} +1 -1
  129. package/src/assets/web-panel/assets/{motion-B9IxS1-S.js → motion-BDGIV9KA.js} +1 -1
  130. package/src/assets/web-panel/assets/{move-NJ5XDNQe.js → move-BITqgluK.js} +1 -1
  131. package/src/assets/web-panel/assets/{omit-ByO8GI_H.js → omit-uD97QKBF.js} +1 -1
  132. package/src/assets/web-panel/assets/{pickAttrs-W6iTcLuH.js → pickAttrs-CZpXhSIE.js} +1 -1
  133. package/src/assets/web-panel/assets/{placementArrow-JMndCFEP.js → placementArrow-ByUvT_08.js} +1 -1
  134. package/src/assets/web-panel/assets/{responsiveObserve-DHV7-FuY.js → responsiveObserve-BQG9LlBs.js} +1 -1
  135. package/src/assets/web-panel/assets/{slide-DioRUeNF.js → slide-Bx9TyeEE.js} +1 -1
  136. package/src/assets/web-panel/assets/{statusUtils-DMp2b9Ze.js → statusUtils-XWaMqYM8.js} +1 -1
  137. package/src/assets/web-panel/assets/{styleChecker-DamP5BTS.js → styleChecker-BZ-nMyDB.js} +1 -1
  138. package/src/assets/web-panel/assets/{useFlexGapSupport-D338iARz.js → useFlexGapSupport-D_iwA3vx.js} +1 -1
  139. package/src/assets/web-panel/assets/{useFs-DE_HJgk6.js → useFs-DuvW_aRX.js} +1 -1
  140. package/src/assets/web-panel/assets/{usePersonalDataHub-914YxO9q.js → usePersonalDataHub-BO7orS0d.js} +1 -1
  141. package/src/assets/web-panel/assets/{vnode-CY39Ky7P.js → vnode-Cc_fqAL4.js} +1 -1
  142. package/src/assets/web-panel/assets/{zoom-BEghlCth.js → zoom-BGkBp90M.js} +1 -1
  143. package/src/assets/web-panel/index.html +1 -1
  144. package/src/lib/cowork-workflow.js +344 -30
  145. package/src/lib/hook-manager.js +3 -2
  146. package/src/lib/workflow-state-reader.js +10 -1
  147. package/src/assets/web-panel/assets/Logs-DRUUVMdc.js +0 -2
  148. package/src/assets/web-panel/assets/OrderTableRenderer-CJJ2GWDf.js +0 -1
  149. package/src/assets/web-panel/assets/Skills-D6mCVKt7.js +0 -1
  150. package/src/assets/web-panel/assets/Tasks-BCmxDMZx.js +0 -1
  151. package/src/assets/web-panel/assets/Terminal-Buc6UbYo.js +0 -3
  152. package/src/assets/web-panel/assets/devWarning-CuIq7zBB.js +0 -1
  153. package/src/assets/web-panel/assets/index-BRsns-SP.js +0 -1
  154. package/src/assets/web-panel/assets/index-QTuoOvJA.js +0 -1
@@ -8,7 +8,7 @@
8
8
  // Injected by web-ui-server.js at serve time
9
9
  window.__CC_CONFIG__ = __CC_CONFIG_PLACEHOLDER__;
10
10
  </script>
11
- <script type="module" crossorigin src="./assets/index-6QGNBg3m.js"></script>
11
+ <script type="module" crossorigin src="./assets/index-CSnTUPQx.js"></script>
12
12
  <link rel="modulepreload" crossorigin href="./assets/vendor-BvqAck49.js">
13
13
  <link rel="modulepreload" crossorigin href="./assets/icons-DP3uiYxy.js">
14
14
  <link rel="stylesheet" crossorigin href="./assets/index-Cq93VfoF.css">
@@ -36,6 +36,9 @@ import { evaluate as evalExpr, resolveReference } from "./workflow-expr.js";
36
36
  /** Maximum number of items a single forEach step can expand into. */
37
37
  export const MAX_FAN_OUT = 500;
38
38
 
39
+ /** Absolute ceiling on a single loop step's iterations (infinite-loop guard). */
40
+ export const MAX_LOOP_ITERATIONS = 100;
41
+
39
42
  export const _deps = {
40
43
  existsSync,
41
44
  mkdirSync,
@@ -46,6 +49,10 @@ export const _deps = {
46
49
  appendFileSync,
47
50
  now: () => Date.now(),
48
51
  runTask: null, // injected by CLI
52
+ // Timer seams (injectable for deterministic retry/timeout tests).
53
+ sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
54
+ setTimeout: (fn, ms) => setTimeout(fn, ms),
55
+ clearTimeout: (t) => clearTimeout(t),
49
56
  };
50
57
 
51
58
  // ─── Paths ───────────────────────────────────────────────────────────────────
@@ -104,6 +111,61 @@ export function validateWorkflow(wf) {
104
111
  );
105
112
  }
106
113
  }
114
+ if (
115
+ s.retries !== undefined &&
116
+ (typeof s.retries !== "number" ||
117
+ !Number.isInteger(s.retries) ||
118
+ s.retries < 0)
119
+ ) {
120
+ errors.push(`steps[${i}].retries must be a non-negative integer`);
121
+ }
122
+ if (
123
+ s.timeoutMs !== undefined &&
124
+ (typeof s.timeoutMs !== "number" ||
125
+ !Number.isFinite(s.timeoutMs) ||
126
+ s.timeoutMs <= 0)
127
+ ) {
128
+ errors.push(`steps[${i}].timeoutMs must be a positive number`);
129
+ }
130
+ if (
131
+ s.retryDelayMs !== undefined &&
132
+ (typeof s.retryDelayMs !== "number" ||
133
+ !Number.isFinite(s.retryDelayMs) ||
134
+ s.retryDelayMs < 0)
135
+ ) {
136
+ errors.push(`steps[${i}].retryDelayMs must be a non-negative number`);
137
+ }
138
+ if (
139
+ s.retryBackoff !== undefined &&
140
+ s.retryBackoff !== "fixed" &&
141
+ s.retryBackoff !== "exponential"
142
+ ) {
143
+ errors.push(
144
+ `steps[${i}].retryBackoff must be "fixed" or "exponential"`,
145
+ );
146
+ }
147
+ const hasWhile = s.loopWhile !== undefined;
148
+ const hasUntil = s.loopUntil !== undefined;
149
+ if (hasWhile && typeof s.loopWhile !== "string") {
150
+ errors.push(`steps[${i}].loopWhile must be a string expression`);
151
+ }
152
+ if (hasUntil && typeof s.loopUntil !== "string") {
153
+ errors.push(`steps[${i}].loopUntil must be a string expression`);
154
+ }
155
+ if (hasWhile && hasUntil) {
156
+ errors.push(`steps[${i}] cannot set both loopWhile and loopUntil`);
157
+ }
158
+ if ((hasWhile || hasUntil) && s.forEach !== undefined) {
159
+ errors.push(`steps[${i}] cannot combine a loop with forEach`);
160
+ }
161
+ if (
162
+ s.maxIterations !== undefined &&
163
+ (typeof s.maxIterations !== "number" ||
164
+ !Number.isInteger(s.maxIterations) ||
165
+ s.maxIterations <= 0)
166
+ ) {
167
+ errors.push(`steps[${i}].maxIterations must be a positive integer`);
168
+ }
107
169
  }
108
170
  // Check dependsOn references exist
109
171
  for (const s of wf.steps) {
@@ -329,12 +391,258 @@ export function removeWorkflow(cwd, id) {
329
391
  return true;
330
392
  }
331
393
 
394
+ // ─── Per-step retry / timeout ─────────────────────────────────────────────────
395
+
396
+ /**
397
+ * Compute the delay (ms) to wait BEFORE a retry, given the just-failed attempt
398
+ * number (1-based). `fixed` returns `retryDelayMs` verbatim; `exponential`
399
+ * doubles it per prior attempt (delay = base · 2^(attempt-1)).
400
+ */
401
+ export function retryDelayFor(step, attempt) {
402
+ const base = Number(step.retryDelayMs) || 0;
403
+ if (base <= 0) return 0;
404
+ if (step.retryBackoff === "exponential") {
405
+ return base * Math.pow(2, attempt - 1);
406
+ }
407
+ return base;
408
+ }
409
+
410
+ /**
411
+ * Race a promise (produced by `factory`) against a per-attempt timeout.
412
+ * Resolves/rejects with the promise when it settles first; rejects with a
413
+ * "timed out" error if the timer fires first. The timer is always cleared, and
414
+ * a late rejection from the losing promise is swallowed to avoid an unhandled
415
+ * rejection (the underlying task is best-effort abandoned — runTask has no
416
+ * cancellation contract).
417
+ */
418
+ export async function withTimeout(factory, timeoutMs) {
419
+ if (!timeoutMs || timeoutMs <= 0) return factory();
420
+ const p = Promise.resolve().then(factory);
421
+ let timer = null;
422
+ const timeout = new Promise((_resolve, reject) => {
423
+ timer = _deps.setTimeout(() => {
424
+ reject(new Error(`step timed out after ${timeoutMs}ms`));
425
+ }, timeoutMs);
426
+ });
427
+ try {
428
+ return await Promise.race([p, timeout]);
429
+ } finally {
430
+ if (timer != null) _deps.clearTimeout(timer);
431
+ p.catch(() => {}); // guard a late rejection from the abandoned task
432
+ }
433
+ }
434
+
435
+ /**
436
+ * Run one step's task with optional `timeoutMs` and `retries` (with `fixed` or
437
+ * `exponential` `retryDelayMs` backoff). An attempt counts as a failure if the
438
+ * task throws, times out, or returns a non-`completed` status. Returns
439
+ * `{ ok, entry?, error?, attempts }`. `attempts` is the total number of tries.
440
+ */
441
+ export async function runStepWithRetry({ step, message, cwd, llmOptions }) {
442
+ const maxRetries = Math.max(0, Math.floor(Number(step.retries) || 0));
443
+ const timeoutMs = Number(step.timeoutMs) || 0;
444
+ let lastEntry = null;
445
+ let lastErr = null;
446
+ for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {
447
+ try {
448
+ const entry = await withTimeout(
449
+ () =>
450
+ _deps.runTask({
451
+ templateId: step.templateId || null,
452
+ userMessage: message,
453
+ files: step.files || [],
454
+ cwd,
455
+ llmOptions,
456
+ }),
457
+ timeoutMs,
458
+ );
459
+ if (entry && entry.status === "completed") {
460
+ return { ok: true, entry, attempts: attempt };
461
+ }
462
+ lastEntry = entry; // ran but not completed → retry-eligible
463
+ lastErr = null;
464
+ } catch (err) {
465
+ lastErr = err; // threw or timed out → retry-eligible
466
+ lastEntry = null;
467
+ }
468
+ if (attempt <= maxRetries) {
469
+ const delay = retryDelayFor(step, attempt);
470
+ if (delay > 0) await _deps.sleep(delay);
471
+ }
472
+ }
473
+ const attempts = maxRetries + 1;
474
+ if (lastEntry) return { ok: false, entry: lastEntry, attempts };
475
+ return { ok: false, error: lastErr, attempts };
476
+ }
477
+
478
+ /** Attach an `attempts` field only when more than one try occurred (keeps the
479
+ * single-attempt result shape byte-identical to the pre-retry behavior). */
480
+ function _withAttempts(result, attempts) {
481
+ if (attempts > 1) return { ...(result || {}), attempts };
482
+ return result;
483
+ }
484
+
485
+ /** Build a single-step outcome object from a `runStepWithRetry` result. */
486
+ function outcomeFromRetry(recordId, r) {
487
+ if (r.ok || r.entry) {
488
+ return {
489
+ id: recordId,
490
+ status: r.entry.status,
491
+ taskId: r.entry.taskId,
492
+ result: _withAttempts(r.entry.result, r.attempts),
493
+ };
494
+ }
495
+ return {
496
+ id: recordId,
497
+ status: "failed",
498
+ taskId: null,
499
+ result: _withAttempts(
500
+ { summary: `Step threw: ${r.error.message}` },
501
+ r.attempts,
502
+ ),
503
+ };
504
+ }
505
+
506
+ // ─── while / until loop nodes ──────────────────────────────────────────────────
507
+
508
+ /** True when a step is a loop node (`loopWhile` or `loopUntil`). */
509
+ export function isLoopStep(step) {
510
+ return step.loopWhile !== undefined || step.loopUntil !== undefined;
511
+ }
512
+
513
+ /** Resolve a loop step's iteration cap, clamped to MAX_LOOP_ITERATIONS. */
514
+ export function loopIterationCap(step) {
515
+ const m = Number(step.maxIterations);
516
+ if (Number.isFinite(m) && m > 0) {
517
+ return Math.min(Math.floor(m), MAX_LOOP_ITERATIONS);
518
+ }
519
+ return MAX_LOOP_ITERATIONS;
520
+ }
521
+
522
+ /**
523
+ * Substitute loop-local tokens in a message template: `${iter}` → the 1-based
524
+ * iteration number, `${self.<field>}` → the step's own most-recent iteration
525
+ * result (empty on the first iteration). Other `${step.<id>.<field>}` tokens
526
+ * are left for `substitutePlaceholders`.
527
+ */
528
+ export function substituteLoopVars(template, { stepId, iter, resultsById }) {
529
+ if (typeof template !== "string") return template;
530
+ let out = template.replace(/\$\{iter\}/g, String(iter));
531
+ out = out.replace(/\$\{self\.([\w-]+)\}/g, (_, field) => {
532
+ const entry = resultsById?.get?.(stepId);
533
+ if (!entry) return "";
534
+ if (field === "summary") return entry.result?.summary ?? "";
535
+ if (field === "status") return entry.status ?? "";
536
+ if (field === "taskId") return entry.taskId ?? "";
537
+ if (field === "iterations") return String(entry.result?.iterations ?? 0);
538
+ if (field === "tokenCount") return String(entry.result?.tokenCount ?? 0);
539
+ const v = entry.result?.[field];
540
+ return v == null ? "" : String(v);
541
+ });
542
+ return out;
543
+ }
544
+
545
+ /**
546
+ * Evaluate whether a loop step should run another iteration (post-test). The
547
+ * condition may reference `${self.<field>}` (the just-stored iteration result)
548
+ * and `${iter}`. `loopWhile` continues while the expression is true; `loopUntil`
549
+ * continues until it becomes true. Throws on a malformed expression.
550
+ */
551
+ export function evalLoopContinue(step, { stepId, iter, resultsById }) {
552
+ const isWhile = step.loopWhile !== undefined;
553
+ const expr = isWhile ? step.loopWhile : step.loopUntil;
554
+ const subst = String(expr)
555
+ .replace(/\$\{iter\}/g, String(iter))
556
+ .replace(/\$\{self\.([\w-]+)\}/g, (_, f) => `\${step.${stepId}.${f}}`);
557
+ const val = evalExpr(subst, { step: resultsById });
558
+ return isWhile ? val === true : val !== true;
559
+ }
560
+
561
+ /**
562
+ * Run a loop step: repeat its task until the `loopWhile`/`loopUntil` condition
563
+ * says to stop, a failing iteration aborts it, or the iteration cap is hit.
564
+ * Each iteration inherits the step's retry/timeout config. The final result
565
+ * carries `iterations`, `loopExhausted`, and `loopStop` (`condition`|`cap`|
566
+ * `failed`|`bad-condition`).
567
+ */
568
+ export async function runLoopStep({
569
+ step,
570
+ recordId,
571
+ cwd,
572
+ llmOptions,
573
+ resultsById,
574
+ }) {
575
+ const cap = loopIterationCap(step);
576
+ let last = null;
577
+ let iterations = 0;
578
+ let stopReason = "cap";
579
+ for (let iter = 1; iter <= cap; iter++) {
580
+ iterations = iter;
581
+ const withSelf = substituteLoopVars(step.message, {
582
+ stepId: recordId,
583
+ iter,
584
+ resultsById,
585
+ });
586
+ const message = substitutePlaceholders(withSelf, resultsById);
587
+ const r = await runStepWithRetry({ step, message, cwd, llmOptions });
588
+ last = outcomeFromRetry(recordId, r);
589
+ resultsById.set(recordId, last);
590
+ if (last.status === "failed") {
591
+ stopReason = "failed";
592
+ break;
593
+ }
594
+ let cont;
595
+ try {
596
+ cont = evalLoopContinue(step, { stepId: recordId, iter, resultsById });
597
+ } catch (err) {
598
+ last = {
599
+ id: recordId,
600
+ status: "failed",
601
+ taskId: null,
602
+ result: {
603
+ summary: `invalid loop condition on '${recordId}': ${err.message}`,
604
+ },
605
+ };
606
+ resultsById.set(recordId, last);
607
+ stopReason = "bad-condition";
608
+ break;
609
+ }
610
+ if (!cont) {
611
+ stopReason = "condition";
612
+ break;
613
+ }
614
+ }
615
+ return {
616
+ id: recordId,
617
+ status: last ? last.status : "skipped",
618
+ taskId: last?.taskId ?? null,
619
+ result: {
620
+ ...(last?.result || {}),
621
+ iterations,
622
+ loopExhausted: stopReason === "cap",
623
+ loopStop: stopReason,
624
+ },
625
+ };
626
+ }
627
+
332
628
  // ─── Execution ───────────────────────────────────────────────────────────────
333
629
 
334
630
  /**
335
631
  * Execute a workflow. The runner for individual tasks must be injected via
336
632
  * `_deps.runTask` (signature matches `runCoworkTask`).
337
633
  *
634
+ * Per-step robustness fields (all optional): `retries` (extra attempts after
635
+ * the first; non-negative integer), `timeoutMs` (per-attempt timeout, positive
636
+ * number), `retryDelayMs` (base delay before each retry, non-negative number),
637
+ * `retryBackoff` (`"fixed"` (default) or `"exponential"`).
638
+ *
639
+ * Loop nodes (optional, mutually exclusive with `forEach`): `loopWhile` /
640
+ * `loopUntil` (a `workflow-expr` condition that may reference `${self.<field>}`
641
+ * — the step's own latest iteration result — and `${iter}`) repeat the step's
642
+ * task (post-test) until the condition stops it, an iteration fails, or
643
+ * `maxIterations` (≤ MAX_LOOP_ITERATIONS) is hit. Each iteration inherits the
644
+ * step's retry/timeout config.
645
+ *
338
646
  * @param {object} options
339
647
  * @param {object} options.workflow - Workflow definition
340
648
  * @param {string} [options.cwd] - Working directory for history
@@ -426,6 +734,18 @@ export async function executeWorkflow(options = {}) {
426
734
  preOutcomes.push(outcome);
427
735
  continue;
428
736
  }
737
+ // loop node — runs its body repeatedly; per-iteration substitution
738
+ // happens inside runLoopStep, so push the raw template.
739
+ if (isLoopStep(step)) {
740
+ runnable.push({
741
+ step,
742
+ message: step.message,
743
+ recordId: step.id,
744
+ parentId: null,
745
+ isLoop: true,
746
+ });
747
+ continue;
748
+ }
429
749
  // forEach-expansion
430
750
  if (step.forEach !== undefined) {
431
751
  let items;
@@ -471,39 +791,33 @@ export async function executeWorkflow(options = {}) {
471
791
  runnable.push({ step, message, recordId: step.id, parentId: null });
472
792
  }
473
793
 
474
- const promises = runnable.map(async ({ step, message, recordId }) => {
475
- if (onStepStart) onStepStart({ stepId: recordId, message });
476
- try {
477
- const entry = await _deps.runTask({
478
- templateId: step.templateId || null,
479
- userMessage: message,
480
- files: step.files || [],
481
- cwd,
482
- llmOptions,
483
- });
484
- const outcome = {
485
- id: recordId,
486
- status: entry.status,
487
- taskId: entry.taskId,
488
- result: entry.result,
489
- };
490
- resultsById.set(recordId, outcome);
491
- if (entry.status !== "completed") anyFailure = true;
492
- if (onStepComplete) onStepComplete(outcome);
493
- return outcome;
494
- } catch (err) {
495
- anyFailure = true;
496
- const outcome = {
497
- id: recordId,
498
- status: "failed",
499
- taskId: null,
500
- result: { summary: `Step threw: ${err.message}` },
501
- };
794
+ const promises = runnable.map(
795
+ async ({ step, message, recordId, isLoop }) => {
796
+ if (onStepStart) onStepStart({ stepId: recordId, message });
797
+ let outcome;
798
+ if (isLoop) {
799
+ outcome = await runLoopStep({
800
+ step,
801
+ recordId,
802
+ cwd,
803
+ llmOptions,
804
+ resultsById,
805
+ });
806
+ } else {
807
+ const r = await runStepWithRetry({
808
+ step,
809
+ message,
810
+ cwd,
811
+ llmOptions,
812
+ });
813
+ outcome = outcomeFromRetry(recordId, r);
814
+ }
815
+ if (outcome.status !== "completed") anyFailure = true;
502
816
  resultsById.set(recordId, outcome);
503
817
  if (onStepComplete) onStepComplete(outcome);
504
818
  return outcome;
505
- }
506
- });
819
+ },
820
+ );
507
821
 
508
822
  const results = await Promise.all(promises);
509
823
  stepOutcomes.push(...preOutcomes, ...results);
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import crypto from "crypto";
7
+ import { execSync } from "child_process";
7
8
 
8
9
  /**
9
10
  * Hook priority levels — lower values run first.
@@ -256,8 +257,8 @@ export async function executeHook(hook, context = {}) {
256
257
  const type = hook.type || HookType.SYNC;
257
258
 
258
259
  if (type === HookType.COMMAND || type === HookType.SCRIPT) {
259
- // Command/script hooks execute a shell command
260
- const { execSync } = await import("child_process");
260
+ // Command/script hooks execute a shell command (execSync hoisted to a
261
+ // top-level import this runs per hook on the tool-use hot path).
261
262
  const cmd = hook.handler || "";
262
263
  if (!cmd) {
263
264
  return {
@@ -19,7 +19,16 @@ import fs from "fs";
19
19
  import path from "path";
20
20
 
21
21
  function safeId(id) {
22
- if (!id || typeof id !== "string" || !/^[A-Za-z0-9._-]+$/.test(id)) {
22
+ // Charset blocks path separators; the explicit "."/".." check closes the
23
+ // remaining single-component traversal (e.g. `..` would join to the parent
24
+ // of the sessions dir and read files outside it).
25
+ if (
26
+ !id ||
27
+ typeof id !== "string" ||
28
+ !/^[A-Za-z0-9._-]+$/.test(id) ||
29
+ id === "." ||
30
+ id === ".."
31
+ ) {
23
32
  throw new Error(`Invalid sessionId: "${id}"`);
24
33
  }
25
34
  return id;
@@ -1,2 +0,0 @@
1
- import{I as s,J as g,U as d,c as n,K as _,V as k,S as V,R as S,F as E,Z as K,w as M,n as C,o as R,b as T,r,P as p,Q as O,_ as Q}from"./vendor-BvqAck49.js";import{_ as U,u as W}from"./index-6QGNBg3m.js";import{R as j}from"./icons-DP3uiYxy.js";const q={__name:"Logs",setup(N,{expose:a}){a();const x=W(),e=r("status"),y=r(!1),v=r(""),c=r(""),i=r(""),f=r(!0),o=r(null),h={status:"status",doctor:"doctor","skill-sources":"skill sources","llm-providers":"llm providers"},m=T(()=>c.value.split(`
2
- `)),b=T(()=>{if(!i.value)return m.value;const t=i.value.toLowerCase();return m.value.filter(u=>u.toLowerCase().includes(t))});function L(t){return t.includes("✖")||t.includes("error")||t.includes("Error")||t.includes("failed")?"line-error":t.includes("✔")||t.includes("✓")||t.includes("success")||t.includes("running")?"line-success":t.includes("warn")||t.includes("Warn")||t.includes("○")?"line-warn":t.startsWith(" ")||t.startsWith(" ")?"line-indent":""}function l(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function w(t){if(!i.value)return t;const u=i.value.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return t.replace(new RegExp(`(${u})`,"gi"),"<mark>$1</mark>")}async function B(){y.value=!0,v.value="",c.value="";const t=h[e.value]||"status";try{const{output:u}=await x.execute(t,3e4);c.value=u,f.value&&(await C(),o.value&&(o.value.scrollTop=o.value.scrollHeight))}catch(u){v.value=`执行失败: ${u.message}`,c.value=v.value}finally{y.value=!1}}M(b,async()=>{f.value&&(await C(),o.value&&(o.value.scrollTop=o.value.scrollHeight))}),R(B);const H={ws:x,activeTab:e,loading:y,error:v,rawOutput:c,searchQuery:i,autoScroll:f,logContainer:o,TAB_COMMANDS:h,allLines:m,filteredLines:b,lineClass:L,escapeHtml:l,highlightSearch:w,loadLog:B,ref:r,computed:T,watch:M,nextTick:C,onMounted:R,get ReloadOutlined(){return j},get useWsStore(){return W}};return Object.defineProperty(H,"__isScriptSetup",{enumerable:!1,value:!0}),H}},z={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},A={style:{display:"flex",gap:"10px",margin:"12px 0"}},D={ref:"logContainer",class:"log-box"},F={key:0,style:{"text-align":"center",padding:"40px",color:"var(--text-muted)"}},I={key:1,style:{"text-align":"center",padding:"40px",color:"var(--text-muted)"}},P={key:2},J=["innerHTML"];function Z(N,a,x,e,y,v){const c=s("a-checkbox"),i=s("a-button"),f=s("a-space"),o=s("a-tab-pane"),h=s("a-tabs"),m=s("a-input-search"),b=s("a-tag"),L=s("a-spin");return p(),g("div",null,[d("div",z,[a[5]||(a[5]=d("div",null,[d("h2",{class:"page-title"},"日志查看"),d("p",{class:"page-sub"},"系统运行日志与诊断输出")],-1)),n(f,null,{default:_(()=>[n(c,{checked:e.autoScroll,"onUpdate:checked":a[0]||(a[0]=l=>e.autoScroll=l)},{default:_(()=>[...a[3]||(a[3]=[O("自动滚动",-1)])]),_:1},8,["checked"]),n(i,{type:"primary",ghost:"",loading:e.loading,onClick:e.loadLog},{icon:_(()=>[n(e.ReloadOutlined)]),default:_(()=>[a[4]||(a[4]=O(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),k(" Tab Selector "),n(h,{activeKey:e.activeTab,"onUpdate:activeKey":a[1]||(a[1]=l=>e.activeTab=l),onChange:e.loadLog,style:{"margin-bottom":"0"}},{default:_(()=>[n(o,{key:"status",tab:"系统状态"}),n(o,{key:"doctor",tab:"环境诊断"}),n(o,{key:"skill-sources",tab:"技能来源"}),n(o,{key:"llm-providers",tab:"LLM 提供商"})]),_:1},8,["activeKey"]),k(" Search Bar "),d("div",A,[n(m,{value:e.searchQuery,"onUpdate:value":a[2]||(a[2]=l=>e.searchQuery=l),placeholder:"搜索日志内容...","allow-clear":"",style:{flex:"1"}},null,8,["value"]),e.filteredLines.length!==e.allLines.length?(p(),V(b,{key:0,color:"blue"},{default:_(()=>[O(S(e.filteredLines.length)+" / "+S(e.allLines.length)+" 行 ",1)]),_:1})):k("v-if",!0)]),k(" Log Output "),d("div",D,[e.loading?(p(),g("div",F,[n(L,{size:"large"}),a[6]||(a[6]=d("div",{style:{"margin-top":"10px"}},"加载中...",-1))])):e.filteredLines.length?(p(),g("div",P,[(p(!0),g(E,null,K(e.filteredLines,(l,w)=>(p(),g("div",{key:w,class:Q(["log-line",e.lineClass(l)]),innerHTML:e.highlightSearch(e.escapeHtml(l))},null,10,J))),128))])):(p(),g("div",I,S(e.error||"暂无日志内容,点击刷新加载"),1))],512)])}const $=U(q,[["render",Z],["__scopeId","data-v-8c2906e0"],["__file","/tmp/cc-web-panel-WsolcE/repo/packages/web-panel/src/views/Logs.vue"]]);export{$ as default};
@@ -1 +0,0 @@
1
- import{I as w,P as d,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-6QGNBg3m.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||{}),l=o(()=>a.event.extra||{}),m=o(()=>l.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(()=>l.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:l,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"},B={class:"row"},D={class:"val"},I={class:"row amount-row"},j={class:"val amount"},A={key:0,class:"row"},E={class:"val mono"},F={key:1,class:"row"};function M(p,r,a,e,l,m){const c=w("a-tag");return d(),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",B,[r[1]||(r[1]=s("span",{class:"key"},"商品/项目",-1)),s("span",D,n(e.itemText),1)]),s("div",I,[r[2]||(r[2]=s("span",{class:"key"},"金额",-1)),s("span",j,n(e.amountText),1)]),e.orderNo?(d(),u("div",A,[r[3]||(r[3]=s("span",{class:"key"},"单号",-1)),s("span",E,n(e.orderNo),1)])):g("v-if",!0),e.statusText?(d(),u("div",F,[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 K=S(k,[["render",M],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-WsolcE/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{K as default};
@@ -1 +0,0 @@
1
- import{E,b as w,r as b,I as m,J as y,U as a,R as g,c as i,K as u,V as h,F as C,Z as L,N as O,o as M,P as p,Q as S,S as R}from"./vendor-BvqAck49.js";import{u as I,_ as N}from"./index-6QGNBg3m.js";import{u as P}from"./useShellMode-CgR0wCYM.js";import{p as V}from"./parsers-UEvh_ShA.js";import{u as z}from"./chat-Iurq_BMY.js";import{a9 as j,ap as q,R as B}from"./icons-DP3uiYxy.js";const A=E("skills",()=>{const _=b(!1),t=b([]),n=b(""),e=b("all"),k=w(()=>{const o=new Set(["all"]);return t.value.forEach(l=>{l.category&&o.add(l.category),l.executionMode&&o.add(l.executionMode)}),[...o]}),v=w(()=>{let o=t.value;if(e.value!=="all"&&(o=o.filter(l=>l.category===e.value||l.executionMode===e.value)),n.value){const l=n.value.toLowerCase();o=o.filter(d=>d.name?.toLowerCase().includes(l)||d.description?.toLowerCase().includes(l)||d.title?.toLowerCase().includes(l))}return o});async function f(){const o=I();_.value=!0;try{if(P().isEmbedded){const c=await o.sendRaw({type:"skill.list"},2e4);c?.ok&&Array.isArray(c.result?.skills)?t.value=c.result.skills:(console.error("skill.list custom topic failed:",c?.error),t.value=[]);return}const{output:l}=await o.execute("skill list",2e4),d=V(l);t.value=d}catch(l){console.error("Failed to load skills:",l)}finally{_.value=!1}}return{loading:_,allSkills:t,searchQuery:n,selectedCategory:e,categories:k,filteredSkills:v,loadSkills:f}}),F={__name:"Skills",setup(_,{expose:t}){t();const n=A(),e=z(),k=O(),v=w(()=>n.categories.filter(r=>r!=="all").slice(0,6));function f(r){return{"built-in":"内置","cli-direct":"CLI",agent:"Agent","llm-query":"LLM",hybrid:"混合",workspace:"工作区",marketplace:"市场"}[r]||r}function o(r){return{"cli-direct":"CLI",agent:"Agent","llm-query":"LLM",hybrid:"混合","built-in":"内置"}[r]||r||"未知"}function l(r){return{"cli-direct":"cyan",agent:"purple","llm-query":"blue",hybrid:"orange","built-in":"green"}[r]||"default"}async function d(r){await e.createSession("agent"),k.push("/chat"),setTimeout(()=>{e.currentSessionId&&e.sendMessage(e.currentSessionId,`/skill run ${r}`)},300)}M(()=>{n.allSkills.length||n.loadSkills()});const c={skillsStore:n,chatStore:e,router:k,displayCategories:v,catLabel:f,modeLabel:o,modeColor:l,runSkill:d,computed:w,onMounted:M,get useRouter(){return O},get ReloadOutlined(){return B},get PlayCircleOutlined(){return q},get AppstoreOutlined(){return j},get useSkillsStore(){return A},get useChatStore(){return z}};return Object.defineProperty(c,"__isScriptSetup",{enumerable:!1,value:!0}),c}},Q={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},U={class:"page-sub"},T={style:{display:"flex",gap:"12px","margin-bottom":"20px","flex-wrap":"wrap"}},W={key:0,style:{"text-align":"center",padding:"60px"}},D={class:"skills-grid"},G={style:{display:"flex","justify-content":"space-between","align-items":"flex-start"}},J={style:{flex:"1","min-width":"0"}},K={style:{"font-weight":"500",color:"#e0e0e0","font-size":"14px","margin-bottom":"4px","font-family":"monospace"}},Z={style:{color:"var(--text-secondary)","font-size":"12px","line-height":"1.5"}},H={style:{"margin-left":"12px","flex-shrink":"0"}},X={style:{"margin-top":"10px",display:"flex","justify-content":"flex-end"}},Y={style:{"text-align":"center",padding:"60px",color:"var(--text-muted)"}};function $(_,t,n,e,k,v){const f=m("a-button"),o=m("a-input-search"),l=m("a-radio-button"),d=m("a-radio-group"),c=m("a-spin"),r=m("a-tag"),x=m("a-card");return p(),y("div",null,[a("div",Q,[a("div",null,[t[3]||(t[3]=a("h2",{class:"page-title"},"技能管理",-1)),a("p",U,g(e.skillsStore.allSkills.length)+" 个可用技能",1)]),i(f,{type:"primary",ghost:"",loading:e.skillsStore.loading,onClick:t[0]||(t[0]=s=>e.skillsStore.loadSkills())},{icon:u(()=>[i(e.ReloadOutlined)]),default:u(()=>[t[4]||(t[4]=S(" 刷新 ",-1))]),_:1},8,["loading"])]),h(" Search & Filter "),a("div",T,[i(o,{value:e.skillsStore.searchQuery,"onUpdate:value":t[1]||(t[1]=s=>e.skillsStore.searchQuery=s),placeholder:"搜索技能名称或描述...",style:{width:"300px"},"allow-clear":""},null,8,["value"]),i(d,{value:e.skillsStore.selectedCategory,"onUpdate:value":t[2]||(t[2]=s=>e.skillsStore.selectedCategory=s),"button-style":"solid"},{default:u(()=>[i(l,{value:"all"},{default:u(()=>[...t[5]||(t[5]=[S("全部",-1)])]),_:1}),(p(!0),y(C,null,L(e.displayCategories,s=>(p(),R(l,{key:s,value:s},{default:u(()=>[S(g(e.catLabel(s)),1)]),_:2},1032,["value"]))),128))]),_:1},8,["value"])]),h(" Loading State "),e.skillsStore.loading?(p(),y("div",W,[i(c,{size:"large"}),t[6]||(t[6]=a("div",{style:{color:"var(--text-muted)","margin-top":"12px"}},"加载技能中...",-1))])):e.skillsStore.filteredSkills.length?(p(),y(C,{key:1},[h(" Skills Grid "),a("div",D,[(p(!0),y(C,null,L(e.skillsStore.filteredSkills,s=>(p(),R(x,{key:s.name,class:"skill-card",size:"small",hoverable:"",style:{background:"var(--bg-card)","border-color":"var(--border-color)",cursor:"default"}},{default:u(()=>[a("div",G,[a("div",J,[a("div",K,g(s.name),1),a("div",Z,g(s.description||"暂无描述"),1)]),a("div",H,[i(r,{color:e.modeColor(s.executionMode),style:{"font-size":"10px"}},{default:u(()=>[S(g(e.modeLabel(s.executionMode)),1)]),_:2},1032,["color"])])]),a("div",X,[i(f,{size:"small",type:"primary",ghost:"",onClick:ee=>e.runSkill(s.name)},{icon:u(()=>[i(e.PlayCircleOutlined)]),default:u(()=>[t[7]||(t[7]=S(" 运行 ",-1))]),_:1},8,["onClick"])])]),_:2},1024))),128))])],2112)):(p(),y(C,{key:2},[h(" Empty State "),a("div",Y,[i(e.AppstoreOutlined,{style:{"font-size":"48px","margin-bottom":"16px",display:"block"}}),a("div",null,g(e.skillsStore.allSkills.length?"没有匹配的技能":"点击刷新加载技能列表"),1)])],2112))])}const ie=N(F,[["render",$],["__scopeId","data-v-d64d43f5"],["__file","/tmp/cc-web-panel-WsolcE/repo/packages/web-panel/src/views/Skills.vue"]]);export{ie as default};
@@ -1 +0,0 @@
1
- import{E as B,b as z,r as D,I as p,J as c,U as _,c as n,K as a,S as T,V as w,o as P,x as I,P as i,Q as g,R as r,F as h,Z as E}from"./vendor-BvqAck49.js";import{u as R,_ as F}from"./index-6QGNBg3m.js";import{R as O}from"./icons-DP3uiYxy.js";const V=B("tasks",()=>{const k=D([]),l=D(!1);let u=null,e=null;const x=z(()=>k.value.filter(t=>t.status==="running")),b=z(()=>k.value.filter(t=>t.status==="pending")),y=z(()=>k.value.filter(t=>t.status==="completed"||t.status==="failed"||t.status==="timeout"));async function f(){const t=R();l.value=!0;try{const s=await t.sendRaw({type:"tasks-list"});s&&Array.isArray(s.tasks)&&(k.value=s.tasks)}catch{}finally{l.value=!1}}async function o(t){const s=R();try{await s.sendRaw({type:"tasks-stop",taskId:t})}catch{}finally{await f()}}const d=D(null);function m(t=5e3){v(),f(),u=setInterval(f,t),C()}function v(){u&&(clearInterval(u),u=null),e&&(e(),e=null)}function C(){const t=R();if(e)return;const s=S=>{S.type==="task:notification"&&S.payload?.task&&(d.value=S.payload.task,f(),setTimeout(()=>{d.value=null},8e3))};e=t.onRuntimeEvent(s)}function N(t){return!t||t<0?"-":t<1e3?`${t}ms`:t<6e4?`${(t/1e3).toFixed(1)}s`:`${(t/6e4).toFixed(1)}m`}function A(t){switch(t){case"running":return"processing";case"pending":return"default";case"completed":return"success";case"failed":return"error";case"timeout":return"warning";default:return"default"}}return{tasks:k,loading:l,running:x,pending:b,completed:y,lastNotification:d,fetchTasks:f,stopTask:o,startPolling:m,stopPolling:v,formatDuration:N,getStatusColor:A}}),U={__name:"Tasks",setup(k,{expose:l}){l();const u=V(),e=[{title:"状态",key:"status",width:90},{title:"描述",key:"description",ellipsis:!0},{title:"类型",dataIndex:"type",width:100},{title:"耗时",key:"duration",width:90},{title:"创建时间",key:"createdAt",width:180},{title:"结果",key:"result",ellipsis:!0},{title:"操作",key:"action",width:80}];function x(o){return o.status==="running"&&o.startedAt?u.formatDuration(Date.now()-o.startedAt):o.completedAt&&o.startedAt?u.formatDuration(o.completedAt-o.startedAt):"-"}function b(o){return o?new Date(o).toLocaleString():"-"}function y(o,d){return o?o.length>d?`${o.slice(0,d)}...`:o:""}P(()=>u.startPolling(5e3)),I(()=>u.stopPolling());const f={store:u,columns:e,getDuration:x,formatTime:b,truncate:y,onMounted:P,onUnmounted:I,get ReloadOutlined(){return O},get useTasksStore(){return V}};return Object.defineProperty(f,"__isScriptSetup",{enumerable:!1,value:!0}),f}},L={class:"page-header"},W={key:0,class:"error-text"},j={key:1},J={class:"task-header"},K={class:"task-desc"},M={class:"task-id"},Q={class:"task-meta"},Z=["title"],q={key:0,class:"error-text"},G={key:1,class:"success-text"},H={key:2,class:"muted-text"};function X(k,l,u,e,x,b){const y=p("a-button"),f=p("a-space"),o=p("a-alert"),d=p("a-statistic"),m=p("a-card"),v=p("a-col"),C=p("a-row"),N=p("a-tag"),A=p("a-table");return i(),c("div",null,[_("div",L,[l[3]||(l[3]=_("div",null,[_("h2",{class:"page-title"},"后台任务"),_("p",{class:"page-sub"},"查看后台任务队列、实时通知和任务执行结果。")],-1)),n(f,null,{default:a(()=>[n(y,{ghost:"",loading:e.store.loading,onClick:l[0]||(l[0]=t=>e.store.fetchTasks())},{icon:a(()=>[n(e.ReloadOutlined)]),default:a(()=>[l[2]||(l[2]=g(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.store.lastNotification?(i(),T(o,{key:0,type:e.store.lastNotification.status==="completed"?"success":"error","show-icon":"",closable:"",class:"banner",onClose:l[1]||(l[1]=t=>e.store.lastNotification=null)},{message:a(()=>[g(" 任务"+r(e.store.lastNotification.status==="completed"?"完成":"结束")+": "+r(e.store.lastNotification.description||e.store.lastNotification.id.slice(0,16)),1)]),description:a(()=>[e.store.lastNotification.error?(i(),c("span",W,r(e.store.lastNotification.error),1)):e.store.lastNotification.result?(i(),c("span",j,r(e.truncate(String(e.store.lastNotification.result),120)),1)):w("v-if",!0)]),_:1},8,["type"])):w("v-if",!0),n(C,{gutter:[16,16],class:"stats-row"},{default:a(()=>[n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"全部任务",value:e.store.tasks.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"运行中",value:e.store.running.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"等待中",value:e.store.pending.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"已完成",value:e.store.completed.length},null,8,["value"])]),_:1})]),_:1})]),_:1}),e.store.running.length>0?(i(),T(m,{key:1,title:"运行中的任务",class:"panel-card",size:"small"},{default:a(()=>[(i(!0),c(h,null,E(e.store.running,t=>(i(),c("div",{key:t.id,class:"task-item running"},[_("div",J,[n(N,{color:e.store.getStatusColor(t.status)},{default:a(()=>[g(r(t.status.toUpperCase()),1)]),_:2},1032,["color"]),_("span",K,r(t.description),1),_("span",M,r(t.id.slice(0,16)),1)]),_("div",Q,[_("span",null,"类型: "+r(t.type||"-"),1),_("span",null,"已运行: "+r(e.store.formatDuration(Date.now()-t.startedAt)),1),n(y,{size:"small",danger:"",onClick:s=>e.store.stopTask(t.id)},{default:a(()=>[...l[4]||(l[4]=[g("停止",-1)])]),_:1},8,["onClick"])])]))),128))]),_:1})):w("v-if",!0),n(m,{class:"panel-card"},{default:a(()=>[n(A,{columns:e.columns,"data-source":e.store.tasks,pagination:{pageSize:15,size:"small"},loading:e.store.loading,"row-key":"id",size:"small"},{bodyCell:a(({column:t,record:s})=>[t.key==="status"?(i(),T(N,{key:0,color:e.store.getStatusColor(s.status)},{default:a(()=>[g(r(s.status),1)]),_:2},1032,["color"])):t.key==="description"?(i(),c("span",{key:1,title:s.command},r(s.description),9,Z)):t.key==="duration"?(i(),c(h,{key:2},[g(r(e.getDuration(s)),1)],64)):t.key==="createdAt"?(i(),c(h,{key:3},[g(r(e.formatTime(s.createdAt)),1)],64)):t.key==="result"?(i(),c(h,{key:4},[s.error?(i(),c("span",q,r(e.truncate(s.error,60)),1)):s.result?(i(),c("span",G,r(e.truncate(String(s.result),60)),1)):(i(),c("span",H,"-"))],64)):t.key==="action"?(i(),c(h,{key:5},[s.status==="running"?(i(),T(y,{key:0,size:"small",danger:"",onClick:S=>e.store.stopTask(s.id)},{default:a(()=>[...l[5]||(l[5]=[g(" 停止 ",-1)])]),_:1},8,["onClick"])):w("v-if",!0)],64)):w("v-if",!0)]),_:1},8,["data-source","loading"])]),_:1})])}const et=F(U,[["render",X],["__scopeId","data-v-da5ff6a2"],["__file","/tmp/cc-web-panel-WsolcE/repo/packages/web-panel/src/views/Tasks.vue"]]);export{et as default};
@@ -1,3 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./xterm-BZcWGsqw.js","./markdown-CsiA8-E5.js","./markdown-Dfs9RUU9.css","./addon-fit-CK6X9sAG.js","./xterm-DFuMZ0ql.css"])))=>i.map(i=>d[i]);
2
- import{u as fe,_ as me,d as V,e as U}from"./index-6QGNBg3m.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,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 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 Fe=me(Se,[["render",Be],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-WsolcE/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
@@ -1 +0,0 @@
1
- import{O as r}from"./index-6QGNBg3m.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-DLFLDxar.js";import{U as t}from"./index-6QGNBg3m.js";import"./vendor-BvqAck49.js";import"./index-DEKeoJ6I.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};
@@ -1 +0,0 @@
1
- import{A as o}from"./Row-Do5iQUFj.js";import{U as t}from"./index-6QGNBg3m.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-DHV7-FuY.js";import"./useFlexGapSupport-D338iARz.js";import"./styleChecker-DamP5BTS.js";import"./index-DEKeoJ6I.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};