zen-gitsync 2.18.11 → 2.18.13

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 (94) hide show
  1. package/README.md +14 -14
  2. package/package.json +6 -1
  3. package/src/cli/ai/agent.js +1385 -1385
  4. package/src/cli/ai/context.js +431 -431
  5. package/src/cli/ai/context.test.js +376 -376
  6. package/src/cli/ai/turn.js +190 -190
  7. package/src/ui/public/assets/AgentView-CuEM6xzC.js +11 -0
  8. package/src/ui/public/assets/{AgentView-CbBLjlfr.css → AgentView-D6MJOrJt.css} +1 -1
  9. package/src/ui/public/assets/AppVersionBadge-BK1Fiv3b.js +2 -0
  10. package/src/ui/public/assets/BranchSelector-avxY_m05.js +1 -0
  11. package/src/ui/public/assets/CommitForm-hThTnoNt.js +14 -0
  12. package/src/ui/public/assets/CommonDialog-zaBdFGFH.js +1 -0
  13. package/src/ui/public/assets/CopySessionButton-CAxaqLQL.js +21 -0
  14. package/src/ui/public/assets/EditorView-B7Rq9QV1.css +1 -0
  15. package/src/ui/public/assets/EditorView-iSA2SXJR.js +37 -0
  16. package/src/ui/public/assets/{FlowExecutionViewer-D7FaZSHd.js → FlowExecutionViewer-C5ylYV2C.js} +1 -1
  17. package/src/ui/public/assets/FlowOrchestrationWorkspace-CiQ07ZQv.js +21 -0
  18. package/src/ui/public/assets/LogList-Sjb8vmvq.js +7 -0
  19. package/src/ui/public/assets/MindmapView-B5rChFMP.js +2 -0
  20. package/src/ui/public/assets/MonitorView-Dcc-i2Fo.js +3 -0
  21. package/src/ui/public/assets/ProjectStartupButton-fz6eLCZU.js +1 -0
  22. package/src/ui/public/assets/RecentDirectoriesChat-BDnNp9jh.js +3 -0
  23. package/src/ui/public/assets/RemoteManagerDialog-NA1jRC7O.js +4 -0
  24. package/src/ui/public/assets/RemoteRepoCard-CKm4KqHs.js +7 -0
  25. package/src/ui/public/assets/SourceMapView-Drfato_u.js +3 -0
  26. package/src/ui/public/assets/SvgIcon-DR_79iBR.js +1 -0
  27. package/src/ui/public/assets/UserInputNode-DroKvDOa.js +1 -0
  28. package/src/ui/public/assets/WorkbenchView-CW7OACCU.js +326 -0
  29. package/src/ui/public/assets/WorkbenchView-C_u6BptZ.css +1 -0
  30. package/src/ui/public/assets/_plugin-vue_export-helper-bQQyMRS6.js +19 -0
  31. package/src/ui/public/assets/agentConversations-wYAksLq1.js +10 -0
  32. package/src/ui/public/assets/{configStore-Z6Z8hVMO.js → configStore-BeHB-gV4.js} +1 -1
  33. package/src/ui/public/assets/{css.worker-BDCmgL4U.js → css.worker-DFdt6_zu.js} +9 -9
  34. package/src/ui/public/assets/{dagre-CiGYsZhd.js → dagre-CXi8gaG9.js} +4 -4
  35. package/src/ui/public/assets/editor.worker-O-CH8JUO.js +26 -0
  36. package/src/ui/public/assets/{element-plus-D-6gla1z.css → element-plus-DJ3ZQa98.css} +1 -1
  37. package/src/ui/public/assets/element-plus-DgSY_Wt4.js +48 -0
  38. package/src/ui/public/assets/{flow-mindmap-C-X_QPQI.js → flow-mindmap-BsTRkgat.js} +56 -56
  39. package/src/ui/public/assets/{html.worker-DG8hnSJR.js → html.worker-JUzsMP-j.js} +8 -8
  40. package/src/ui/public/assets/index-BRQstBzy.js +211 -0
  41. package/src/ui/public/assets/json.worker-B4dEhy0e.js +58 -0
  42. package/src/ui/public/assets/{monaco-CbN14ZVi.js → monaco-CnWeufxc.js} +6 -6
  43. package/src/ui/public/assets/{office-docx-8MF5-THx.js → office-docx-EUfAIM4w.js} +6 -6
  44. package/src/ui/public/assets/{office-excel-BTzQyK6y.js → office-excel-BZW0bXQo.js} +1 -1
  45. package/src/ui/public/assets/{office-pptx-DhxvWA0D.js → office-pptx-CBvDNZ4m.js} +3 -3
  46. package/src/ui/public/assets/{ts.worker-DgFMIcEs.js → ts.worker-CmEKzkmF.js} +49 -49
  47. package/src/ui/public/assets/useOrchestrator-Bhl7DGKW.js +1 -0
  48. package/src/ui/public/assets/{vendor-Bd8DyOF9.css → vendor-CSFGMcMB.css} +1 -1
  49. package/src/ui/public/assets/{vendor-Cd7TGb0b.js → vendor-CZlKgriV.js} +43 -43
  50. package/src/ui/public/assets/vue-flow-DawpR_uk.js +39 -0
  51. package/src/ui/public/index.html +13 -13
  52. package/src/ui/server/routes/config.js +1348 -1348
  53. package/src/ui/server/routes/fileOpen.js +85 -16
  54. package/src/ui/server/routes/workbench/agentChat.js +752 -752
  55. package/src/ui/server/routes/workbench/agentChatShared.test.js +496 -497
  56. package/src/ui/server/routes/workbench/agentRoutes.js +13 -1
  57. package/src/ui/server/routes/workbench/agentRoutes.test.js +75 -0
  58. package/src/ui/server/routes/workbench/dispatchInstruction.js +6 -7
  59. package/src/ui/server/routes/workbench/dispatchInstruction.test.js +3 -19
  60. package/src/ui/server/routes/workbench/index.js +8 -17
  61. package/src/ui/server/routes/workbench/orchestratorPrompt.test.js +2 -2
  62. package/src/ui/server/routes/workbench/orchestratorStore.js +2 -16
  63. package/src/ui/server/routes/workbench/projectRegistry.test.js +1 -5
  64. package/src/ui/server/routes/workbench/scheduleRoutes.js +2 -2
  65. package/src/ui/server/routes/workbench/shared.js +18 -1
  66. package/src/ui/public/assets/AgentView-D3I3D3YR.js +0 -11
  67. package/src/ui/public/assets/AppVersionBadge-CrDf0lYs.js +0 -2
  68. package/src/ui/public/assets/BranchSelector-DEHLVln4.js +0 -1
  69. package/src/ui/public/assets/CommitForm-D2rVFZf2.js +0 -14
  70. package/src/ui/public/assets/CommonDialog-CV7T8OCb.js +0 -1
  71. package/src/ui/public/assets/CopySessionButton-BbVtrOa7.js +0 -21
  72. package/src/ui/public/assets/EditorView-BiNRO222.css +0 -1
  73. package/src/ui/public/assets/EditorView-CiW0kkpS.js +0 -37
  74. package/src/ui/public/assets/FlowOrchestrationWorkspace-BR3cPhyU.js +0 -21
  75. package/src/ui/public/assets/LogList-D_Q3pyMF.js +0 -7
  76. package/src/ui/public/assets/MindmapView-A4QZ6_c3.js +0 -2
  77. package/src/ui/public/assets/MonitorView-BljWw76B.js +0 -3
  78. package/src/ui/public/assets/ProjectStartupButton-Be5DovFL.js +0 -1
  79. package/src/ui/public/assets/RecentDirectoriesChat-DN7ruCU7.js +0 -3
  80. package/src/ui/public/assets/RemoteManagerDialog-BSCNy4RC.js +0 -4
  81. package/src/ui/public/assets/RemoteRepoCard-CeCRQp9p.js +0 -7
  82. package/src/ui/public/assets/SourceMapView-B_S-vspy.js +0 -3
  83. package/src/ui/public/assets/SvgIcon-9IbiSszR.js +0 -1
  84. package/src/ui/public/assets/UserInputNode-DASGnUCl.js +0 -1
  85. package/src/ui/public/assets/WorkbenchView-B3v-0vWa.js +0 -305
  86. package/src/ui/public/assets/WorkbenchView-DO2ndsES.css +0 -1
  87. package/src/ui/public/assets/_plugin-vue_export-helper-zp6tdw8N.js +0 -19
  88. package/src/ui/public/assets/agentConversations-Cplq42kA.js +0 -10
  89. package/src/ui/public/assets/editor.worker-GCPm6rMv.js +0 -26
  90. package/src/ui/public/assets/element-plus-CJqN49tX.js +0 -48
  91. package/src/ui/public/assets/index-C90dYckz.js +0 -211
  92. package/src/ui/public/assets/json.worker-CxwlJRnL.js +0 -58
  93. package/src/ui/public/assets/useOrchestrator-C3wjJ7p4.js +0 -1
  94. package/src/ui/public/assets/vue-flow-x4TlHHzT.js +0 -39
