chainlesschain 0.162.193 → 0.162.197

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 (169) hide show
  1. package/README.md +29 -6
  2. package/completions/_cc +2 -2
  3. package/completions/cc.bash +2 -2
  4. package/completions/cc.fish +2 -2
  5. package/completions/cc.ps1 +2 -2
  6. package/package.json +1 -1
  7. package/src/assets/web-panel/assets/{AIOps-DBLkaTje.js → AIOps-D3Gu1a5d.js} +1 -1
  8. package/src/assets/web-panel/assets/{ActionButton-BAy-Qebo.js → ActionButton-DrwAoKaz.js} +1 -1
  9. package/src/assets/web-panel/assets/{Analytics-Dfb1Mlau.js → Analytics-C7Q-gd_3.js} +3 -3
  10. package/src/assets/web-panel/assets/{AppLayout-BbFkN8m0.js → AppLayout-DgBtae-n.js} +5 -5
  11. package/src/assets/web-panel/assets/{Artifacts-kM4-cEEH.js → Artifacts-pQ6LcA-W.js} +1 -1
  12. package/src/assets/web-panel/assets/{Audit-BSQfYWf3.js → Audit-DK61tocB.js} +1 -1
  13. package/src/assets/web-panel/assets/{BackgroundAgents-CWDbI_fG.js → BackgroundAgents-BOKgDFRh.js} +1 -1
  14. package/src/assets/web-panel/assets/{Backup-BxLPbq_Q.js → Backup-Bo9G4vTP.js} +1 -1
  15. package/src/assets/web-panel/assets/{BaseInput-DuIbdrp6.js → BaseInput-Do_dE9_v.js} +1 -1
  16. package/src/assets/web-panel/assets/{Chat-NEmjGahU.js → Chat-COVvZzOL.js} +5 -5
  17. package/src/assets/web-panel/assets/ChatBubbleRenderer-BUUyJ5QO.js +1 -0
  18. package/src/assets/web-panel/assets/{Checkbox-CaoeG3Ns.js → Checkbox-Z9MJMolt.js} +1 -1
  19. package/src/assets/web-panel/assets/{Codegen-BFf_g3xY.js → Codegen-BVzWKVbf.js} +1 -1
  20. package/src/assets/web-panel/assets/{Col-CNOd8mdQ.js → Col-C8MnYcbT.js} +1 -1
  21. package/src/assets/web-panel/assets/{Community-BhpDqz-i.js → Community-DQxqw15l.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compact-CQ42T7Z6.js → Compact-BAUmrh3y.js} +1 -1
  23. package/src/assets/web-panel/assets/{Compliance-DI5PcLMN.js → Compliance-jPAkQ3zK.js} +1 -1
  24. package/src/assets/web-panel/assets/{Cowork-wYYZe0wR.js → Cowork-BBQyxbh8.js} +3 -3
  25. package/src/assets/web-panel/assets/{Cron-Dlq03DD_.js → Cron-W5koq8Z5.js} +2 -2
  26. package/src/assets/web-panel/assets/{Crosschain-BzqS8PP3.js → Crosschain-BQhnu5hS.js} +1 -1
  27. package/src/assets/web-panel/assets/{DID-It55Yem7.js → DID-DD7PlI18.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dashboard-9HkH6oxn.js → Dashboard-w_ILuwKI.js} +2 -2
  29. package/src/assets/web-panel/assets/{Dropdown-00e2YWRB.js → Dropdown-qiDUAyAo.js} +1 -1
  30. package/src/assets/web-panel/assets/{EmailListRenderer-By-ugRDL.js → EmailListRenderer-PDeBcI5H.js} +1 -1
  31. package/src/assets/web-panel/assets/{FamilyGuardDashboard-C396yu5m.js → FamilyGuardDashboard-SuArscRM.js} +1 -1
  32. package/src/assets/web-panel/assets/{Federation-BME5sbZY.js → Federation-BCovZaUn.js} +1 -1
  33. package/src/assets/web-panel/assets/{FormItemContext-B4TEZCr-.js → FormItemContext-DjlFdVFk.js} +1 -1
  34. package/src/assets/web-panel/assets/{GenericCardRenderer-_9CX9ieY.js → GenericCardRenderer-DoEZ7fcS.js} +1 -1
  35. package/src/assets/web-panel/assets/{Git-BrS6WVSr.js → Git-CV0-6GPI.js} +2 -2
  36. package/src/assets/web-panel/assets/{Governance-BMdCWnKF.js → Governance-B_SFN50w.js} +1 -1
  37. package/src/assets/web-panel/assets/{Inference-Bcp3vzcA.js → Inference-heI0Eo6k.js} +1 -1
  38. package/src/assets/web-panel/assets/{KnowledgeGraph-DlLuqGY5.js → KnowledgeGraph-Cz5INS5p.js} +1 -1
  39. package/src/assets/web-panel/assets/Logs-BSFxiHkg.js +2 -0
  40. package/src/assets/web-panel/assets/MarkdownRenderer-1mNozZ8v.js +1 -0
  41. package/src/assets/web-panel/assets/{Marketplace-Dzn2guvI.js → Marketplace-0TWTpE7k.js} +1 -1
  42. package/src/assets/web-panel/assets/{McpTools-uPict-KL.js → McpTools-CV4-wBLm.js} +6 -6
  43. package/src/assets/web-panel/assets/{Memory-BCw43kOb.js → Memory-x5bH5rw5.js} +2 -2
  44. package/src/assets/web-panel/assets/{MobileBridge-DmV8Wv7F.js → MobileBridge-DaBmUu9G.js} +1 -1
  45. package/src/assets/web-panel/assets/MobileProjects-DqnoFPgR.js +1 -0
  46. package/src/assets/web-panel/assets/{Mtc-C6jxJ34Y.js → Mtc-B_zKEBif.js} +6 -6
  47. package/src/assets/web-panel/assets/{MtcAudit-Za8ExwhQ.js → MtcAudit-BCfKD2yg.js} +5 -5
  48. package/src/assets/web-panel/assets/{Multisig-KKDbuEgb.js → Multisig-DgYfj6c_.js} +3 -3
  49. package/src/assets/web-panel/assets/{NLProgramming-Dj97zbCk.js → NLProgramming-Dz09lFUm.js} +1 -1
  50. package/src/assets/web-panel/assets/{Notes-DBXvMraU.js → Notes-Cuj6ugBE.js} +4 -4
  51. package/src/assets/web-panel/assets/{NotificationSettings-DOxITLYl.js → NotificationSettings-DK2WXjhg.js} +1 -1
  52. package/src/assets/web-panel/assets/OrderTableRenderer-D1IAOQoo.js +1 -0
  53. package/src/assets/web-panel/assets/{Organization-D1i73mjb.js → Organization-9fqnPvTw.js} +4 -4
  54. package/src/assets/web-panel/assets/{Overflow-kW6Q3rvg.js → Overflow-n5xHkhow.js} +1 -1
  55. package/src/assets/web-panel/assets/{P2P-C-v_8p2v.js → P2P-B5AUWwH-.js} +2 -2
  56. package/src/assets/web-panel/assets/{PdhVaultBrowser-tUbbY64W.js → PdhVaultBrowser-CoUDV6dy.js} +5 -5
  57. package/src/assets/web-panel/assets/{Permissions-DkHxEZ58.js → Permissions-DPRmQf_H.js} +4 -4
  58. package/src/assets/web-panel/assets/{PersonalDataHub-DWuMPGrK.js → PersonalDataHub-B37bsbEN.js} +4 -4
  59. package/src/assets/web-panel/assets/{Pipeline-30IYXWWm.js → Pipeline-CCAuPqu9.js} +1 -1
  60. package/src/assets/web-panel/assets/{Privacy-DZNQ4RrH.js → Privacy-B81msZdv.js} +1 -1
  61. package/src/assets/web-panel/assets/{ProjectInit-De2MCElf.js → ProjectInit-B-Py2NbF.js} +2 -2
  62. package/src/assets/web-panel/assets/{ProjectSettings-5uHk9wsC.js → ProjectSettings-CYsneiRB.js} +2 -2
  63. package/src/assets/web-panel/assets/{Projects-XjDfrFLb.js → Projects-Y975Mh6R.js} +1 -1
  64. package/src/assets/web-panel/assets/{Providers-Bgwj6gcE.js → Providers-uO-10aP1.js} +1 -1
  65. package/src/assets/web-panel/assets/{QrScannerModal-gKql9umv.js → QrScannerModal-Bj_6gJ0l.js} +1 -1
  66. package/src/assets/web-panel/assets/{QuickAsk-BWvmwkh7.js → QuickAsk-BgpBCMPE.js} +1 -1
  67. package/src/assets/web-panel/assets/{Recommend-Uok4hZPd.js → Recommend-DhUW3YUA.js} +1 -1
  68. package/src/assets/web-panel/assets/{RemoteSession-DLJzTk9a.js → RemoteSession-DdeyfbkA.js} +3 -3
  69. package/src/assets/web-panel/assets/{Reputation-ZVwIPMSO.js → Reputation-fxW421xd.js} +1 -1
  70. package/src/assets/web-panel/assets/{Row-CN04HxWR.js → Row-De73w1og.js} +1 -1
  71. package/src/assets/web-panel/assets/{RssFeed-BdSrEG4g.js → RssFeed-3US_Q_lj.js} +3 -3
  72. package/src/assets/web-panel/assets/{Search-5PwVd0IR.js → Search-DbZ_DU74.js} +1 -1
  73. package/src/assets/web-panel/assets/{Security-DdBo4zjN.js → Security-DoIU1vMF.js} +4 -4
  74. package/src/assets/web-panel/assets/{Services-D3letU7M.js → Services-DB_RGqpc.js} +2 -2
  75. package/src/assets/web-panel/assets/{Skeleton--Jb83f1v.js → Skeleton-DnzLaayC.js} +1 -1
  76. package/src/assets/web-panel/assets/{Skills-Bg-CulHX.js → Skills-VzVXHENF.js} +1 -1
  77. package/src/assets/web-panel/assets/{Sla-7QOa7S-X.js → Sla-DMfvjCAI.js} +1 -1
  78. package/src/assets/web-panel/assets/{SpeechSettings-DQwppjRw.js → SpeechSettings-DQQOYWbF.js} +1 -1
  79. package/src/assets/web-panel/assets/{SyncSettings-dNPQGL-s.js → SyncSettings-Bmx3FG1P.js} +2 -2
  80. package/src/assets/web-panel/assets/{Tasks-Ggs-Z48q.js → Tasks-DOQyfb-2.js} +1 -1
  81. package/src/assets/web-panel/assets/{Templates-78TYHgRO.js → Templates-D6hTRT7c.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tenant-xHwwv9vO.js → Tenant-CTPQZAzs.js} +1 -1
  83. package/src/assets/web-panel/assets/{Terminal-BJXSJfm4.js → Terminal-B7vII3oH.js} +2 -2
  84. package/src/assets/web-panel/assets/{TimelineRenderer-fLbjRhJw.js → TimelineRenderer-BkiFJeXV.js} +1 -1
  85. package/src/assets/web-panel/assets/{Tokens-oMSBSBmB.js → Tokens-BPPdQMNo.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trigger-CfnY_wX_.js → Trigger-BxG8JAEI.js} +1 -1
  87. package/src/assets/web-panel/assets/{Trust-AdyTgYKO.js → Trust-DHD7nMpM.js} +1 -1
  88. package/src/assets/web-panel/assets/{UkeySign-C5K_81dS.js → UkeySign-B4BJpU47.js} +1 -1
  89. package/src/assets/web-panel/assets/{VideoEditing-vcGVDqki.js → VideoEditing-CRiGpFx2.js} +1 -1
  90. package/src/assets/web-panel/assets/{Wallet-hhOc3hlY.js → Wallet-BSDSNiem.js} +4 -4
  91. package/src/assets/web-panel/assets/{WebAuthn-CVloC11s.js → WebAuthn-DLTUh5Zv.js} +5 -5
  92. package/src/assets/web-panel/assets/{WorkflowEditor-CYeE32R5.js → WorkflowEditor-tW2MwjhD.js} +1 -1
  93. package/src/assets/web-panel/assets/{chat-CNROR5bN.js → chat-SgsLQ3FC.js} +1 -1
  94. package/src/assets/web-panel/assets/{colors-Cjx-cnwU.js → colors-BHjjLIKO.js} +1 -1
  95. package/src/assets/web-panel/assets/{compact-item-DOIfelvD.js → compact-item-VceErdKq.js} +1 -1
  96. package/src/assets/web-panel/assets/{createContext-DfA7UZ8u.js → createContext-BZ332MYl.js} +1 -1
  97. package/src/assets/web-panel/assets/devWarning-DosMaL-k.js +1 -0
  98. package/src/assets/web-panel/assets/{hasIn-BMSCzcfM.js → hasIn-CBTjJOjn.js} +1 -1
  99. package/src/assets/web-panel/assets/index-0O5ePnUq.js +1 -0
  100. package/src/assets/web-panel/assets/{index-CshQbilz.js → index-1n7xjKDU.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DPAWBrMf.js → index-29wVzi-k.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BbQ2eQ8H.js → index-B2u26AS3.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DBpWXFed.js → index-B40dQn0G.js} +3 -3
  104. package/src/assets/web-panel/assets/{index-5-HXgOX5.js → index-B5KAGxNo.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BxOk9vkG.js → index-BC1xuQgX.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BemJ2u_E.js → index-BETEjuNr.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BEMwBBHk.js → index-BOtvPdHt.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-B4iYzpkL.js → index-BPXFLYdW.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-B7gf77CJ.js → index-BQSmZGgs.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Cs6l7uRu.js → index-BRWhLbWF.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-C7xn0Nub.js → index-BTlc-Bve.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CVm1_i3t.js → index-BY1wexYG.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CNC5onm4.js → index-BcUenmCX.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DLmn0BoK.js → index-BeiqkxJG.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-m2vG9gG_.js → index-BhXZEUAc.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BM1y_9hM.js → index-By5jBtkV.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-By61ojUx.js → index-CLc19alH.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Cyweh0Hy.js → index-CMVvxIS8.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-ClNMrqEY.js → index-C_B9rFQE.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CEKMcOyU.js → index-CaIS_TNX.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CAnvhwg6.js → index-CawpdGTW.js} +1 -1
  122. package/src/assets/web-panel/assets/index-ChAzPigF.js +1 -0
  123. package/src/assets/web-panel/assets/{index-C3L5gdiD.js → index-CpumS98o.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-FBc_CJBd.js → index-Cr4rjlW5.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CdYBye8B.js → index-CrUgDQkf.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-AWg-0M1S.js → index-CtjLcCNU.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DjEsxO5h.js → index-DUkVN794.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-dCd8cSUq.js → index-D_SePDWj.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Icdoqmzt.js → index-DaCCy6lq.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BolaOQxx.js → index-DdefYBSw.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-C2K9SNVX.js → index-DePOeMDM.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-B5Udeb_6.js → index-DgPvuIn2.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-ti_lnTWl.js → index-FJ3zC9LK.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BUonmKSE.js → index-_PHrIO4O.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-mTpHoEzr.js → index-fU7wNHDB.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-DHtpHZAQ.js → index-iYQNU9za.js} +1 -1
  137. package/src/assets/web-panel/assets/{index-CVL27kXC.js → index-vIXOpcjD.js} +1 -1
  138. package/src/assets/web-panel/assets/{initDefaultProps-Bu8k7H1Y.js → initDefaultProps-D1oZNz0D.js} +1 -1
  139. package/src/assets/web-panel/assets/{motion-s3iVK41k.js → motion-C8k6doMO.js} +1 -1
  140. package/src/assets/web-panel/assets/{move-B6B-E5Jz.js → move-DJ4qSbYt.js} +1 -1
  141. package/src/assets/web-panel/assets/{mtc-parser-BiYgTidA.js → mtc-parser-CdpJD85j.js} +1 -1
  142. package/src/assets/web-panel/assets/{omit-pU1RdUDA.js → omit-B0V4slKA.js} +1 -1
  143. package/src/assets/web-panel/assets/{pickAttrs-Cdoq_SeM.js → pickAttrs-Di5NiW1F.js} +1 -1
  144. package/src/assets/web-panel/assets/{placementArrow-DIuvAn2K.js → placementArrow-B5OMHgEM.js} +1 -1
  145. package/src/assets/web-panel/assets/{responsiveObserve-8w16YR2D.js → responsiveObserve-C6U9IWql.js} +1 -1
  146. package/src/assets/web-panel/assets/{slide-VZ01cZe3.js → slide-BMyTH3rN.js} +1 -1
  147. package/src/assets/web-panel/assets/{statusUtils-lh8YMN8Z.js → statusUtils-C7d6BG7Z.js} +1 -1
  148. package/src/assets/web-panel/assets/{styleChecker-CmDyreec.js → styleChecker-CR50QnQy.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFlexGapSupport-hiJWMU5y.js → useFlexGapSupport-DBEeoMb8.js} +1 -1
  150. package/src/assets/web-panel/assets/{useFs-Thnu-Iaj.js → useFs-3r099cjv.js} +1 -1
  151. package/src/assets/web-panel/assets/{usePersonalDataHub-LBdOxjwY.js → usePersonalDataHub-C5IYNdTK.js} +1 -1
  152. package/src/assets/web-panel/assets/{vnode-Cg6lFY_X.js → vnode-DmEOLRHf.js} +1 -1
  153. package/src/assets/web-panel/assets/{zoom-DVfsR1YO.js → zoom-DnpUiVCB.js} +1 -1
  154. package/src/assets/web-panel/index.html +1 -1
  155. package/src/command-manifest.json +214 -50
  156. package/src/command-surface-policy.js +115 -0
  157. package/src/data/changelog.json +5 -5
  158. package/src/lib/public-ide-capability-manifest.js +6 -0
  159. package/src/repl/agent-repl.js +175 -8
  160. package/src/repl/prompt-interactions.js +67 -7
  161. package/src/repl/slash-command-registry.js +3 -4
  162. package/src/assets/web-panel/assets/ChatBubbleRenderer-DfJEo-5_.js +0 -1
  163. package/src/assets/web-panel/assets/Logs-D-W_6x09.js +0 -2
  164. package/src/assets/web-panel/assets/MarkdownRenderer-DElGPxCZ.js +0 -1
  165. package/src/assets/web-panel/assets/MobileProjects-C-HaCmSM.js +0 -1
  166. package/src/assets/web-panel/assets/OrderTableRenderer-7DVjZwMM.js +0 -1
  167. package/src/assets/web-panel/assets/devWarning-ChcCBGs7.js +0 -1
  168. package/src/assets/web-panel/assets/index-Q2IajL54.js +0 -1
  169. package/src/assets/web-panel/assets/index-bRkHgOMc.js +0 -1
