zen-gitsync 2.18.12 → 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.
- package/package.json +1 -1
- package/src/cli/ai/agent.js +1385 -1385
- package/src/cli/ai/context.js +431 -431
- package/src/cli/ai/context.test.js +376 -376
- package/src/cli/ai/turn.js +190 -190
- package/src/ui/public/assets/AgentView-CuEM6xzC.js +11 -0
- package/src/ui/public/assets/AppVersionBadge-BK1Fiv3b.js +2 -0
- package/src/ui/public/assets/BranchSelector-avxY_m05.js +1 -0
- package/src/ui/public/assets/CommitForm-hThTnoNt.js +14 -0
- package/src/ui/public/assets/CommonDialog-zaBdFGFH.js +1 -0
- package/src/ui/public/assets/CopySessionButton-CAxaqLQL.js +21 -0
- package/src/ui/public/assets/EditorView-iSA2SXJR.js +37 -0
- package/src/ui/public/assets/{FlowExecutionViewer-Ce4Q5ia6.js → FlowExecutionViewer-C5ylYV2C.js} +1 -1
- package/src/ui/public/assets/FlowOrchestrationWorkspace-CiQ07ZQv.js +21 -0
- package/src/ui/public/assets/LogList-Sjb8vmvq.js +7 -0
- package/src/ui/public/assets/MindmapView-B5rChFMP.js +2 -0
- package/src/ui/public/assets/MonitorView-Dcc-i2Fo.js +3 -0
- package/src/ui/public/assets/ProjectStartupButton-fz6eLCZU.js +1 -0
- package/src/ui/public/assets/RecentDirectoriesChat-BDnNp9jh.js +3 -0
- package/src/ui/public/assets/RemoteManagerDialog-NA1jRC7O.js +4 -0
- package/src/ui/public/assets/RemoteRepoCard-CKm4KqHs.js +7 -0
- package/src/ui/public/assets/SourceMapView-Drfato_u.js +3 -0
- package/src/ui/public/assets/SvgIcon-DR_79iBR.js +1 -0
- package/src/ui/public/assets/UserInputNode-DroKvDOa.js +1 -0
- package/src/ui/public/assets/WorkbenchView-CW7OACCU.js +326 -0
- package/src/ui/public/assets/{WorkbenchView-DzBtCzay.css → WorkbenchView-C_u6BptZ.css} +1 -1
- package/src/ui/public/assets/{_plugin-vue_export-helper-BY0jlMBE.js → _plugin-vue_export-helper-bQQyMRS6.js} +5 -5
- package/src/ui/public/assets/{agentConversations-CC01a7SP.js → agentConversations-wYAksLq1.js} +8 -8
- package/src/ui/public/assets/{configStore-EvRYufor.js → configStore-BeHB-gV4.js} +1 -1
- package/src/ui/public/assets/{css.worker-BDCmgL4U.js → css.worker-DFdt6_zu.js} +9 -9
- package/src/ui/public/assets/{dagre-Ct-SQ-7k.js → dagre-CXi8gaG9.js} +4 -4
- package/src/ui/public/assets/editor.worker-O-CH8JUO.js +26 -0
- package/src/ui/public/assets/{element-plus-D-6gla1z.css → element-plus-DJ3ZQa98.css} +1 -1
- package/src/ui/public/assets/element-plus-DgSY_Wt4.js +48 -0
- package/src/ui/public/assets/{flow-mindmap-C8x6ucsA.js → flow-mindmap-BsTRkgat.js} +56 -56
- package/src/ui/public/assets/{html.worker-DG8hnSJR.js → html.worker-JUzsMP-j.js} +8 -8
- package/src/ui/public/assets/index-BRQstBzy.js +211 -0
- package/src/ui/public/assets/json.worker-B4dEhy0e.js +58 -0
- package/src/ui/public/assets/{monaco-BV4P06MT.js → monaco-CnWeufxc.js} +6 -6
- package/src/ui/public/assets/{office-docx-B8BoOvth.js → office-docx-EUfAIM4w.js} +6 -6
- package/src/ui/public/assets/{office-excel-CFRkxKv8.js → office-excel-BZW0bXQo.js} +1 -1
- package/src/ui/public/assets/{office-pptx-DXdbDvLM.js → office-pptx-CBvDNZ4m.js} +3 -3
- package/src/ui/public/assets/{ts.worker-DgFMIcEs.js → ts.worker-CmEKzkmF.js} +49 -49
- package/src/ui/public/assets/{useOrchestrator-C8BD2JSO.js → useOrchestrator-Bhl7DGKW.js} +1 -1
- package/src/ui/public/assets/{vendor-DYtaPSUU.js → vendor-CZlKgriV.js} +43 -43
- package/src/ui/public/assets/vue-flow-DawpR_uk.js +39 -0
- package/src/ui/public/index.html +12 -12
- package/src/ui/server/routes/config.js +1348 -1348
- package/src/ui/server/routes/workbench/agentChat.js +752 -752
- package/src/ui/server/routes/workbench/agentChatShared.test.js +496 -496
- package/src/ui/server/routes/workbench/agentRoutes.js +13 -1
- package/src/ui/server/routes/workbench/agentRoutes.test.js +75 -0
- package/src/ui/server/routes/workbench/index.js +2 -1
- package/src/ui/server/routes/workbench/scheduleRoutes.js +2 -2
- package/src/ui/server/routes/workbench/shared.js +17 -0
- package/src/ui/public/assets/AgentView-CVbcrngz.js +0 -11
- package/src/ui/public/assets/AppVersionBadge-7gFB6t_t.js +0 -2
- package/src/ui/public/assets/BranchSelector-BIRNxA6U.js +0 -1
- package/src/ui/public/assets/CommitForm-CWpaazi7.js +0 -14
- package/src/ui/public/assets/CommonDialog-DrxsmpDL.js +0 -1
- package/src/ui/public/assets/CopySessionButton-C_01fcd3.js +0 -21
- package/src/ui/public/assets/EditorView-D80wG480.js +0 -37
- package/src/ui/public/assets/FlowOrchestrationWorkspace-Cq1zEt5K.js +0 -21
- package/src/ui/public/assets/LogList-DtmJG27U.js +0 -7
- package/src/ui/public/assets/MindmapView-BR2_C4Du.js +0 -2
- package/src/ui/public/assets/MonitorView-Cs_kwPBu.js +0 -3
- package/src/ui/public/assets/ProjectStartupButton-BfQJ0i5X.js +0 -1
- package/src/ui/public/assets/RecentDirectoriesChat-_gNQGqkM.js +0 -3
- package/src/ui/public/assets/RemoteManagerDialog-KY5I3Ftv.js +0 -4
- package/src/ui/public/assets/RemoteRepoCard-BUgdGtwC.js +0 -7
- package/src/ui/public/assets/SourceMapView-RkGgdvnN.js +0 -3
- package/src/ui/public/assets/SvgIcon-CP7WAT4C.js +0 -1
- package/src/ui/public/assets/UserInputNode-CwSqPh4O.js +0 -1
- package/src/ui/public/assets/WorkbenchView-CBfccRIP.js +0 -320
- package/src/ui/public/assets/editor.worker-GCPm6rMv.js +0 -26
- package/src/ui/public/assets/element-plus-CDrtgG55.js +0 -48
- package/src/ui/public/assets/index-CyEcaEC9.js +0 -211
- package/src/ui/public/assets/json.worker-CxwlJRnL.js +0 -58
- package/src/ui/public/assets/vue-flow-B7Hdmt-y.js +0 -39
package/src/cli/ai/turn.js
CHANGED
|
@@ -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};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"./rolldown-runtime-C0FnF6B9.js";import{$n as e,An as t,At as n,Dn as r,Fn as i,Hn as a,In as o,J as s,Kn as c,Lr as l,On as u,Rn as d,Sr as f,W as p,Xr as m,Yn as h,Zn as g,a as _,cr as v,hr as y,i as b,jn as x,kn as S,ni as C,nt as w,rt as T,ur as E,z as D}from"./element-plus-DgSY_Wt4.js";import{n as O,t as k}from"./_plugin-vue_export-helper-bQQyMRS6.js";import{t as A}from"./CommonDialog-zaBdFGFH.js";async function j(e,t){let n=e.body.getReader(),r=new TextDecoder(`utf-8`),i=``;for(;;){let{done:e,value:a}=await n.read();if(e)break;i+=r.decode(a,{stream:!0});let o=i.split(`
|
|
2
|
+
`);i=o.pop()??``;for(let e of o)e.trim()&&t(e)}i.trim()&&t(i)}async function M(){let e=await fetch(`/api/app-version`);return e.ok?e.json():{success:!1,current:``,latest:null,hasUpdate:!1,error:`HTTP ${e.status}`}}async function N(e){let t=await fetch(`/api/app-upgrade`,{method:`POST`});if(!t.ok){let n=`HTTP ${t.status}`;try{let e=await t.json();e?.error&&(n=e.error)}catch{}e({type:`error`,message:n}),e({type:`done`,code:t.status});return}if(!t.body){e({type:`error`,message:`响应无 body`}),e({type:`done`,code:-1});return}await j(t,t=>{try{e(JSON.parse(t))}catch{}})}async function P(){let e=await fetch(`/api/app-restart`,{method:`POST`});if(!e.ok){let t=`HTTP ${e.status}`;try{let n=await e.json();n?.error&&(t=n.error)}catch{}throw Error(t)}if(!e.body)throw Error(`响应无 body`);return new Promise((t,n)=>{let r=!1,i=e=>{r||(r=!0,e())};j(e,e=>{try{let r=JSON.parse(e);r.type===`ready`&&typeof r.port==`number`&&r.port>0?i(()=>t(r.port)):r.type===`timeout`?i(()=>n(Error(`restart.timeout`))):r.type===`error`&&i(()=>n(Error(r.message||`restart.failed`)))}catch{}}).then(()=>{i(()=>n(Error(`restart.stream-closed`)))}).catch(()=>{})})}a(),y();var F=`npm install -g zen-gitsync --registry https://registry.npmjs.org/`,I=d({__name:`UpgradeDialog`,props:{modelValue:{type:Boolean,required:!0},logs:{type:String,required:!0},status:{type:String,required:!0},countdown:{type:Number,required:!1,default:0}},emits:[`update:modelValue`,`retry`,`restart`,`cancel`],setup(e,{expose:t,emit:r}){t();let i=e,a=r,o=f(null);v(()=>i.logs,async()=>{await c(),o.value&&(o.value.scrollTop=o.value.scrollHeight)});function s(){i.status!==`running`&&(i.status===`success`&&i.countdown>0&&a(`cancel`),a(`update:modelValue`,!1))}function l(){a(`retry`)}function u(){a(`restart`)}function d(){a(`cancel`),a(`update:modelValue`,!1)}async function p(){try{await navigator.clipboard.writeText(F),_.success(O(`@F13B4:已复制升级命令`))}catch{_.warning(O(`@F13B4:复制失败,请手动复制`))}}let m={MANUAL_COMMAND:F,props:i,emit:a,logEl:o,close:s,onRetry:l,onRestart:u,onLater:d,onCopyCommand:p,get Loading(){return n},get CircleCheck(){return w},get CircleClose(){return T},get $t(){return O},CommonDialog:A};return Object.defineProperty(m,"__isScriptSetup",{enumerable:!1,value:!0}),m}});a(),l();var L={key:3},R={key:4},z={key:5},B={key:0,class:`upgrade-hint`},V={key:0,class:`upgrade-countdown`},H={key:1,class:`upgrade-manual`},U={class:`upgrade-manual__label`};function W(n,r,a,c,l,d){let f=s,p=D;return e(),S(c.CommonDialog,{"model-value":a.modelValue,"onUpdate:modelValue":r[0]||=e=>c.emit(`update:modelValue`,e),title:c.$t(`@F13B4:升级`),width:`680px`,type:`flex`,"close-on-click-modal":!1,"close-on-press-escape":!1,"show-close":a.status!==`running`,"append-to-body":``,onClose:c.close},{footer:E(()=>[a.status===`failed`?(e(),S(p,{key:0,type:`primary`,onClick:c.onRetry},{default:E(()=>[i(C(c.$t(`@F13B4:重试`)),1)]),_:1})):t(`v-if`,!0),a.status===`failed`?(e(),S(p,{key:1,onClick:c.onCopyCommand},{default:E(()=>[i(C(c.$t(`@F13B4:复制升级命令`)),1)]),_:1})):t(`v-if`,!0),a.status===`success`?(e(),S(p,{key:2,type:`primary`,onClick:c.onRestart},{default:E(()=>[i(C(c.$t(`@F13B4:立即重启并刷新`)),1)]),_:1})):t(`v-if`,!0),a.status===`success`?(e(),S(p,{key:3,onClick:c.onLater},{default:E(()=>[i(C(c.$t(`@F13B4:稍后手动重启`)),1)]),_:1})):t(`v-if`,!0),a.status===`running`?(e(),S(p,{key:4,disabled:``},{default:E(()=>[i(C(c.$t(`@F13B4:升级中`))+`... `,1)]),_:1})):t(`v-if`,!0)]),default:E(()=>[u(`div`,{class:m([`upgrade-status`,`is-${a.status}`])},[a.status===`running`?(e(),S(f,{key:0,class:`is-loading`},{default:E(()=>[o(c.Loading)]),_:1})):a.status===`success`?(e(),S(f,{key:1,color:`var(--color-success)`},{default:E(()=>[o(c.CircleCheck)]),_:1})):(e(),S(f,{key:2,color:`var(--color-danger)`},{default:E(()=>[o(c.CircleClose)]),_:1})),a.status===`running`?(e(),x(`span`,L,C(c.$t(`@F13B4:升级中`)),1)):a.status===`success`?(e(),x(`span`,R,C(c.$t(`@F13B4:升级完成`)),1)):(e(),x(`span`,z,C(c.$t(`@F13B4:升级失败`)),1))],2),a.status===`success`?(e(),x(`p`,B,[i(C(c.$t(`@F13B4:新版本已全局安装,需要重启服务才能生效`))+` `,1),a.countdown>0?(e(),x(`span`,V,C(c.$t(`@F13B4:{seconds} 秒后自动刷新`,{seconds:a.countdown})),1)):t(`v-if`,!0)])):t(`v-if`,!0),a.status===`failed`?(e(),x(`p`,H,[u(`span`,U,C(c.$t(`@F13B4:手动升级命令`)),1),u(`code`,{class:`upgrade-manual__cmd`},C(c.MANUAL_COMMAND))])):t(`v-if`,!0),u(`pre`,{ref:`logEl`,class:`upgrade-log`},C(a.logs||c.$t(`@F13B4:等待日志输出`)),513)]),_:1},8,[`model-value`,`title`,`show-close`])}var G=k(I,[[`render`,W],[`__scopeId`,`data-v-bc566bba`],[`__file`,`C:/workspace/github_workspace/xz333221/zen-gitsync/src/ui/client/src/components/UpgradeDialog.vue`]]);a(),y();var K=`https://github.com/xz333221/zen-gitsync/tags`,q=5,J=`app-version-check`,Y=36e5,X=d({__name:`AppVersionBadge`,setup(e,{expose:t}){t();let n=`2.18.13`,i=f(n),a=r(()=>i.value||n),o=f(null),s=f(!1),c=f(``),l=f(`running`),u=f(0),d=null,p=f(!1);function m(){try{let e=sessionStorage.getItem(J);if(!e)return null;let{at:t,data:n}=JSON.parse(e);return Date.now()-t>Y?null:n}catch{return null}}function v(e){try{sessionStorage.setItem(J,JSON.stringify({at:Date.now(),data:e}))}catch{}}async function y(e=!1){let t=m();t&&(o.value=t);try{let t=await M();o.value=t,v(t),t.current&&(i.value=t.current),!e&&t.success&&t.hasUpdate&&_({type:`success`,message:O(`@F13B4:发现新版本 {version}`,{version:t.latest??``}),duration:4e3})}catch(t){e||_({type:`warning`,message:O(`@F13B4:检查更新失败 {error}`,{error:t?.message||``})})}}async function x(){if(o.value?.hasUpdate){try{await b.confirm(O(`@F13B4:确定要从 {current} 升级到 {latest} 吗?`,{current:o.value.current,latest:o.value.latest}),O(`@F13B4:升级`),{confirmButtonText:O(`@F13B4:确定升级`),cancelButtonText:O(`@F13B4:取消`),type:`info`})}catch{return}c.value=``,l.value=`running`,s.value=!0,await N(e=>{if(e.type===`done`){if(l.value=e.code===0?`success`:`failed`,e.code===0){try{sessionStorage.removeItem(J)}catch{}o.value?.latest&&(i.value=o.value.latest),S()}}else e.message&&(c.value+=e.message)})}}function S(){C(),u.value=q,d=setInterval(()=>{--u.value,u.value<=0&&(d&&=(clearInterval(d),null),T())},1e3)}function C(){d&&=(clearInterval(d),null),u.value=0}function w(){C()}async function T(){if(C(),!p.value){p.value=!0;try{let e=await P(),{pathname:t,search:n,hash:r}=window.location;window.location.href=`http://localhost:${e}${t}${n}${r}`}catch(e){let t=e?.message||``,n={"restart.timeout":`@F13B4:重启超时`,"restart.stream-closed":`@F13B4:重启失败,请刷新页面重试`,"restart.failed":`@F13B4:重启失败`}[t];_({type:`warning`,message:n?O(n):O(`@F13B4:重启失败 {error}`,{error:t})}),p.value=!1}}}h(()=>{C()}),g(()=>{y(!0)});let E={buildVersion:n,releasesUrl:K,runtimeVersion:i,displayVersion:a,latestInfo:o,upgradeDialogVisible:s,upgradeLogs:c,upgradeStatus:l,AUTO_REFRESH_SECONDS:q,countdown:u,get countdownTimer(){return d},set countdownTimer(e){d=e},restartInFlight:p,CACHE_KEY:J,CACHE_TTL_MS:Y,readCache:m,writeCache:v,checkUpdate:y,handleUpgrade:x,startAutoRefreshCountdown:S,cancelAutoRefreshCountdown:C,handleCancelAutoRefresh:w,handleRestart:T,get $t(){return O},UpgradeDialog:G};return Object.defineProperty(E,"__isScriptSetup",{enumerable:!1,value:!0}),E}});a(),l();var Z={class:`app-version-badge`},Q=[`aria-label`],$=[`aria-label`],ee=[`title`,`aria-label`],te={class:`upgrade-btn__label`},ne={class:`upgrade-btn__version`};function re(n,r,i,a,s,c){let l=p;return e(),x(`div`,Z,[t(` GitHub 链接 `),o(l,{content:a.$t(`@F13B4:在 GitHub 上查看源码`),placement:`top`,effect:`dark`,"show-after":300},{default:E(()=>[u(`a`,{href:`https://github.com/xz333221/zen-gitsync`,target:`_blank`,rel:`noopener noreferrer`,class:`badge-icon-link`,"aria-label":a.$t(`@F13B4:在 GitHub 上查看源码`)},[...r[1]||=[u(`svg`,{viewBox:`0 0 24 24`,width:`15`,height:`15`,"aria-hidden":`true`,fill:`currentColor`,xmlns:`http://www.w3.org/2000/svg`},[u(`path`,{d:`M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0 1 12 6.844a9.59 9.59 0 0 1 2.504.337c1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.02 10.02 0 0 0 22 12.017C22 6.484 17.522 2 12 2z`})],-1)]],8,Q)]),_:1},8,[`content`]),t(` NPM 链接 `),o(l,{content:a.$t(`@F13B4:在 npm 上查看包`),placement:`top`,effect:`dark`,"show-after":300},{default:E(()=>[u(`a`,{href:`https://www.npmjs.com/package/zen-gitsync`,target:`_blank`,rel:`noopener noreferrer`,class:`badge-icon-link badge-icon-link--npm`,"aria-label":a.$t(`@F13B4:在 npm 上查看包`)},[...r[2]||=[u(`svg`,{viewBox:`0 0 24 24`,width:`15`,height:`15`,"aria-hidden":`true`,fill:`currentColor`,xmlns:`http://www.w3.org/2000/svg`},[u(`path`,{d:`M2 2v20h20V2H2zm17.167 17.167H12.5v-10h-3.333v10H4.833V4.833h14.334v14.334z`})],-1)]],8,$)]),_:1},8,[`content`]),t(` 版本号 `),o(l,{content:a.$t(`@F13B4:查看更新`),placement:`top`,effect:`dark`,"show-after":300},{default:E(()=>[u(`a`,{href:a.releasesUrl,target:`_blank`,rel:`noopener noreferrer`,class:`version-link`},`v`+C(a.displayVersion),1)]),_:1},8,[`content`]),a.latestInfo?.hasUpdate?(e(),x(`button`,{key:0,type:`button`,class:`upgrade-btn`,title:a.$t(`@F13B4:发现新版本 {version},点击升级`,{version:a.latestInfo.latest??``}),"aria-label":a.$t(`@F13B4:发现新版本 {version},点击升级`,{version:a.latestInfo.latest??``}),onClick:a.handleUpgrade},[r[3]||=u(`span`,{class:`upgrade-btn__dot`,"aria-hidden":`true`},null,-1),u(`span`,te,C(a.$t(`@F13B4:升级`)),1),u(`span`,ne,`v`+C(a.latestInfo.latest),1)],8,ee)):t(`v-if`,!0),o(a.UpgradeDialog,{modelValue:a.upgradeDialogVisible,"onUpdate:modelValue":r[0]||=e=>a.upgradeDialogVisible=e,logs:a.upgradeLogs,status:a.upgradeStatus,countdown:a.countdown,onRetry:a.handleUpgrade,onRestart:a.handleRestart,onCancel:a.handleCancelAutoRefresh},null,8,[`modelValue`,`logs`,`status`,`countdown`])])}var ie=k(X,[[`render`,re],[`__scopeId`,`data-v-7e0300ec`],[`__file`,`C:/workspace/github_workspace/xz333221/zen-gitsync/src/ui/client/src/components/AppVersionBadge.vue`]]);export{ie as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./rolldown-runtime-C0FnF6B9.js";import{$n as e,An as t,Bt as n,Cn as r,Dn as i,F as a,G as o,Hn as s,I as c,In as l,J as u,K as d,Lr as f,On as p,Pt as m,Rn as h,Sr as g,U as _,Ut as v,Xr as y,fn as b,hr as x,jn as S,kn as C,ni as w,r as T,tr as E,tt as D,ur as O,xn as k}from"./element-plus-DgSY_Wt4.js";import{n as A,t as j}from"./_plugin-vue_export-helper-bQQyMRS6.js";import{t as M}from"./SvgIcon-DR_79iBR.js";import{t as N}from"./CommonDialog-zaBdFGFH.js";import{G as P,K as F}from"./index-BRQstBzy.js";s(),x();var I=h({__name:`BranchSelector`,emits:[`branchChanged`],setup(e,{expose:t,emit:r}){t();let a=P(),o=r,s=g(!1),c=g(``),l=i(()=>{let e=c.value.trim().toLowerCase();return e?a.allBranches.filter(t=>t.toLowerCase().includes(e)):a.allBranches});async function u(e){if(e===a.currentBranch){s.value=!1;return}s.value=!1,await a.changeBranch(e)&&(o(`branchChanged`),a.refreshLog())}let d=g(!1),f=g(``),p=g(``);function h(){s.value=!1,p.value=a.currentBranch,d.value=!0}async function _(){await a.createBranch(f.value,p.value)&&(d.value=!1,f.value=``,o(`branchChanged`))}let y=g(!1);async function b(){if(!y.value){y.value=!0;try{await Promise.all([a.getCurrentBranch(!0),a.getBranchStatus(!0),a.getAllBranches()]),o(`branchChanged`),a.refreshLog()}finally{y.value=!1}}}let x={gitStore:a,emit:o,branchPopoverVisible:s,branchFilter:c,filteredBranches:l,selectBranch:u,createBranchDialogVisible:d,newBranchName:f,selectedBaseBranch:p,openCreateBranchDialog:h,createNewBranch:_,isRefreshingBranch:y,refreshCurrentBranch:b,get $t(){return A},get Plus(){return n},get Menu(){return m},get Check(){return D},get Refresh(){return v},CommonDialog:N,IconButton:F,SvgIcon:M};return Object.defineProperty(x,"__isScriptSetup",{enumerable:!1,value:!0}),x}});s(),f(),b();var L={key:0,class:`branch-info`},R={class:`branch-wrapper`},z={class:`branch-btn`},B={class:`branch-btn-name`},V={class:`branch-btn-caret`},H={class:`branch-popover-inner`},U={class:`branch-search`},W={class:`branch-list`},G=[`onClick`],K={key:1,class:`branch-item-check-placeholder`},q={class:`branch-item-name`},J={key:0,class:`branch-empty`},Y={class:`branch-popover-footer`},X={class:`create-branch-content`},Z={class:`form-label`},Q={class:`form-label`},$={class:`dialog-footer`},ee={class:`footer-actions`},te=[`disabled`];function ne(n,i,s,f,m,h){let g=u,v=_,b=T,x=d,D=a,A=c,j=o;return f.gitStore.currentBranch?(e(),S(`div`,L,[p(`div`,R,[t(` VSCode 风格分支按钮 + 弹出列表 `),l(b,{visible:f.branchPopoverVisible,"onUpdate:visible":i[1]||=e=>f.branchPopoverVisible=e,placement:`top-start`,width:260,trigger:`click`,"popper-class":`branch-popover`,"show-arrow":!1,onShow:i[2]||=e=>f.branchFilter=``},{reference:O(()=>[p(`button`,z,[l(f.SvgIcon,{"icon-class":`git-branch`,"class-name":`branch-btn-icon`}),p(`span`,B,w(f.gitStore.currentBranch),1),p(`span`,V,[l(g,null,{default:O(()=>[...i[7]||=[p(`svg`,{viewBox:`0 0 1024 1024`,xmlns:`http://www.w3.org/2000/svg`},[p(`path`,{fill:`currentColor`,d:`M831.872 340.864 512 652.672 192.128 340.864a30.592 30.592 0 0 0-42.752 0 29.12 29.12 0 0 0 0 41.6L489.664 714.24a32 32 0 0 0 44.672 0l340.288-331.776a29.12 29.12 0 0 0 0-41.6 30.592 30.592 0 0 0-42.752 0z`})],-1)]]),_:1})])])]),default:O(()=>[p(`div`,H,[t(` 搜索框 `),p(`div`,U,[l(v,{modelValue:f.branchFilter,"onUpdate:modelValue":i[0]||=e=>f.branchFilter=e,placeholder:f.$t(`@F13B4:搜索或签出分支`),size:`small`,clearable:``,autofocus:``},null,8,[`modelValue`,`placeholder`])]),t(` 分支列表 `),p(`div`,W,[(e(!0),S(r,null,E(f.filteredBranches,t=>(e(),S(`div`,{key:t,class:y([`branch-item`,{"is-active":t===f.gitStore.currentBranch}]),onClick:e=>f.selectBranch(t)},[t===f.gitStore.currentBranch?(e(),C(g,{key:0,class:`branch-item-check`},{default:O(()=>[l(f.Check)]),_:1})):(e(),S(`span`,K)),l(f.SvgIcon,{"icon-class":`git-branch`,"class-name":`branch-item-icon`}),p(`span`,q,w(t),1)],10,G))),128)),f.filteredBranches.length===0?(e(),S(`div`,J,w(f.$t(`@F13B4:没有匹配的分支`)),1)):t(`v-if`,!0)]),t(` 底部:创建新分支 `),p(`div`,Y,[p(`button`,{class:`branch-create-btn`,onClick:f.openCreateBranchDialog},[l(g,null,{default:O(()=>[l(f.Plus)]),_:1}),p(`span`,null,w(f.$t(`@F13B4:创建新分支`)),1)])])])]),_:1},8,[`visible`]),t(` 刷新按钮 `),l(f.IconButton,{tooltip:f.$t(`@CMDCON:刷新`),onClick:f.refreshCurrentBranch},{default:O(()=>[l(g,{class:y({"is-loading":f.isRefreshingBranch})},{default:O(()=>[l(f.Refresh)]),_:1},8,[`class`])]),_:1},8,[`tooltip`])]),t(` 创建分支对话框 `),l(f.CommonDialog,{modelValue:f.createBranchDialogVisible,"onUpdate:modelValue":i[6]||=e=>f.createBranchDialogVisible=e,title:f.$t(`@F13B4:创建新分支`),size:`small`,"destroy-on-close":!0,"append-to-body":!0,"custom-class":`create-branch-dialog`},{footer:O(()=>[p(`div`,$,[p(`div`,ee,[p(`button`,{type:`button`,class:`dialog-cancel-btn`,onClick:i[5]||=e=>f.createBranchDialogVisible=!1},w(f.$t(`@F13B4:取消`)),1),p(`button`,{type:`button`,class:`dialog-confirm-btn`,onClick:f.createNewBranch,disabled:f.gitStore.isCreatingBranch},[f.gitStore.isCreatingBranch?(e(),C(g,{key:1,class:`is-loading`},{default:O(()=>[...i[8]||=[p(`svg`,{viewBox:`0 0 1024 1024`,xmlns:`http://www.w3.org/2000/svg`},[p(`path`,{fill:`currentColor`,d:`M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V736a32 32 0 0 1 32-32zm448-192a32 32 0 0 1-32 32H736a32 32 0 1 1 0-64h192a32 32 0 0 1 32 32zm-640 0a32 32 0 0 1-32 32H96a32 32 0 0 1 0-64h192a32 32 0 0 1 32 32z`})],-1)]]),_:1})):(e(),C(g,{key:0},{default:O(()=>[l(f.Check)]),_:1})),p(`span`,null,w(f.$t(`@F13B4:创建`)),1)],8,te)])])]),default:O(()=>[p(`div`,X,[l(j,{model:{newBranchName:f.newBranchName,selectedBaseBranch:f.selectedBaseBranch},"label-position":`top`},{default:O(()=>[l(x,null,{label:O(()=>[p(`div`,Z,[l(g,{class:`label-icon`},{default:O(()=>[l(f.Plus)]),_:1}),p(`span`,null,w(f.$t(`@F13B4:新分支名称`)),1)])]),default:O(()=>[l(v,{modelValue:f.newBranchName,"onUpdate:modelValue":i[3]||=e=>f.newBranchName=e,placeholder:f.$t(`@F13B4:请输入新分支名称`),class:`modern-input`,size:`large`,onKeyup:k(f.createNewBranch,[`enter`])},null,8,[`modelValue`,`placeholder`])]),_:1}),l(x,null,{label:O(()=>[p(`div`,Q,[l(g,{class:`label-icon`},{default:O(()=>[l(f.Menu)]),_:1}),p(`span`,null,w(f.$t(`@F13B4:基于分支`)),1)])]),default:O(()=>[l(A,{modelValue:f.selectedBaseBranch,"onUpdate:modelValue":i[4]||=e=>f.selectedBaseBranch=e,placeholder:f.$t(`@F13B4:选择基础分支`),class:`modern-select`,size:`large`,style:{width:`100%`}},{default:O(()=>[(e(!0),S(r,null,E(f.gitStore.allBranches,t=>(e(),C(D,{key:t,label:t,value:t},null,8,[`label`,`value`]))),128))]),_:1},8,[`modelValue`,`placeholder`])]),_:1})]),_:1},8,[`model`])])]),_:1},8,[`modelValue`,`title`])])):t(`v-if`,!0)}var re=j(I,[[`render`,ne],[`__scopeId`,`data-v-9548a76f`],[`__file`,`C:/workspace/github_workspace/xz333221/zen-gitsync/src/ui/client/src/components/BranchSelector.vue`]]);export{re as default};
|