@@ -1,190 +1,190 @@
1
- import { executeTool, splitToolOutput, toolMessageContent } from './tools.js'
2
- import { streamChatOnce } from './transport.js'
3
- import { createThinkFilter } from './streamFilter.js'
4
- import { imageToDataUrl } from './images.js'
5
- import { prepareRequestMessages } from './context.js'
6
- import { createTurnStats, addUsage, accumulateSessionStats } from './telemetry.js'
7
- import { recordTurnTiming } from './sessionStore.js'
8
- import * as terminal from './termui.js'
9
-
10
- // 「等人」型工具:执行期间会接管输入行、停下来等用户作答(目前只有 ask_user)。
11
- // 这类工具不能转工具 spinner —— ora 每 80ms 在同一行 clearLine + 重绘,会把
12
- // readline 刚画出的提示符(「请输入序号或直接输入回答:」)连同用户正在敲的字
13
- // 一起清掉,屏幕上只剩下一个不断跳秒数的「执行 ask_user...」,看起来就像"选不了"。
14
- // 它自己的交互界面(问题 + 编号选项 + 提示符)就是进度提示,不需要再叠一层。
15
- const INTERACTIVE_TOOLS = new Set(['ask_user'])
16
-
17
- export async function runAgentTurn(state, userText, t, images = [], dependencies = {}) {
18
- const chat = dependencies.chat || streamChatOnce
19
- const baseExecute = dependencies.execute || executeTool
20
- // 扩展(目前是 MCP)工具按名字分流:名字属于扩展就走扩展,否则回落内置工具。
21
- // 必须先用 owns() 判断 —— 不能把所有调用都先喂给扩展再靠 null 回落,
22
- // 那样每个内置工具都会多绕一层,而且扩展端也无法假设"进来的都是自己的"。
23
- // 没装扩展时 owns() 恒为 false,等价于直接调内置工具,零开销。
24
- const extensions = dependencies.extensions || state.extensions
25
- const execute = extensions
26
- ? async (name, args, ctx) => {
27
- if (extensions.owns?.(name)) {
28
- const output = await extensions.execute(name, args, ctx)
29
- if (output !== null && output !== undefined) return output
30
- }
31
- return baseExecute(name, args, ctx)
32
- }
33
- : baseExecute
34
- const ui = { ...terminal, ...dependencies.ui }
35
- const stats = createTurnStats()
36
- const started = performance.now()
37
- const cancelled = () => state.cancelRequested || state.abortController?.signal.aborted
38
- const checkpoint = () => state.persistSession?.()
39
- const recordUsage = usage => {
40
- if (!usage) return
41
- stats.usageRequests++
42
- stats.usage = addUsage(stats.usage, usage)
43
- }
44
- // 本轮是第几轮(0 基 user 序号),供 finally 里记用时用。
45
- // 声明在 try 外面:finally 看不到 try 块里的 const,而 -1 正好是"这轮没轮到记"的哨兵值
46
- let turnIndex = -1
47
- try {
48
- let userContent = userText
49
- if (images.length) {
50
- userContent = [{ type: 'text', text: userText }]
51
- for (const img of images) {
52
- try { userContent.push({ type: 'image_url', image_url: { url: await imageToDataUrl(img.path) } }) }
53
- catch { ui.printWarn(t.imageBadPath(img.path)) }
54
- }
55
- }
56
- // 本轮用时记录要对齐到"第几条 user 消息",序号得在这条消息入栈之前取
57
- // (与 Web 侧 agentRoutes.js 同一口径,见 sessionStore.js 的 recordTurnTiming)
58
- turnIndex = state.messages.filter(m => m?.role === 'user').length
59
- state.messages.push({ role: 'user', content: userContent })
60
- await checkpoint()
61
-
62
- // 兜底只在 state.maxToolIterations 缺失/非正数时生效,正常路径由 loadConfig 规范化后传入。
63
- // 默认值与 config.js 的 aiMaxToolIterations 保持一致(1000),别让两处悄悄分叉。
64
- const maxIterations = state.maxToolIterations > 0 ? state.maxToolIterations : 1000
65
- for (let iter = 0; iter < maxIterations; iter++) {
66
- if (cancelled()) { stats.status = 'cancelled'; return stats }
67
- const spinner = ui.startSpinner(t.waiting)
68
- // 一次请求可能被传输层自动重试多次(长静默 / 网关 5xx / 流中断)。
69
- // 每次尝试都换一套 writer + filter:终端没法把已经打出去的字擦掉,
70
- // 与其让两次尝试的输出拼在一起,不如把上一截收尾、重开一块新的(中间一行重试提示)。
71
- const makeWriter = () => ui.createAssistantWriter({
72
- showThinking: state.showThinking !== false,
73
- thinkingHeader: t.thinkingLabel,
74
- answerHeader: t.answerLabel,
75
- thinkingLimit: state.thinkingMode === 'compact' ? terminal.THINKING_PREVIEW_LINES : Infinity,
76
- thinkingHint: t.thinkingHint,
77
- })
78
- let writer = makeWriter()
79
- let filter = createThinkFilter()
80
- const render = seg => {
81
- if (seg.content) {
82
- if (seg.content.trim() && stats.firstAnswerMs === null) stats.firstAnswerMs = performance.now() - started
83
- writer.writeContent(seg.content)
84
- } else if (seg.thinking) writer.writeThinking(seg.thinking)
85
- }
86
- let result
87
- const llmStart = performance.now()
88
- stats.requests++
89
- try {
90
- // 统一入口(与 Web 智能体面板共用):有界化 + 旧图片降级 + 消毒,只作用于请求副本,
91
- // 磁盘上的完整会话记录不受影响。
92
- // 预算来自 state.requestBudget(agent.js 按全局配置 aiMaxRequestTokens 解析);
93
- // 缺失时 prepareRequestMessages 各自兜底默认值,老调用方不用改。
94
- const messages = prepareRequestMessages(state.messages, { locale: state.locale, ...(state.requestBudget || {}) })
95
- result = await chat({ model: state.model, messages, signal: state.abortController?.signal,
96
- sessionId: state.sessionId, extraTools: extensions?.tools,
97
- onRetry: info => {
98
- filter.flush().forEach(render)
99
- writer.finish()
100
- ui.printWarn(t.llmRetrying(info.attempt, info.maxRetries, info.error?.message || ''))
101
- writer = makeWriter()
102
- filter = createThinkFilter()
103
- // 重试是一次**真的**请求,计入本轮请求数(/stats 里那个"请求数"要能对得上网关账单)
104
- stats.requests++
105
- stats.retries++
106
- },
107
- onToken: token => {
108
- if (stats.firstTokenMs === null) stats.firstTokenMs = performance.now() - started
109
- if (token.content || (token.thinking && state.showThinking !== false)) spinner.stop()
110
- if (token.thinking) render({ thinking: token.thinking })
111
- if (token.content) filter.feed(token.content).forEach(render)
112
- } })
113
- recordUsage(result.usage)
114
- } catch (err) {
115
- recordUsage(err.usage)
116
- throw err
117
- } finally {
118
- stats.llmMs += performance.now() - llmStart
119
- spinner.stop()
120
- filter.flush().forEach(render)
121
- writer.finish()
122
- }
123
- if (result.aborted || cancelled()) {
124
- if (result.content) state.messages.push({ role: 'assistant', content: result.content })
125
- stats.status = 'cancelled'; return stats
126
- }
127
- const { content, toolCalls } = result
128
- const assistant = { role: 'assistant', content: content || null }
129
- if (result.reasoning) assistant.reasoning_content = result.reasoning
130
- if (!toolCalls.length) {
131
- if (!content?.trim()) throw new Error(t.emptyResponse)
132
- state.messages.push(assistant)
133
- stats.status = 'completed'; return stats
134
- }
135
- // Assign fallback IDs once, so every result references its assistant call.
136
- toolCalls.forEach((call, i) => { if (!call.id) call.id = `call_${iter}_${i}` })
137
- state.messages.push({ ...assistant, tool_calls: toolCalls })
138
- await checkpoint()
139
- for (const tc of toolCalls) {
140
- const name = tc.function?.name || ''
141
- let output
142
- let args
143
- let toolMs // 只有真执行过的工具才有耗时(见下面的渲染判断)
144
- if (cancelled()) {
145
- // 与改动前一致:取消的这次调用只入历史,不渲染结果块
146
- output = 'Cancelled by user; this tool was not executed.'
147
- } else {
148
- try { args = JSON.parse(tc.function?.arguments || '{}') }
149
- catch { output = '错误: 工具参数不是合法 JSON,请修正后重试。' }
150
- if (output === undefined) {
151
- ui.printToolHeader(name, ui.summarizeToolArgs(name, args, { chars: t.chars }), undefined, { locale: state.locale })
152
- const toolSpinner = INTERACTIVE_TOOLS.has(name) ? null : ui.startSpinner(t.toolRunning(name))
153
- const toolStart = performance.now()
154
- stats.toolCalls++
155
- try { output = await execute(name, args, { ...state.ctx, signal: state.abortController?.signal }) }
156
- finally { toolSpinner?.stop(); toolMs = performance.now() - toolStart; stats.toolsMs += toolMs }
157
- } else {
158
- ui.printToolResult(output)
159
- }
160
- }
161
- // 工具结果可能是多模态的(read_image)。渲染层和回灌的消息都只吃**文本部分**,
162
- // 图片要进 content 数组 —— 拆在最后统一做,免得上面每个分支各写一遍。
163
- const { text: outText, images: outImages } = splitToolOutput(output)
164
- if (toolMs !== undefined) {
165
- ui.printToolResult(outText, undefined, toolMs, { full: state.fullTools, locale: state.locale })
166
- // 工具级的收尾渲染(目前只有 update_plan 画计划清单)。
167
- // 走钩子而不是在这里写 if (name === 'x'):再加工具时这一行不用动。
168
- ui.afterTool?.(name, args, outText, { locale: state.locale })
169
- }
170
- state.messages.push({ role: 'tool', tool_call_id: tc.id, name, content: toolMessageContent(outText, outImages) })
171
- await checkpoint()
172
- }
173
- }
174
- stats.status = cancelled() ? 'cancelled' : 'limit'
175
- if (!cancelled()) ui.printWarn(t.toolIterLimit(maxIterations))
176
- } catch (err) {
177
- stats.status = cancelled() ? 'cancelled' : 'failed'
178
- if (!cancelled()) ui.printError(t.llmError(err.message))
179
- } finally {
180
- stats.totalMs = performance.now() - started
181
- stats.completedAt = new Date().toISOString()
182
- state.lastTurnStats = stats
183
- state.sessionStats = accumulateSessionStats(state.sessionStats, stats)
184
- // 界面读的是这条(Web 端 g ai 对话列表里也能看到 CLI 会话的每轮用时)
185
- recordTurnTiming(state, { turnIndex, durationMs: stats.totalMs, finishedAt: stats.completedAt })
186
- await checkpoint()
187
- ui.printTurnSummary(stats, { locale: state.locale })
188
- }
189
- return stats
190
- }
1
+ import { executeTool, splitToolOutput, toolMessageContent } from './tools.js'
2
+ import { streamChatOnce } from './transport.js'
3
+ import { createThinkFilter } from './streamFilter.js'
4
+ import { imageToDataUrl } from './images.js'
5
+ import { prepareRequestMessages } from './context.js'
6
+ import { createTurnStats, addUsage, accumulateSessionStats } from './telemetry.js'
7
+ import { recordTurnTiming } from './sessionStore.js'
8
+ import * as terminal from './termui.js'
9
+
10
+ // 「等人」型工具:执行期间会接管输入行、停下来等用户作答(目前只有 ask_user)。
11
+ // 这类工具不能转工具 spinner —— ora 每 80ms 在同一行 clearLine + 重绘,会把
12
+ // readline 刚画出的提示符(「请输入序号或直接输入回答:」)连同用户正在敲的字
13
+ // 一起清掉,屏幕上只剩下一个不断跳秒数的「执行 ask_user...」,看起来就像"选不了"。
14
+ // 它自己的交互界面(问题 + 编号选项 + 提示符)就是进度提示,不需要再叠一层。
15
+ const INTERACTIVE_TOOLS = new Set(['ask_user'])
16
+
17
+ export async function runAgentTurn(state, userText, t, images = [], dependencies = {}) {
18
+ const chat = dependencies.chat || streamChatOnce
19
+ const baseExecute = dependencies.execute || executeTool
20
+ // 扩展(目前是 MCP)工具按名字分流:名字属于扩展就走扩展,否则回落内置工具。
21
+ // 必须先用 owns() 判断 —— 不能把所有调用都先喂给扩展再靠 null 回落,
22
+ // 那样每个内置工具都会多绕一层,而且扩展端也无法假设"进来的都是自己的"。
23
+ // 没装扩展时 owns() 恒为 false,等价于直接调内置工具,零开销。
24
+ const extensions = dependencies.extensions || state.extensions
25
+ const execute = extensions
26
+ ? async (name, args, ctx) => {
27
+ if (extensions.owns?.(name)) {
28
+ const output = await extensions.execute(name, args, ctx)
29
+ if (output !== null && output !== undefined) return output
30
+ }
31
+ return baseExecute(name, args, ctx)
32
+ }
33
+ : baseExecute
34
+ const ui = { ...terminal, ...dependencies.ui }
35
+ const stats = createTurnStats()
36
+ const started = performance.now()
37
+ const cancelled = () => state.cancelRequested || state.abortController?.signal.aborted
38
+ const checkpoint = () => state.persistSession?.()
39
+ const recordUsage = usage => {
40
+ if (!usage) return
41
+ stats.usageRequests++
42
+ stats.usage = addUsage(stats.usage, usage)
43
+ }
44
+ // 本轮是第几轮(0 基 user 序号),供 finally 里记用时用。
45
+ // 声明在 try 外面:finally 看不到 try 块里的 const,而 -1 正好是"这轮没轮到记"的哨兵值
46
+ let turnIndex = -1
47
+ try {
48
+ let userContent = userText
49
+ if (images.length) {
50
+ userContent = [{ type: 'text', text: userText }]
51
+ for (const img of images) {
52
+ try { userContent.push({ type: 'image_url', image_url: { url: await imageToDataUrl(img.path) } }) }
53
+ catch { ui.printWarn(t.imageBadPath(img.path)) }
54
+ }
55
+ }
56
+ // 本轮用时记录要对齐到"第几条 user 消息",序号得在这条消息入栈之前取
57
+ // (与 Web 侧 agentRoutes.js 同一口径,见 sessionStore.js 的 recordTurnTiming)
58
+ turnIndex = state.messages.filter(m => m?.role === 'user').length
59
+ state.messages.push({ role: 'user', content: userContent })
60
+ await checkpoint()
61
+
62
+ // 兜底只在 state.maxToolIterations 缺失/非正数时生效,正常路径由 loadConfig 规范化后传入。
63
+ // 默认值与 config.js 的 aiMaxToolIterations 保持一致(1000),别让两处悄悄分叉。
64
+ const maxIterations = state.maxToolIterations > 0 ? state.maxToolIterations : 1000
65
+ for (let iter = 0; iter < maxIterations; iter++) {
66
+ if (cancelled()) { stats.status = 'cancelled'; return stats }
67
+ const spinner = ui.startSpinner(t.waiting)
68
+ // 一次请求可能被传输层自动重试多次(长静默 / 网关 5xx / 流中断)。
69
+ // 每次尝试都换一套 writer + filter:终端没法把已经打出去的字擦掉,
70
+ // 与其让两次尝试的输出拼在一起,不如把上一截收尾、重开一块新的(中间一行重试提示)。
71
+ const makeWriter = () => ui.createAssistantWriter({
72
+ showThinking: state.showThinking !== false,
73
+ thinkingHeader: t.thinkingLabel,
74
+ answerHeader: t.answerLabel,
75
+ thinkingLimit: state.thinkingMode === 'compact' ? terminal.THINKING_PREVIEW_LINES : Infinity,
76
+ thinkingHint: t.thinkingHint,
77
+ })
78
+ let writer = makeWriter()
79
+ let filter = createThinkFilter()
80
+ const render = seg => {
81
+ if (seg.content) {
82
+ if (seg.content.trim() && stats.firstAnswerMs === null) stats.firstAnswerMs = performance.now() - started
83
+ writer.writeContent(seg.content)
84
+ } else if (seg.thinking) writer.writeThinking(seg.thinking)
85
+ }
86
+ let result
87
+ const llmStart = performance.now()
88
+ stats.requests++
89
+ try {
90
+ // 统一入口(与 Web 智能体面板共用):有界化 + 旧图片降级 + 消毒,只作用于请求副本,
91
+ // 磁盘上的完整会话记录不受影响。
92
+ // 预算来自 state.requestBudget(agent.js 按全局配置 aiMaxRequestTokens 解析);
93
+ // 缺失时 prepareRequestMessages 各自兜底默认值,老调用方不用改。
94
+ const messages = prepareRequestMessages(state.messages, { locale: state.locale, ...(state.requestBudget || {}) })
95
+ result = await chat({ model: state.model, messages, signal: state.abortController?.signal,
96
+ sessionId: state.sessionId, extraTools: extensions?.tools,
97
+ onRetry: info => {
98
+ filter.flush().forEach(render)
99
+ writer.finish()
100
+ ui.printWarn(t.llmRetrying(info.attempt, info.maxRetries, info.error?.message || ''))
101
+ writer = makeWriter()
102
+ filter = createThinkFilter()
103
+ // 重试是一次**真的**请求,计入本轮请求数(/stats 里那个"请求数"要能对得上网关账单)
104
+ stats.requests++
105
+ stats.retries++
106
+ },
107
+ onToken: token => {
108
+ if (stats.firstTokenMs === null) stats.firstTokenMs = performance.now() - started
109
+ if (token.content || (token.thinking && state.showThinking !== false)) spinner.stop()
110
+ if (token.thinking) render({ thinking: token.thinking })
111
+ if (token.content) filter.feed(token.content).forEach(render)
112
+ } })
113
+ recordUsage(result.usage)
114
+ } catch (err) {
115
+ recordUsage(err.usage)
116
+ throw err
117
+ } finally {
118
+ stats.llmMs += performance.now() - llmStart
119
+ spinner.stop()
120
+ filter.flush().forEach(render)
121
+ writer.finish()
122
+ }
123
+ if (result.aborted || cancelled()) {
124
+ if (result.content) state.messages.push({ role: 'assistant', content: result.content })
125
+ stats.status = 'cancelled'; return stats
126
+ }
127
+ const { content, toolCalls } = result
128
+ const assistant = { role: 'assistant', content: content || null }
129
+ if (result.reasoning) assistant.reasoning_content = result.reasoning
130
+ if (!toolCalls.length) {
131
+ if (!content?.trim()) throw new Error(t.emptyResponse)
132
+ state.messages.push(assistant)
133
+ stats.status = 'completed'; return stats
134
+ }
135
+ // Assign fallback IDs once, so every result references its assistant call.
136
+ toolCalls.forEach((call, i) => { if (!call.id) call.id = `call_${iter}_${i}` })
137
+ state.messages.push({ ...assistant, tool_calls: toolCalls })
138
+ await checkpoint()
139
+ for (const tc of toolCalls) {
140
+ const name = tc.function?.name || ''
141
+ let output
142
+ let args
143
+ let toolMs // 只有真执行过的工具才有耗时(见下面的渲染判断)
144
+ if (cancelled()) {
145
+ // 与改动前一致:取消的这次调用只入历史,不渲染结果块
146
+ output = 'Cancelled by user; this tool was not executed.'
147
+ } else {
148
+ try { args = JSON.parse(tc.function?.arguments || '{}') }
149
+ catch { output = '错误: 工具参数不是合法 JSON,请修正后重试。' }
150
+ if (output === undefined) {
151
+ ui.printToolHeader(name, ui.summarizeToolArgs(name, args, { chars: t.chars }), undefined, { locale: state.locale })
152
+ const toolSpinner = INTERACTIVE_TOOLS.has(name) ? null : ui.startSpinner(t.toolRunning(name))
153
+ const toolStart = performance.now()
154
+ stats.toolCalls++
155
+ try { output = await execute(name, args, { ...state.ctx, signal: state.abortController?.signal }) }
156
+ finally { toolSpinner?.stop(); toolMs = performance.now() - toolStart; stats.toolsMs += toolMs }
157
+ } else {
158
+ ui.printToolResult(output)
159
+ }
160
+ }
161
+ // 工具结果可能是多模态的(read_image)。渲染层和回灌的消息都只吃**文本部分**,
162
+ // 图片要进 content 数组 —— 拆在最后统一做,免得上面每个分支各写一遍。
163
+ const { text: outText, images: outImages } = splitToolOutput(output)
164
+ if (toolMs !== undefined) {
165
+ ui.printToolResult(outText, undefined, toolMs, { full: state.fullTools, locale: state.locale })
166
+ // 工具级的收尾渲染(目前只有 update_plan 画计划清单)。
167
+ // 走钩子而不是在这里写 if (name === 'x'):再加工具时这一行不用动。
168
+ ui.afterTool?.(name, args, outText, { locale: state.locale })
169
+ }
170
+ state.messages.push({ role: 'tool', tool_call_id: tc.id, name, content: toolMessageContent(outText, outImages) })
171
+ await checkpoint()
172
+ }
173
+ }
174
+ stats.status = cancelled() ? 'cancelled' : 'limit'
175
+ if (!cancelled()) ui.printWarn(t.toolIterLimit(maxIterations))
176
+ } catch (err) {
177
+ stats.status = cancelled() ? 'cancelled' : 'failed'
178
+ if (!cancelled()) ui.printError(t.llmError(err.message))
179
+ } finally {
180
+ stats.totalMs = performance.now() - started
181
+ stats.completedAt = new Date().toISOString()
182
+ state.lastTurnStats = stats
183
+ state.sessionStats = accumulateSessionStats(state.sessionStats, stats)
184
+ // 界面读的是这条(Web 端 g ai 对话列表里也能看到 CLI 会话的每轮用时)
185
+ recordTurnTiming(state, { turnIndex, durationMs: stats.totalMs, finishedAt: stats.completedAt })
186
+ await checkpoint()
187
+ ui.printTurnSummary(stats, { locale: state.locale })
188
+ }
189
+ return stats
190
+ }
@@ -0,0 +1,11 @@
1
+ import"./rolldown-runtime-C0FnF6B9.js";import{$n as e,An as t,At as n,Cn as r,Ct as i,Dn as a,Fn as o,Hn as s,In as c,J as l,Kn as u,Kt as d,Lr as f,M as p,On as m,Qr as h,Rn as g,Sr as _,Tt as v,Ut as y,W as b,Xr as x,Xt as S,Yn as C,Yt as w,Zn as T,_n as E,a as D,br as O,cr as k,dr as A,en as ee,et as j,fn as M,hn as N,hr as P,i as F,ir as I,j as L,jn as R,kn as z,kt as B,lt as te,mt as ne,ni as V,o as re,on as ie,st as ae,tr as H,tt as oe,ur as U,vn as W,yn as G}from"./element-plus-DgSY_Wt4.js";import{c as se,t as ce}from"./vendor-CZlKgriV.js";import{n as K,t as q}from"./_plugin-vue_export-helper-bQQyMRS6.js";import{t as le}from"./configStore-BeHB-gV4.js";import{t as ue}from"./CommonDialog-zaBdFGFH.js";import{J as de,b as fe,q as pe}from"./index-BRQstBzy.js";import{a as me,c as he,i as ge,l as _e,m as ve,n as ye,o as be,r as xe,s as Se,t as Ce,u as we}from"./agentConversations-wYAksLq1.js";import{l as Te,s as Ee,t as De,u as Oe}from"./CopySessionButton-CAxaqLQL.js";import{t as ke}from"./useOrchestrator-Bhl7DGKW.js";async function J(e,t){let n=await fetch(e,{headers:{"Content-Type":`application/json`},...t}),r={};try{r=await n.json()}catch{}if(!n.ok||r.success===!1)throw Error(r.error||`请求失败 (${n.status})`);return r}async function Ae(){let e=await J(`/api/schedules`);return Array.isArray(e.tasks)?e.tasks:[]}async function je(e){return(await J(`/api/schedules`,{method:`POST`,body:JSON.stringify(e)})).task}async function Me(e,t){return(await J(`/api/schedules/${encodeURIComponent(e)}`,{method:`PUT`,body:JSON.stringify(t)})).task}async function Ne(e){await J(`/api/schedules/${encodeURIComponent(e)}`,{method:`DELETE`})}async function Y(e){await J(`/api/schedules/${encodeURIComponent(e)}/run`,{method:`POST`})}async function Pe(e){await J(`/api/schedules/${encodeURIComponent(e)}/stop`,{method:`POST`})}function Fe(e){if(typeof EventSource>`u`)return()=>{};let t=new EventSource(`/api/schedules/events`);return t.onmessage=t=>{try{e(JSON.parse(t.data))}catch{}},()=>t.close()}var X=e=>/^\d+$/.test(e)?Number(e):null;function Ie(e){let t=String(e||``).trim(),n=t.split(/\s+/);if(n.length!==5)return{kind:`custom`,raw:t};let[r,i,a,o,s]=n,c=X(r),l=X(i);if(t===`* * * * *`)return{kind:`every-minute`,raw:t};let u=r.match(/^\*\/(\d+)$/);if(u&&i===`*`&&a===`*`&&o===`*`&&s===`*`)return{kind:`every-n-minutes`,n:Number(u[1]),raw:t};if(c!==null&&i===`*`&&a===`*`&&o===`*`&&s===`*`)return{kind:`hourly`,minute:c,raw:t};if(c!==null&&l!==null&&a===`*`&&o===`*`&&s===`*`)return{kind:`daily`,hour:l,minute:c,raw:t};let d=X(s);if(c!==null&&l!==null&&a===`*`&&o===`*`&&d!==null)return{kind:`weekly`,weekday:d%7,hour:l,minute:c,raw:t};let f=X(a);return c!==null&&l!==null&&f!==null&&o===`*`&&s===`*`?{kind:`monthly`,day:f,hour:l,minute:c,raw:t}:{kind:`custom`,raw:t}}var Z=e=>String(e).padStart(2,`0`),Q=e=>new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime();function Le(e,t=new Date){if(!e)return{kind:`none`};let n=new Date(e);if(Number.isNaN(n.getTime()))return{kind:`none`};let r=`${Z(n.getHours())}:${Z(n.getMinutes())}`,i=Math.round((Q(n)-Q(t))/864e5);return i<0?{kind:`date`,date:`${n.getMonth()+1}-${Z(n.getDate())}`,time:r}:i===0?{kind:`today`,time:r}:i===1?{kind:`tomorrow`,time:r}:i<7?{kind:`weekday`,weekday:n.getDay(),time:r}:{kind:`date`,date:`${n.getMonth()+1}-${Z(n.getDate())}`,time:r}}function Re(e){switch(e){case`ok`:return`ok`;case`error`:case`timed-out`:return`error`;case`skipped-busy`:case`missed`:case`cancelled`:return`skipped`;default:return`pending`}}function ze(e){let t=Number(e);if(!Number.isFinite(t)||t<0)return``;if(t<1e3)return`<1s`;let n=Math.round(t/1e3);if(n<60)return`${n}s`;let r=Math.floor(n/60);return r<60?`${r}m${Z(n%60)}s`:`${Math.floor(r/60)}h${Z(r%60)}m`}function $(e){let t=Math.min(59,Math.max(0,Math.floor(e.minute))),n=Math.min(23,Math.max(0,Math.floor(e.hour))),r=(Math.floor(e.weekday)%7+7)%7;switch(e.freq){case`minutes`:return`*/${Math.min(59,Math.max(1,Math.floor(e.everyMinutes??30)))} * * * *`;case`hourly`:return`${t} * * * *`;case`daily`:return`${t} ${n} * * *`;case`weekly`:return`${t} ${n} * * ${r}`;case`custom`:return String(e.custom||``).trim()}}s(),P();var Be=g({__name:`MarketplacePanel`,props:{type:{type:String,required:!0}},setup(e,{expose:t}){t();let n=e,r=le(),o=_([]),s=_([]),c=_(!1),l=_(``),u=_(``),f=_([]),p=_(`project`),m=_(new Set),h=_(new Set),g=_(new Set),v=a(()=>r.currentDirectory||``),b=null;async function x(){if(!c.value){c.value=!0;try{let e=new URLSearchParams({type:n.type,cwd:v.value});u.value&&e.set(`q`,u.value),f.value.length&&e.set(`sources`,f.value.join(`,`));let t=await(await fetch(`/api/agent/marketplace/catalog?${e}`)).json();t?.success?(o.value=t.groups||[],s.value=t.installed||[]):D.error(t?.error||K(`@MKT:加载失败`))}catch{D.error(K(`@MKT:加载失败`))}finally{c.value=!1}}}k(l,e=>{b&&clearTimeout(b),b=setTimeout(()=>{u.value=e.trim(),x()},400)}),k(f,()=>x()),k(()=>n.type,()=>{f.value=[],u.value=``,l.value=``,x()}),k(v,()=>x()),x();let C=a(()=>{let e=v.value?v.value.split(/[\\/]/).filter(Boolean).pop():``;return p.value===`project`?e||K(`@MKT:当前项目`):K(`@MKT:g ai 智能体`)});function w(e){return e.stars?`${T(e.stars)} ★`:e.downloads?`${T(e.downloads)} ${K(`@MKT:周下载`)}`:e.uses?`${T(e.uses)} ${K(`@MKT:次使用`)}`:``}function T(e){return e>=1e3?`${(e/1e3).toFixed(e>=1e4?0:1)}k`:String(e)}function E(e){return`${e.id}`}function A(e){return m.value.has(E(e))}let ee=a(()=>{let e={project:[],global:[]};for(let t of s.value)(e[t.target]||=[]).push(t);return e}),j=O({visible:!1,item:null,env:{},args:``});function M(e){return n.type===`mcp`&&(!!e.envKeys?.length||!!e.args?.length)}function N(e){j.item=e,j.env=Object.fromEntries((e.envKeys||[]).map(e=>[e,``])),j.args=(e.args||[]).join(` `),j.visible=!0}function P(){let e=j.item;if(j.visible=!1,!e)return;let t=Object.fromEntries(Object.entries(j.env).filter(([,e])=>e.trim()!==``)),n=j.args.trim()?j.args.trim().match(/(?:[^\s"]+|"[^"]*")+/g)?.map(e=>e.replace(/^"|"$/g,``))??void 0:void 0;L(e,{env:t,...n?{args:n}:{}})}async function I(e){if(!e.installed||await R(e)){if(M(e)){N(e);return}await L(e,{})}}async function L(e,t){let r=E(e);m.value.add(r);try{let r=await fetch(`/api/agent/marketplace/install`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({type:n.type,target:p.value,cwd:v.value,item:{...e,...t}})}),i=await r.json().catch(()=>null);if(!r.ok||!i?.success){D.error(i?.error||K(`@MKT:安装失败`));return}i.item?.warning&&D.warning(i.item.warning),i.item?.envKeys?.length?D.warning(`${K(`@MKT:还缺环境变量`)}: ${i.item.envKeys.join(`, `)}`):D.success(K(`@MKT:安装成功`)),await x()}catch{D.error(K(`@MKT:安装失败`))}finally{m.value.delete(r)}}async function R(e){try{return await F.confirm(`${e.name} ${K(`@MKT:已安装,要重新安装吗?`)}`,K(`@MKT:重新安装`),{confirmButtonText:K(`@MKT:重装`),cancelButtonText:K(`@MKT:取消`),type:`warning`}),!0}catch{return!1}}async function z(e){let t=`${e.target}:${e.id}`;g.value.add(t);try{let t=await fetch(`/api/agent/marketplace/reveal`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({type:n.type,target:e.target,cwd:v.value,id:e.id})}),r=await t.json().catch(()=>null);(!t.ok||!r?.success)&&D.error(r?.error||K(`@MKT:打开失败`))}catch{D.error(K(`@MKT:打开失败`))}finally{g.value.delete(t)}}async function V(e){try{await F.confirm(`${K(`@MKT:确定卸载`)} ${e.name}?`,K(`@MKT:卸载`),{confirmButtonText:K(`@MKT:卸载`),cancelButtonText:K(`@MKT:取消`),type:`warning`})}catch{return}let t=`${e.target}:${e.id}`;h.value.add(t);try{let t=new URLSearchParams({target:e.target,cwd:v.value}),r=await fetch(`/api/agent/marketplace/item/${n.type}/${encodeURIComponent(e.id)}?${t}`,{method:`DELETE`}),i=await r.json().catch(()=>null);if(!r.ok||!i?.success){D.error(i?.error||K(`@MKT:卸载失败`));return}D.success(K(`@MKT:已卸载`)),await x()}catch{D.error(K(`@MKT:卸载失败`))}finally{h.value.delete(t)}}let re={props:n,configStore:r,groups:o,installed:s,loading:c,searchInput:l,query:u,selectedSources:f,installTarget:p,installing:m,removing:h,revealing:g,cwd:v,get searchTimer(){return b},set searchTimer(e){b=e},loadCatalog:x,targetLabel:C,metricText:w,formatCount:T,cardKey:E,isBusy:A,installedByTarget:ee,configDialog:j,needsConfig:M,openConfigDialog:N,confirmConfig:P,onInstall:I,doInstall:L,confirmReinstall:R,onReveal:z,onRemove:V,get $t(){return K},get Search(){return d},get Refresh(){return y},get Delete(){return te},get Link(){return B},get Check(){return oe},get Star(){return S},get Download(){return ne},get Warning(){return ie},get FolderOpened(){return i},CommonDialog:ue};return Object.defineProperty(re,"__isScriptSetup",{enumerable:!1,value:!0}),re}});s(),M(),f();var Ve={class:`marketplace-panel`},He={class:`mp-toolbar`},Ue={class:`mp-search`},We=[`placeholder`],Ge={class:`mp-toolbar-sub`},Ke={class:`mp-target-hint`},qe={class:`mp-source-filter`},Je=[`onClick`],Ye={class:`mp-body`},Xe={class:`mp-group-header`},Ze={class:`mp-group-title`},Qe={key:0,class:`mp-group-count`},$e={key:1,class:`mp-group-error`},et=[`href`,`title`],tt={key:0,class:`mp-grid`},nt={class:`mp-card-head`},rt=[`title`],it={key:0,class:`mp-card-metric`},at=[`title`],ot={class:`mp-card-meta`},st=[`title`],ct=[`title`],lt={key:2,class:`mp-tag remote`},ut={class:`mp-card-foot`},dt=[`href`],ft={key:1,class:`mp-installed-chip`},pt=[`disabled`,`onClick`],mt={key:3,class:`mp-not-installable`},ht={key:1,class:`mp-empty`},gt={key:0,class:`mp-group installed`},_t={class:`mp-group-header`},vt={class:`mp-group-title`},yt={class:`mp-group-count`},bt={key:0,class:`mp-installed-block`},xt={class:`mp-installed-target`},St={class:`mp-installed-list`},Ct=[`title`],wt=[`title`],Tt={key:1,class:`mp-meta-pkg`},Et={key:2,class:`mp-tag warn`},Dt=[`disabled`,`title`,`onClick`],Ot=[`disabled`,`onClick`],kt={key:1,class:`mp-empty all`},At={key:0,class:`mkt-form`},jt={class:`mkt-form-name`},Mt=[`onUpdate:modelValue`,`placeholder`],Nt={key:0,class:`mkt-field`},Pt={class:`mkt-hint`};function Ft(n,i,a,s,u,d){let f=l,h=L,g=p,_=b,v=re;return e(),R(`div`,Ve,[t(` ── 工具栏 ───────────────────────────────── `),m(`div`,He,[m(`div`,Ue,[c(f,{class:`mp-search-icon`},{default:U(()=>[c(s.Search)]),_:1}),A(m(`input`,{"onUpdate:modelValue":i[0]||=e=>s.searchInput=e,class:`mp-search-input`,type:`text`,placeholder:a.type===`skill`?s.$t(`@MKT:搜索 Skill...`):s.$t(`@MKT:搜索 MCP 服务...`)},null,8,We),[[G,s.searchInput]])]),c(g,{modelValue:s.installTarget,"onUpdate:modelValue":i[1]||=e=>s.installTarget=e,size:`small`,class:`mp-target`},{default:U(()=>[c(h,{value:`project`},{default:U(()=>[o(V(s.$t(`@MKT:当前项目`)),1)]),_:1}),c(h,{value:`global`},{default:U(()=>[o(V(s.$t(`@MKT:g ai 智能体`)),1)]),_:1})]),_:1},8,[`modelValue`]),c(_,{content:s.$t(`@MKT:刷新`),placement:`top`,"show-after":300},{default:U(()=>[m(`button`,{class:x([`mp-refresh`,{spinning:s.loading}]),onClick:s.loadCatalog},[c(f,null,{default:U(()=>[c(s.Refresh)]),_:1})],2)]),_:1},8,[`content`])]),m(`div`,Ge,[m(`span`,Ke,[o(V(s.$t(`@MKT:安装到`))+` `,1),m(`b`,null,V(s.targetLabel),1)]),m(`div`,qe,[(e(!0),R(r,null,H(s.groups,t=>(e(),R(`button`,{key:t.id,class:x([`mp-chip`,{active:s.selectedSources.includes(t.id)}]),onClick:()=>{let e=s.selectedSources.indexOf(t.id);e>=0?s.selectedSources.splice(e,1):s.selectedSources.push(t.id)}},V(t.label),11,Je))),128)),s.selectedSources.length?(e(),R(`button`,{key:0,class:`mp-chip clear`,onClick:i[2]||=e=>s.selectedSources=[]},V(s.$t(`@MKT:全部来源`)),1)):t(`v-if`,!0)])]),t(` ── 内容 ─────────────────────────────────── `),A((e(),R(`div`,Ye,[(e(!0),R(r,null,H(s.groups,n=>(e(),R(`section`,{key:n.id,class:`mp-group`},[m(`header`,Xe,[m(`h3`,Ze,V(n.label),1),n.status===`ok`?(e(),R(`span`,Qe,V(n.items.length),1)):(e(),R(`span`,$e,[c(f,null,{default:U(()=>[c(s.Warning)]),_:1}),o(` `+V(n.error||s.$t(`@MKT:来源不可用`)),1)])),n.homepage?(e(),R(`a`,{key:2,class:`mp-group-link`,href:n.homepage,target:`_blank`,rel:`noopener noreferrer`,title:n.homepage},[c(f,null,{default:U(()=>[c(s.Link)]),_:1})],8,et)):t(`v-if`,!0)]),n.status===`ok`&&n.items.length?(e(),R(`div`,tt,[(e(!0),R(r,null,H(n.items,n=>(e(),R(`article`,{key:s.cardKey(n),class:`mp-card`},[m(`div`,nt,[m(`span`,{class:`mp-card-name`,title:n.name},V(n.name),9,rt),s.metricText(n)?(e(),R(`span`,it,[c(f,null,{default:U(()=>[n.stars?(e(),z(s.Star,{key:0})):(e(),z(s.Download,{key:1}))]),_:2},1024),o(` `+V(s.metricText(n)),1)])):t(`v-if`,!0)]),m(`p`,{class:`mp-card-desc`,title:n.description},V(n.description||s.$t(`@MKT:暂无描述`)),9,at),m(`div`,ot,[n.package?(e(),R(`code`,{key:0,class:`mp-meta-pkg`,title:n.package},V(n.package),9,st)):n.repository?(e(),R(`span`,{key:1,class:`mp-meta-repo`,title:n.repository+(n.subpath?` · `+n.subpath:``)},[o(V(n.repository),1),n.subpath?(e(),R(r,{key:0},[o(` · `+V(n.subpath),1)],64)):t(`v-if`,!0)],8,ct)):t(`v-if`,!0),n.transport===`remote`?(e(),R(`span`,lt,V(s.$t(`@MKT:远程服务`)),1)):t(`v-if`,!0),(e(!0),R(r,null,H((n.tags||[]).slice(0,2),t=>(e(),R(`span`,{key:t,class:`mp-tag`},V(t),1))),128))]),m(`div`,ut,[n.upstream?(e(),R(`a`,{key:0,class:`mp-card-link`,href:n.upstream,target:`_blank`,rel:`noopener noreferrer`},V(s.$t(`@MKT:查看来源`)),9,dt)):t(`v-if`,!0),i[6]||=m(`span`,{class:`mp-foot-spacer`},null,-1),n.installed?(e(),R(`span`,ft,[c(f,null,{default:U(()=>[c(s.Check)]),_:1}),o(V(s.$t(`@MKT:已安装`)),1)])):n.installable===!1?(e(),R(`span`,mt,V(s.$t(`@MKT:暂不支持一键安装`)),1)):(e(),R(`button`,{key:2,class:`mp-install-btn`,disabled:s.isBusy(n),onClick:e=>s.onInstall(n)},V(s.isBusy(n)?s.$t(`@MKT:安装中...`):s.$t(`@MKT:安装`)),9,pt))])]))),128))])):n.status===`ok`?(e(),R(`div`,ht,V(s.$t(`@MKT:该来源暂无结果`)),1)):t(`v-if`,!0)]))),128)),t(` ── 已安装 ─────────────────────────────── `),s.installed.length?(e(),R(`section`,gt,[m(`header`,_t,[m(`h3`,vt,V(s.$t(`@MKT:已安装`)),1),m(`span`,yt,V(s.installed.length),1)]),(e(),R(r,null,H([`project`,`global`],n=>m(`div`,{key:n},[s.installedByTarget[n]?.length?(e(),R(`div`,bt,[m(`div`,xt,V(n===`project`?s.$t(`@MKT:当前项目`):s.$t(`@MKT:g ai 智能体`)),1),m(`div`,St,[(e(!0),R(r,null,H(s.installedByTarget[n],r=>(e(),R(`div`,{key:n+r.id,class:`mp-installed-row`},[m(`span`,{class:`mp-installed-name`,title:r.name},V(r.name),9,Ct),t(` 实际落盘的标识:SKILL.md 里的 name 常与仓库名不同(如仓库 taste-skill
2
+ 里的 skill 自称 brandkit),不显示这个用户就对不上广场卡片上的名字 `),r.id&&r.id!==r.name?(e(),R(`code`,{key:0,class:`mp-installed-id`,title:r.dir||r.file||r.id},V(r.id),9,wt)):t(`v-if`,!0),r.package?(e(),R(`code`,Tt,V(r.package),1)):t(`v-if`,!0),r.requiredEnv?.length?(e(),R(`span`,Et,V(s.$t(`@MKT:待配置`))+`: `+V(r.requiredEnv.join(`, `)),1)):t(`v-if`,!0),i[7]||=m(`span`,{class:`mp-foot-spacer`},null,-1),m(`button`,{class:`mp-reveal-btn`,disabled:s.revealing.has(n+r.id),title:r.dir||r.file||``,onClick:e=>s.onReveal(r)},[c(f,null,{default:U(()=>[c(s.FolderOpened)]),_:1}),o(` `+V(s.$t(`@MKT:打开文件夹`)),1)],8,Dt),m(`button`,{class:`mp-remove-btn`,disabled:s.removing.has(n+r.id),onClick:e=>s.onRemove(r)},[c(f,null,{default:U(()=>[c(s.Delete)]),_:1}),o(` `+V(s.removing.has(n+r.id)?s.$t(`@MKT:卸载中...`):s.$t(`@MKT:卸载`)),1)],8,Ot)]))),128))])])):t(`v-if`,!0)])),64))])):t(`v-if`,!0),!s.loading&&!s.groups.length?(e(),R(`div`,kt,V(s.$t(`@MKT:加载失败`)),1)):t(`v-if`,!0)])),[[v,s.loading]]),t(` ── MCP 安装前配置 ───────────────────────── `),c(s.CommonDialog,{modelValue:s.configDialog.visible,"onUpdate:modelValue":i[5]||=e=>s.configDialog.visible=e,title:s.$t(`@MKT:配置 MCP`),width:`460px`,type:`flex`,"close-on-click-modal":!1,"append-to-body":``},{footer:U(()=>[m(`button`,{class:`mkt-cancel`,onClick:i[4]||=e=>s.configDialog.visible=!1},V(s.$t(`@MKT:取消`)),1),m(`button`,{class:`mkt-confirm`,onClick:s.confirmConfig},V(s.$t(`@MKT:安装`)),1)]),default:U(()=>[s.configDialog.item?(e(),R(`div`,At,[m(`p`,jt,V(s.configDialog.item.name),1),(e(!0),R(r,null,H(Object.keys(s.configDialog.env),t=>(e(),R(`div`,{key:t,class:`mkt-field`},[m(`label`,null,V(t),1),A(m(`input`,{"onUpdate:modelValue":e=>s.configDialog.env[t]=e,type:`text`,autocomplete:`off`,placeholder:s.$t(`@MKT:环境变量值`),spellcheck:`false`},null,8,Mt),[[G,s.configDialog.env[t]]])]))),128)),s.configDialog.item.args?.length?(e(),R(`div`,Nt,[m(`label`,null,V(s.$t(`@MKT:启动参数`)),1),A(m(`input`,{"onUpdate:modelValue":i[3]||=e=>s.configDialog.args=e,type:`text`,autocomplete:`off`,spellcheck:`false`},null,512),[[G,s.configDialog.args]]),m(`p`,Pt,V(s.$t(`@MKT:参数提示`)),1)])):t(`v-if`,!0)])):t(`v-if`,!0)]),_:1},8,[`modelValue`,`title`])])}var It=q(Be,[[`render`,Ft],[`__scopeId`,`data-v-e9f9e851`],[`__file`,`C:/workspace/github_workspace/xz333221/zen-gitsync/src/ui/client/src/components/MarketplacePanel.vue`]]);s(),P();var Lt=g({__name:`SchedulePanel`,emits:[`open-session`],setup(e,{expose:t,emit:n}){t();let r=n,i=le(),o=_([]),s=_(!0),c=_(``),l=_({}),u=null,d=null;async function f(){try{o.value=await Ae(),c.value=``}catch(e){c.value=e?.message||String(e)}finally{s.value=!1}}function p(){d===null&&(d=window.setTimeout(()=>{d=null,f()},150))}T(async()=>{await f(),u=Fe(e=>{[`tasks_changed`,`task_started`,`task_finished`,`hello`].includes(e.type)&&p()})}),C(()=>{u?.(),d!==null&&window.clearTimeout(d)});let m=a(()=>{let e=o.value.filter(e=>e.enabled).length,t=o.value.length-e;return o.value.length?K(`@SCHED:{on} 个启用 · {off} 个停用`,{on:e,off:t}):``}),h=[`@SCHED:周日`,`@SCHED:周一`,`@SCHED:周二`,`@SCHED:周三`,`@SCHED:周四`,`@SCHED:周五`,`@SCHED:周六`];function g(e){let t=Ie(e.schedule);switch(t.kind){case`every-minute`:return K(`@SCHED:每分钟`);case`every-n-minutes`:return K(`@SCHED:每 {n} 分钟`,{n:t.n});case`hourly`:return K(`@SCHED:每小时第 {minute} 分钟`,{minute:t.minute});case`daily`:return K(`@SCHED:每天 {time}`,{time:`${String(t.hour).padStart(2,`0`)}:${String(t.minute).padStart(2,`0`)}`});case`weekly`:return K(`@SCHED:每周 {weekday} {time}`,{weekday:K(h[t.weekday]),time:`${String(t.hour).padStart(2,`0`)}:${String(t.minute).padStart(2,`0`)}`});case`monthly`:return K(`@SCHED:每月 {day} 日 {time}`,{day:t.day,time:`${String(t.hour).padStart(2,`0`)}:${String(t.minute).padStart(2,`0`)}`});default:return t.raw}}function v(e){if(!e.enabled)return K(`@SCHED:已停用`);if(e.running)return K(`@SCHED:运行中...`);let t=Le(e.nextRunAt);switch(t.kind){case`none`:return``;case`today`:return K(`@SCHED:下次 今天 {time}`,{time:t.time});case`tomorrow`:return K(`@SCHED:下次 明天 {time}`,{time:t.time});case`weekday`:return K(`@SCHED:下次 {weekday} {time}`,{weekday:K(h[t.weekday]),time:t.time});case`date`:return K(`@SCHED:下次 {date} {time}`,{date:t.date,time:t.time})}}function y(e){let t=e.lastRun;if(!t)return K(`@SCHED:还没执行过`);switch(t.status){case`ok`:return K(`@SCHED:成功`);case`error`:return K(`@SCHED:失败`);case`timed-out`:return K(`@SCHED:超时中止`);case`skipped-busy`:return K(`@SCHED:已跳过(会话忙)`);case`missed`:return K(`@SCHED:已错过(未运行)`);case`cancelled`:return K(`@SCHED:已停止`);default:return t.status}}function b(e){let t=e.lastRun;if(!t)return K(`@SCHED:还没执行过`);let n=ze(t.durationMs),r=K(`@SCHED:上次 {status}`,{status:y(e)});return n?`${r} · ${n}`:r}function x(e){return e.lastRun?`is-${Re(e.lastRun.status)}`:`is-muted`}async function S(e,t){if(!l.value[e.id]){l.value={...l.value,[e.id]:!0};try{await t(),await f()}catch(e){D.error(e?.message||String(e))}finally{let t={...l.value};delete t[e.id],l.value=t}}}function w(e){return S(e,()=>Me(e.id,{enabled:!e.enabled}))}function E(e){return S(e,()=>Y(e.id))}function O(e){return S(e,()=>Pe(e.id))}let k=_(!1),A=_(null);function ee(e){A.value=e,k.value=!0}async function j(){let e=A.value;if(e)try{await Ne(e.id),k.value=!1,await f()}catch(e){D.error(e?.message||String(e))}}let M=_(!1),N=_(``),P=_(``),F=_(!1),I=_({name:``,freq:`daily`,everyMinutes:30,minute:0,hour:9,weekday:1,custom:``,cwd:``,prompt:``,onMissed:`run`,enabled:!0}),L=a(()=>[{value:`minutes`,label:K(`@SCHED:每 N 分钟`)},{value:`hourly`,label:K(`@SCHED:每小时`)},{value:`daily`,label:K(`@SCHED:每天`)},{value:`weekly`,label:K(`@SCHED:每周`)},{value:`custom`,label:K(`@SCHED:自定义 cron`)}]),R=a(()=>$({freq:I.value.freq,everyMinutes:I.value.everyMinutes,minute:I.value.minute,hour:I.value.hour,weekday:I.value.weekday,custom:I.value.custom}));function z(){I.value={name:``,freq:`daily`,everyMinutes:30,minute:0,hour:9,weekday:1,custom:``,cwd:i.currentDirectory||``,prompt:``,onMissed:`run`,enabled:!0},P.value=``}function B(){N.value=``,z(),M.value=!0}function te(e){N.value=e.id;let t=Ie(e.schedule),n={name:e.name,freq:`custom`,everyMinutes:30,minute:0,hour:9,weekday:1,custom:e.schedule,cwd:e.cwd,prompt:e.prompt,onMissed:e.onMissed===`skip`?`skip`:`run`,enabled:e.enabled};switch(t.kind){case`every-n-minutes`:n.freq=`minutes`,n.everyMinutes=t.n;break;case`hourly`:n.freq=`hourly`,n.minute=t.minute;break;case`daily`:n.freq=`daily`,n.minute=t.minute,n.hour=t.hour;break;case`weekly`:n.freq=`weekly`,n.minute=t.minute,n.hour=t.hour,n.weekday=t.weekday;break;default:n.freq=`custom`}I.value=n,P.value=``,M.value=!0}async function ne(){let e=I.value;if(!e.name.trim()){P.value=K(`@SCHED:任务名不能为空`);return}if(!e.prompt.trim()){P.value=K(`@SCHED:提示词不能为空`);return}let t=R.value;if(!t){P.value=K(`@SCHED:cron 表达式不能为空`);return}let n={name:e.name.trim(),schedule:t,cwd:e.cwd.trim(),prompt:e.prompt.trim(),enabled:e.enabled,onMissed:e.onMissed};F.value=!0;try{N.value?await Me(N.value,n):await je(n),M.value=!1,await f()}catch(e){P.value=e?.message||String(e)}finally{F.value=!1}}let V={emit:r,configStore:i,tasks:o,loading:s,errorMsg:c,pending:l,get disposeEvents(){return u},set disposeEvents(e){u=e},get refreshTimer(){return d},set refreshTimer(e){d=e},refresh:f,scheduleRefresh:p,summaryText:m,WEEKDAY_KEYS:h,descText:g,nextText:v,lastStatusText:y,lastText:b,lastClass:x,withPending:S,toggle:w,runNow:E,stop:O,confirmVisible:k,confirmTarget:A,askRemove:ee,confirmRemove:j,formVisible:M,editingId:N,formError:P,saving:F,form:I,freqOptions:L,cronPreview:R,resetForm:z,openCreate:B,openEdit:te,submitForm:ne,get $t(){return K},CommonDialog:ue};return Object.defineProperty(V,"__isScriptSetup",{enumerable:!1,value:!0}),V}});f(),s(),M();var Rt={class:`schedule-panel`},zt={class:`schedule-toolbar`},Bt={class:`schedule-summary`},Vt={key:0,class:`schedule-error`},Ht={key:1,class:`schedule-loading`},Ut={key:2,class:`schedule-empty`},Wt={class:`schedule-empty-title`},Gt={class:`schedule-empty-desc`},Kt={key:3,class:`schedule-list`},qt={class:`schedule-card-body`},Jt={class:`schedule-card-head`},Yt={class:`schedule-name`},Xt={key:0,class:`schedule-running`},Zt=[`aria-checked`,`aria-label`,`onClick`],Qt={class:`schedule-card-sub`},$t={class:`schedule-desc`},en=[`onClick`],tn={class:`schedule-card-side`},nn={class:`schedule-actions`},rn=[`disabled`,`onClick`],an=[`disabled`,`onClick`],on=[`onClick`],sn=[`onClick`],cn={class:`sch-form`},ln={class:`sch-field`},un={class:`sch-field-label`},dn=[`placeholder`],fn={class:`sch-field`},pn={class:`sch-field-label`},mn={class:`sch-freq-row`},hn=[`value`],gn={class:`sch-inline-label`},_n=[`value`],vn={class:`sch-inline-label`},yn=[`value`],bn=[`value`],xn=[`value`],Sn={class:`sch-inline-label`},Cn=[`value`],wn={class:`sch-inline-label`},Tn=[`placeholder`],En={class:`sch-hint`},Dn={class:`sch-field`},On={class:`sch-field-label`},kn=[`placeholder`],An={class:`sch-field`},jn={class:`sch-field-label`},Mn=[`placeholder`],Nn={class:`sch-field`},Pn={class:`sch-field-label`},Fn={class:`sch-radio-row`},In={class:`sch-radio`},Ln={class:`sch-radio`},Rn={class:`sch-radio`},zn={key:0,class:`sch-form-error`},Bn={class:`sch-form-footer`},Vn=[`disabled`],Hn={class:`sch-confirm-text`},Un={class:`sch-form-footer`};function Wn(n,i,a,o,s,l){return e(),R(`div`,Rt,[m(`div`,zt,[m(`span`,Bt,V(o.summaryText),1),m(`button`,{type:`button`,class:`sch-btn sch-btn-primary`,onClick:o.openCreate},V(o.$t(`@SCHED:新建任务`)),1)]),o.errorMsg?(e(),R(`div`,Vt,V(o.$t(`@SCHED:操作失败:{error}`,{error:o.errorMsg})),1)):t(`v-if`,!0),o.loading?(e(),R(`div`,Ht,V(o.$t(`@SCHED:加载中...`)),1)):o.tasks.length?(e(),R(`div`,Kt,[(e(!0),R(r,null,H(o.tasks,n=>(e(),R(`article`,{key:n.id,class:x([`schedule-card`,{"is-disabled":!n.enabled,"is-running":!!n.running}])},[m(`div`,qt,[m(`div`,Jt,[m(`span`,Yt,V(n.name),1),n.running?(e(),R(`span`,Xt,V(o.$t(`@SCHED:运行中`)),1)):t(`v-if`,!0),m(`button`,{type:`button`,class:x([`sch-switch`,{on:n.enabled}]),role:`switch`,"aria-checked":n.enabled,"aria-label":n.enabled?o.$t(`@SCHED:停用`):o.$t(`@SCHED:启用`),onClick:e=>o.toggle(n)},[...i[17]||=[m(`span`,{class:`sch-switch-knob`},null,-1)]],10,Zt)]),m(`div`,Qt,[m(`span`,$t,V(o.descText(n)),1),i[18]||=m(`span`,{class:`schedule-sep`},`·`,-1),m(`span`,{class:x([`schedule-last`,o.lastClass(n)])},V(o.lastText(n)),3),n.sessionId?(e(),R(`button`,{key:0,type:`button`,class:`sch-link`,onClick:e=>o.emit(`open-session`,n.sessionId)},V(o.$t(`@SCHED:查看会话`)),9,en)):t(`v-if`,!0)])]),m(`div`,tn,[m(`div`,{class:x([`schedule-next`,{"is-muted":!n.enabled}])},V(o.nextText(n)),3),m(`div`,nn,[n.running?(e(),R(`button`,{key:0,type:`button`,class:`sch-btn`,disabled:!!o.pending[n.id],onClick:e=>o.stop(n)},V(o.$t(`@SCHED:停止`)),9,rn)):(e(),R(`button`,{key:1,type:`button`,class:`sch-btn`,disabled:!!o.pending[n.id],onClick:e=>o.runNow(n)},V(o.$t(`@SCHED:运行`)),9,an)),m(`button`,{type:`button`,class:`sch-btn`,onClick:e=>o.openEdit(n)},V(o.$t(`@SCHED:编辑`)),9,on),m(`button`,{type:`button`,class:`sch-btn sch-btn-danger`,onClick:e=>o.askRemove(n)},V(o.$t(`@SCHED:删除`)),9,sn)])])],2))),128))])):(e(),R(`div`,Ut,[m(`p`,Wt,V(o.$t(`@SCHED:还没有定时任务`)),1),m(`p`,Gt,V(o.$t(`@SCHED:让 g ai 在指定时间自动做事:定时拉代码、定时巡检、定时汇总。也可以在对话里直接说「每天 9 点帮我…」,让 g ai 来创建。`)),1)])),t(` 新建 / 编辑 `),c(o.CommonDialog,{modelValue:o.formVisible,"onUpdate:modelValue":i[14]||=e=>o.formVisible=e,title:o.editingId?o.$t(`@SCHED:编辑任务`):o.$t(`@SCHED:新建任务`),"close-on-click-modal":!1,"append-to-body":!0,size:`medium`,width:`560px`,"z-index":3e6,"custom-class":`schedule-dialog`},{default:U(()=>[m(`div`,cn,[m(`label`,ln,[m(`span`,un,V(o.$t(`@SCHED:任务名`)),1),A(m(`input`,{"onUpdate:modelValue":i[0]||=e=>o.form.name=e,class:`sch-input`,type:`text`,placeholder:o.$t(`@SCHED:如:每日拉代码`)},null,8,dn),[[G,o.form.name]])]),m(`div`,fn,[m(`span`,pn,V(o.$t(`@SCHED:执行计划`)),1),m(`div`,mn,[A(m(`select`,{"onUpdate:modelValue":i[1]||=e=>o.form.freq=e,class:`sch-input sch-select`},[(e(!0),R(r,null,H(o.freqOptions,t=>(e(),R(`option`,{key:t.value,value:t.value},V(t.label),9,hn))),128))],512),[[W,o.form.freq]]),o.form.freq===`minutes`?(e(),R(r,{key:0},[m(`span`,gn,V(o.$t(`@SCHED:每`)),1),A(m(`select`,{"onUpdate:modelValue":i[2]||=e=>o.form.everyMinutes=e,class:`sch-input sch-select sch-select-sm`},[(e(),R(r,null,H([5,10,15,20,30,60],e=>m(`option`,{key:e,value:e},V(e),9,_n)),64))],512),[[W,o.form.everyMinutes,void 0,{number:!0}]]),m(`span`,vn,V(o.$t(`@SCHED:分钟`)),1)],64)):o.form.freq===`daily`||o.form.freq===`weekly`?(e(),R(r,{key:1},[o.form.freq===`weekly`?A((e(),R(`select`,{key:0,"onUpdate:modelValue":i[3]||=e=>o.form.weekday=e,class:`sch-input sch-select sch-select-sm`},[(e(),R(r,null,H(o.WEEKDAY_KEYS,(e,t)=>m(`option`,{key:t,value:t},V(o.$t(e)),9,yn)),64))],512)),[[W,o.form.weekday,void 0,{number:!0}]]):t(`v-if`,!0),A(m(`select`,{"onUpdate:modelValue":i[4]||=e=>o.form.hour=e,class:`sch-input sch-select sch-select-sm`},[(e(),R(r,null,H(24,e=>m(`option`,{key:e-1,value:e-1},V(String(e-1).padStart(2,`0`)),9,bn)),64))],512),[[W,o.form.hour,void 0,{number:!0}]]),i[19]||=m(`span`,{class:`sch-inline-label`},`:`,-1),A(m(`select`,{"onUpdate:modelValue":i[5]||=e=>o.form.minute=e,class:`sch-input sch-select sch-select-sm`},[(e(),R(r,null,H(60,e=>m(`option`,{key:e-1,value:e-1},V(String(e-1).padStart(2,`0`)),9,xn)),64))],512),[[W,o.form.minute,void 0,{number:!0}]])],64)):o.form.freq===`hourly`?(e(),R(r,{key:2},[m(`span`,Sn,V(o.$t(`@SCHED:第`)),1),A(m(`select`,{"onUpdate:modelValue":i[6]||=e=>o.form.minute=e,class:`sch-input sch-select sch-select-sm`},[(e(),R(r,null,H(60,e=>m(`option`,{key:e-1,value:e-1},V(String(e-1).padStart(2,`0`)),9,Cn)),64))],512),[[W,o.form.minute,void 0,{number:!0}]]),m(`span`,wn,V(o.$t(`@SCHED:分钟`)),1)],64)):A((e(),R(`input`,{key:3,"onUpdate:modelValue":i[7]||=e=>o.form.custom=e,class:`sch-input sch-input-cron`,type:`text`,spellcheck:`false`,placeholder:o.$t(`@SCHED:如:0 9 * * 1-5`)},null,8,Tn)),[[G,o.form.custom]])]),m(`span`,En,V(o.$t(`@SCHED:cron:{cron}(分 时 日 月 周,本地时间)`,{cron:o.cronPreview||`—`})),1)]),m(`label`,Dn,[m(`span`,On,V(o.$t(`@SCHED:项目目录`)),1),A(m(`input`,{"onUpdate:modelValue":i[8]||=e=>o.form.cwd=e,class:`sch-input`,type:`text`,spellcheck:`false`,placeholder:o.$t(`@SCHED:任务在该目录下执行(默认当前项目)`)},null,8,kn),[[G,o.form.cwd]])]),m(`label`,An,[m(`span`,jn,V(o.$t(`@SCHED:提示词`)),1),A(m(`textarea`,{"onUpdate:modelValue":i[9]||=e=>o.form.prompt=e,class:`sch-input sch-textarea`,rows:`4`,placeholder:o.$t(`@SCHED:到点后发给 g ai 的完整指令,例如:检查所有仓库远端更新,有变更就 pull;写成一次自足的请求(未来那一轮没有现在的上下文)`)},null,8,Mn),[[G,o.form.prompt]])]),m(`div`,Nn,[m(`span`,Pn,V(o.$t(`@SCHED:错过补偿`)),1),m(`div`,Fn,[m(`label`,In,[A(m(`input`,{"onUpdate:modelValue":i[10]||=e=>o.form.onMissed=e,type:`radio`,value:`run`},null,512),[[E,o.form.onMissed]]),m(`span`,null,V(o.$t(`@SCHED:补跑一次(g ui 重新运行后)`)),1)]),m(`label`,Ln,[A(m(`input`,{"onUpdate:modelValue":i[11]||=e=>o.form.onMissed=e,type:`radio`,value:`skip`},null,512),[[E,o.form.onMissed]]),m(`span`,null,V(o.$t(`@SCHED:跳过`)),1)]),m(`label`,Rn,[A(m(`input`,{"onUpdate:modelValue":i[12]||=e=>o.form.enabled=e,type:`checkbox`},null,512),[[N,o.form.enabled]]),m(`span`,null,V(o.$t(`@SCHED:创建后启用`)),1)])])]),o.formError?(e(),R(`p`,zn,V(o.formError),1)):t(`v-if`,!0)]),m(`div`,Bn,[m(`button`,{type:`button`,class:`sch-btn`,onClick:i[13]||=e=>o.formVisible=!1},V(o.$t(`@SCHED:取消`)),1),m(`button`,{type:`button`,class:`sch-btn sch-btn-primary`,disabled:o.saving,onClick:o.submitForm},V(o.saving?o.$t(`@SCHED:保存中...`):o.$t(`@SCHED:保存`)),9,Vn)])]),_:1},8,[`modelValue`,`title`]),t(` 删除确认 `),c(o.CommonDialog,{modelValue:o.confirmVisible,"onUpdate:modelValue":i[16]||=e=>o.confirmVisible=e,title:o.$t(`@SCHED:删除任务`),"close-on-click-modal":!1,"append-to-body":!0,size:`small`,width:`400px`,"z-index":3e6,"custom-class":`schedule-dialog-confirm`},{default:U(()=>[m(`p`,Hn,V(o.$t(`@SCHED:确定删除「{name}」吗?已产生的会话会保留,但任务不再执行。`,{name:o.confirmTarget?.name||``})),1),m(`div`,Un,[m(`button`,{type:`button`,class:`sch-btn`,onClick:i[15]||=e=>o.confirmVisible=!1},V(o.$t(`@SCHED:取消`)),1),m(`button`,{type:`button`,class:`sch-btn sch-btn-danger`,onClick:o.confirmRemove},V(o.$t(`@SCHED:删除`)),1)])]),_:1},8,[`modelValue`,`title`])])}var Gn=q(Lt,[[`render`,Wn],[`__scopeId`,`data-v-63dc658b`],[`__file`,`C:/workspace/github_workspace/xz333221/zen-gitsync/src/ui/client/src/components/SchedulePanel.vue`]]);s(),P();var Kn=4e3,qn=g({__name:`AgentPromptSettings`,setup(e,{expose:t}){t();let n=le(),{defaultPrompt:r,projectPrompts:i,loadOrchestrator:o,saveDefaultPrompt:s,saveProjectPrompt:c}=ke(),l=_(``),u=_(!1),d=_(!1),f=a(()=>n.agentDefaultPrompt||``),p=a(()=>l.value.trim()!==f.value.trim());async function m(){if(!u.value&&p.value){u.value=!0;try{await n.saveAiSettings({agentDefaultPrompt:l.value})&&(l.value=f.value,d.value=!0,D.success(K(`@AGENT:已保存 g ai 默认提示词`)))}finally{u.value=!1}}}let h=a(()=>n.currentDirectory||``),g=a(()=>de(h.value)||h.value),v=a(()=>{let e=pe(h.value);return e&&i.value?.[e]?.prompt||``}),y=_(``),b=_(``),x=_(!1),S=_(!1),C=_(!1),w=a(()=>y.value.trim()!==(r.value||``).trim()||!!h.value&&b.value.trim()!==v.value.trim());function E(){y.value=r.value||``,b.value=v.value}T(async()=>{l.value=f.value,E();let e=await o(!0);C.value=!e,e&&E()});async function O(){if(!x.value&&w.value){x.value=!0;try{let e=!0,t=y.value.trim();t!==(r.value||``).trim()&&(e=await s(t));let n=b.value.trim();e&&h.value&&n!==v.value.trim()&&(e=await c(h.value,n)),e&&(E(),S.value=!0)}finally{x.value=!1}}}let k={configStore:n,defaultPrompt:r,projectPrompts:i,loadOrchestrator:o,saveDefaultPrompt:s,saveProjectPrompt:c,MAX_CHARS:Kn,gaiDraft:l,savingGai:u,gaiSaved:d,gaiStored:f,gaiDirty:p,saveGai:m,projectPath:h,projectName:g,projectPrompt:v,globalDraft:y,projectDraft:b,savingDispatch:x,dispatchSaved:S,dispatchLoadFailed:C,dispatchDirty:w,syncDispatchDraft:E,saveDispatch:O,get $t(){return K}};return Object.defineProperty(k,"__isScriptSetup",{enumerable:!1,value:!0}),k}});f(),s(),M();var Jn={class:`aps`},Yn={class:`aps__scroll`},Xn={class:`aps__head`},Zn={class:`aps__title`},Qn={class:`aps__intro`},$n={class:`aps__card aps__card--gai`},er={class:`aps__card-head`},tr={class:`aps__card-title`},nr={class:`aps__count`},rr={class:`aps__hint`},ir=[`placeholder`],ar={class:`aps__foot`},or={key:0,class:`aps__saved`},sr=[`disabled`],cr={class:`aps__card aps__card--dispatch`},lr={class:`aps__card-head`},ur={class:`aps__card-title`},dr={class:`aps__hint`},fr={class:`aps__field`},pr={class:`aps__card-head`},mr={class:`aps__label`,for:`aps-global`},hr={class:`aps__count`},gr=[`placeholder`],_r={class:`aps__field`},vr={class:`aps__card-head`},yr={class:`aps__label`,for:`aps-project`},br={key:0,class:`aps__count`},xr=[`disabled`,`placeholder`],Sr={class:`aps__hint`},Cr={class:`aps__foot`},wr={key:0,class:`aps__saved`},Tr={key:1,class:`aps__saved`},Er=[`disabled`];function Dr(n,r,i,a,o,s){return e(),R(`div`,Jn,[m(`div`,Yn,[m(`header`,Xn,[m(`h3`,Zn,V(a.$t(`@AGENT:提示词设置`)),1),m(`p`,Qn,V(a.$t(`@AGENT:这里配的两块提示词,和 g ai 对话时每一轮都会自动带上。改完下一次发消息就生效,不用新开会话。`)),1)]),t(` ── ① g ai 智能体的默认提示词 ── `),m(`section`,$n,[m(`div`,er,[m(`h4`,tr,V(a.$t(`@AGENT:g ai 智能体的默认提示词`)),1),m(`span`,nr,V(a.gaiDraft.length)+` / `+V(a.MAX_CHARS),1)]),m(`p`,rr,V(a.$t(`@AGENT:只作用于 g ai 自己:每次对话都会带上(定时任务也一样)。派发出去的任务读不到这一段。`)),1),A(m(`textarea`,{id:`aps-gai`,"onUpdate:modelValue":r[0]||=e=>a.gaiDraft=e,class:`aps__area`,rows:`6`,maxlength:a.MAX_CHARS,placeholder:a.$t(`@AGENT:例如:回答用中文;改完代码先跑一遍验证再汇报;不要动 dist 目录`)},null,8,ir),[[G,a.gaiDraft]]),m(`div`,ar,[a.gaiSaved&&!a.gaiDirty?(e(),R(`span`,or,V(a.$t(`@AGENT:已保存`)),1)):t(`v-if`,!0),r[3]||=m(`span`,{class:`aps__spacer`},null,-1),m(`button`,{type:`button`,class:`aps__btn aps__btn--primary`,disabled:a.savingGai||!a.gaiDirty,onClick:a.saveGai},V(a.savingGai?a.$t(`@AGENT:保存中…`):a.$t(`@AGENT:保存`)),9,sr)])]),t(` ── ② 派发任务的提示词 ── `),m(`section`,cr,[m(`div`,lr,[m(`h4`,ur,V(a.$t(`@AGENT:派发任务的提示词`)),1)]),m(`p`,dr,V(a.$t(`@AGENT:与工作台「预设提示词」是同一份设置,在哪边改都一样。派发任务时附加在指令之前,和 g ai 对话时也会带上。`)),1),m(`div`,fr,[m(`div`,pr,[m(`label`,mr,V(a.$t(`@AGENT:全局提示词`)),1),m(`span`,hr,V(a.globalDraft.length)+` / `+V(a.MAX_CHARS),1)]),A(m(`textarea`,{id:`aps-global`,"onUpdate:modelValue":r[1]||=e=>a.globalDraft=e,class:`aps__area`,rows:`5`,maxlength:a.MAX_CHARS,placeholder:a.$t(`@AGENT:对所有项目生效。例如:回答用中文;改完代码必须跑一遍测试;不要动 dist 目录`)},null,8,gr),[[G,a.globalDraft]])]),m(`div`,_r,[m(`div`,vr,[m(`label`,yr,V(a.projectPath?a.$t(`@AGENT:「{name}」的项目提示词`,{name:a.projectName}):a.$t(`@AGENT:项目提示词`)),1),a.projectPath?(e(),R(`span`,br,V(a.projectDraft.length)+` / `+V(a.MAX_CHARS),1)):t(`v-if`,!0)]),A(m(`textarea`,{id:`aps-project`,"onUpdate:modelValue":r[2]||=e=>a.projectDraft=e,class:`aps__area`,rows:`5`,maxlength:a.MAX_CHARS,disabled:!a.projectPath,placeholder:a.projectPath?a.$t(`@AGENT:只在这个项目派发/对话时附加。例如:包管理器用 pnpm;改动集中在 src/ui 下`):a.$t(`@AGENT:当前没有打开项目,项目级提示词暂时不能设置`)},null,8,xr),[[G,a.projectDraft]]),m(`p`,Sr,V(a.projectPath?a.$t(`@AGENT:项目提示词追加在全局提示词之后(不覆盖全局),在「{name}」里派发或对话时一起带上`,{name:a.projectName}):a.$t(`@AGENT:先在左上角切到一个项目,才能设置它的提示词`)),1)]),m(`div`,Cr,[a.dispatchSaved&&!a.dispatchDirty?(e(),R(`span`,wr,V(a.$t(`@AGENT:已保存`)),1)):a.dispatchLoadFailed?(e(),R(`span`,Tr,V(a.$t(`@AGENT:读取设置失败,请稍后重试`)),1)):t(`v-if`,!0),r[4]||=m(`span`,{class:`aps__spacer`},null,-1),m(`button`,{type:`button`,class:`aps__btn aps__btn--primary`,disabled:a.savingDispatch||!a.dispatchDirty,onClick:a.saveDispatch},V(a.savingDispatch?a.$t(`@AGENT:保存中…`):a.$t(`@AGENT:保存`)),9,Er)])])])])}var Or=q(qn,[[`render`,Dr],[`__scopeId`,`data-v-f9ada51b`],[`__file`,`C:/workspace/github_workspace/xz333221/zen-gitsync/src/ui/client/src/components/AgentPromptSettings.vue`]]);s(),P();var kr=40,Ar=g({__name:`AgentView`,setup(e,{expose:t}){t();let r=le(),i=_(null),{narrow:o}=Oe(i),s=_(`chat`),c=_(`chat`),d=a(()=>c.value===`mcp`?`mcp`:`skill`),f=a(()=>[{id:`chat`,label:K(`@AGENT:对话`),icon:j},{id:`schedule`,label:K(`@AGENT:定时任务`),icon:ee},{id:`skill`,label:K(`@AGENT:Skill 广场`),icon:v},{id:`mcp`,label:K(`@AGENT:MCP 广场`),icon:ae},{id:`settings`,label:K(`@AGENT:设置`),icon:w}]),{sessions:p,sessionsLoading:m,currentSessionId:h,messages:g,displayMessages:y,isStreaming:b,sessionLoading:x,loadSessions:S,loadSession:E,deleteSession:D,renameSession:O,newSession:A,sendMessage:M,retryTurn:N,questionPanel:P,answeringQuestion:F,answerQuestion:I,isSessionGenerating:L,currentEngine:R,pendingEngine:z,isEngineLocked:B,pickEngine:te,stop:ne,inputContextUsage:V,queuedMessages:re,queuePaused:ie,removeQueuedMessage:H,flushQueued:oe}=we(),U=a(()=>B.value?R.value:z.value);function W(e){B.value||te(e)}let G=a(()=>{let e=r.theme;return e===`dark`||e===`auto`&&window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}),q=a(()=>he(p.value,L)),ue=me(),de=a(()=>q.value.find(e=>e.id===h.value)?.title||K(`@AGENT:对话`)),pe={"--welcome-avatar":`url("${Ce}")`},ke=a(()=>fe(r.agentPresetPrompts));async function J(e){await M(e.text,e.files),await u(),Y()}async function Ae(e){await M(e.prompt),await u(),Y()}let je=be(),Me=_(null),Ne=Se();function Y(e=!0){Me.value?.scrollToBottom(e)}k(()=>g.value.length,()=>{u(()=>Y(!1))});function Pe(e){E(e),s.value=`chat`}function X(e){e&&(c.value=`chat`,Pe(e))}function Ie(){A(),s.value=`chat`}let Z=_(280),Q=_(!1),{convListCollapsed:Le,setConvListCollapsed:Re}=Te();function ze(e){if(Le.value)return;Q.value=!0;let t=e.clientX,n=Z.value,r=e=>{let r=e.clientX-t,i=Math.max(200,Math.min(500,n+r));Z.value=i},i=()=>{Q.value=!1,document.removeEventListener(`mousemove`,r),document.removeEventListener(`mouseup`,i)};document.addEventListener(`mousemove`,r),document.addEventListener(`mouseup`,i)}k(o,e=>{e||(s.value=`chat`)}),k(()=>[r.currentDirectory,b.value],async([e,t],n)=>{let r=!n||e!==n[0],i=!!n&&n[1]===!0&&!t;(r||i)&&await S(),h.value&&!b.value&&!p.value.some(e=>e.sessionId===h.value)&&A()},{immediate:!0});let $=null;T(()=>{$=Fe(e=>{e.type===`task_finished`&&S().catch(()=>{})})}),C(()=>{$?.(),$=null});let Be={configStore:r,rootRef:i,narrow:o,chatPage:s,activeTab:c,marketplaceType:d,tabs:f,sessions:p,sessionsLoading:m,currentSessionId:h,messages:g,displayMessages:y,isStreaming:b,sessionLoading:x,loadSessions:S,loadSession:E,deleteSession:D,renameSession:O,newSession:A,sendMessage:M,retryTurn:N,questionPanel:P,answeringQuestion:F,answerQuestion:I,isSessionGenerating:L,currentEngine:R,pendingEngine:z,isEngineLocked:B,pickEngine:te,stop:ne,inputContextUsage:V,queuedMessages:re,queuePaused:ie,removeQueuedMessage:H,flushQueued:oe,displayEngine:U,handleEngineSelect:W,chatTheme:G,conversationItems:q,conversationLabels:ue,currentSessionTitle:de,welcomeAvatarStyle:pe,presetQuestions:ke,onSend:J,onSelectPreset:Ae,questionLabels:je,chatContainerRef:Me,queueLabels:Ne,scrollToBottom:Y,selectSession:Pe,handleScheduleOpenSession:X,handleNewSession:Ie,sidebarWidth:Z,isResizing:Q,convListCollapsed:Le,setConvListCollapsed:Re,CONV_RAIL_WIDTH:kr,startResize:ze,get disposeScheduleEvents(){return $},set disposeScheduleEvents(e){$=e},get $t(){return K},get ElIcon(){return l},get Loading(){return n},get ChatContainer(){return se},get ConversationList(){return ce},get AGENT_UPLOAD_ACCEPT(){return _e},get AGENT_ASSISTANT_NAME(){return ye},get AGENT_ASSISTANT_AVATAR(){return Ce},get MESSAGE_RAIL_CONFIG(){return ge},get MESSAGE_META_CONFIG(){return xe},get agentEngineName(){return ve},MarketplacePanel:It,SchedulePanel:Gn,AgentPromptSettings:Or,AgentEngineSelector:Ee,CopySessionButton:De};return Object.defineProperty(Be,"__isScriptSetup",{enumerable:!1,value:!0}),Be}});s(),f();var jr={ref:`rootRef`,class:`agent-view`},Mr={class:`agent-chat-area`},Nr={class:`agent-tabs`,role:`tablist`},Pr=[`aria-selected`,`onClick`],Fr={class:`agent-tab-body`},Ir={key:0,class:`agent-chat-pane`},Lr={key:0,class:`agent-list-page`},Rr={key:0,class:`agent-page-bar`},zr=[`title`,`aria-label`],Br={class:`agent-page-title`},Vr={key:0,class:`chat-loading`};function Hr(n,i,a,o,s,l){return e(),R(`div`,jr,[t(` ═══ 宽屏:左侧会话列表(只在「对话」Tab 显示)═══
3
+ 窄屏时这一整块不渲染,会话列表改成 body 里的一个整页(见 .agent-list-page) `),o.activeTab===`chat`&&!o.narrow?(e(),R(r,{key:0},[m(`aside`,{class:x([`agent-sidebar`,{"is-convs-collapsed":o.convListCollapsed}]),style:h({width:(o.convListCollapsed?o.CONV_RAIL_WIDTH:o.sidebarWidth)+`px`})},[t(` 会话列表:UI 与交互都在组件库的 ConversationList 里(含收起 / 展开) `),c(o.ConversationList,{class:`agent-conversations`,items:o.conversationItems,"active-id":o.currentSessionId,loading:o.sessionsLoading,labels:o.conversationLabels,collapsible:``,collapsed:o.convListCollapsed,"onUpdate:collapsed":o.setConvListCollapsed,onSelect:o.selectSession,onNew:o.handleNewSession,onRename:o.renameSession,onDelete:o.deleteSession},null,8,[`items`,`active-id`,`loading`,`labels`,`collapsed`,`onUpdate:collapsed`,`onRename`,`onDelete`])],6),t(` 拖拽分隔条(收起时藏起来:40px 的收纳条没有可拖的余地) `),o.convListCollapsed?t(`v-if`,!0):(e(),R(`div`,{key:0,class:x([`sidebar-resizer`,{active:o.isResizing}]),onMousedown:o.startResize},null,34))],64)):t(`v-if`,!0),t(` ═══ 右侧:Tab 栏 + 内容区 ═══ `),m(`main`,Mr,[m(`nav`,Nr,[(e(!0),R(r,null,H(o.tabs,t=>(e(),R(`button`,{key:t.id,type:`button`,class:x([`agent-tab`,{active:o.activeTab===t.id}]),role:`tab`,"aria-selected":o.activeTab===t.id,onClick:e=>o.activeTab=t.id},[c(o.ElIcon,null,{default:U(()=>[(e(),z(I(t.icon)))]),_:2},1024),m(`span`,null,V(t.label),1)],10,Pr))),128)),t(` ═══ 引擎选择器 ═══
4
+ 与工作台执行器下拉同一套交互(点击展开、未安装标出来、点了直接开安装弹窗)。
5
+ 下拉本体收口在 AgentEngineSelector,文件空间 g ai 面板复用同一份实现。
6
+ 会话一旦落盘就置灰:引擎在会话建立时锁定(三家续聊标识互不通用),要换请新建。 `),o.activeTab===`chat`?(e(),z(o.AgentEngineSelector,{key:0,class:`agent-engine`,engine:o.displayEngine,locked:o.isEngineLocked,onSelect:o.handleEngineSelect},null,8,[`engine`,`locked`])):t(`v-if`,!0),t(` 复制整条会话(默认精简范围,小箭头可选全量)——与工作台的「复制执行内容」同一套口径 `),o.activeTab===`chat`?(e(),z(o.CopySessionButton,{key:1,class:`agent-copy`,messages:o.messages,title:o.currentSessionTitle,engine:o.agentEngineName(o.displayEngine)},null,8,[`messages`,`title`,`engine`])):t(`v-if`,!0)]),m(`div`,Fr,[t(` ── 对话 ── `),o.activeTab===`chat`?(e(),R(`div`,Ir,[t(` 窄屏 · 会话列表页:列表独占整页 `),o.narrow&&o.chatPage===`list`?(e(),R(`div`,Lr,[c(o.ConversationList,{class:`agent-conversations`,items:o.conversationItems,"active-id":o.currentSessionId,loading:o.sessionsLoading,labels:o.conversationLabels,onSelect:o.selectSession,onNew:o.handleNewSession,onRename:o.renameSession,onDelete:o.deleteSession},null,8,[`items`,`active-id`,`loading`,`labels`,`onRename`,`onDelete`])])):(e(),R(r,{key:1},[t(` 对话页(窄屏时顶上多一条返回条;宽屏左侧就摆着列表,不需要) `),o.narrow?(e(),R(`div`,Rr,[m(`button`,{type:`button`,class:`agent-page-back`,title:o.$t(`@AGENT:返回会话列表`),"aria-label":o.$t(`@AGENT:返回会话列表`),onClick:i[0]||=e=>o.chatPage=`list`},[...i[1]||=[m(`svg`,{viewBox:`0 0 24 24`,width:`14`,height:`14`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`},[m(`line`,{x1:`19`,y1:`12`,x2:`5`,y2:`12`}),m(`polyline`,{points:`12 19 5 12 12 5`})],-1)]],8,zr),m(`span`,Br,V(o.currentSessionTitle),1)])):t(`v-if`,!0),t(`
7
+ 对话宿主:单独开一层裁剪边界。
8
+ 欢迎页在矮/窄窗口里会比可用高度还高,而它是垂直居中的 —— 溢出的部分
9
+ 会**向上**跑出 .acu-chat,盖到刚加的返回条上(把返回条的点击也一起吃掉,
10
+ e2e 实测就是这个症状)。宿主的 overflow:hidden 把它裁在自己这一格里。
11
+ `),m(`div`,{class:`agent-chat-host`,style:o.welcomeAvatarStyle},[t(` 加载中 `),o.sessionLoading?(e(),R(`div`,Vr,[c(o.ElIcon,{class:`is-loading`,size:32},{default:U(()=>[c(o.Loading)]),_:1}),m(`span`,null,V(o.$t(`@AGENT:加载会话中...`)),1)])):(e(),R(r,{key:1},[t(` ChatContainer `),c(o.ChatContainer,{ref:`chatContainerRef`,messages:o.displayMessages,"preset-questions":o.presetQuestions,"welcome-title":o.$t(`@AGENT:智能体助手`),"welcome-description":o.$t(`@AGENT:我可以帮你阅读代码、执行命令、修改文件。选择下方话题或直接输入你的问题。`),"assistant-name":o.AGENT_ASSISTANT_NAME,"assistant-avatar":o.AGENT_ASSISTANT_AVATAR,theme:o.chatTheme,generating:o.isStreaming,"allow-queue":!0,queued:o.queuedMessages,"queue-paused":o.queuePaused,"queue-labels":o.queueLabels,"upload-config":{accept:o.AGENT_UPLOAD_ACCEPT},"context-usage":o.inputContextUsage,placeholder:o.isStreaming?o.$t(`@AGENT:生成中,发送后会排队,等本轮跑完自动接上…`):o.$t(`@AGENT:输入消息,Enter 发送`),question:o.questionPanel,"question-submitting":o.answeringQuestion,"question-labels":o.questionLabels,"plan-config":{labels:{title:o.$t(`@AGENT:计划`),raw:o.$t(`@AGENT:原始参数`)}},"message-rail-config":o.MESSAGE_RAIL_CONFIG,"message-meta-config":o.MESSAGE_META_CONFIG,onSend:o.onSend,onSelect:o.onSelectPreset,onStop:o.stop,onUnqueue:o.removeQueuedMessage,onFlushQueued:o.flushQueued,onAnswer:o.answerQuestion,onRetry:o.retryTurn},null,8,[`messages`,`preset-questions`,`welcome-title`,`welcome-description`,`assistant-name`,`assistant-avatar`,`theme`,`generating`,`queued`,`queue-paused`,`queue-labels`,`upload-config`,`context-usage`,`placeholder`,`question`,`question-submitting`,`question-labels`,`plan-config`,`message-rail-config`,`message-meta-config`,`onStop`,`onUnqueue`,`onFlushQueued`,`onAnswer`,`onRetry`])],2112))])],64))])):o.activeTab===`schedule`?(e(),R(r,{key:1},[t(` ── 定时任务 ── `),c(o.SchedulePanel,{onOpenSession:o.handleScheduleOpenSession})],2112)):o.activeTab===`skill`||o.activeTab===`mcp`?(e(),R(r,{key:2},[t(` ── Skill 广场 / MCP 广场 ── `),c(o.MarketplacePanel,{type:o.marketplaceType},null,8,[`type`])],2112)):(e(),R(r,{key:3},[t(` ── 设置(提示词设置)── `),c(o.AgentPromptSettings)],2112))])])],512)}var Ur=q(Ar,[[`render`,Hr],[`__scopeId`,`data-v-bd681ddd`],[`__file`,`C:/workspace/github_workspace/xz333221/zen-gitsync/src/ui/client/src/views/AgentView.vue`]]);export{Ur as default};
@@ -1 +1 @@
1
- .marketplace-panel[data-v-e9f9e851]{background:var(--bg-container);flex-direction:column;height:100%;min-height:0;display:flex}.mp-toolbar[data-v-e9f9e851]{flex-shrink:0;align-items:center;gap:12px;padding:12px 16px 8px;display:flex}.mp-search[data-v-e9f9e851]{border:1px solid var(--border-color);border-radius:var(--radius-md);background:var(--bg-panel);max-width:420px;height:32px;transition:border-color var(--transition-fast) ease;flex:1;align-items:center;gap:6px;padding:0 10px;display:flex}.mp-search[data-v-e9f9e851]:focus-within{border-color:var(--color-primary)}.mp-search .mp-search-icon[data-v-e9f9e851]{color:var(--text-meta);flex-shrink:0}.mp-search .mp-search-input[data-v-e9f9e851]{color:var(--text-primary);font-size:var(--font-size-mid);background:0 0;border:none;outline:none;flex:1;font-family:inherit}.mp-search .mp-search-input[data-v-e9f9e851]::placeholder{color:var(--text-meta)}.mp-target[data-v-e9f9e851]{flex-shrink:0}.mp-refresh[data-v-e9f9e851]{border:1px solid var(--border-color);border-radius:var(--radius-md);background:var(--bg-panel);width:30px;height:30px;color:var(--text-secondary);cursor:pointer;transition:var(--transition-ui-fast);justify-content:center;align-items:center;display:flex}.mp-refresh[data-v-e9f9e851]:hover{color:var(--color-primary);border-color:var(--color-primary)}.mp-refresh.spinning svg[data-v-e9f9e851]{animation:.9s linear infinite mkt-spin-e9f9e851}@keyframes mkt-spin-e9f9e851{to{transform:rotate(360deg)}}.mp-toolbar-sub[data-v-e9f9e851]{flex-wrap:wrap;flex-shrink:0;align-items:center;gap:12px;padding:0 16px 10px;display:flex}.mp-target-hint[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--text-meta)}.mp-target-hint b[data-v-e9f9e851]{color:var(--color-primary);font-weight:600}.mp-source-filter[data-v-e9f9e851]{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.mp-chip[data-v-e9f9e851]{font-size:var(--font-size-sm);border:1px solid var(--border-color);border-radius:var(--radius-xl);color:var(--text-meta);cursor:pointer;transition:var(--transition-ui-fast);background:0 0;padding:2px 10px;font-family:inherit}.mp-chip[data-v-e9f9e851]:hover{color:var(--text-secondary);border-color:var(--text-tertiary)}.mp-chip.active[data-v-e9f9e851]{color:var(--color-primary);border-color:var(--color-primary);background:color-mix(in srgb, var(--color-primary) 8%, transparent)}.mp-chip.clear[data-v-e9f9e851]{color:var(--text-meta);border-style:dashed}.mp-body[data-v-e9f9e851]{flex:1;min-height:0;padding:0 16px 20px;overflow-y:auto}.mp-group[data-v-e9f9e851]{margin-bottom:20px}.mp-group.installed[data-v-e9f9e851]{border-top:1px dashed var(--border-color);padding-top:14px}.mp-group-header[data-v-e9f9e851]{align-items:center;gap:8px;margin-bottom:10px;display:flex}.mp-group-title[data-v-e9f9e851]{font-size:var(--font-size-mid);color:var(--text-primary);margin:0;font-weight:600}.mp-group-count[data-v-e9f9e851]{min-width:20px;height:18px;font-size:var(--font-size-xs);border-radius:var(--radius-lg);background:var(--bg-hover);color:var(--text-meta);justify-content:center;align-items:center;padding:0 6px;display:inline-flex}.mp-group-error[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--color-warning-dark);align-items:center;gap:4px;display:inline-flex}.mp-group-link[data-v-e9f9e851]{color:var(--text-meta);transition:color var(--transition-fast) ease;display:inline-flex}.mp-group-link[data-v-e9f9e851]:hover{color:var(--color-primary)}.mp-grid[data-v-e9f9e851]{grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:10px;display:grid}.mp-card[data-v-e9f9e851]{border:1px solid var(--border-color);border-radius:var(--radius-md);background:var(--bg-panel);transition:border-color var(--transition-fast) ease, box-shadow var(--transition-fast) ease;flex-direction:column;gap:6px;padding:12px;display:flex}.mp-card[data-v-e9f9e851]:hover{border-color:color-mix(in srgb, var(--color-primary) 40%, var(--border-color));box-shadow:var(--shadow-sm)}.mp-card-head[data-v-e9f9e851]{align-items:center;gap:8px;display:flex}.mp-card-name[data-v-e9f9e851]{min-width:0;font-size:var(--font-size-mid);color:var(--text-primary);white-space:nowrap;text-overflow:ellipsis;flex:1;font-weight:600;overflow:hidden}.mp-card-metric[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta);flex-shrink:0;align-items:center;gap:3px;display:inline-flex}.mp-card-desc[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--text-secondary);-webkit-line-clamp:2;-webkit-box-orient:vertical;min-height:36px;margin:0;line-height:1.5;display:-webkit-box;overflow:hidden}.mp-card-meta[data-v-e9f9e851]{flex-wrap:wrap;align-items:center;gap:6px;min-height:18px;display:flex}.mp-meta-pkg[data-v-e9f9e851],.mp-meta-repo[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta);white-space:nowrap;text-overflow:ellipsis;max-width:220px;overflow:hidden}.mp-tag[data-v-e9f9e851]{font-size:var(--font-size-xs);border-radius:var(--radius-lg);background:var(--bg-hover);color:var(--text-meta);flex-shrink:0;padding:1px 6px}.mp-tag.remote[data-v-e9f9e851]{background:color-mix(in srgb, var(--color-info,var(--action-teal)) 14%, transparent);color:var(--color-info,var(--action-teal))}.mp-tag.warn[data-v-e9f9e851]{background:color-mix(in srgb, var(--color-warning) 14%, transparent);color:var(--color-warning-dark)}.mp-card-foot[data-v-e9f9e851]{align-items:center;gap:8px;margin-top:2px;display:flex}.mp-card-link[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta);text-decoration:none}.mp-card-link[data-v-e9f9e851]:hover{color:var(--color-primary);text-decoration:underline}.mp-foot-spacer[data-v-e9f9e851]{flex:1}.mp-install-btn[data-v-e9f9e851]{font-size:var(--font-size-sm);border:1px solid var(--color-primary);border-radius:var(--radius-base);color:var(--color-primary);cursor:pointer;transition:var(--transition-ui-fast);background:0 0;padding:4px 14px;font-family:inherit}.mp-install-btn[data-v-e9f9e851]:hover:not(:disabled){background:var(--color-primary);color:#fff}.mp-install-btn[data-v-e9f9e851]:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.mp-installed-chip[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--color-success,var(--action-emerald));align-items:center;gap:3px;display:inline-flex}.mp-not-installable[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta)}.mp-empty[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--text-meta);padding:16px 0}.mp-empty.all[data-v-e9f9e851]{text-align:center;padding:48px 0}.mp-installed-block[data-v-e9f9e851]{margin-bottom:12px}.mp-installed-target[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta);text-transform:uppercase;letter-spacing:.4px;margin-bottom:6px;font-weight:600}.mp-installed-list[data-v-e9f9e851]{flex-direction:column;gap:4px;display:flex}.mp-installed-row[data-v-e9f9e851]{border:1px solid var(--border-color);border-radius:var(--radius-base);background:var(--bg-panel);align-items:center;gap:10px;padding:6px 10px;display:flex}.mp-installed-name[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--text-primary);white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:500;overflow:hidden}.mp-installed-id[data-v-e9f9e851]{font-size:var(--font-size-xs);font-family:var(--font-mono);color:var(--text-meta);white-space:nowrap;text-overflow:ellipsis;max-width:40%;overflow:hidden}.mp-reveal-btn[data-v-e9f9e851],.mp-remove-btn[data-v-e9f9e851]{font-size:var(--font-size-xs);border:1px solid var(--border-color);border-radius:var(--radius-xs);color:var(--text-meta);cursor:pointer;white-space:nowrap;transition:var(--transition-ui-fast);background:0 0;align-items:center;gap:4px;padding:3px 10px;font-family:inherit;display:inline-flex}.mp-reveal-btn[data-v-e9f9e851]:disabled,.mp-remove-btn[data-v-e9f9e851]:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.mp-reveal-btn[data-v-e9f9e851]:hover:not(:disabled){color:var(--text-primary);border-color:var(--text-tertiary)}.mp-remove-btn[data-v-e9f9e851]:hover:not(:disabled){color:var(--color-danger-dark);border-color:var(--color-danger)}@media (prefers-reduced-motion:reduce){.mp-refresh.spinning svg[data-v-e9f9e851]{animation:none}}.mkt-form[data-v-e9f9e851]{flex-direction:column;gap:12px;display:flex}.mkt-form-name[data-v-e9f9e851]{font-size:var(--font-size-mid);color:var(--text-primary);margin:0;font-weight:600}.mkt-field[data-v-e9f9e851]{flex-direction:column;gap:4px;display:flex}.mkt-field label[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--text-secondary);font-weight:600}.mkt-field input[data-v-e9f9e851]{border:1px solid var(--border-color);border-radius:var(--radius-md);background:var(--bg-container);height:30px;color:var(--text-primary);font-size:var(--font-size-mid);transition:border-color var(--transition-fast) ease;padding:0 8px;font-family:inherit}.mkt-field input[data-v-e9f9e851]:focus{border-color:var(--color-primary);outline:none}.mkt-hint[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta);margin:0}.mkt-cancel[data-v-e9f9e851],.mkt-confirm[data-v-e9f9e851]{font-size:var(--font-size-mid);border-radius:var(--radius-base);cursor:pointer;transition:var(--transition-ui-fast);padding:6px 16px;font-family:inherit}.mkt-cancel[data-v-e9f9e851]{border:1px solid var(--border-color);color:var(--text-secondary);background:0 0;margin-right:8px}.mkt-cancel[data-v-e9f9e851]:hover{color:var(--text-primary);border-color:var(--text-tertiary)}.mkt-confirm[data-v-e9f9e851]{border:1px solid var(--color-primary);background:var(--color-primary);color:#fff}.mkt-confirm[data-v-e9f9e851]:hover{opacity:.9}.schedule-panel[data-v-63dc658b]{flex-direction:column;flex:1;gap:12px;min-height:0;padding:16px 20px 24px;display:flex;overflow-y:auto}.schedule-toolbar[data-v-63dc658b]{justify-content:space-between;align-items:center;gap:12px;display:flex}.schedule-summary[data-v-63dc658b]{color:var(--text-secondary);font-size:12px}.schedule-error[data-v-63dc658b]{color:var(--text-danger);background:color-mix(in srgb, var(--color-danger) 8%, transparent);border:1px solid color-mix(in srgb, var(--color-danger) 25%, transparent);border-radius:6px;padding:8px 10px;font-size:12px}.schedule-loading[data-v-63dc658b],.schedule-empty[data-v-63dc658b]{color:var(--text-secondary);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;padding:40px 20px;font-size:13px;display:flex}.schedule-empty-title[data-v-63dc658b]{color:var(--text-primary);margin:0;font-size:14px;font-weight:500}.schedule-empty-desc[data-v-63dc658b]{text-align:center;max-width:440px;color:var(--text-tertiary);margin:0;font-size:12px;line-height:1.7}.schedule-list[data-v-63dc658b]{flex-direction:column;gap:8px;display:flex}.schedule-card[data-v-63dc658b]{background:var(--bg-card);border:1px solid var(--border-color);border-radius:8px;justify-content:space-between;align-items:center;gap:12px;padding:10px 14px;transition:border-color .15s,background .15s;display:flex}.schedule-card[data-v-63dc658b]:hover{border-color:var(--border-color-medium)}.schedule-card.is-running[data-v-63dc658b]{border-color:var(--tint-primary-35);background:var(--tint-primary-04)}.schedule-card.is-disabled .schedule-name[data-v-63dc658b]{color:var(--text-secondary)}.schedule-card-body[data-v-63dc658b]{flex-direction:column;gap:4px;min-width:0;display:flex}.schedule-card-head[data-v-63dc658b]{align-items:center;gap:8px;min-width:0;display:flex}.schedule-name[data-v-63dc658b]{color:var(--text-primary);white-space:nowrap;text-overflow:ellipsis;font-size:13px;font-weight:500;overflow:hidden}.schedule-running[data-v-63dc658b]{color:var(--color-primary);background:var(--tint-primary-10);white-space:nowrap;border-radius:4px;padding:1px 6px;font-size:11px}.schedule-card-sub[data-v-63dc658b]{color:var(--text-secondary);white-space:nowrap;align-items:center;gap:6px;min-width:0;font-size:12px;display:flex;overflow:hidden}.schedule-desc[data-v-63dc658b]{text-overflow:ellipsis;overflow:hidden}.schedule-sep[data-v-63dc658b]{color:var(--text-tertiary)}.schedule-last[data-v-63dc658b]{text-overflow:ellipsis;overflow:hidden}.schedule-last.is-ok[data-v-63dc658b]{color:var(--text-success)}.schedule-last.is-error[data-v-63dc658b]{color:var(--text-danger)}.schedule-last.is-skipped[data-v-63dc658b]{color:var(--text-warning)}.schedule-last.is-muted[data-v-63dc658b]{color:var(--text-tertiary)}.sch-link[data-v-63dc658b]{color:var(--color-primary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px}.sch-link[data-v-63dc658b]:hover{text-decoration:underline}.schedule-card-side[data-v-63dc658b]{flex-shrink:0;align-items:center;gap:12px;display:flex}.schedule-next[data-v-63dc658b]{color:var(--text-secondary);white-space:nowrap;font-size:12px}.schedule-next.is-muted[data-v-63dc658b]{color:var(--text-tertiary)}.schedule-actions[data-v-63dc658b]{align-items:center;gap:2px;display:flex}.sch-switch[data-v-63dc658b]{border:1px solid var(--border-color-medium);background:var(--bg-subtle);cursor:pointer;border-radius:10px;flex-shrink:0;width:34px;height:20px;padding:0;transition:background .15s,border-color .15s;position:relative}.sch-switch .sch-switch-knob[data-v-63dc658b]{background:var(--text-tertiary);border-radius:50%;width:14px;height:14px;transition:transform .15s,background .15s;position:absolute;top:2px;left:2px}.sch-switch.on[data-v-63dc658b]{background:var(--tint-primary-18);border-color:var(--tint-primary-45)}.sch-switch.on .sch-switch-knob[data-v-63dc658b]{background:var(--color-primary);transform:translate(14px)}.sch-btn[data-v-63dc658b]{border:1px solid var(--border-color);color:var(--text-secondary);cursor:pointer;background:0 0;border-radius:6px;padding:3px 10px;font-size:12px;transition:background .15s,color .15s,border-color .15s}.sch-btn[data-v-63dc658b]:hover:not(:disabled){background:var(--bg-subtle-hover);color:var(--text-primary);border-color:var(--border-color-medium)}.sch-btn[data-v-63dc658b]:disabled{opacity:.5;cursor:default}.sch-btn-primary[data-v-63dc658b]{background:var(--tint-primary-10);border-color:var(--tint-primary-35);color:var(--color-primary)}.sch-btn-primary[data-v-63dc658b]:hover:not(:disabled){background:var(--tint-primary-18);color:var(--color-primary);border-color:var(--tint-primary-45)}.sch-btn-danger[data-v-63dc658b]{color:var(--text-danger)}.sch-btn-danger[data-v-63dc658b]:hover:not(:disabled){background:color-mix(in srgb, var(--color-danger) 8%, transparent);color:var(--text-danger);border-color:color-mix(in srgb, var(--color-danger) 30%, transparent)}.sch-form[data-v-63dc658b]{flex-direction:column;gap:14px;display:flex}.sch-field[data-v-63dc658b]{flex-direction:column;gap:6px;display:flex}.sch-field-label[data-v-63dc658b]{color:var(--text-secondary);font-size:12px}.sch-input[data-v-63dc658b]{box-sizing:border-box;width:100%;color:var(--text-primary);background:var(--bg-container);border:1px solid var(--border-color-medium);border-radius:6px;outline:none;padding:6px 10px;font-family:inherit;font-size:13px;transition:border-color .15s}.sch-input[data-v-63dc658b]:focus{border-color:var(--tint-primary-55)}.sch-select[data-v-63dc658b]{cursor:pointer}.sch-select-sm[data-v-63dc658b]{width:auto;min-width:64px}.sch-input-cron[data-v-63dc658b]{font-family:var(--font-mono,monospace)}.sch-textarea[data-v-63dc658b]{resize:vertical;min-height:72px;line-height:1.6}.sch-freq-row[data-v-63dc658b]{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.sch-inline-label[data-v-63dc658b]{color:var(--text-secondary);white-space:nowrap;font-size:12px}.sch-hint[data-v-63dc658b]{color:var(--text-tertiary);font-size:11px}.sch-radio-row[data-v-63dc658b]{flex-wrap:wrap;align-items:center;gap:16px;display:flex}.sch-radio[data-v-63dc658b]{color:var(--text-secondary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:inline-flex}.sch-radio input[data-v-63dc658b]{accent-color:var(--color-primary);cursor:pointer;margin:0}.sch-form-error[data-v-63dc658b]{color:var(--text-danger);margin:0;font-size:12px}.sch-form-footer[data-v-63dc658b]{justify-content:flex-end;gap:8px;margin-top:14px;display:flex}.sch-confirm-text[data-v-63dc658b]{color:var(--text-primary);margin:0;font-size:13px;line-height:1.7}.aps[data-v-f9ada51b]{background:var(--bg-container);flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.aps__scroll[data-v-f9ada51b]{flex-direction:column;flex:1;gap:14px;max-width:860px;min-height:0;padding:16px 18px 24px;line-height:1.5;display:flex;overflow-y:auto}.aps__head[data-v-f9ada51b]{flex-direction:column;gap:5px;display:flex}.aps__title[data-v-f9ada51b]{font-size:var(--font-size-lg);color:var(--text-primary);margin:0;font-weight:600}.aps__intro[data-v-f9ada51b]{font-size:var(--font-size-sm);color:var(--text-meta);margin:0;line-height:1.6}.aps__card[data-v-f9ada51b]{background:var(--bg-panel);border:1px solid var(--border-color);border-radius:var(--radius-lg);flex-direction:column;gap:9px;padding:14px 16px;display:flex}.aps__card-head[data-v-f9ada51b]{align-items:baseline;gap:8px;display:flex}.aps__card-title[data-v-f9ada51b]{font-size:var(--font-size-mid);color:var(--text-primary);margin:0;font-weight:600}.aps__label[data-v-f9ada51b]{font-size:var(--font-size-sm);color:var(--text-secondary);font-weight:500}.aps__count[data-v-f9ada51b]{font-size:var(--font-size-xs);color:var(--text-meta);font-variant-numeric:tabular-nums;margin-left:auto}.aps__field[data-v-f9ada51b]{flex-direction:column;gap:5px;display:flex}.aps__hint[data-v-f9ada51b]{font-size:var(--font-size-xs);color:var(--text-meta);margin:0;line-height:1.6}.aps__area[data-v-f9ada51b]{box-sizing:border-box;resize:vertical;width:100%;min-height:92px;max-height:320px;font-size:var(--font-size-mid);color:var(--text-primary);background:var(--bg-subtle);border:1px solid var(--border-color);border-radius:var(--radius-md);transition:border-color var(--transition-fast) var(--ease-custom);outline:none;padding:7px 9px;font-family:inherit;line-height:1.5}.aps__area[data-v-f9ada51b]:focus{border-color:var(--color-primary)}.aps__area[data-v-f9ada51b]::placeholder{color:var(--text-meta)}.aps__area[data-v-f9ada51b]:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.aps__foot[data-v-f9ada51b]{align-items:center;gap:8px;display:flex}.aps__spacer[data-v-f9ada51b]{flex:1}.aps__saved[data-v-f9ada51b]{font-size:var(--font-size-xs);color:var(--text-meta)}.aps__btn[data-v-f9ada51b]{color:var(--text-secondary);font-size:var(--font-size-sm);border-radius:var(--radius-md);cursor:pointer;transition:color var(--transition-fast) var(--ease-custom), background var(--transition-fast) var(--ease-custom);background:0 0;border:none;padding:0 12px;line-height:28px}.aps__btn[data-v-f9ada51b]:hover:not(:disabled){color:var(--color-primary);background:var(--bg-container-hover)}.aps__btn[data-v-f9ada51b]:disabled{opacity:var(--disabled-opacity);cursor:default}.aps__btn[data-v-f9ada51b]:focus-visible{outline:var(--focus-outline);outline-offset:1px}.aps__btn--primary[data-v-f9ada51b]{background:var(--color-primary);color:#fff}.aps__btn--primary[data-v-f9ada51b]:hover:not(:disabled){background:var(--color-primary);color:#fff;opacity:.88}.agent-view[data-v-bd681ddd]{background:var(--bg-container);height:100%;min-height:0;display:flex}.agent-sidebar[data-v-bd681ddd]{background:var(--bg-panel);border-right:1px solid var(--border-color);flex-direction:column;flex-shrink:0;display:flex;overflow:hidden}.agent-conversations[data-v-bd681ddd]{flex:1;min-height:0;padding:10px 6px 8px 12px}.sidebar-resizer[data-v-bd681ddd]{cursor:col-resize;width:4px;transition:background var(--transition-fast) ease;background:0 0;flex-shrink:0}.sidebar-resizer[data-v-bd681ddd]:hover,.sidebar-resizer.active[data-v-bd681ddd]{background:var(--color-primary);opacity:.3}.agent-chat-area[data-v-bd681ddd]{flex-direction:column;flex:1;min-width:0;display:flex;position:relative;overflow:hidden}.agent-engine[data-v-bd681ddd]{margin-bottom:7px;margin-left:auto}.agent-copy[data-v-bd681ddd]{margin-bottom:7px;margin-left:2px}.agent-tabs[data-v-bd681ddd]{border-bottom:1px solid var(--border-color);background:var(--bg-panel);flex-shrink:0;align-items:center;gap:4px;padding:8px 12px 0;display:flex}.agent-tab[data-v-bd681ddd]{color:var(--text-meta);font-size:var(--font-size-mid);cursor:pointer;transition:color var(--transition-fast) ease, border-color var(--transition-fast) ease, background var(--transition-fast) ease;border-radius:var(--radius-base) var(--radius-base) 0 0;background:0 0;border:none;border-bottom:2px solid #0000;align-items:center;gap:6px;padding:7px 14px 9px;font-family:inherit;display:inline-flex}.agent-tab[data-v-bd681ddd]:hover{color:var(--text-secondary);background:var(--bg-hover)}.agent-tab.active[data-v-bd681ddd]{color:var(--color-primary);border-bottom-color:var(--color-primary);font-weight:600}.agent-tab-body[data-v-bd681ddd]{flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.agent-chat-pane[data-v-bd681ddd]{flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.agent-tab-body[data-v-bd681ddd]>.marketplace-panel{flex:1;min-height:0}.chat-loading[data-v-bd681ddd]{color:var(--text-meta);font-size:var(--font-size-base);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:12px;display:flex}.agent-list-page[data-v-bd681ddd]{background:var(--bg-panel);flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.agent-list-page .agent-conversations[data-v-bd681ddd]{padding:12px 12px 10px 14px}.agent-page-bar[data-v-bd681ddd]{border-bottom:1px solid var(--border-color);background:var(--bg-panel);flex-shrink:0;align-items:center;gap:6px;height:34px;padding:0 12px 0 6px;display:flex}.agent-page-back[data-v-bd681ddd]{border-radius:var(--radius-xs);width:24px;height:24px;color:var(--text-meta);cursor:pointer;transition:var(--transition-ui-fast);background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;display:flex}.agent-page-back[data-v-bd681ddd]:hover{background:var(--bg-hover);color:var(--text-secondary)}.agent-page-title[data-v-bd681ddd]{min-width:0;font-size:var(--font-size-mid);color:var(--text-secondary);white-space:nowrap;text-overflow:ellipsis;flex:1;overflow:hidden}.agent-chat-host[data-v-bd681ddd]{flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.agent-chat-host[data-v-bd681ddd] .acu-avatar--left{background:0 0}.agent-chat-host[data-v-bd681ddd] .acu-bubble-row.is-assistant .acu-bubble-main{width:var(--acu-bubble-max-width);max-width:var(--acu-bubble-max-width);position:relative}.agent-chat-host[data-v-bd681ddd] .acu-bubble-row.is-assistant .acu-bubble{align-self:flex-start}.agent-chat-host[data-v-bd681ddd] .acu-message-meta{margin:0;position:absolute;top:0;right:0}.agent-chat-host[data-v-bd681ddd] .acu-input-queue{--acu-queue-edge:var(--role-pending-edge);--acu-queue-surface:var(--role-pending-surface);--acu-queue-ink:var(--role-pending-ink);--acu-queue-wash:var(--role-pending-wash)}.agent-chat-host[data-v-bd681ddd] .acu-welcome-logo{background:var(--welcome-avatar) center/46px 46px no-repeat;width:56px;height:56px;box-shadow:none}.agent-chat-host[data-v-bd681ddd] .acu-welcome-logo>svg{display:none}.agent-chat-host[data-v-bd681ddd] .acu-welcome-grid{flex-wrap:wrap;display:flex}.agent-chat-host[data-v-bd681ddd] .acu-welcome-grid>.acu-preset-q{flex:260px;min-width:0}[data-theme=dark]{background:var(--bg-panel)}
1
+ .marketplace-panel[data-v-e9f9e851]{background:var(--bg-container);flex-direction:column;height:100%;min-height:0;display:flex}.mp-toolbar[data-v-e9f9e851]{flex-shrink:0;align-items:center;gap:12px;padding:12px 16px 8px;display:flex}.mp-search[data-v-e9f9e851]{border:1px solid var(--border-color);border-radius:var(--radius-md);background:var(--bg-panel);max-width:420px;height:32px;transition:border-color var(--transition-fast) ease;flex:1;align-items:center;gap:6px;padding:0 10px;display:flex}.mp-search[data-v-e9f9e851]:focus-within{border-color:var(--color-primary)}.mp-search .mp-search-icon[data-v-e9f9e851]{color:var(--text-meta);flex-shrink:0}.mp-search .mp-search-input[data-v-e9f9e851]{color:var(--text-primary);font-size:var(--font-size-mid);background:0 0;border:none;outline:none;flex:1;font-family:inherit}.mp-search .mp-search-input[data-v-e9f9e851]::placeholder{color:var(--text-meta)}.mp-target[data-v-e9f9e851]{flex-shrink:0}.mp-refresh[data-v-e9f9e851]{border:1px solid var(--border-color);border-radius:var(--radius-md);background:var(--bg-panel);width:30px;height:30px;color:var(--text-secondary);cursor:pointer;transition:var(--transition-ui-fast);justify-content:center;align-items:center;display:flex}.mp-refresh[data-v-e9f9e851]:hover{color:var(--color-primary);border-color:var(--color-primary)}.mp-refresh.spinning svg[data-v-e9f9e851]{animation:.9s linear infinite mkt-spin-e9f9e851}@keyframes mkt-spin-e9f9e851{to{transform:rotate(360deg)}}.mp-toolbar-sub[data-v-e9f9e851]{flex-wrap:wrap;flex-shrink:0;align-items:center;gap:12px;padding:0 16px 10px;display:flex}.mp-target-hint[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--text-meta)}.mp-target-hint b[data-v-e9f9e851]{color:var(--color-primary);font-weight:600}.mp-source-filter[data-v-e9f9e851]{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.mp-chip[data-v-e9f9e851]{font-size:var(--font-size-sm);border:1px solid var(--border-color);border-radius:var(--radius-xl);color:var(--text-meta);cursor:pointer;transition:var(--transition-ui-fast);background:0 0;padding:2px 10px;font-family:inherit}.mp-chip[data-v-e9f9e851]:hover{color:var(--text-secondary);border-color:var(--text-tertiary)}.mp-chip.active[data-v-e9f9e851]{color:var(--color-primary);border-color:var(--color-primary);background:color-mix(in srgb, var(--color-primary) 8%, transparent)}.mp-chip.clear[data-v-e9f9e851]{color:var(--text-meta);border-style:dashed}.mp-body[data-v-e9f9e851]{flex:1;min-height:0;padding:0 16px 20px;overflow-y:auto}.mp-group[data-v-e9f9e851]{margin-bottom:20px}.mp-group.installed[data-v-e9f9e851]{border-top:1px dashed var(--border-color);padding-top:14px}.mp-group-header[data-v-e9f9e851]{align-items:center;gap:8px;margin-bottom:10px;display:flex}.mp-group-title[data-v-e9f9e851]{font-size:var(--font-size-mid);color:var(--text-primary);margin:0;font-weight:600}.mp-group-count[data-v-e9f9e851]{min-width:20px;height:18px;font-size:var(--font-size-xs);border-radius:var(--radius-lg);background:var(--bg-hover);color:var(--text-meta);justify-content:center;align-items:center;padding:0 6px;display:inline-flex}.mp-group-error[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--color-warning-dark);align-items:center;gap:4px;display:inline-flex}.mp-group-link[data-v-e9f9e851]{color:var(--text-meta);transition:color var(--transition-fast) ease;display:inline-flex}.mp-group-link[data-v-e9f9e851]:hover{color:var(--color-primary)}.mp-grid[data-v-e9f9e851]{grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:10px;display:grid}.mp-card[data-v-e9f9e851]{border:1px solid var(--border-color);border-radius:var(--radius-md);background:var(--bg-panel);transition:border-color var(--transition-fast) ease, box-shadow var(--transition-fast) ease;flex-direction:column;gap:6px;padding:12px;display:flex}.mp-card[data-v-e9f9e851]:hover{border-color:color-mix(in srgb, var(--color-primary) 40%, var(--border-color));box-shadow:var(--shadow-sm)}.mp-card-head[data-v-e9f9e851]{align-items:center;gap:8px;display:flex}.mp-card-name[data-v-e9f9e851]{min-width:0;font-size:var(--font-size-mid);color:var(--text-primary);white-space:nowrap;text-overflow:ellipsis;flex:1;font-weight:600;overflow:hidden}.mp-card-metric[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta);flex-shrink:0;align-items:center;gap:3px;display:inline-flex}.mp-card-desc[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--text-secondary);-webkit-line-clamp:2;-webkit-box-orient:vertical;min-height:36px;margin:0;line-height:1.5;display:-webkit-box;overflow:hidden}.mp-card-meta[data-v-e9f9e851]{flex-wrap:wrap;align-items:center;gap:6px;min-height:18px;display:flex}.mp-meta-pkg[data-v-e9f9e851],.mp-meta-repo[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta);white-space:nowrap;text-overflow:ellipsis;max-width:220px;overflow:hidden}.mp-tag[data-v-e9f9e851]{font-size:var(--font-size-xs);border-radius:var(--radius-lg);background:var(--bg-hover);color:var(--text-meta);flex-shrink:0;padding:1px 6px}.mp-tag.remote[data-v-e9f9e851]{background:color-mix(in srgb, var(--color-info,var(--action-teal)) 14%, transparent);color:var(--color-info,var(--action-teal))}.mp-tag.warn[data-v-e9f9e851]{background:color-mix(in srgb, var(--color-warning) 14%, transparent);color:var(--color-warning-dark)}.mp-card-foot[data-v-e9f9e851]{align-items:center;gap:8px;margin-top:2px;display:flex}.mp-card-link[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta);text-decoration:none}.mp-card-link[data-v-e9f9e851]:hover{color:var(--color-primary);text-decoration:underline}.mp-foot-spacer[data-v-e9f9e851]{flex:1}.mp-install-btn[data-v-e9f9e851]{font-size:var(--font-size-sm);border:1px solid var(--color-primary);border-radius:var(--radius-base);color:var(--color-primary);cursor:pointer;transition:var(--transition-ui-fast);background:0 0;padding:4px 14px;font-family:inherit}.mp-install-btn[data-v-e9f9e851]:hover:not(:disabled){background:var(--color-primary);color:#fff}.mp-install-btn[data-v-e9f9e851]:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.mp-installed-chip[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--color-success,var(--action-emerald));align-items:center;gap:3px;display:inline-flex}.mp-not-installable[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta)}.mp-empty[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--text-meta);padding:16px 0}.mp-empty.all[data-v-e9f9e851]{text-align:center;padding:48px 0}.mp-installed-block[data-v-e9f9e851]{margin-bottom:12px}.mp-installed-target[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta);text-transform:uppercase;letter-spacing:.4px;margin-bottom:6px;font-weight:600}.mp-installed-list[data-v-e9f9e851]{flex-direction:column;gap:4px;display:flex}.mp-installed-row[data-v-e9f9e851]{border:1px solid var(--border-color);border-radius:var(--radius-base);background:var(--bg-panel);align-items:center;gap:10px;padding:6px 10px;display:flex}.mp-installed-name[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--text-primary);white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:500;overflow:hidden}.mp-installed-id[data-v-e9f9e851]{font-size:var(--font-size-xs);font-family:var(--font-mono);color:var(--text-meta);white-space:nowrap;text-overflow:ellipsis;max-width:40%;overflow:hidden}.mp-reveal-btn[data-v-e9f9e851],.mp-remove-btn[data-v-e9f9e851]{font-size:var(--font-size-xs);border:1px solid var(--border-color);border-radius:var(--radius-xs);color:var(--text-meta);cursor:pointer;white-space:nowrap;transition:var(--transition-ui-fast);background:0 0;align-items:center;gap:4px;padding:3px 10px;font-family:inherit;display:inline-flex}.mp-reveal-btn[data-v-e9f9e851]:disabled,.mp-remove-btn[data-v-e9f9e851]:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.mp-reveal-btn[data-v-e9f9e851]:hover:not(:disabled){color:var(--text-primary);border-color:var(--text-tertiary)}.mp-remove-btn[data-v-e9f9e851]:hover:not(:disabled){color:var(--color-danger-dark);border-color:var(--color-danger)}@media (prefers-reduced-motion:reduce){.mp-refresh.spinning svg[data-v-e9f9e851]{animation:none}}.mkt-form[data-v-e9f9e851]{flex-direction:column;gap:12px;display:flex}.mkt-form-name[data-v-e9f9e851]{font-size:var(--font-size-mid);color:var(--text-primary);margin:0;font-weight:600}.mkt-field[data-v-e9f9e851]{flex-direction:column;gap:4px;display:flex}.mkt-field label[data-v-e9f9e851]{font-size:var(--font-size-sm);color:var(--text-secondary);font-weight:600}.mkt-field input[data-v-e9f9e851]{border:1px solid var(--border-color);border-radius:var(--radius-md);background:var(--bg-container);height:30px;color:var(--text-primary);font-size:var(--font-size-mid);transition:border-color var(--transition-fast) ease;padding:0 8px;font-family:inherit}.mkt-field input[data-v-e9f9e851]:focus{border-color:var(--color-primary);outline:none}.mkt-hint[data-v-e9f9e851]{font-size:var(--font-size-xs);color:var(--text-meta);margin:0}.mkt-cancel[data-v-e9f9e851],.mkt-confirm[data-v-e9f9e851]{font-size:var(--font-size-mid);border-radius:var(--radius-base);cursor:pointer;transition:var(--transition-ui-fast);padding:6px 16px;font-family:inherit}.mkt-cancel[data-v-e9f9e851]{border:1px solid var(--border-color);color:var(--text-secondary);background:0 0;margin-right:8px}.mkt-cancel[data-v-e9f9e851]:hover{color:var(--text-primary);border-color:var(--text-tertiary)}.mkt-confirm[data-v-e9f9e851]{border:1px solid var(--color-primary);background:var(--color-primary);color:#fff}.mkt-confirm[data-v-e9f9e851]:hover{opacity:.9}.schedule-panel[data-v-63dc658b]{flex-direction:column;flex:1;gap:12px;min-height:0;padding:16px 20px 24px;display:flex;overflow-y:auto}.schedule-toolbar[data-v-63dc658b]{justify-content:space-between;align-items:center;gap:12px;display:flex}.schedule-summary[data-v-63dc658b]{color:var(--text-secondary);font-size:12px}.schedule-error[data-v-63dc658b]{color:var(--text-danger);background:color-mix(in srgb, var(--color-danger) 8%, transparent);border:1px solid color-mix(in srgb, var(--color-danger) 25%, transparent);border-radius:6px;padding:8px 10px;font-size:12px}.schedule-loading[data-v-63dc658b],.schedule-empty[data-v-63dc658b]{color:var(--text-secondary);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;padding:40px 20px;font-size:13px;display:flex}.schedule-empty-title[data-v-63dc658b]{color:var(--text-primary);margin:0;font-size:14px;font-weight:500}.schedule-empty-desc[data-v-63dc658b]{text-align:center;max-width:440px;color:var(--text-tertiary);margin:0;font-size:12px;line-height:1.7}.schedule-list[data-v-63dc658b]{flex-direction:column;gap:8px;display:flex}.schedule-card[data-v-63dc658b]{background:var(--bg-card);border:1px solid var(--border-color);border-radius:8px;justify-content:space-between;align-items:center;gap:12px;padding:10px 14px;transition:border-color .15s,background .15s;display:flex}.schedule-card[data-v-63dc658b]:hover{border-color:var(--border-color-medium)}.schedule-card.is-running[data-v-63dc658b]{border-color:var(--tint-primary-35);background:var(--tint-primary-04)}.schedule-card.is-disabled .schedule-name[data-v-63dc658b]{color:var(--text-secondary)}.schedule-card-body[data-v-63dc658b]{flex-direction:column;gap:4px;min-width:0;display:flex}.schedule-card-head[data-v-63dc658b]{align-items:center;gap:8px;min-width:0;display:flex}.schedule-name[data-v-63dc658b]{color:var(--text-primary);white-space:nowrap;text-overflow:ellipsis;font-size:13px;font-weight:500;overflow:hidden}.schedule-running[data-v-63dc658b]{color:var(--color-primary);background:var(--tint-primary-10);white-space:nowrap;border-radius:4px;padding:1px 6px;font-size:11px}.schedule-card-sub[data-v-63dc658b]{color:var(--text-secondary);white-space:nowrap;align-items:center;gap:6px;min-width:0;font-size:12px;display:flex;overflow:hidden}.schedule-desc[data-v-63dc658b]{text-overflow:ellipsis;overflow:hidden}.schedule-sep[data-v-63dc658b]{color:var(--text-tertiary)}.schedule-last[data-v-63dc658b]{text-overflow:ellipsis;overflow:hidden}.schedule-last.is-ok[data-v-63dc658b]{color:var(--text-success)}.schedule-last.is-error[data-v-63dc658b]{color:var(--text-danger)}.schedule-last.is-skipped[data-v-63dc658b]{color:var(--text-warning)}.schedule-last.is-muted[data-v-63dc658b]{color:var(--text-tertiary)}.sch-link[data-v-63dc658b]{color:var(--color-primary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px}.sch-link[data-v-63dc658b]:hover{text-decoration:underline}.schedule-card-side[data-v-63dc658b]{flex-shrink:0;align-items:center;gap:12px;display:flex}.schedule-next[data-v-63dc658b]{color:var(--text-secondary);white-space:nowrap;font-size:12px}.schedule-next.is-muted[data-v-63dc658b]{color:var(--text-tertiary)}.schedule-actions[data-v-63dc658b]{align-items:center;gap:2px;display:flex}.sch-switch[data-v-63dc658b]{border:1px solid var(--border-color-medium);background:var(--bg-subtle);cursor:pointer;border-radius:10px;flex-shrink:0;width:34px;height:20px;padding:0;transition:background .15s,border-color .15s;position:relative}.sch-switch .sch-switch-knob[data-v-63dc658b]{background:var(--text-tertiary);border-radius:50%;width:14px;height:14px;transition:transform .15s,background .15s;position:absolute;top:2px;left:2px}.sch-switch.on[data-v-63dc658b]{background:var(--tint-primary-18);border-color:var(--tint-primary-45)}.sch-switch.on .sch-switch-knob[data-v-63dc658b]{background:var(--color-primary);transform:translate(14px)}.sch-btn[data-v-63dc658b]{border:1px solid var(--border-color);color:var(--text-secondary);cursor:pointer;background:0 0;border-radius:6px;padding:3px 10px;font-size:12px;transition:background .15s,color .15s,border-color .15s}.sch-btn[data-v-63dc658b]:hover:not(:disabled){background:var(--bg-subtle-hover);color:var(--text-primary);border-color:var(--border-color-medium)}.sch-btn[data-v-63dc658b]:disabled{opacity:.5;cursor:default}.sch-btn-primary[data-v-63dc658b]{background:var(--tint-primary-10);border-color:var(--tint-primary-35);color:var(--color-primary)}.sch-btn-primary[data-v-63dc658b]:hover:not(:disabled){background:var(--tint-primary-18);color:var(--color-primary);border-color:var(--tint-primary-45)}.sch-btn-danger[data-v-63dc658b]{color:var(--text-danger)}.sch-btn-danger[data-v-63dc658b]:hover:not(:disabled){background:color-mix(in srgb, var(--color-danger) 8%, transparent);color:var(--text-danger);border-color:color-mix(in srgb, var(--color-danger) 30%, transparent)}.sch-form[data-v-63dc658b]{flex-direction:column;gap:14px;display:flex}.sch-field[data-v-63dc658b]{flex-direction:column;gap:6px;display:flex}.sch-field-label[data-v-63dc658b]{color:var(--text-secondary);font-size:12px}.sch-input[data-v-63dc658b]{box-sizing:border-box;width:100%;color:var(--text-primary);background:var(--bg-container);border:1px solid var(--border-color-medium);border-radius:6px;outline:none;padding:6px 10px;font-family:inherit;font-size:13px;transition:border-color .15s}.sch-input[data-v-63dc658b]:focus{border-color:var(--tint-primary-55)}.sch-select[data-v-63dc658b]{cursor:pointer}.sch-select-sm[data-v-63dc658b]{width:auto;min-width:64px}.sch-input-cron[data-v-63dc658b]{font-family:var(--font-mono,monospace)}.sch-textarea[data-v-63dc658b]{resize:vertical;min-height:72px;line-height:1.6}.sch-freq-row[data-v-63dc658b]{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.sch-inline-label[data-v-63dc658b]{color:var(--text-secondary);white-space:nowrap;font-size:12px}.sch-hint[data-v-63dc658b]{color:var(--text-tertiary);font-size:11px}.sch-radio-row[data-v-63dc658b]{flex-wrap:wrap;align-items:center;gap:16px;display:flex}.sch-radio[data-v-63dc658b]{color:var(--text-secondary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:inline-flex}.sch-radio input[data-v-63dc658b]{accent-color:var(--color-primary);cursor:pointer;margin:0}.sch-form-error[data-v-63dc658b]{color:var(--text-danger);margin:0;font-size:12px}.sch-form-footer[data-v-63dc658b]{justify-content:flex-end;gap:8px;margin-top:14px;display:flex}.sch-confirm-text[data-v-63dc658b]{color:var(--text-primary);margin:0;font-size:13px;line-height:1.7}.aps[data-v-f9ada51b]{background:var(--bg-container);flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.aps__scroll[data-v-f9ada51b]{flex-direction:column;flex:1;gap:14px;max-width:860px;min-height:0;padding:16px 18px 24px;line-height:1.5;display:flex;overflow-y:auto}.aps__head[data-v-f9ada51b]{flex-direction:column;gap:5px;display:flex}.aps__title[data-v-f9ada51b]{font-size:var(--font-size-lg);color:var(--text-primary);margin:0;font-weight:600}.aps__intro[data-v-f9ada51b]{font-size:var(--font-size-sm);color:var(--text-meta);margin:0;line-height:1.6}.aps__card[data-v-f9ada51b]{background:var(--bg-panel);border:1px solid var(--border-color);border-radius:var(--radius-lg);flex-direction:column;gap:9px;padding:14px 16px;display:flex}.aps__card-head[data-v-f9ada51b]{align-items:baseline;gap:8px;display:flex}.aps__card-title[data-v-f9ada51b]{font-size:var(--font-size-mid);color:var(--text-primary);margin:0;font-weight:600}.aps__label[data-v-f9ada51b]{font-size:var(--font-size-sm);color:var(--text-secondary);font-weight:500}.aps__count[data-v-f9ada51b]{font-size:var(--font-size-xs);color:var(--text-meta);font-variant-numeric:tabular-nums;margin-left:auto}.aps__field[data-v-f9ada51b]{flex-direction:column;gap:5px;display:flex}.aps__hint[data-v-f9ada51b]{font-size:var(--font-size-xs);color:var(--text-meta);margin:0;line-height:1.6}.aps__area[data-v-f9ada51b]{box-sizing:border-box;resize:vertical;width:100%;min-height:92px;max-height:320px;font-size:var(--font-size-mid);color:var(--text-primary);background:var(--bg-subtle);border:1px solid var(--border-color);border-radius:var(--radius-md);transition:border-color var(--transition-fast) var(--ease-custom);outline:none;padding:7px 9px;font-family:inherit;line-height:1.5}.aps__area[data-v-f9ada51b]:focus{border-color:var(--color-primary)}.aps__area[data-v-f9ada51b]::placeholder{color:var(--text-meta)}.aps__area[data-v-f9ada51b]:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.aps__foot[data-v-f9ada51b]{align-items:center;gap:8px;display:flex}.aps__spacer[data-v-f9ada51b]{flex:1}.aps__saved[data-v-f9ada51b]{font-size:var(--font-size-xs);color:var(--text-meta)}.aps__btn[data-v-f9ada51b]{color:var(--text-secondary);font-size:var(--font-size-sm);border-radius:var(--radius-md);cursor:pointer;transition:color var(--transition-fast) var(--ease-custom), background var(--transition-fast) var(--ease-custom);background:0 0;border:none;padding:0 12px;line-height:28px}.aps__btn[data-v-f9ada51b]:hover:not(:disabled){color:var(--color-primary);background:var(--bg-container-hover)}.aps__btn[data-v-f9ada51b]:disabled{opacity:var(--disabled-opacity);cursor:default}.aps__btn[data-v-f9ada51b]:focus-visible{outline:var(--focus-outline);outline-offset:1px}.aps__btn--primary[data-v-f9ada51b]{background:var(--color-primary);color:#fff}.aps__btn--primary[data-v-f9ada51b]:hover:not(:disabled){background:var(--color-primary);color:#fff;opacity:.88}.agent-view[data-v-bd681ddd]{background:var(--bg-container);height:100%;min-height:0;display:flex}.agent-sidebar[data-v-bd681ddd]{background:var(--bg-panel);border-right:1px solid var(--border-color);transition:width var(--transition-base) var(--ease-custom);flex-direction:column;flex-shrink:0;display:flex;overflow:hidden}.agent-conversations[data-v-bd681ddd]{flex:1;min-height:0;padding:10px 6px 8px 12px}.agent-sidebar.is-convs-collapsed .agent-conversations[data-v-bd681ddd]{padding:10px 4px 8px}.sidebar-resizer[data-v-bd681ddd]{cursor:col-resize;width:4px;transition:background var(--transition-fast) ease;background:0 0;flex-shrink:0}.sidebar-resizer[data-v-bd681ddd]:hover,.sidebar-resizer.active[data-v-bd681ddd]{background:var(--color-primary);opacity:.3}.agent-chat-area[data-v-bd681ddd]{flex-direction:column;flex:1;min-width:0;display:flex;position:relative;overflow:hidden}.agent-engine[data-v-bd681ddd]{margin-bottom:7px;margin-left:auto}.agent-copy[data-v-bd681ddd]{margin-bottom:7px;margin-left:2px}.agent-tabs[data-v-bd681ddd]{border-bottom:1px solid var(--border-color);background:var(--bg-panel);flex-shrink:0;align-items:center;gap:4px;padding:8px 12px 0;display:flex}.agent-tab[data-v-bd681ddd]{color:var(--text-meta);font-size:var(--font-size-mid);cursor:pointer;transition:color var(--transition-fast) ease, border-color var(--transition-fast) ease, background var(--transition-fast) ease;border-radius:var(--radius-base) var(--radius-base) 0 0;background:0 0;border:none;border-bottom:2px solid #0000;align-items:center;gap:6px;padding:7px 14px 9px;font-family:inherit;display:inline-flex}.agent-tab[data-v-bd681ddd]:hover{color:var(--text-secondary);background:var(--bg-hover)}.agent-tab.active[data-v-bd681ddd]{color:var(--color-primary);border-bottom-color:var(--color-primary);font-weight:600}.agent-tab-body[data-v-bd681ddd]{flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.agent-chat-pane[data-v-bd681ddd]{flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.agent-tab-body[data-v-bd681ddd]>.marketplace-panel{flex:1;min-height:0}.chat-loading[data-v-bd681ddd]{color:var(--text-meta);font-size:var(--font-size-base);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:12px;display:flex}.agent-list-page[data-v-bd681ddd]{background:var(--bg-panel);flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.agent-list-page .agent-conversations[data-v-bd681ddd]{padding:12px 12px 10px 14px}.agent-page-bar[data-v-bd681ddd]{border-bottom:1px solid var(--border-color);background:var(--bg-panel);flex-shrink:0;align-items:center;gap:6px;height:34px;padding:0 12px 0 6px;display:flex}.agent-page-back[data-v-bd681ddd]{border-radius:var(--radius-xs);width:24px;height:24px;color:var(--text-meta);cursor:pointer;transition:var(--transition-ui-fast);background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;display:flex}.agent-page-back[data-v-bd681ddd]:hover{background:var(--bg-hover);color:var(--text-secondary)}.agent-page-title[data-v-bd681ddd]{min-width:0;font-size:var(--font-size-mid);color:var(--text-secondary);white-space:nowrap;text-overflow:ellipsis;flex:1;overflow:hidden}.agent-chat-host[data-v-bd681ddd]{flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.agent-chat-host[data-v-bd681ddd] .acu-avatar--left{background:0 0}.agent-chat-host[data-v-bd681ddd] .acu-bubble-row.is-assistant .acu-bubble-main{width:var(--acu-bubble-max-width);max-width:var(--acu-bubble-max-width);position:relative}.agent-chat-host[data-v-bd681ddd] .acu-bubble-row.is-assistant .acu-bubble{align-self:flex-start}.agent-chat-host[data-v-bd681ddd] .acu-message-meta{margin:0;position:absolute;top:0;right:0}.agent-chat-host[data-v-bd681ddd] .acu-input-queue{--acu-queue-edge:var(--role-pending-edge);--acu-queue-surface:var(--role-pending-surface);--acu-queue-ink:var(--role-pending-ink);--acu-queue-wash:var(--role-pending-wash)}.agent-chat-host[data-v-bd681ddd] .acu-welcome-logo{background:var(--welcome-avatar) center/46px 46px no-repeat;width:56px;height:56px;box-shadow:none}.agent-chat-host[data-v-bd681ddd] .acu-welcome-logo>svg{display:none}.agent-chat-host[data-v-bd681ddd] .acu-welcome-grid{flex-wrap:wrap;display:flex}.agent-chat-host[data-v-bd681ddd] .acu-welcome-grid>.acu-preset-q{flex:260px;min-width:0}[data-theme=dark]{background:var(--bg-panel)}