@@ -123,7 +123,7 @@ import {
123
123
  } from "../runtime/agent-core.js";
124
124
  import { formatBackgroundTasks } from "./tasks-status.js";
125
125
  import { expandFileRefsAsync } from "../runtime/file-ref-expander.js";
126
- import { prepareVisionTurn } from "../lib/image-input.js";
126
+ import { prepareVisionTurn, resolveVisionLlm } from "../lib/image-input.js";
127
127
  import { composeSystemPrompt } from "../runtime/system-prompt.js";
128
128
  import { installPipeSafety } from "../runtime/pipe-safety.js";
129
129
  import {
@@ -145,6 +145,10 @@ import {
145
145
  } from "./btw-command.js";
146
146
  import { shouldStreamLive } from "./stream-decision.js";
147
147
  import { emptyTurnNotice } from "./empty-turn-notice.js";
148
+ import {
149
+ createPromptInteractionSurface,
150
+ mergeClipboardImageChips,
151
+ } from "./prompt-interactions.js";
148
152
  import {
149
153
  buildPermissionPrompt,
150
154
  resolveAskIdleTimeoutMs,
@@ -2134,6 +2138,8 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
2134
2138
  // an auto-detected image path so the REPL switches to a vision-capable model
2135
2139
  // for that turn only (resolveVisionLlm falls back to the default when unset).
2136
2140
  let _visionModel;
2141
+ let _promptInteractionConfig = {};
2142
+ let _persistPromptSuggestionsEnabled = null;
2137
2143
  // Hard stream inactivity timeout override (config.llm.streamStallTimeoutMs,
2138
2144
  // ms): a stream silent that long is aborted + retried instead of hanging.
2139
2145
  // Unset → agent-core's 180s default (matches cc chat/ask). Set to 0 to
@@ -2148,8 +2154,11 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
2148
2154
  // CC_PERMISSION_ASK_TIMEOUT_MS env > config permissions.askTimeoutMs > off.
2149
2155
  let _askIdleTimeoutMs = resolveAskIdleTimeoutMs();
2150
2156
  try {
2151
- const { loadConfig } = await import("../lib/config-manager.js");
2152
- const _cfg = loadConfig();
2157
+ const configManager = await import("../lib/config-manager.js");
2158
+ const _cfg = configManager.loadConfig();
2159
+ _promptInteractionConfig = _cfg || {};
2160
+ _persistPromptSuggestionsEnabled = (enabled) =>
2161
+ configManager.setConfigValue("cli.promptSuggestions", enabled === true);
2153
2162
  _visionModel = _cfg?.llm?.visionModel || undefined;
2154
2163
  _autoPinCfgValue = _cfg?.context?.autoPin;
2155
2164
  _askIdleTimeoutMs = resolveAskIdleTimeoutMs({
@@ -3588,11 +3597,13 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
3588
3597
  "/note-next",
3589
3598
  "/output-style",
3590
3599
  "/permissions",
3600
+ "/paste-image",
3591
3601
  "/plan",
3592
3602
  "/pr-comments",
3593
3603
  "/profile",
3594
3604
  "/provider",
3595
3605
  "/quit",
3606
+ "/recap",
3596
3607
  "/reindex",
3597
3608
  "/release-notes",
3598
3609
  "/reload-plugins",
@@ -3606,7 +3617,9 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
3606
3617
  "/stats",
3607
3618
  "/status",
3608
3619
  "/statusline",
3620
+ "/stash",
3609
3621
  "/sub-agents",
3622
+ "/suggestions",
3610
3623
  "/task",
3611
3624
  "/tasks",
3612
3625
  "/terminal-setup",
@@ -3617,6 +3630,7 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
3617
3630
  "/ultrathink",
3618
3631
  "/vim",
3619
3632
  "/voice",
3633
+ "/editor",
3620
3634
  ],
3621
3635
  // User/project custom commands (.claude/commands/*.md) join TAB completion
3622
3636
  // alongside the built-ins above. Sync + best-effort; the completer
@@ -3660,6 +3674,28 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
3660
3674
  // "close" cleanup instead of a bare exit.
3661
3675
  _replRl = rl;
3662
3676
 
3677
+ // Prompt-side interaction modules share the production readline surface.
3678
+ // A per-REPL registry avoids singleton handlers retaining an old session.
3679
+ const _promptInteractionSurface = createPromptInteractionSurface({
3680
+ readline: rl,
3681
+ config: _promptInteractionConfig,
3682
+ keybindings: _promptInteractionConfig,
3683
+ getSessionId: () => sessionId,
3684
+ getSuggestionContext: () => ({ messages: messages.slice() }),
3685
+ persistSuggestionEnabled: _persistPromptSuggestionsEnabled,
3686
+ clipboardBinding: options.clipboardBinding || null,
3687
+ generateSuggestions: options.generatePromptSuggestions,
3688
+ suggestionDebounceMs: options.promptSuggestionDebounceMs,
3689
+ screenReader: _screenReaderMode,
3690
+ write: (text) => process.stdout.write(String(text)),
3691
+ writeError: (text) => process.stderr.write(String(text)),
3692
+ getColumns: () => process.stdout.columns || 80,
3693
+ });
3694
+ const _promptInteractions = _promptInteractionSurface.controller;
3695
+ for (const diagnostic of _promptInteractions.diagnostics().keybindingErrors) {
3696
+ logger.warn(`prompt keybinding ignored: ${diagnostic}`);
3697
+ }
3698
+
3663
3699
  // MCP elicitation in the interactive REPL uses the same readline surface as
3664
3700
  // approvals, while MCPClient retains the protocol-level response shape.
3665
3701
  const mcpElicitationClients = [_adhocMcp?.mcpClient, _bundleMcpClient].filter(
@@ -3757,9 +3793,34 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
3757
3793
  // Vim-mode plumbing: capture readline's OWN keypress listeners now so we can
3758
3794
  // suspend them while in NORMAL mode (the engine drives editing then) and
3759
3795
  // reattach them for INSERT mode (readline's rich editing/history/completion).
3760
- const _rlKeypressListeners = process.stdin.isTTY
3796
+ const _nativeReadlineKeypressListeners = process.stdin.isTTY
3761
3797
  ? process.stdin.listeners("keypress").slice()
3762
3798
  : [];
3799
+ const _consumedReadlineKeypresses = new WeakSet();
3800
+ const _consumeReadlineKeypress = (key) => {
3801
+ if (key && typeof key === "object") _consumedReadlineKeypresses.add(key);
3802
+ };
3803
+ const _rlKeypressListeners = _nativeReadlineKeypressListeners.map(
3804
+ (listener) =>
3805
+ function guardedReadlineKeypress(input, key) {
3806
+ if (
3807
+ key &&
3808
+ typeof key === "object" &&
3809
+ _consumedReadlineKeypresses.has(key)
3810
+ ) {
3811
+ return;
3812
+ }
3813
+ return listener.call(this, input, key);
3814
+ },
3815
+ );
3816
+ if (process.stdin.isTTY) {
3817
+ for (const listener of _nativeReadlineKeypressListeners) {
3818
+ process.stdin.removeListener("keypress", listener);
3819
+ }
3820
+ for (const listener of _rlKeypressListeners) {
3821
+ process.stdin.on("keypress", listener);
3822
+ }
3823
+ }
3763
3824
  const _suspendReadlineKeys = () => {
3764
3825
  for (const l of _rlKeypressListeners)
3765
3826
  process.stdin.removeListener("keypress", l);
@@ -3809,11 +3870,13 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
3809
3870
  // sequences (arrows etc.) never reach here as bare "escape".
3810
3871
  let _turnAbort = null;
3811
3872
  let _lastIdleEscAt = 0;
3873
+ let _replKeypressHandler = null;
3812
3874
  if (process.stdin.isTTY) {
3813
- process.stdin.on("keypress", (_str, key) => {
3875
+ _replKeypressHandler = (_str, key) => {
3814
3876
  const k = key || {};
3815
3877
  // 1) Turn abort always wins, regardless of vim mode.
3816
3878
  if (k.name === "escape" && !k.meta && _turnAbort) {
3879
+ _consumeReadlineKeypress(key);
3817
3880
  process.stdout.write(chalk.yellow("\n⎋ interrupting…\n"));
3818
3881
  try {
3819
3882
  _turnAbort.abort();
@@ -3849,6 +3912,7 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
3849
3912
  const isShiftTab =
3850
3913
  (k.name === "tab" && k.shift) || k.sequence === "\u001b[Z";
3851
3914
  if (isShiftTab) {
3915
+ _consumeReadlineKeypress(key);
3852
3916
  if (
3853
3917
  _approvalGate &&
3854
3918
  sessionId &&
@@ -3877,14 +3941,30 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
3877
3941
  return;
3878
3942
  }
3879
3943
 
3944
+ // 1.75) Prompt interaction keybindings share the controller used by
3945
+ // slash commands. They are idle-only and stay out of Vim NORMAL mode,
3946
+ // where the modal editor owns every key.
3947
+ if (
3948
+ !_turnAbort &&
3949
+ (!_vimEnabled || !_vim) &&
3950
+ _promptInteractions.handleKeypress(_str, k)
3951
+ ) {
3952
+ _consumeReadlineKeypress(key);
3953
+ return;
3954
+ }
3955
+
3880
3956
  // 2) Vim mode: modal editing on the current input line.
3881
3957
  if (_vimEnabled && !_turnAbort) {
3882
3958
  if (!_vim) {
3883
3959
  // INSERT mode — readline owns the keys; Esc switches to NORMAL.
3884
- if (k.name === "escape" && !k.meta) _vimEnterNormal();
3960
+ if (k.name === "escape" && !k.meta) {
3961
+ _consumeReadlineKeypress(key);
3962
+ _vimEnterNormal();
3963
+ }
3885
3964
  return;
3886
3965
  }
3887
3966
  // NORMAL mode — readline suspended; the engine interprets every key.
3967
+ _consumeReadlineKeypress(key);
3888
3968
  const res = feedNormalKey(_vim, _str || "", k);
3889
3969
  if (res.submit) {
3890
3970
  // Hand the line to readline as a normal Enter (fires 'line', clears).
@@ -3906,6 +3986,7 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
3906
3986
 
3907
3987
  // 3) Non-vim: double-Esc while idle → rewind picker shortcut.
3908
3988
  if (k.name !== "escape" || k.meta) return;
3989
+ _consumeReadlineKeypress(key);
3909
3990
  const nowTs = Date.now();
3910
3991
  if (nowTs - _lastIdleEscAt < 600) {
3911
3992
  _lastIdleEscAt = 0;
@@ -3930,7 +4011,8 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
3930
4011
  } else {
3931
4012
  _lastIdleEscAt = nowTs;
3932
4013
  }
3933
- });
4014
+ };
4015
+ process.stdin.prependListener("keypress", _replKeypressHandler);
3934
4016
  }
3935
4017
 
3936
4018
  logger.log(chalk.bold("\nChainlessChain Agent"));
@@ -4206,6 +4288,19 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
4206
4288
  return;
4207
4289
  }
4208
4290
 
4291
+ // The interaction commands are registered through the shared registry,
4292
+ // while the mature REPL handlers below remain on their existing direct
4293
+ // paths. --disable-slash-commands replaces `trimmed` with a sentinel, so
4294
+ // it cannot accidentally reach this dispatcher.
4295
+ if (trimmed.startsWith("/")) {
4296
+ const commandName = trimmed.split(/\s+/, 1)[0];
4297
+ if (_promptInteractionSurface.commandNames.has(commandName)) {
4298
+ await _promptInteractionSurface.dispatchSlash(trimmed);
4299
+ prompt();
4300
+ return;
4301
+ }
4302
+ }
4303
+
4209
4304
  if (trimmed === "/help") {
4210
4305
  logger.log(chalk.bold("\nCommands:"));
4211
4306
  logger.log(
@@ -4264,6 +4359,21 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
4264
4359
  logger.log(
4265
4360
  ` ${chalk.cyan("/output-style")} Response persona (/output-style <name|list>; explanatory/learning built-in)`,
4266
4361
  );
4362
+ logger.log(
4363
+ ` ${chalk.cyan("/editor")} Edit a draft prompt in an external editor`,
4364
+ );
4365
+ logger.log(
4366
+ ` ${chalk.cyan("/stash")} Stash/list/pop/clear draft prompts`,
4367
+ );
4368
+ logger.log(
4369
+ ` ${chalk.cyan("/recap")} Show a lightweight session recap`,
4370
+ );
4371
+ logger.log(
4372
+ ` ${chalk.cyan("/suggestions")} Prompt suggestions on|off|status|refresh`,
4373
+ );
4374
+ logger.log(
4375
+ ` ${chalk.cyan("/paste-image")} Attach a clipboard image from a supporting host`,
4376
+ );
4267
4377
  logger.log(
4268
4378
  ` ${chalk.cyan("/config")} Show config; ${chalk.cyan("/config <key>")} read, ${chalk.cyan("/config <key>=<val>")} set, ${chalk.cyan("/config --help")} keys`,
4269
4379
  );
@@ -7364,6 +7474,35 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
7364
7474
  return;
7365
7475
  }
7366
7476
 
7477
+ // Explicit clipboard attachment chips are consumed only when a real model
7478
+ // turn is about to start. They compose with auto-detected path images and
7479
+ // enter the same provider-neutral multimodal message/vision override.
7480
+ const clipboardImageChips = _promptInteractions.takeClipboardImageChips();
7481
+ const clipboardMerge = mergeClipboardImageChips(
7482
+ _userMessageContent,
7483
+ clipboardImageChips,
7484
+ );
7485
+ if (clipboardMerge.attached > 0) {
7486
+ _userMessageContent = clipboardMerge.content;
7487
+ if (!_visionLlm) {
7488
+ _visionLlm = resolveVisionLlm({
7489
+ hasImage: true,
7490
+ flags: {},
7491
+ llm: {
7492
+ provider,
7493
+ baseUrl,
7494
+ apiKey,
7495
+ visionModel: _visionModel,
7496
+ },
7497
+ });
7498
+ }
7499
+ logger.info(
7500
+ chalk.gray(
7501
+ `[image] ${clipboardMerge.attached} clipboard image(s) attached -> vision model ${_visionLlm.model}`,
7502
+ ),
7503
+ );
7504
+ }
7505
+
7367
7506
  // Add user message (keep the object ref so /note-next can be injected for
7368
7507
  // this turn's model call and then stripped before persistence).
7369
7508
  const _userMsg = { role: "user", content: _userMessageContent };
@@ -7426,7 +7565,17 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
7426
7565
  .map(([k, v]) => `${k}: ${v}`);
7427
7566
  // Append context to the last user message
7428
7567
  const lastMsg = messages[messages.length - 1];
7429
- lastMsg.content += `\n\n[Context — user provided: ${parts.join(", ")}]`;
7568
+ const slotContext = `[Context - user provided: ${parts.join(", ")}]`;
7569
+ if (Array.isArray(lastMsg.content)) {
7570
+ const textPart = lastMsg.content.find(
7571
+ (part) => part?.type === "text",
7572
+ );
7573
+ if (textPart)
7574
+ textPart.text = `${textPart.text}\n\n${slotContext}`;
7575
+ else lastMsg.content.unshift({ type: "text", text: slotContext });
7576
+ } else {
7577
+ lastMsg.content = `${lastMsg.content}\n\n${slotContext}`;
7578
+ }
7430
7579
  logger.info(chalk.gray(`[slot-fill] ${parts.join(", ")}`));
7431
7580
  }
7432
7581
  }
@@ -7868,6 +8017,15 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
7868
8017
  );
7869
8018
  }
7870
8019
 
8020
+ // Generate follow-up suggestions from the settled assistant turn. The
8021
+ // controller snapshots the actual conversation context and debounces in
8022
+ // the background, so readline and persistence remain non-blocking.
8023
+ const suggestionRun = _promptInteractions.scheduleSuggestions({
8024
+ messages: messages.slice(),
8025
+ lastAssistantText: effectiveResponse || "",
8026
+ });
8027
+ void suggestionRun.promise;
8028
+
7871
8029
  // Auto-save session
7872
8030
  if (sessionId) {
7873
8031
  try {
@@ -8046,6 +8204,15 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
8046
8204
  });
8047
8205
 
8048
8206
  rl.on("close", async () => {
8207
+ _promptInteractions.dispose();
8208
+ if (process.stdin.isTTY) {
8209
+ if (_replKeypressHandler) {
8210
+ process.stdin.removeListener("keypress", _replKeypressHandler);
8211
+ }
8212
+ for (const listener of _rlKeypressListeners) {
8213
+ process.stdin.removeListener("keypress", listener);
8214
+ }
8215
+ }
8049
8216
  // Leave the alternate screen buffer first so the terminal is restored to
8050
8217
  // the user's scrollback no matter how the REPL exits.
8051
8218
  if (_tuiMode === "fullscreen" && process.stdout.isTTY) {
@@ -21,6 +21,7 @@ import {
21
21
  readClipboardImageChip,
22
22
  } from "./clipboard-image.js";
23
23
  import { layoutTerminalText } from "./terminal-layout.js";
24
+ import { SlashCommandRegistry } from "./slash-command-registry.js";
24
25
 
25
26
  function commandArgs(line, command) {
26
27
  const text = String(line || "");
@@ -80,6 +81,29 @@ export function registerPromptInteractionCommands(registry, controller) {
80
81
  return PROMPT_INTERACTION_SLASH_COMMANDS.map((command) => command.name);
81
82
  }
82
83
 
84
+ /** Build one session-local controller + registry dispatcher for production. */
85
+ export function createPromptInteractionSurface(options = {}) {
86
+ const controller =
87
+ options.controller || new PromptInteractionController(options);
88
+ const registry = options.registry || new SlashCommandRegistry();
89
+ const commandNames = new Set(
90
+ registerPromptInteractionCommands(registry, controller),
91
+ );
92
+ return {
93
+ controller,
94
+ registry,
95
+ commandNames,
96
+ async dispatchSlash(line) {
97
+ const text = String(line || "").trim();
98
+ const commandName = text.split(/\s+/, 1)[0];
99
+ if (!commandNames.has(commandName)) return { handled: false };
100
+ const command = registry.getCommand(commandName);
101
+ const args = text.slice(commandName.length).trim();
102
+ return command.handler(args);
103
+ },
104
+ };
105
+ }
106
+
83
107
  export class PromptInteractionController {
84
108
  constructor(options = {}) {
85
109
  this.readline = options.readline || null;
@@ -96,6 +120,10 @@ export class PromptInteractionController {
96
120
  typeof options.getSessionId === "function"
97
121
  ? options.getSessionId
98
122
  : () => options.sessionId || null;
123
+ this.getSuggestionContext =
124
+ typeof options.getSuggestionContext === "function"
125
+ ? options.getSuggestionContext
126
+ : () => ({});
99
127
  this.screenReader = options.screenReader === true;
100
128
  this.getColumns =
101
129
  typeof options.getColumns === "function"
@@ -160,6 +188,22 @@ export class PromptInteractionController {
160
188
  this._print(`\n${renderPromptSuggestions(suggestions)}`, { refresh: true });
161
189
  }
162
190
 
191
+ _suggestionContext(overrides = {}) {
192
+ let live = {};
193
+ try {
194
+ const value = this.getSuggestionContext();
195
+ if (value && typeof value === "object") live = value;
196
+ } catch {
197
+ // Suggestion context is optional polish and cannot break prompt input.
198
+ }
199
+ return {
200
+ ...live,
201
+ ...overrides,
202
+ sessionId:
203
+ overrides.sessionId || live.sessionId || this.getSessionId() || null,
204
+ };
205
+ }
206
+
163
207
  diagnostics() {
164
208
  return {
165
209
  keybindingErrors: this.keybindingDiagnostics.slice(),
@@ -219,7 +263,7 @@ export class PromptInteractionController {
219
263
  const result = runPromptSuggestionsCommand(suggestionArgs, {
220
264
  controller: this.suggestions,
221
265
  persistEnabled: this.persistSuggestionEnabled,
222
- context: optionsContext(this.getSessionId()),
266
+ context: this._suggestionContext(),
223
267
  });
224
268
  this._print(result.message, { error: !result.ok });
225
269
  return { handled: true, ...result };
@@ -321,10 +365,7 @@ export class PromptInteractionController {
321
365
  }
322
366
 
323
367
  scheduleSuggestions(context = {}) {
324
- return this.suggestions.schedule({
325
- ...context,
326
- sessionId: context.sessionId || this.getSessionId(),
327
- });
368
+ return this.suggestions.schedule(this._suggestionContext(context));
328
369
  }
329
370
 
330
371
  takeClipboardImageChips() {
@@ -339,6 +380,25 @@ export class PromptInteractionController {
339
380
  }
340
381
  }
341
382
 
342
- function optionsContext(sessionId) {
343
- return { sessionId: sessionId || null };
383
+ /**
384
+ * Merge host-provided clipboard image chips into a prepared user message.
385
+ * Only bounded data-image blocks produced by clipboard-image.js are accepted;
386
+ * a host cannot smuggle a remote URL into the model through this seam.
387
+ */
388
+ export function mergeClipboardImageChips(content, chips = []) {
389
+ const accepted = (Array.isArray(chips) ? chips : []).filter(
390
+ (chip) =>
391
+ chip?.type === "image_url" &&
392
+ /^data:image\/(?:png|jpeg|gif|webp);base64,[A-Za-z0-9+/]+={0,2}$/u.test(
393
+ String(chip.image_url?.url || ""),
394
+ ),
395
+ );
396
+ if (!accepted.length) return { content, attached: 0 };
397
+ const parts = Array.isArray(content)
398
+ ? content.slice()
399
+ : String(content || "")
400
+ ? [{ type: "text", text: String(content) }]
401
+ : [];
402
+ parts.push(...accepted);
403
+ return { content: parts, attached: accepted.length };
344
404
  }
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { formatBackgroundTasks } from "./tasks-status.js";
7
- import { runDoctorChecks } from "./doctor-status.js";
7
+ import { buildDoctorChecks, renderDoctor } from "./doctor-status.js";
8
8
 
9
9
  export class SlashCommandRegistry {
10
10
  static _instance = null;
@@ -124,9 +124,8 @@ export class SlashCommandRegistry {
124
124
  [
125
125
  "/doctor",
126
126
  "Check system health",
127
- async (args, { write }) => {
128
- write("Running system diagnostics...");
129
- await runDoctorChecks(write);
127
+ (args, { write, doctorInput = {} }) => {
128
+ write(renderDoctor(buildDoctorChecks(doctorInput)));
130
129
  },
131
130
  ],
132
131
  [
@@ -1 +0,0 @@
1
- import{I as v,P as u,J as S,U as n,R as a,S as y,K as C,Q as x,V as w,_ as B,b as s}from"./vendor-Bn1JzzAn.js";import{_ as T}from"./index-DBpWXFed.js";import"./icons-DG5UD-6K.js";const k={__name:"ChatBubbleRenderer",props:{event:{type:Object,required:!0}},setup(c,{expose:d}){d();const t=c,r=s(()=>{const e=t.event.content||{};return e.text||e.body||e.message||e.title||JSON.stringify(e).slice(0,200)}),i=s(()=>{const e=t.event.content||{};return e.from||e.sender||e.senderName||t.event.actor||"(unknown)"}),l=s(()=>{const e=(t.event.actor||"").toLowerCase();return e.includes("self")||e==="me"||e.endsWith("_self")}),o=s(()=>{const e=t.event.source.adapter||"";return e.startsWith("messaging-qq")?"magenta":e==="wechat"?"green":"blue"}),m=s(()=>{if(!t.event.occurredAt)return"";try{const e=new Date(t.event.occurredAt),p=e.getFullYear(),f=String(e.getMonth()+1).padStart(2,"0"),g=String(e.getDate()).padStart(2,"0"),b=String(e.getHours()).padStart(2,"0"),h=String(e.getMinutes()).padStart(2,"0");return`${p}-${f}-${g} ${b}:${h}`}catch{return""}}),_={props:t,messageText:r,actorLabel:i,isMine:l,adapterColor:o,formattedTime:m,computed:s};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}},N={class:"bubble"},R={class:"meta"},M={class:"actor"},V={class:"time"},q={class:"body"};function D(c,d,t,r,i,l){const o=v("a-tag");return u(),S("div",{class:B(["chat-row",{mine:r.isMine}])},[n("div",N,[n("div",R,[n("span",M,a(r.actorLabel),1),n("span",V,a(r.formattedTime),1)]),n("div",q,a(r.messageText),1),t.event.source.adapter?(u(),y(o,{key:0,class:"src",color:r.adapterColor},{default:C(()=>[x(a(t.event.source.adapter),1)]),_:1},8,["color"])):w("v-if",!0)])],2)}const j=T(k,[["render",D],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-RQTT6I/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{j as default};
@@ -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 W,Z as K,w as H,n as C,o as M,b as T,r,P as p,Q as O,_ as U}from"./vendor-Bn1JzzAn.js";import{_ as E,u as N}from"./index-DBpWXFed.js";import{R as I}from"./icons-DG5UD-6K.js";const j={__name:"Logs",setup(Q,{expose:a}){a();const x=N(),e=r("status"),y=r(!1),v=r(""),i=r(""),c=r(""),f=r(!0),o=r(null),h={status:"status",doctor:"doctor","skill-sources":"skill sources","llm-providers":"llm providers"},m=T(()=>i.value.split(`
2
- `)),b=T(()=>{if(!c.value)return m.value;const t=c.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(!c.value)return t;const u=c.value.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return t.replace(new RegExp(`(${u})`,"gi"),"<mark>$1</mark>")}async function R(){y.value=!0,v.value="",i.value="";const t=h[e.value]||"status";try{const{output:u}=await x.execute(t,3e4);i.value=u,f.value&&(await C(),o.value&&(o.value.scrollTop=o.value.scrollHeight))}catch(u){v.value=`执行失败: ${u.message}`,i.value=v.value}finally{y.value=!1}}H(b,async()=>{f.value&&(await C(),o.value&&(o.value.scrollTop=o.value.scrollHeight))}),M(R);const B={ws:x,activeTab:e,loading:y,error:v,rawOutput:i,searchQuery:c,autoScroll:f,logContainer:o,TAB_COMMANDS:h,allLines:m,filteredLines:b,lineClass:L,escapeHtml:l,highlightSearch:w,loadLog:R,ref:r,computed:T,watch:H,nextTick:C,onMounted:M,get ReloadOutlined(){return I},get useWsStore(){return N}};return Object.defineProperty(B,"__isScriptSetup",{enumerable:!1,value:!0}),B}},q={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},z={style:{display:"flex",gap:"10px",margin:"12px 0"}},A={ref:"logContainer",class:"log-box"},D={key:0,style:{"text-align":"center",padding:"40px",color:"var(--text-muted)"}},F={key:1,style:{"text-align":"center",padding:"40px",color:"var(--text-muted)"}},P={key:2},J=["innerHTML"];function Z(Q,a,x,e,y,v){const i=s("a-checkbox"),c=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",q,[a[5]||(a[5]=d("div",null,[d("h2",{class:"page-title"},"日志查看"),d("p",{class:"page-sub"},"系统运行日志与诊断输出")],-1)),n(f,null,{default:_(()=>[n(i,{checked:e.autoScroll,"onUpdate:checked":a[0]||(a[0]=l=>e.autoScroll=l)},{default:_(()=>[...a[3]||(a[3]=[O("自动滚动",-1)])]),_:1},8,["checked"]),n(c,{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",z,[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",A,[e.loading?(p(),g("div",D,[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(W,null,K(e.filteredLines,(l,w)=>(p(),g("div",{key:w,class:U(["log-line",e.lineClass(l)]),innerHTML:e.highlightSearch(e.escapeHtml(l))},null,10,J))),128))])):(p(),g("div",F,S(e.error||"暂无日志内容,点击刷新加载"),1))],512)])}const $=E(j,[["render",Z],["__scopeId","data-v-8c2906e0"],["__file","/tmp/cc-web-panel-RQTT6I/repo/packages/web-panel/src/views/Logs.vue"]]);export{$ as default};
@@ -1 +0,0 @@
1
- import{P as c,J as p,b as s}from"./vendor-Bn1JzzAn.js";import{r as a}from"./markdown-Yo_c6Krv.js";import{_ as d}from"./index-DBpWXFed.js";const _={__name:"MarkdownRenderer",props:{content:{type:String,default:""}},setup(t,{expose:o}){o();const e=t,r=s(()=>a(e.content||"")),n={props:e,rendered:r,computed:s,get renderMarkdown(){return a}};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}},i=["innerHTML"];function m(t,o,e,r,n,u){return c(),p("div",{class:"markdown-content",innerHTML:r.rendered},null,8,i)}const w=d(_,[["render",m],["__scopeId","data-v-0b0b9f63"],["__file","/tmp/cc-web-panel-RQTT6I/repo/packages/web-panel/src/components/MarkdownRenderer.vue"]]);export{w as M};
@@ -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-Bn1JzzAn.js";import{_ as v,b as m}from"./index-DBpWXFed.js";import{a8 as y,M}from"./icons-DG5UD-6K.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"},T={class:"subtitle"},k={class:"explainer"};function w(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",T,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",k,[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",w],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-RQTT6I/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 T,b as a}from"./vendor-Bn1JzzAn.js";import{_ as S}from"./index-DBpWXFed.js";import"./icons-DG5UD-6K.js";const k={__name:"OrderTableRenderer",props:{event:{type:Object,required:!0}},setup(p,{expose:r}){r();const o=p,e=a(()=>o.event.content||{}),d=a(()=>o.event.extra||{}),m=a(()=>d.value.merchant||e.value.merchant||e.value.counterparty||"—"),c=a(()=>e.value.title||e.value.name||e.value.itemName||e.value.text||"—"),g=a(()=>{const t=e.value.amount??e.value.price??e.value.total;return t==null?"—":`${e.value.currency||"¥"} ${typeof t=="number"?t.toFixed(2):t}`}),y=a(()=>d.value.orderNo||e.value.orderNo||e.value.orderId),f=a(()=>e.value.status||e.value.state),b=a(()=>{const t=(f.value||"").toLowerCase();return t.includes("成功")||t.includes("succe")||t.includes("paid")?"green":t.includes("退")||t.includes("refund")?"orange":t.includes("失败")||t.includes("fail")?"red":"default"}),h=a(()=>{if(!o.event.occurredAt)return"";const t=new Date(o.event.occurredAt);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}),x={props:o,c:e,e:d,merchantText:m,itemText:c,amountText:g,orderNo:y,statusText:f,statusColor:b,formattedTime:h,computed:a};return Object.defineProperty(x,"__isScriptSetup",{enumerable:!1,value:!0}),x}},N={class:"order-card"},C={class:"head"},O={class:"time"},R={class:"row"},V={class:"val"},I={class:"row"},B={class:"val"},D={class:"row amount-row"},j={class:"val amount"},A={key:0,class:"row"},F={class:"val mono"},M={key:1,class:"row"};function P(p,r,o,e,d,m){const c=w("a-tag");return l(),u("div",N,[s("div",C,[s("span",O,n(e.formattedTime),1),i(c,{color:"gold"},{default:v(()=>[_(n(o.event.source.adapter),1)]),_:1}),i(c,null,{default:v(()=>[_(n(o.event.subtype),1)]),_:1})]),s("div",R,[r[0]||(r[0]=s("span",{class:"key"},"商户",-1)),s("span",V,n(e.merchantText),1)]),s("div",I,[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",j,n(e.amountText),1)]),e.orderNo?(l(),u("div",A,[r[3]||(r[3]=s("span",{class:"key"},"单号",-1)),s("span",F,n(e.orderNo),1)])):T("v-if",!0),e.statusText?(l(),u("div",M,[r[4]||(r[4]=s("span",{class:"key"},"状态",-1)),i(c,{color:e.statusColor},{default:v(()=>[_(n(e.statusText),1)]),_:1},8,["color"])])):T("v-if",!0)])}const J=S(k,[["render",P],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-RQTT6I/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{J as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-DBpWXFed.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-CN04HxWR.js";import{a0 as t}from"./index-DBpWXFed.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-8w16YR2D.js";import"./useFlexGapSupport-hiJWMU5y.js";import"./styleChecker-CmDyreec.js";import"./index-AWg-0M1S.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-CNOd8mdQ.js";import{a0 as t}from"./index-DBpWXFed.js";import"./vendor-Bn1JzzAn.js";import"./index-AWg-0M1S.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};