zen-gitsync 2.17.13 → 2.17.15
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/README.md +211 -185
- package/package.json +2 -2
- package/scripts/release.js +33 -16
- package/src/cli/ai/tools.js +62 -13
- package/src/cli/ai/tools.test.js +35 -1
- package/src/config.js +4 -0
- package/src/gitCommit.js +18 -1
- package/src/ui/public/assets/AgentView-Bz9LFamz.js +5 -0
- package/src/ui/public/assets/{AppVersionBadge-QszUpjxK.js → AppVersionBadge-D5iXcAEV.js} +2 -2
- package/src/ui/public/assets/{BranchSelector-C_j7ayIX.js → BranchSelector-DP4u1f_B.js} +1 -1
- package/src/ui/public/assets/{CommitForm-CH_YTHmd.js → CommitForm-boOw8uGS.js} +1 -1
- package/src/ui/public/assets/{CommonDialog-78tuotW4.js → CommonDialog-B_qUsIGr.js} +1 -1
- package/src/ui/public/assets/{EditorView-CGKjSpRs.js → EditorView-ZULtfIzl.js} +1 -1
- package/src/ui/public/assets/{FileDiffViewer-kQ3WnrlJ.js → FileDiffViewer-C4xxq5S0.js} +1 -1
- package/src/ui/public/assets/{FlowExecutionViewer-PtAICyWn.js → FlowExecutionViewer-BmfstdaT.js} +1 -1
- package/src/ui/public/assets/{FlowOrchestrationWorkspace-tyQdIh0A.js → FlowOrchestrationWorkspace-28kErqrn.js} +1 -1
- package/src/ui/public/assets/{IconButton-CNMPSvnE.js → IconButton-DcOAqpq0.js} +1 -1
- package/src/ui/public/assets/{LogList-X739IWXT.js → LogList-FEP7EeJt.js} +2 -2
- package/src/ui/public/assets/MindmapView-8X6z245q.css +1 -0
- package/src/ui/public/assets/MindmapView-NDJvfSCn.js +2 -0
- package/src/ui/public/assets/{MonitorView-C_Jj5hEy.js → MonitorView-DU4aBCK0.js} +1 -1
- package/src/ui/public/assets/{ProjectStartupButton-wjBZWElK.js → ProjectStartupButton-JQk4Etsu.js} +1 -1
- package/src/ui/public/assets/{RemoteManagerDialog-DuS66D7T.js → RemoteManagerDialog-Di2WizMS.js} +1 -1
- package/src/ui/public/assets/{RemoteRepoCard-DgOTYE8p.js → RemoteRepoCard-DxB8Q8yE.js} +1 -1
- package/src/ui/public/assets/{SourceMapView-wrchi7Si.js → SourceMapView-CfmrPMBm.js} +1 -1
- package/src/ui/public/assets/{SvgIcon-BwCRUb-C.js → SvgIcon-yefEMV0-.js} +1 -1
- package/src/ui/public/assets/{TemplateManager-B6pI5C4y.js → TemplateManager-CCy_WcSK.js} +1 -1
- package/src/ui/public/assets/{UserInputNode-Di1kFO5g.js → UserInputNode-3Gv_9YZx.js} +1 -1
- package/src/ui/public/assets/{WorkbenchView-CI_sSeYY.js → WorkbenchView-Dgp6A83v.js} +5 -5
- package/src/ui/public/assets/_plugin-vue_export-helper-B1mHBne9.js +19 -0
- package/src/ui/public/assets/configStore-BDxel6Co.js +1 -0
- package/src/ui/public/assets/element-plus-Cwwq-Gje.css +1 -0
- package/src/ui/public/assets/{flow-mindmap-Dybg7aXu.js → flow-mindmap-BqFb1WO5.js} +1 -1
- package/src/ui/public/assets/gitStore-D5CWxPLv.js +6 -0
- package/src/ui/public/assets/index-CmbatbSR.css +1 -0
- package/src/ui/public/assets/index-gpuX9fhG.js +111 -0
- package/src/ui/public/assets/{office-docx-BZoGgigI.js → office-docx-CZXLkCf5.js} +1 -1
- package/src/ui/public/assets/{office-excel-CWXhvPQt.js → office-excel-CBKszjVA.js} +1 -1
- package/src/ui/public/assets/{office-pptx-Di9Tw3Lc.js → office-pptx-NeUSnN3k.js} +1 -1
- package/src/ui/public/assets/{previewSandbox-DMg4ngSx.js → previewSandbox-qLKxghfr.js} +0 -0
- package/src/ui/public/assets/{useThemeObserver-COR_mDL-.js → useThemeObserver-E7Hk50l3.js} +1 -1
- package/src/ui/public/assets/vendor-C5qX_I8r.css +1 -0
- package/src/ui/public/assets/{vendor-DP-rcIZp.js → vendor-IQQMq-1c.js} +20 -20
- package/src/ui/public/assets/{vue-flow-CLj74gJJ.js → vue-flow-fLUQ0_kE.js} +1 -1
- package/src/ui/public/index.html +18 -19
- package/src/ui/server/index.js +4 -0
- package/src/ui/server/routes/explorerContextMenu.js +208 -0
- package/src/ui/server/routes/explorerContextMenu.test.js +180 -0
- package/src/ui/server/routes/workbench/agentChat.js +11 -1
- package/src/ui/public/assets/AgentView-DHXZJLpl.js +0 -5
- package/src/ui/public/assets/MindmapView-BQTqx842.css +0 -1
- package/src/ui/public/assets/MindmapView-Ci2gttUI.js +0 -2
- package/src/ui/public/assets/_plugin-vue_export-helper-BsV3BiZm.js +0 -19
- package/src/ui/public/assets/configStore-Cubt3KDP.js +0 -1
- package/src/ui/public/assets/element-plus-VKM0Y6Ty.css +0 -1
- package/src/ui/public/assets/gitStore-J2f7bmAs.js +0 -4
- package/src/ui/public/assets/index-BZUAVMg6.css +0 -1
- package/src/ui/public/assets/index-ClPoUp9g.js +0 -102
- package/src/ui/public/assets/toolsStore-B2XGcQx-.js +0 -1
- package/src/ui/public/assets/vendor-4ojsjDYc.css +0 -1
- /package/src/ui/public/assets/{element-plus-CqvO58xa.js → element-plus-DxBPQwL7.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zen-gitsync",
|
|
3
|
-
"version": "2.17.
|
|
3
|
+
"version": "2.17.15",
|
|
4
4
|
"description": "Auto commit, scheduled sync, and visual GUI for Git. Run `g` in any repo for one-key commit & push, AI commit messages, scheduled background sync, and a drag-and-drop workflow builder.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
"date-fns": "^4.1.0",
|
|
131
131
|
"express": "^5.1.0",
|
|
132
132
|
"iconv-lite": "^0.7.0",
|
|
133
|
-
"local-file-picker": "^0.2.
|
|
133
|
+
"local-file-picker": "^0.2.4",
|
|
134
134
|
"log-update": "^6.1.0",
|
|
135
135
|
"open": "^10.1.2",
|
|
136
136
|
"ora": "^8.1.1",
|
package/scripts/release.js
CHANGED
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
* npm run release -- --skip-push # 只发布到 npm,不 push git
|
|
29
29
|
* npm run release -- --dry-run # 只打印计划,不真正改 package.json / commit / publish
|
|
30
30
|
* npm run release -- --poll-interval=20 --poll-timeout=600 # 调自更新重试节奏(秒)
|
|
31
|
+
* npm run release -- --install-timeout=900 # 单次 npm install 上限(秒),0 = 不限时(默认)
|
|
31
32
|
*
|
|
32
33
|
* 发布后自更新:每轮先探 tarball 能不能取,能取到才调 npm;两条路(`pkg@<版本>` /
|
|
33
34
|
* tarball URL 直连)都试,装上后校验全局版本,失败把原因打出来。
|
|
@@ -92,8 +93,9 @@ function readNumberArg(name, fallback) {
|
|
|
92
93
|
// 于是 600s 眼看要耗尽、终端上 25 轮只有"→ npm install"没有任何原因。
|
|
93
94
|
// 对策两条:① 每轮先自己探一次 tarball(isTarballFetchable,GET 而非 HEAD),
|
|
94
95
|
// 取不到就跳过这一轮的 npm 调用并把状态打出来;② 失败原因压一行打出来。
|
|
95
|
-
//
|
|
96
|
-
//
|
|
96
|
+
// 单次 npm 调用不再硬性截断(见 INSTALL_TIMEOUT_MS):曾经给 180s 是为了"快速失败、
|
|
97
|
+
// 把重试交给外层循环",但实测更常见的是 180s 不够 —— 每轮装到一半被杀、下轮从零重来,
|
|
98
|
+
// 进度永远清零(2026-09-24 v2.17.14 卡了 27 轮)。要收紧可用 `--install-timeout=<秒>`。
|
|
97
99
|
//
|
|
98
100
|
// 默认 15s 一轮、上限 600s;可用 `--poll-interval=<秒>` / `--poll-timeout=<秒>` 调。
|
|
99
101
|
const POLL_INTERVAL_MS = readNumberArg('--poll-interval', 15) * 1000
|
|
@@ -627,30 +629,43 @@ function readGlobalInstalledVersion() {
|
|
|
627
629
|
// 输出先兜住不打印:重试期间每失败一次就刷一屏 `npm error` 太吵,
|
|
628
630
|
// 失败时由调用方压成一行打出来(summarizeInstallError),整轮失败才回放全文。
|
|
629
631
|
//
|
|
630
|
-
//
|
|
631
|
-
//
|
|
632
|
-
//
|
|
633
|
-
//
|
|
634
|
-
//
|
|
635
|
-
|
|
632
|
+
// 单次安装要不要设上限:**默认不设**(--install-timeout=0)。
|
|
633
|
+
//
|
|
634
|
+
// 早期这里硬写 180s,理由是"npm 自己的 fetch-timeout 是 5 分钟、还要重试 2 次,
|
|
635
|
+
// 网络卡住时单次 install 能吃掉十几分钟";但实测发现更常见的是反过来的坑 ——
|
|
636
|
+
// 首次装一个大包 + 冷缓存 + 国内直连 registry.npmjs.org,180s 根本不够,
|
|
637
|
+
// 于是每一轮都是"装到一半被杀 → 下一轮从零重来",27 轮全卡在同一处,
|
|
638
|
+
// 永远装不上(2026-09-24 v2.17.14)。**杀掉重来 ≠ 快速失败**,它只是把进度清零。
|
|
639
|
+
//
|
|
640
|
+
// 现在把上限交给调用方:INSTALL_TIMEOUT_MS > 0 时才给 execSync 传 timeout;
|
|
641
|
+
// 为 0 时不传该选项 —— 单次 install 跑到自然结束(npm 自身的 fetch-timeout 仍在,
|
|
642
|
+
// 所以不会真的无限挂住)。
|
|
643
|
+
const INSTALL_TIMEOUT_MS = readNumberArg('--install-timeout', 0) * 1000
|
|
636
644
|
function tryInstallGlobal(spec) {
|
|
637
|
-
|
|
645
|
+
const limit = INSTALL_TIMEOUT_MS
|
|
646
|
+
console.log(chalk.gray(` → npm install -g ${spec}${limit > 0 ? `(上限 ${limit / 1000}s)` : '(不限时)'}`))
|
|
638
647
|
try {
|
|
648
|
+
const opts = {
|
|
649
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
650
|
+
maxBuffer: 8 * 1024 * 1024,
|
|
651
|
+
}
|
|
652
|
+
if (limit > 0) opts.timeout = limit
|
|
639
653
|
execSync(
|
|
640
654
|
`npm install -g ${spec} --registry=${NPM_REGISTRY} --prefer-online`
|
|
641
655
|
+ ' --fetch-retries=1 --fetch-retry-mintimeout=3000 --fetch-retry-maxtimeout=10000',
|
|
642
|
-
|
|
643
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
644
|
-
maxBuffer: 8 * 1024 * 1024,
|
|
645
|
-
timeout: INSTALL_TIMEOUT_MS,
|
|
646
|
-
}
|
|
656
|
+
opts
|
|
647
657
|
)
|
|
648
658
|
return { ok: true }
|
|
649
659
|
} catch (err) {
|
|
650
660
|
// 超时会被 execSync 杀掉(带 SIGTERM),stderr 可能是空的 —— 补一句可读的原因
|
|
651
661
|
const out = `${err.stdout ?? ''}${err.stderr ?? ''}`.trim()
|
|
652
662
|
if (!out && (err.killed || err.signal)) {
|
|
653
|
-
return {
|
|
663
|
+
return {
|
|
664
|
+
ok: false,
|
|
665
|
+
output: limit > 0
|
|
666
|
+
? `安装超时(${limit / 1000}s 到点被终止,可用 --install-timeout=<秒> 放宽或 =0 不限时)`
|
|
667
|
+
: '安装被中断(信号终止)',
|
|
668
|
+
}
|
|
654
669
|
}
|
|
655
670
|
return { ok: false, output: out || String(err.message || err) }
|
|
656
671
|
}
|
|
@@ -818,7 +833,9 @@ async function selfUpdateGlobal(version) {
|
|
|
818
833
|
console.log(chalk.gray('不空等 dist-tags:每轮先探 tarball,能取到才调 npm,失败会打印原因。'))
|
|
819
834
|
console.log(chalk.gray(
|
|
820
835
|
`间隔 ${POLL_INTERVAL_MS / 1000}s,上限 ${POLL_TIMEOUT_MS / 1000}s`
|
|
821
|
-
+ '(可用 --poll-interval / --poll-timeout 调)
|
|
836
|
+
+ '(可用 --poll-interval / --poll-timeout 调);'
|
|
837
|
+
+ `单次安装${INSTALL_TIMEOUT_MS > 0 ? `上限 ${INSTALL_TIMEOUT_MS / 1000}s` : '不限时'}`
|
|
838
|
+
+ '(可用 --install-timeout=<秒> 调,0 = 不限时)。'
|
|
822
839
|
))
|
|
823
840
|
|
|
824
841
|
const startedAt = Date.now()
|
package/src/cli/ai/tools.js
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
// - 工具内部异常一律 catch 成字符串返回,不抛给 agent 循环 ——
|
|
25
25
|
// 让模型看到错误信息自己修正,而不是中断整轮对话
|
|
26
26
|
|
|
27
|
-
import {
|
|
27
|
+
import { execFile, spawn } from 'node:child_process'
|
|
28
28
|
import { promises as fs } from 'node:fs'
|
|
29
29
|
import path from 'node:path'
|
|
30
30
|
import iconv from 'iconv-lite'
|
|
@@ -45,6 +45,19 @@ const MAX_SEARCH_FILE_SIZE = 1024 * 1024 // search_text 跳过大文件(1MB)
|
|
|
45
45
|
const CMD_TIMEOUT_DEFAULT = 120 // run_command 默认超时(秒)
|
|
46
46
|
const CMD_TIMEOUT_MAX = 600 // run_command 超时上限(秒)
|
|
47
47
|
|
|
48
|
+
// 已知的长耗时命令(装依赖 / 构建 / 测试 / clone …)。模型不给 timeout_seconds 时
|
|
49
|
+
// 默认只有 120s,这类命令经常跑不完就被终止,模型再换个写法重试 —— 白等好几轮。
|
|
50
|
+
// 命中即直接给到上限,不再依赖模型自己判断。
|
|
51
|
+
const LONG_CMD_RE = /(?:^|[\s;&|(])(?:npm|pnpm|yarn|bun)\s+(?:i\b|install\b|ci\b|add\b|create\b)|(?:^|[\s;&|(])(?:npm|pnpm|yarn|bun)\s+(?:run\s+)?(?:build|test|lint|e2e|typecheck)\b|(?:^|[\s;&|(])git\s+clone\b|(?:^|[\s;&|(])pip3?\s+install\b/i
|
|
52
|
+
|
|
53
|
+
// run_command 本次执行的超时(秒)。长耗时命令即使模型给了更小的值也抬到上限 ——
|
|
54
|
+
// 它填小值基本都是照抄默认值,而不是"想快速失败"。
|
|
55
|
+
export function resolveCommandTimeout(command, requestedSeconds) {
|
|
56
|
+
const n = Number(requestedSeconds) || CMD_TIMEOUT_DEFAULT
|
|
57
|
+
const clamped = Math.max(1, Math.min(CMD_TIMEOUT_MAX, n))
|
|
58
|
+
return LONG_CMD_RE.test(String(command || '')) ? CMD_TIMEOUT_MAX : clamped
|
|
59
|
+
}
|
|
60
|
+
|
|
48
61
|
// 目录遍历时跳过的目录名(产物/依赖/VCS)
|
|
49
62
|
const SKIP_DIRS = new Set([
|
|
50
63
|
'node_modules', '.git', '.svn', '.hg', 'dist', 'build', 'out',
|
|
@@ -237,8 +250,9 @@ function decodeOutput(buf) {
|
|
|
237
250
|
}
|
|
238
251
|
}
|
|
239
252
|
|
|
240
|
-
//
|
|
241
|
-
//
|
|
253
|
+
// 子进程执行封装:stdout/stderr 原始字节累计到结束再整体解码
|
|
254
|
+
// (由 decodeOutput 决定真实编码,GBK 兜底);执行中若有 onOutput 回调,
|
|
255
|
+
// 每来一块就推一块已解码文本 —— Web 端据此把命令输出实时推给界面。
|
|
242
256
|
export function terminateCommand(child) {
|
|
243
257
|
if (!child?.pid || child.exitCode !== null) return Promise.resolve()
|
|
244
258
|
if (process.platform === 'win32') {
|
|
@@ -250,21 +264,56 @@ export function terminateCommand(child) {
|
|
|
250
264
|
|
|
251
265
|
function execCommand(command, options) {
|
|
252
266
|
return new Promise((resolve) => {
|
|
253
|
-
const { signal, timeout, onChild, ...
|
|
267
|
+
const { signal, timeout, onChild, onOutput, ...spawnOptions } = options
|
|
254
268
|
let timedOut = false
|
|
269
|
+
let spawnError = null
|
|
270
|
+
const child = spawn(command, {
|
|
271
|
+
...spawnOptions,
|
|
272
|
+
shell: true,
|
|
273
|
+
detached: process.platform !== 'win32',
|
|
274
|
+
windowsHide: true,
|
|
275
|
+
// stdin 直接给 EOF:命令等输入时尽快失败,不再挂在永不关闭的 stdin 管道上干等超时
|
|
276
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
// 原始字节缓冲上限(对应 exec 时代的 maxBuffer);超限丢最老的块,保留尾部
|
|
280
|
+
const MAX_BUFFER_BYTES = 32 * 1024 * 1024
|
|
281
|
+
const chunks = { stdout: [], stderr: [] }
|
|
282
|
+
const bytes = { stdout: 0, stderr: 0 }
|
|
283
|
+
// 实时预览用增量 UTF-8 解码。GBK 输出在预览里可能显示成乱码,
|
|
284
|
+
// 但最终结果仍走 decodeOutput(UTF-8 严格解码失败 → GBK 兜底),不影响回喂模型。
|
|
285
|
+
const decoders = { stdout: new TextDecoder('utf-8'), stderr: new TextDecoder('utf-8') }
|
|
286
|
+
|
|
287
|
+
const onChunk = (stream, buf) => {
|
|
288
|
+
chunks[stream].push(buf)
|
|
289
|
+
bytes[stream] += buf.length
|
|
290
|
+
while (bytes[stream] > MAX_BUFFER_BYTES && chunks[stream].length > 1) {
|
|
291
|
+
bytes[stream] -= chunks[stream].shift().length
|
|
292
|
+
}
|
|
293
|
+
if (typeof onOutput === 'function') {
|
|
294
|
+
const text = decoders[stream].decode(buf, { stream: true })
|
|
295
|
+
if (text) onOutput(text)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
child.stdout?.on('data', (buf) => onChunk('stdout', buf))
|
|
299
|
+
child.stderr?.on('data', (buf) => onChunk('stderr', buf))
|
|
300
|
+
child.on('error', (err) => { spawnError = err })
|
|
301
|
+
|
|
255
302
|
const abort = () => { void terminateCommand(child) }
|
|
256
|
-
const
|
|
303
|
+
const finish = (code) => {
|
|
257
304
|
clearTimeout(timer)
|
|
258
305
|
signal?.removeEventListener('abort', abort)
|
|
259
306
|
resolve({
|
|
260
|
-
code:
|
|
307
|
+
code: typeof code === 'number' ? code : 1,
|
|
261
308
|
killed: timedOut,
|
|
262
309
|
cancelled: !!signal?.aborted,
|
|
263
|
-
stdout: decodeOutput(stdout),
|
|
264
|
-
stderr: decodeOutput(stderr),
|
|
265
|
-
errorMessage:
|
|
310
|
+
stdout: decodeOutput(Buffer.concat(chunks.stdout)),
|
|
311
|
+
stderr: decodeOutput(Buffer.concat(chunks.stderr)),
|
|
312
|
+
errorMessage: spawnError ? spawnError.message : null,
|
|
266
313
|
})
|
|
267
|
-
}
|
|
314
|
+
}
|
|
315
|
+
child.on('close', finish)
|
|
316
|
+
|
|
268
317
|
const timer = setTimeout(() => { timedOut = true; void terminateCommand(child) }, timeout)
|
|
269
318
|
timer.unref()
|
|
270
319
|
signal?.addEventListener('abort', abort, { once: true })
|
|
@@ -297,8 +346,7 @@ async function toolRunCommand(args, ctx) {
|
|
|
297
346
|
}
|
|
298
347
|
|
|
299
348
|
const cwd = resolvePath(ctx, args.cwd)
|
|
300
|
-
|
|
301
|
-
timeoutSec = Math.max(1, Math.min(CMD_TIMEOUT_MAX, timeoutSec))
|
|
349
|
+
const timeoutSec = resolveCommandTimeout(command, args.timeout_seconds)
|
|
302
350
|
|
|
303
351
|
// 验证 cwd 存在,避免 exec 抛模糊错误
|
|
304
352
|
try {
|
|
@@ -316,10 +364,11 @@ async function toolRunCommand(args, ctx) {
|
|
|
316
364
|
const execOptions = {
|
|
317
365
|
cwd,
|
|
318
366
|
timeout: timeoutSec * 1000,
|
|
319
|
-
maxBuffer: 32 * 1024 * 1024,
|
|
320
367
|
windowsHide: true,
|
|
321
368
|
onChild: ctx.onChild,
|
|
322
369
|
signal: ctx.signal,
|
|
370
|
+
// 执行中的增量输出(Web 端推 SSE 给界面;CLI 不传,等于没有副作用)
|
|
371
|
+
onOutput: ctx.onOutput,
|
|
323
372
|
}
|
|
324
373
|
const firstEnv = await augmentEnvPath(baseEnv)
|
|
325
374
|
let result = await execCommand(command, { ...execOptions, env: firstEnv })
|
package/src/cli/ai/tools.test.js
CHANGED
|
@@ -19,7 +19,7 @@ import assert from 'node:assert/strict'
|
|
|
19
19
|
import { promises as fs } from 'node:fs'
|
|
20
20
|
import os from 'node:os'
|
|
21
21
|
import path from 'node:path'
|
|
22
|
-
import { TOOL_DEFINITIONS, executeTool } from './tools.js'
|
|
22
|
+
import { TOOL_DEFINITIONS, executeTool, resolveCommandTimeout } from './tools.js'
|
|
23
23
|
|
|
24
24
|
let tmpDir
|
|
25
25
|
const ctx = { cwd: null, onChild: null }
|
|
@@ -260,6 +260,40 @@ test('run_command 本地化错误消息解码正确(Windows GBK 回归)', async
|
|
|
260
260
|
}
|
|
261
261
|
})
|
|
262
262
|
|
|
263
|
+
// ========== run_command: 实时输出 + 超时选择 ==========
|
|
264
|
+
|
|
265
|
+
test('run_command 执行期间通过 onOutput 增量回传输出(命令结束前就能拿到)', async () => {
|
|
266
|
+
const chunks = []
|
|
267
|
+
let returned = false
|
|
268
|
+
const pending = executeTool('run_command', {
|
|
269
|
+
command: 'node -e "console.log(\'live-1\'); setTimeout(()=>console.log(\'live-2\'), 600)"',
|
|
270
|
+
}, { ...ctx, onOutput: text => chunks.push(text) }).then(r => { returned = true; return r })
|
|
271
|
+
|
|
272
|
+
const deadline = Date.now() + 5000
|
|
273
|
+
while (!chunks.join('').includes('live-1') && Date.now() < deadline) {
|
|
274
|
+
await new Promise(r => setTimeout(r, 20))
|
|
275
|
+
}
|
|
276
|
+
assert.match(chunks.join(''), /live-1/, '命令还在跑时就该收到第一行输出')
|
|
277
|
+
assert.equal(returned, false, '此时 run_command 不应已返回')
|
|
278
|
+
|
|
279
|
+
const result = await pending
|
|
280
|
+
assert.match(result, /live-1/)
|
|
281
|
+
assert.match(result, /live-2/)
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
test('resolveCommandTimeout: 长耗时命令抬到上限,普通命令保持默认 / 模型给的值', () => {
|
|
285
|
+
// 安装 / 构建 / clone 这类命令:模型不给够超时容易被 120s 杀掉再重试
|
|
286
|
+
assert.equal(resolveCommandTimeout('npm install', undefined), 600)
|
|
287
|
+
assert.equal(resolveCommandTimeout('npm i --save-dev vite', undefined), 600)
|
|
288
|
+
assert.equal(resolveCommandTimeout('pnpm install && npm run build', 60), 600)
|
|
289
|
+
assert.equal(resolveCommandTimeout('git clone git@github.com:a/b.git', undefined), 600)
|
|
290
|
+
// 普通命令不动
|
|
291
|
+
assert.equal(resolveCommandTimeout('echo hi', undefined), 120)
|
|
292
|
+
assert.equal(resolveCommandTimeout('echo hi', 30), 30)
|
|
293
|
+
// 起服务这类命令不抬:它本来就不该等到超时
|
|
294
|
+
assert.equal(resolveCommandTimeout('npm run dev', 60), 60)
|
|
295
|
+
})
|
|
296
|
+
|
|
263
297
|
// ========== list_projects: 只在 GUI 里有实现,CLI 下要给一句能照着做的话 ==========
|
|
264
298
|
|
|
265
299
|
test('list_projects 把参数透传给注入的实现', async () => {
|
package/src/config.js
CHANGED
|
@@ -163,6 +163,10 @@ const defaultConfig = {
|
|
|
163
163
|
splitPercent: 25, // 15-85
|
|
164
164
|
},
|
|
165
165
|
editorAutoSave: false,
|
|
166
|
+
// 顶栏工具图标(VSCode / Claude Code / Codex / …)中**隐藏**的那几个。
|
|
167
|
+
// 白名单式的默认空数组:以后新增工具默认就固定显示,不需要回头改默认值。
|
|
168
|
+
// 未勾选(= 落在本数组里)的工具连同未安装的一起收进顶栏右侧「更多」菜单。
|
|
169
|
+
headerToolsHidden: [],
|
|
166
170
|
}
|
|
167
171
|
};
|
|
168
172
|
|
package/src/gitCommit.js
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
import {
|
|
18
18
|
coloredLog, errorLog, execGitCommand, showHelp,
|
|
19
19
|
getCwd, judgePlatform, judgeLog, judgeHelp, exec_exit, judgeUnmerged, formatDuration,
|
|
20
|
-
exec_push, execPull, judgeRemote, execDiff, execAddAndCommit, delay, addScriptToPackageJson, addResetScriptToPackageJson
|
|
20
|
+
exec_push, execPull, judgeRemote, execDiff, execAddAndCommit, delay, addScriptToPackageJson, addResetScriptToPackageJson,
|
|
21
|
+
parseCwdArg, invalidateCwdCache
|
|
21
22
|
} from './utils/index.js';
|
|
22
23
|
import readline from 'readline'
|
|
23
24
|
import ora from 'ora';
|
|
@@ -258,6 +259,22 @@ async function main() {
|
|
|
258
259
|
|
|
259
260
|
// 检查是否是UI命令
|
|
260
261
|
if (process.argv.includes('ui')) {
|
|
262
|
+
// `g ui --path=<目录>`:资源管理器右键菜单写进注册表的命令就是
|
|
263
|
+
// node <pkg>/src/gitCommit.js ui --path="%V"
|
|
264
|
+
// (%V = 被右键的目录,由 Explorer 展开)。先切到目标目录再起服务端 ——
|
|
265
|
+
// server 用 process.cwd() 当"当前项目",这样浏览器打开的就是右键的那个仓库。
|
|
266
|
+
// 路径带空格时命令行里的引号会被 Windows 的 argv 解析吞掉(node 实测),这里拿到
|
|
267
|
+
// 的已是干净路径。切目录失败只警告、不阻断,否则目录被删就整个 GUI 起不来。
|
|
268
|
+
const uiPath = parseCwdArg(process.argv);
|
|
269
|
+
if (uiPath) {
|
|
270
|
+
try {
|
|
271
|
+
process.chdir(uiPath);
|
|
272
|
+
invalidateCwdCache(); // getCwd() 缓存的是"启动时的目录"语义,换目录后必须失效
|
|
273
|
+
} catch (error) {
|
|
274
|
+
console.warn(chalk.yellow(`⚠️ 无法切换到目录 ${uiPath},仍从 ${process.cwd()} 启动: ${error.message}`));
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
261
278
|
const startUIServer = await loadStartUIServer();
|
|
262
279
|
await startUIServer(false, false); // 传入noOpen=false, savePort=false
|
|
263
280
|
return;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import"./rolldown-runtime-C0FnF6B9.js";import{$ as e,$r as t,A as n,Dn as r,E as i,En as a,Fn as o,H as s,Jt as c,K as l,Mn as u,Nn as d,On as f,Ot as p,Pr as m,Q as h,Qn as g,Rt as _,Tn as v,Un as y,Vt as b,Wt as x,Xn as S,Yr as C,_r as w,a as T,ar as E,bn as D,cn as O,cr as k,ct as ee,et as te,fr as A,gn as j,i as M,in as ne,j as N,kt as P,mt as F,ot as re,pt as I,qr as L,r as R,sr as z,tr as ie,un as B,wn as V,wt as ae,yn as H,yr as U,zn as W}from"./element-plus-DxBPQwL7.js";import{i as oe,n as G,t as K}from"./vendor-IQQMq-1c.js";import{n as q,t as J}from"./_plugin-vue_export-helper-B1mHBne9.js";import{t as Y}from"./configStore-BDxel6Co.js";W(),A();var X=65536,Z=`local-`;function Q(e){if(!e||!Array.isArray(e.messages))return[];let t=[],n=e.messages.length;for(let r=0;r<n;r++){let i=e.messages[r];if(i.role!==`system`){if(i.role===`user`){let e=``,n;if(typeof i.content==`string`)e=i.content;else if(Array.isArray(i.content)){e=i.content.filter(e=>e?.type===`text`).map(e=>e.text||``).join(` `);let t=i.content.filter(e=>e?.type===`image_url`&&typeof e.image_url?.url==`string`).map((e,t)=>({id:`att-${r}-${t}`,name:`image`,size:0,type:ce(e.image_url?.url||``)||`image/*`,preview:e.image_url?.url}));t.length>0&&(n=t)}(e||n)&&t.push({id:`msg-${r}`,role:`user`,content:e,attachments:n,status:`done`,createdAt:Date.now()})}else if(i.role===`assistant`){let i=`msg-${r}`,a=``,o=[],s=r;for(;s<n;){let t=e.messages[s];if(t.role!==`assistant`&&t.role!==`tool`)break;if(t.role===`assistant`){if(typeof t.content==`string`&&(a+=t.content),t.tool_calls&&t.tool_calls.length>0)for(let e of t.tool_calls)o.push({id:e.id||e.function?.name||K(),name:e.function?.name||``,arguments:e.function?.arguments||``,argsPreview:se(e.function?.name||``,e.function?.arguments||``),status:`done`,result:``})}else{let e=t.tool_call_id||t.name||``,n=o.find(t=>t.id===e);if(n){let e=t.content;typeof e!=`string`&&(e=`(non-text result)`),e.length>X&&(e=`…(前文已截断)\n${e.slice(-65536)}`),n.result=e}}s++}r=s-1,a.length>X&&(a=`…(前文已截断)\n${a.slice(-65536)}`);let c=!!a,l=o.length>0;(c||l)&&t.push({id:i,role:`assistant`,content:a,toolCalls:l?o:void 0,status:`done`,createdAt:Date.now()})}}}return t}function se(e,t){try{let n=JSON.parse(t);switch(e){case`run_command`:return String(n.command||``).slice(0,200);case`read_file`:case`write_file`:case`edit_file`:return String(n.path||``);case`list_files`:return String(n.path||`.`);case`search_text`:return String(n.pattern||``);default:return JSON.stringify(n).slice(0,200)}}catch{return t.slice(0,200)}}function $(e){return new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(String(r.result||``)),r.onerror=()=>n(r.error||Error(`FileReader failed`)),r.readAsDataURL(e)})}function ce(e){let t=/^data:([^;,]+)/.exec(e);return t?t[1]:``}function le(){let e=Y(),t=U([]),n=U(!1),r=w(new Map),i=U(null),a=U(!1),o=0,s=0;function c(e){return{key:e,sessionId:e.startsWith(Z)?null:e,title:``,messages:[],isStreaming:!1,abortController:null,nonce:0,pendingQuestion:null,answeringQuestion:!1}}function l(e){let t=r.get(e);return t||=(r.set(e,c(e)),r.get(e)),t}let u=V(()=>i.value?r.get(i.value)??null:null),d=V(()=>u.value?.messages??[]),f=V(()=>u.value?.isStreaming??!1),p=V(()=>u.value?.pendingQuestion??null),m=V(()=>u.value?.answeringQuestion??!1);function h(e){return!!r.get(e)?.isStreaming}function g(t){let n=[...t];for(let t of r.values()){if(!t.isStreaming||!t.sessionId)continue;let r=n.findIndex(e=>e.sessionId===t.sessionId);if(r===-1){let r=new Date().toISOString();n.unshift({sessionId:t.sessionId,title:t.title||q(`@AGENT:无标题`),source:`web`,cwd:e.currentDirectory||``,model:``,createdAt:r,updatedAt:r,messageCount:t.messages.filter(e=>e.role===`user`).length||1,size:0,isGenerating:!0})}else n[r]={...n[r],isGenerating:!0}}return n}async function _(){let r=++o,i=e.currentDirectory||``;if(!i){t.value=[],n.value=!1;return}n.value=!0;try{let e=`/api/agent/sessions?cwd=${encodeURIComponent(i)}`,n=await fetch(e).then(e=>e.json());if(r!==o)return;if(!n.success){M.error(n.error||q(`@AGENT:加载会话列表失败`));return}let a=Array.isArray(n.sessions)?n.sessions:[];t.value=g(a)}catch(e){if(r!==o)return;M.error(q(`@AGENT:加载会话列表失败`)+`: `+(e?.message||e))}finally{r===o&&(n.value=!1)}}function v(n,r){let i=new Date().toISOString(),a=t.value.find(e=>e.sessionId===n);if(a){a.isGenerating=!0,a.updatedAt=i;return}t.value=[{sessionId:n,title:r||q(`@AGENT:无标题`),source:`web`,cwd:e.currentDirectory||``,model:``,createdAt:i,updatedAt:i,messageCount:1,size:0,isGenerating:!0},...t.value]}function y(e){let n=t.value.find(t=>t.sessionId===e);n&&(n.isGenerating=!1)}async function b(e){if(r.get(e)?.isStreaming){i.value=e;return}a.value=!0,i.value=e;try{let t=await fetch(`/api/agent/sessions/${encodeURIComponent(e)}`).then(e=>e.json());if(!t.success){M.error(t.error||q(`@AGENT:加载会话失败`));return}let n=l(e);n.sessionId=e,n.messages=Q(t.session),t.session?.title&&(n.title=t.session.title)}catch(e){M.error(q(`@AGENT:加载会话失败`)+`: `+(e?.message||e))}finally{a.value=!1}}async function x(e){try{await R.confirm(q(`@AGENT:确认删除该会话`),q(`@AGENT:删除后无法恢复`),{type:`warning`})}catch{return}let n=r.get(e);if(n?.abortController)try{n.abortController.abort()}catch{}r.delete(e);try{let n=await fetch(`/api/agent/sessions/${encodeURIComponent(e)}`,{method:`DELETE`}).then(e=>e.json());if(!n.success){M.error(n.error||q(`@AGENT:删除失败`));return}t.value=t.value.filter(t=>t.sessionId!==e),i.value===e&&(i.value=null),M.success(q(`@AGENT:已删除`))}catch(e){M.error(q(`@AGENT:删除失败`)+`: `+(e?.message||e))}}async function S(e,n){try{let i=await fetch(`/api/agent/sessions/${encodeURIComponent(e)}`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({title:n})}).then(e=>e.json());if(!i.success){M.error(i.error||q(`@AGENT:重命名失败`));return}let a=t.value.find(t=>t.sessionId===e);a&&(a.title=n);let o=r.get(e);o&&(o.title=n),M.success(q(`@AGENT:已重命名`))}catch(e){M.error(q(`@AGENT:重命名失败`)+`: `+(e?.message||e))}}function C(){i.value=null}async function T(t,n=[]){let a=n.filter(e=>e?.file?.type?.startsWith(`image/`));a.length<n.length&&M.warning(q(`@AGENT:仅支持发送图片,非图片文件已忽略`));let o=l(i.value||`${Z}${Date.now()}-${++s}`);if(!t.trim()&&a.length===0||o.isStreaming)return;let c=(await Promise.allSettled(a.map(e=>$(e.file)))).map(e=>e.status===`fulfilled`?e.value:``).filter(e=>e.startsWith(`data:image/`));i.value=o.key,o.nonce+=1;let u=o.nonce;o.abortController=new AbortController;let d=o.abortController;o.pendingQuestion=null,o.answeringQuestion=!1;let f={id:K(),role:`user`,content:t,status:`done`,createdAt:Date.now()};a.length>0&&(f.attachments=a.map(e=>({id:e.id,name:e.file.name||`image`,size:e.file.size||0,type:e.file.type||``,preview:e.preview}))),o.messages.push(f);let p=w({id:K(),role:`assistant`,content:``,status:`pending`,createdAt:Date.now()});o.messages.push(p),o.isStreaming=!0;let m=[],h=o.sessionId;try{let n=await fetch(`/api/agent/chat`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`text/event-stream`},body:JSON.stringify({sessionId:o.sessionId||``,userMessage:t,cwd:e.currentDirectory||``,...c.length>0?{images:c}:{}}),signal:d.signal});if(u!==o.nonce)return;if(!n.ok||!n.body){let e=await n.text().catch(()=>``);throw Error(e||`HTTP ${n.status}`)}let a=n.body.getReader(),s=new TextDecoder(`utf-8`),l=``;for(;;){let{value:e,done:n}=await a.read();if(u!==o.nonce)return;if(n)break;l+=s.decode(e,{stream:!0});let c=l.split(`
|
|
2
|
+
`);l=c.pop()??``;for(let e of c){let n=e.trim();if(!n.startsWith(`data:`))continue;let a=n.slice(5).trim();if(!a)continue;let s;try{s=JSON.parse(a)}catch{continue}switch(s.type){case`meta`:if(s.sessionId){let e=String(s.sessionId);if(h=e,o.sessionId!==e){let t=o.key;o.sessionId=e,o.key=e,t!==e&&(r.delete(t),r.set(e,o),i.value===t&&(i.value=e))}let n=String(s.title||``).trim()||t.trim().split(`
|
|
3
|
+
`)[0].trim().slice(0,40)||q(`@AGENT:无标题`);o.title||=n,v(e,n)}break;case`thinking`:p.reasoning||(p.reasoning=``,p.reasoningStatus=`streaming`),p.reasoning+=String(s.delta||``),p.status=`streaming`;break;case`content`:p.status===`pending`&&(p.status=`streaming`);{let e=String(s.delta||``);p.content+=e;let t=G(p.content);t.reasoning&&(p.reasoning||(p.reasoning=``,p.reasoningStatus=`streaming`),p.reasoning=t.reasoning,p.content=t.content)}break;case`tool_call_start`:{let e=w({id:s.toolCallId||K(),name:s.name||``,argsPreview:s.argsPreview||``,arguments:s.argsPreview||``,status:`running`,result:``});m.push(e),p.toolCalls||=[],p.toolCalls.push(e),p.status===`pending`&&(p.status=`streaming`);break}case`tool_output`:{let e=m.find(e=>e.id===s.toolCallId);if(e){let t=`${e.result||``}${String(s.chunk||``)}`;e.result=t.length>X?`…(前文已截断)\n${t.slice(-65536)}`:t}break}case`tool_result`:{let e=m.find(e=>e.id===s.toolCallId);e&&(e.result=String(s.result||``),e.status=`done`,e.name===`ask_user`&&(o.pendingQuestion=null));break}case`ask_user`:o.pendingQuestion={interactionId:String(s.interactionId||``),question:String(s.question||``),options:Array.isArray(s.options)?s.options.map(e=>String(e)):[],allowFreeText:s.allowFreeText!==!1};break;case`done`:{let e=s.content||p.content,t=G(e);t.reasoning&&!p.reasoning&&(p.reasoning=t.reasoning),p.content=t.content,p.status=`done`,p.reasoningStatus===`streaming`&&(p.reasoningStatus=`done`);break}case`error`:p.status=`error`,p.error=String(s.error||q(`@AGENT:未知错误`)),p.reasoningStatus===`streaming`&&(p.reasoningStatus=`done`)}}}if(u!==o.nonce)return;p.status===`pending`&&(p.status=`done`)}catch(e){if(u!==o.nonce)return;e?.name===`AbortError`||d.signal.aborted?(p.content=(p.content||``)+`
|
|
4
|
+
|
|
5
|
+
[`+q(`@AGENT:已停止`)+`]`,p.status=`done`,p.reasoningStatus===`streaming`&&(p.reasoningStatus=`done`)):(p.status=`error`,p.error=e?.message||String(e),M.error(p.error||q(`@AGENT:对话失败`)))}finally{u===o.nonce&&(o.isStreaming=!1,o.pendingQuestion=null,o.answeringQuestion=!1,o.abortController=null),h&&y(h),_().catch(()=>{})}}async function E(e){let t=u.value,n=t?.pendingQuestion,r=t?.sessionId,i=String(e||``).trim();if(!t||!n||!r||!i||t.answeringQuestion)return!1;t.answeringQuestion=!0;try{let e=await fetch(`/api/agent/respond`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sessionId:r,interactionId:n.interactionId,answer:i})}).then(e=>e.json());if(!e.success)throw Error(e.error||q(`@AGENT:回答提交失败`));return t.pendingQuestion=null,!0}catch(e){return M.error(e?.message||q(`@AGENT:回答提交失败`)),!1}finally{t.answeringQuestion=!1}}function D(){let e=u.value;e?.abortController&&(e.abortController.abort(),e.abortController=null)}return{sessions:t,sessionsLoading:n,currentSessionId:i,messages:d,isStreaming:f,sessionLoading:a,pendingQuestion:p,answeringQuestion:m,isSessionGenerating:h,loadSessions:_,loadSession:b,deleteSession:x,renameSession:S,newSession:C,sendMessage:T,answerQuestion:E,stop:D}}W(),A();var ue=o({__name:`MarketplacePanel`,props:{type:{type:String,required:!0}},setup(e,{expose:t}){t();let n=e,r=Y(),i=U([]),a=U([]),o=U(!1),s=U(``),l=U(``),u=U([]),d=U(`project`),f=U(new Set),m=U(new Set),h=V(()=>r.currentDirectory||``),g=null;async function _(){if(!o.value){o.value=!0;try{let e=new URLSearchParams({type:n.type,cwd:h.value});l.value&&e.set(`q`,l.value),u.value.length&&e.set(`sources`,u.value.join(`,`));let t=await(await fetch(`/api/agent/marketplace/catalog?${e}`)).json();t?.success?(i.value=t.groups||[],a.value=t.installed||[]):M.error(t?.error||q(`@MKT:加载失败`))}catch{M.error(q(`@MKT:加载失败`))}finally{o.value=!1}}}E(s,e=>{g&&clearTimeout(g),g=setTimeout(()=>{l.value=e.trim(),_()},400)}),E(u,()=>_()),E(()=>n.type,()=>{u.value=[],l.value=``,s.value=``,_()}),E(h,()=>_()),_();let v=V(()=>{let e=h.value?h.value.split(/[\\/]/).filter(Boolean).pop():``;return d.value===`project`?e||q(`@MKT:当前项目`):q(`@MKT:g ai 智能体`)});function y(e){return e.stars?`${S(e.stars)} ★`:e.downloads?`${S(e.downloads)} ${q(`@MKT:周下载`)}`:e.uses?`${S(e.uses)} ${q(`@MKT:次使用`)}`:``}function S(e){return e>=1e3?`${(e/1e3).toFixed(e>=1e4?0:1)}k`:String(e)}function C(e){return`${e.id}`}function T(e){return f.value.has(C(e))}let D=V(()=>{let e={project:[],global:[]};for(let t of a.value)(e[t.target]||=[]).push(t);return e}),O=w({visible:!1,item:null,env:{},args:``});function k(e){return n.type===`mcp`&&(!!e.envKeys?.length||!!e.args?.length)}function A(e){O.item=e,O.env=Object.fromEntries((e.envKeys||[]).map(e=>[e,``])),O.args=(e.args||[]).join(` `),O.visible=!0}function j(){let e=O.item;if(O.visible=!1,!e)return;let t=Object.fromEntries(Object.entries(O.env).filter(([,e])=>e.trim()!==``)),n=O.args.trim()?O.args.trim().match(/(?:[^\s"]+|"[^"]*")+/g)?.map(e=>e.replace(/^"|"$/g,``))??void 0:void 0;P(e,{env:t,...n?{args:n}:{}})}async function N(e){if(!e.installed||await F(e)){if(k(e)){A(e);return}await P(e,{})}}async function P(e,t){let r=C(e);f.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:d.value,cwd:h.value,item:{...e,...t}})}),i=await r.json().catch(()=>null);if(!r.ok||!i?.success){M.error(i?.error||q(`@MKT:安装失败`));return}i.item?.warning&&M.warning(i.item.warning),i.item?.envKeys?.length?M.warning(`${q(`@MKT:还缺环境变量`)}: ${i.item.envKeys.join(`, `)}`):M.success(q(`@MKT:安装成功`)),await _()}catch{M.error(q(`@MKT:安装失败`))}finally{f.value.delete(r)}}async function F(e){try{return await R.confirm(`${e.name} ${q(`@MKT:已安装,要重新安装吗?`)}`,q(`@MKT:重新安装`),{confirmButtonText:q(`@MKT:重装`),cancelButtonText:q(`@MKT:取消`),type:`warning`}),!0}catch{return!1}}async function re(e){try{await R.confirm(`${q(`@MKT:确定卸载`)} ${e.name}?`,q(`@MKT:卸载`),{confirmButtonText:q(`@MKT:卸载`),cancelButtonText:q(`@MKT:取消`),type:`warning`})}catch{return}let t=`${e.target}:${e.id}`;m.value.add(t);try{let t=new URLSearchParams({target:e.target,cwd:h.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){M.error(i?.error||q(`@MKT:卸载失败`));return}M.success(q(`@MKT:已卸载`)),await _()}catch{M.error(q(`@MKT:卸载失败`))}finally{m.value.delete(t)}}let L={props:n,configStore:r,groups:i,installed:a,loading:o,searchInput:s,query:l,selectedSources:u,installTarget:d,installing:f,removing:m,cwd:h,get searchTimer(){return g},set searchTimer(e){g=e},loadCatalog:_,targetLabel:v,metricText:y,formatCount:S,cardKey:C,isBusy:T,installedByTarget:D,configDialog:O,needsConfig:k,openConfigDialog:A,confirmConfig:j,onInstall:N,doInstall:P,confirmReinstall:F,onRemove:re,get $t(){return q},get Search(){return x},get Refresh(){return b},get Delete(){return ee},get Link(){return p},get Check(){return te},get Star(){return c},get Download(){return I},get Warning(){return ne}};return Object.defineProperty(L,"__isScriptSetup",{enumerable:!1,value:!0}),L}});W(),B(),m();var de={class:`marketplace-panel`},fe={class:`mp-toolbar`},pe={class:`mp-search`},me=[`placeholder`],he={class:`mp-toolbar-sub`},ge={class:`mp-target-hint`},_e={class:`mp-source-filter`},ve=[`onClick`],ye={class:`mp-body`},be={class:`mp-group-header`},xe={class:`mp-group-title`},Se={key:0,class:`mp-group-count`},Ce={key:1,class:`mp-group-error`},we=[`href`,`title`],Te={key:0,class:`mp-grid`},Ee={class:`mp-card-head`},De=[`title`],Oe={key:0,class:`mp-card-metric`},ke=[`title`],Ae={class:`mp-card-meta`},je=[`title`],Me=[`title`],Ne={key:2,class:`mp-tag remote`},Pe={class:`mp-card-foot`},Fe=[`href`],Ie={key:1,class:`mp-installed-chip`},Le=[`disabled`,`onClick`],Re={key:3,class:`mp-not-installable`},ze={key:1,class:`mp-empty`},Be={key:0,class:`mp-group installed`},Ve={class:`mp-group-header`},He={class:`mp-group-title`},Ue={class:`mp-group-count`},We={key:0,class:`mp-installed-block`},Ge={class:`mp-installed-target`},Ke={class:`mp-installed-list`},qe={class:`mp-installed-name`},Je={key:0,class:`mp-meta-pkg`},Ye={key:1,class:`mp-tag warn`},Xe=[`disabled`,`onClick`],Ze={key:1,class:`mp-empty all`},Qe={key:0,class:`mkt-form`},$e={class:`mkt-form-name`},et=[`onUpdate:modelValue`,`placeholder`],tt={key:0,class:`mkt-field`},nt={class:`mkt-hint`};function rt(e,o,c,p,m,h){let _=l,y=n,b=N,x=s,C=i,w=T;return S(),f(`div`,de,[r(` ── 工具栏 ───────────────────────────────── `),v(`div`,fe,[v(`div`,pe,[d(_,{class:`mp-search-icon`},{default:z(()=>[d(p.Search)]),_:1}),k(v(`input`,{"onUpdate:modelValue":o[0]||=e=>p.searchInput=e,class:`mp-search-input`,type:`text`,placeholder:c.type===`skill`?p.$t(`@MKT:搜索 Skill...`):p.$t(`@MKT:搜索 MCP 服务...`)},null,8,me),[[j,p.searchInput]])]),d(b,{modelValue:p.installTarget,"onUpdate:modelValue":o[1]||=e=>p.installTarget=e,size:`small`,class:`mp-target`},{default:z(()=>[d(y,{value:`project`},{default:z(()=>[u(t(p.$t(`@MKT:当前项目`)),1)]),_:1}),d(y,{value:`global`},{default:z(()=>[u(t(p.$t(`@MKT:g ai 智能体`)),1)]),_:1})]),_:1},8,[`modelValue`]),d(x,{content:p.$t(`@MKT:刷新`),placement:`top`,"show-after":300},{default:z(()=>[v(`button`,{class:L([`mp-refresh`,{spinning:p.loading}]),onClick:p.loadCatalog},[d(_,null,{default:z(()=>[d(p.Refresh)]),_:1})],2)]),_:1},8,[`content`])]),v(`div`,he,[v(`span`,ge,[u(t(p.$t(`@MKT:安装到`))+` `,1),v(`b`,null,t(p.targetLabel),1)]),v(`div`,_e,[(S(!0),f(D,null,g(p.groups,e=>(S(),f(`button`,{key:e.id,class:L([`mp-chip`,{active:p.selectedSources.includes(e.id)}]),onClick:()=>{let t=p.selectedSources.indexOf(e.id);t>=0?p.selectedSources.splice(t,1):p.selectedSources.push(e.id)}},t(e.label),11,ve))),128)),p.selectedSources.length?(S(),f(`button`,{key:0,class:`mp-chip clear`,onClick:o[2]||=e=>p.selectedSources=[]},t(p.$t(`@MKT:全部来源`)),1)):r(`v-if`,!0)])]),r(` ── 内容 ─────────────────────────────────── `),k((S(),f(`div`,ye,[(S(!0),f(D,null,g(p.groups,e=>(S(),f(`section`,{key:e.id,class:`mp-group`},[v(`header`,be,[v(`h3`,xe,t(e.label),1),e.status===`ok`?(S(),f(`span`,Se,t(e.items.length),1)):(S(),f(`span`,Ce,[d(_,null,{default:z(()=>[d(p.Warning)]),_:1}),u(` `+t(e.error||p.$t(`@MKT:来源不可用`)),1)])),e.homepage?(S(),f(`a`,{key:2,class:`mp-group-link`,href:e.homepage,target:`_blank`,rel:`noopener noreferrer`,title:e.homepage},[d(_,null,{default:z(()=>[d(p.Link)]),_:1})],8,we)):r(`v-if`,!0)]),e.status===`ok`&&e.items.length?(S(),f(`div`,Te,[(S(!0),f(D,null,g(e.items,e=>(S(),f(`article`,{key:p.cardKey(e),class:`mp-card`},[v(`div`,Ee,[v(`span`,{class:`mp-card-name`,title:e.name},t(e.name),9,De),p.metricText(e)?(S(),f(`span`,Oe,[d(_,null,{default:z(()=>[e.stars?(S(),a(p.Star,{key:0})):(S(),a(p.Download,{key:1}))]),_:2},1024),u(` `+t(p.metricText(e)),1)])):r(`v-if`,!0)]),v(`p`,{class:`mp-card-desc`,title:e.description},t(e.description||p.$t(`@MKT:暂无描述`)),9,ke),v(`div`,Ae,[e.package?(S(),f(`code`,{key:0,class:`mp-meta-pkg`,title:e.package},t(e.package),9,je)):e.repository?(S(),f(`span`,{key:1,class:`mp-meta-repo`,title:e.repository+(e.subpath?` · `+e.subpath:``)},[u(t(e.repository),1),e.subpath?(S(),f(D,{key:0},[u(` · `+t(e.subpath),1)],64)):r(`v-if`,!0)],8,Me)):r(`v-if`,!0),e.transport===`remote`?(S(),f(`span`,Ne,t(p.$t(`@MKT:远程服务`)),1)):r(`v-if`,!0),(S(!0),f(D,null,g((e.tags||[]).slice(0,2),e=>(S(),f(`span`,{key:e,class:`mp-tag`},t(e),1))),128))]),v(`div`,Pe,[e.upstream?(S(),f(`a`,{key:0,class:`mp-card-link`,href:e.upstream,target:`_blank`,rel:`noopener noreferrer`},t(p.$t(`@MKT:查看来源`)),9,Fe)):r(`v-if`,!0),o[6]||=v(`span`,{class:`mp-foot-spacer`},null,-1),e.installed?(S(),f(`span`,Ie,[d(_,null,{default:z(()=>[d(p.Check)]),_:1}),u(t(p.$t(`@MKT:已安装`)),1)])):e.installable===!1?(S(),f(`span`,Re,t(p.$t(`@MKT:暂不支持一键安装`)),1)):(S(),f(`button`,{key:2,class:`mp-install-btn`,disabled:p.isBusy(e),onClick:t=>p.onInstall(e)},t(p.isBusy(e)?p.$t(`@MKT:安装中...`):p.$t(`@MKT:安装`)),9,Le))])]))),128))])):e.status===`ok`?(S(),f(`div`,ze,t(p.$t(`@MKT:该来源暂无结果`)),1)):r(`v-if`,!0)]))),128)),r(` ── 已安装 ─────────────────────────────── `),p.installed.length?(S(),f(`section`,Be,[v(`header`,Ve,[v(`h3`,He,t(p.$t(`@MKT:已安装`)),1),v(`span`,Ue,t(p.installed.length),1)]),(S(),f(D,null,g([`project`,`global`],e=>v(`div`,{key:e},[p.installedByTarget[e]?.length?(S(),f(`div`,We,[v(`div`,Ge,t(e===`project`?p.$t(`@MKT:当前项目`):p.$t(`@MKT:g ai 智能体`)),1),v(`div`,Ke,[(S(!0),f(D,null,g(p.installedByTarget[e],n=>(S(),f(`div`,{key:e+n.id,class:`mp-installed-row`},[v(`span`,qe,t(n.name),1),n.package?(S(),f(`code`,Je,t(n.package),1)):r(`v-if`,!0),n.requiredEnv?.length?(S(),f(`span`,Ye,t(p.$t(`@MKT:待配置`))+`: `+t(n.requiredEnv.join(`, `)),1)):r(`v-if`,!0),o[7]||=v(`span`,{class:`mp-foot-spacer`},null,-1),v(`button`,{class:`mp-remove-btn`,disabled:p.removing.has(e+n.id),onClick:e=>p.onRemove(n)},[d(_,null,{default:z(()=>[d(p.Delete)]),_:1}),u(` `+t(p.removing.has(e+n.id)?p.$t(`@MKT:卸载中...`):p.$t(`@MKT:卸载`)),1)],8,Xe)]))),128))])])):r(`v-if`,!0)])),64))])):r(`v-if`,!0),!p.loading&&!p.groups.length?(S(),f(`div`,Ze,t(p.$t(`@MKT:加载失败`)),1)):r(`v-if`,!0)])),[[w,p.loading]]),r(` ── MCP 安装前配置 ───────────────────────── `),d(C,{modelValue:p.configDialog.visible,"onUpdate:modelValue":o[5]||=e=>p.configDialog.visible=e,title:p.$t(`@MKT:配置 MCP`),width:`460px`,"close-on-click-modal":!1,"append-to-body":``},{footer:z(()=>[v(`button`,{class:`mkt-cancel`,onClick:o[4]||=e=>p.configDialog.visible=!1},t(p.$t(`@MKT:取消`)),1),v(`button`,{class:`mkt-confirm`,onClick:p.confirmConfig},t(p.$t(`@MKT:安装`)),1)]),default:z(()=>[p.configDialog.item?(S(),f(`div`,Qe,[v(`p`,$e,t(p.configDialog.item.name),1),(S(!0),f(D,null,g(Object.keys(p.configDialog.env),e=>(S(),f(`div`,{key:e,class:`mkt-field`},[v(`label`,null,t(e),1),k(v(`input`,{"onUpdate:modelValue":t=>p.configDialog.env[e]=t,type:`text`,autocomplete:`off`,placeholder:p.$t(`@MKT:环境变量值`),spellcheck:`false`},null,8,et),[[j,p.configDialog.env[e]]])]))),128)),p.configDialog.item.args?.length?(S(),f(`div`,tt,[v(`label`,null,t(p.$t(`@MKT:启动参数`)),1),k(v(`input`,{"onUpdate:modelValue":o[3]||=e=>p.configDialog.args=e,type:`text`,autocomplete:`off`,spellcheck:`false`},null,512),[[j,p.configDialog.args]]),v(`p`,nt,t(p.$t(`@MKT:参数提示`)),1)])):r(`v-if`,!0)])):r(`v-if`,!0)]),_:1},8,[`modelValue`,`title`])])}var it=J(ue,[[`render`,rt],[`__scopeId`,`data-v-e9f9e851`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/components/MarketplacePanel.vue`]]);W(),A();var at=o({__name:`AgentView`,setup(t,{expose:n}){n();let r=Y(),i=U(`chat`),a=V(()=>i.value===`mcp`?`mcp`:`skill`),o=V(()=>[{id:`chat`,label:q(`@AGENT:对话`),icon:h},{id:`skill`,label:q(`@AGENT:Skill 广场`),icon:ae},{id:`mcp`,label:q(`@AGENT:MCP 广场`),icon:re}]),{sessions:c,sessionsLoading:u,currentSessionId:d,messages:f,isStreaming:p,sessionLoading:m,loadSessions:g,loadSession:v,deleteSession:b,renameSession:S,newSession:C,sendMessage:w,pendingQuestion:T,answeringQuestion:D,answerQuestion:O,isSessionGenerating:k,stop:A}=le(),j=V(()=>{let e=r.theme;return e===`dark`||e===`auto`&&window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}),M=U(``),ne=V(()=>{if(!M.value.trim())return c.value;let e=M.value.toLowerCase();return c.value.filter(t=>(t.title||``).toLowerCase().includes(e)||(t.model||``).toLowerCase().includes(e))}),N=V(()=>[{id:`p1`,label:q(`@AGENT:查看项目结构`),prompt:q(`@AGENT:prompt_p1`)},{id:`p2`,label:q(`@AGENT:分析代码质量`),prompt:q(`@AGENT:prompt_p2`)},{id:`p3`,label:q(`@AGENT:帮我写测试`),prompt:q(`@AGENT:prompt_p3`)},{id:`p4`,label:q(`@AGENT:Git 状态检查`),prompt:q(`@AGENT:prompt_p4`)},{id:`p5`,label:q(`@AGENT:帮我启动项目`),prompt:q(`@AGENT:prompt_p5`)}]);async function I(e){await w(e.text,e.files),await y(),H()}async function L(e){await w(e.prompt),await y(),H()}let z=U(``);async function ie(e=z.value){await O(e)&&(z.value=``)}let B=U(null);function H(e=!0){B.value?.scrollToBottom(e)}E(()=>f.value.length,()=>{y(()=>H(!1))});function W(e){v(e)}function G(){C()}function K(e,t){t.stopPropagation(),b(e)}async function J(e,t,n){n.stopPropagation();try{let{value:n}=await R.prompt(q(`@AGENT:请输入新的会话标题`),q(`@AGENT:重命名会话`),{inputValue:t,inputPattern:/.+/,inputErrorMessage:q(`@AGENT:标题不能为空`)});n&&n!==t&&await S(e,n)}catch{}}function X(e){if(!e)return``;try{let t=new Date(e);if(Number.isNaN(t.getTime()))return e;let n=new Date,r=n.getTime()-t.getTime(),i=e=>String(e).padStart(2,`0`);if(t.toDateString()===n.toDateString())return`${i(t.getHours())}:${i(t.getMinutes())}`;if(r<6048e5){let e=Math.floor(r/864e5);return e===0?q(`@AGENT:今天`):`${e}${q(`@AGENT:天前`)}`}return`${t.getFullYear()}-${i(t.getMonth()+1)}-${i(t.getDate())}`}catch{return e}}let Z=U(280),Q=U(!1);function se(e){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)}E(()=>[r.currentDirectory,p.value],async([e,t],n)=>{let r=!n||e!==n[0],i=!!n&&n[1]===!0&&!t;(r||i)&&await g(),d.value&&!p.value&&!c.value.some(e=>e.sessionId===d.value)&&C()},{immediate:!0});let $={configStore:r,activeTab:i,marketplaceType:a,tabs:o,sessions:c,sessionsLoading:u,currentSessionId:d,messages:f,isStreaming:p,sessionLoading:m,loadSessions:g,loadSession:v,deleteSession:b,renameSession:S,newSession:C,sendMessage:w,pendingQuestion:T,answeringQuestion:D,answerQuestion:O,isSessionGenerating:k,stop:A,chatTheme:j,searchQuery:M,filteredSessions:ne,presetQuestions:N,onSend:I,onSelectPreset:L,pendingAnswer:z,submitPendingAnswer:ie,chatContainerRef:B,scrollToBottom:H,selectSession:W,handleNewSession:G,handleDelete:K,handleRename:J,formatDate:X,sidebarWidth:Z,isResizing:Q,startResize:se,get $t(){return q},get ElTooltip(){return s},get ElIcon(){return l},get Plus(){return _},get Search(){return x},get Delete(){return ee},get Edit(){return F},get ChatLineRound(){return e},get Loading(){return P},get Check(){return te},get ChatContainer(){return oe},MarketplacePanel:it};return Object.defineProperty($,"__isScriptSetup",{enumerable:!1,value:!0}),$}});W(),m(),B();var ot={class:`agent-view`},st={class:`sidebar-header`},ct={class:`sidebar-search`},lt=[`placeholder`],ut={class:`session-list`},dt={key:0,class:`empty-state`},ft={class:`empty-text`},pt={key:0,class:`empty-hint`},mt=[`onClick`],ht={class:`session-item-main`},gt={class:`session-item-title`},_t={class:`session-item-meta`},vt={key:0,class:`meta-generating`},yt={class:`meta-time`},bt={class:`meta-count`},xt={key:2,class:`meta-source cli`},St=[`onClick`],Ct=[`onClick`],wt={class:`agent-chat-area`},Tt={class:`agent-tabs`,role:`tablist`},Et=[`aria-selected`,`onClick`],Dt={class:`agent-tab-body`},Ot={key:0,class:`agent-chat-pane`},kt={key:0,class:`chat-loading`},At={key:0,class:`ask-user-panel`,"aria-live":`polite`},jt={class:`ask-user-title`},Mt={class:`ask-user-question`},Nt={key:0,class:`ask-user-options`},Pt=[`disabled`,`onClick`],Ft=[`disabled`,`placeholder`,`aria-label`],It=[`disabled`],Lt={key:0,class:`stop-button-bar`};function Rt(e,n,i,o,s,c){let l=T;return S(),f(`div`,ot,[r(` ═══ 左侧:会话列表(只在「对话」Tab 显示)═══ `),o.activeTab===`chat`?(S(),f(D,{key:0},[v(`aside`,{class:`agent-sidebar`,style:C({width:o.sidebarWidth+`px`})},[r(` 顶部操作栏 `),v(`div`,st,[v(`button`,{class:`new-session-btn`,onClick:o.handleNewSession},[d(o.ElIcon,null,{default:z(()=>[d(o.Plus)]),_:1}),v(`span`,null,t(o.$t(`@AGENT:新建会话`)),1)])]),r(` 搜索框 `),v(`div`,ct,[d(o.ElIcon,{class:`search-icon`},{default:z(()=>[d(o.Search)]),_:1}),k(v(`input`,{"onUpdate:modelValue":n[0]||=e=>o.searchQuery=e,placeholder:o.$t(`@AGENT:搜索会话...`),class:`search-input`,type:`text`},null,8,lt),[[j,o.searchQuery]])]),r(` 会话列表 `),k((S(),f(`div`,ut,[o.filteredSessions.length===0&&!o.sessionsLoading?(S(),f(`div`,dt,[d(o.ElIcon,{size:28,color:`var(--text-tertiary)`},{default:z(()=>[d(o.ChatLineRound)]),_:1}),v(`div`,ft,t(o.searchQuery?o.$t(`@AGENT:未找到匹配的会话`):o.$t(`@AGENT:暂无会话`)),1),o.searchQuery?r(`v-if`,!0):(S(),f(`div`,pt,t(o.$t(`@AGENT:点击上方按钮开始对话`)),1))])):r(`v-if`,!0),(S(!0),f(D,null,g(o.filteredSessions,e=>(S(),f(`div`,{key:e.sessionId,class:L([`session-item`,{active:o.currentSessionId===e.sessionId}]),onClick:t=>o.selectSession(e.sessionId)},[v(`div`,ht,[v(`div`,gt,t(e.title||o.$t(`@AGENT:无标题`)),1),v(`div`,_t,[e.isGenerating||o.isSessionGenerating(e.sessionId)?(S(),f(`span`,vt,[d(o.ElIcon,{class:`is-loading`},{default:z(()=>[d(o.Loading)]),_:1}),u(` `+t(o.$t(`@AGENT:正在生成中...`)),1)])):(S(),f(D,{key:1},[v(`span`,yt,t(o.formatDate(e.updatedAt)),1),n[5]||=v(`span`,{class:`meta-dot`},`·`,-1),v(`span`,bt,t(e.messageCount)+` `+t(o.$t(`@AGENT:条`)),1)],64)),e.source===`cli`?(S(),f(`span`,xt,`CLI`)):r(`v-if`,!0)])]),v(`div`,{class:`session-item-actions`,onClick:n[1]||=H(()=>{},[`stop`])},[d(o.ElTooltip,{content:o.$t(`@AGENT:重命名`),placement:`top`,"show-after":500},{default:z(()=>[v(`button`,{class:`item-action-btn`,onClick:t=>o.handleRename(e.sessionId,e.title,t)},[d(o.ElIcon,null,{default:z(()=>[d(o.Edit)]),_:1})],8,St)]),_:2},1032,[`content`]),d(o.ElTooltip,{content:o.$t(`@AGENT:删除`),placement:`top`,"show-after":500},{default:z(()=>[v(`button`,{class:`item-action-btn danger`,onClick:t=>o.handleDelete(e.sessionId,t)},[d(o.ElIcon,null,{default:z(()=>[d(o.Delete)]),_:1})],8,Ct)]),_:2},1032,[`content`])])],10,mt))),128))])),[[l,o.sessionsLoading]])],4),r(` 拖拽分隔条 `),v(`div`,{class:L([`sidebar-resizer`,{active:o.isResizing}]),onMousedown:o.startResize},null,34)],64)):r(`v-if`,!0),r(` ═══ 右侧:Tab 栏 + 内容区 ═══ `),v(`main`,wt,[v(`nav`,Tt,[(S(!0),f(D,null,g(o.tabs,e=>(S(),f(`button`,{key:e.id,type:`button`,class:L([`agent-tab`,{active:o.activeTab===e.id}]),role:`tab`,"aria-selected":o.activeTab===e.id,onClick:t=>o.activeTab=e.id},[d(o.ElIcon,null,{default:z(()=>[(S(),a(ie(e.icon)))]),_:2},1024),v(`span`,null,t(e.label),1)],10,Et))),128))]),v(`div`,Dt,[r(` ── 对话 ── `),o.activeTab===`chat`?(S(),f(`div`,Ot,[r(` 加载中 `),o.sessionLoading?(S(),f(`div`,kt,[d(o.ElIcon,{class:`is-loading`,size:32},{default:z(()=>[d(o.Loading)]),_:1}),v(`span`,null,t(o.$t(`@AGENT:加载会话中...`)),1)])):(S(),f(D,{key:1},[r(` ChatContainer `),d(o.ChatContainer,{ref:`chatContainerRef`,messages:o.messages,"preset-questions":o.presetQuestions,"welcome-title":o.$t(`@AGENT:智能体助手`),"welcome-description":o.$t(`@AGENT:我可以帮你阅读代码、执行命令、修改文件。选择下方话题或直接输入你的问题。`),"assistant-name":`g ai`,theme:o.chatTheme,disabled:o.isStreaming,"upload-config":{accept:`image/*`},placeholder:o.isStreaming?o.$t(`@AGENT:正在生成中...`):o.$t(`@AGENT:输入消息,Enter 发送`),onSend:o.onSend,onSelect:o.onSelectPreset},null,8,[`messages`,`preset-questions`,`welcome-title`,`welcome-description`,`theme`,`disabled`,`placeholder`])],2112)),d(O,{name:`fade`},{default:z(()=>[o.pendingQuestion?(S(),f(`section`,At,[v(`div`,jt,[d(o.ElIcon,null,{default:z(()=>[d(o.ChatLineRound)]),_:1}),v(`span`,null,t(o.$t(`@AGENT:等待你的回答`)),1)]),v(`div`,Mt,t(o.pendingQuestion.question),1),o.pendingQuestion.options.length?(S(),f(`div`,Nt,[(S(!0),f(D,null,g(o.pendingQuestion.options,e=>(S(),f(`button`,{key:e,type:`button`,class:`ask-user-option`,disabled:o.answeringQuestion,onClick:t=>o.submitPendingAnswer(e)},[d(o.ElIcon,null,{default:z(()=>[d(o.Check)]),_:1}),v(`span`,null,t(e),1)],8,Pt))),128))])):r(`v-if`,!0),o.pendingQuestion.allowFreeText||o.pendingQuestion.options.length===0?(S(),f(`form`,{key:1,class:`ask-user-form`,onSubmit:n[3]||=H(e=>o.submitPendingAnswer(),[`prevent`])},[k(v(`input`,{"onUpdate:modelValue":n[2]||=e=>o.pendingAnswer=e,type:`text`,disabled:o.answeringQuestion,placeholder:o.$t(`@AGENT:输入回答`),"aria-label":o.$t(`@AGENT:输入回答`)},null,8,Ft),[[j,o.pendingAnswer]]),v(`button`,{type:`submit`,disabled:o.answeringQuestion||!o.pendingAnswer.trim()},[d(o.ElIcon,null,{default:z(()=>[d(o.Check)]),_:1}),v(`span`,null,t(o.$t(`@AGENT:提交回答`)),1)],8,It)],32)):r(`v-if`,!0)])):r(`v-if`,!0)]),_:1}),r(` 停止按钮浮层 `),d(O,{name:`fade`},{default:z(()=>[o.isStreaming?(S(),f(`div`,Lt,[v(`button`,{class:`stop-button`,onClick:n[4]||=(...e)=>o.stop&&o.stop(...e)},[d(o.ElIcon,null,{default:z(()=>[d(o.Loading,{class:`is-loading`})]),_:1}),v(`span`,null,t(o.$t(`@AGENT:停止生成`)),1)])])):r(`v-if`,!0)]),_:1})])):(S(),f(D,{key:1},[r(` ── Skill 广场 / MCP 广场 ── `),d(o.MarketplacePanel,{type:o.marketplaceType},null,8,[`type`])],2112))])])])}var zt=J(at,[[`render`,Rt],[`__scopeId`,`data-v-bd681ddd`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/views/AgentView.vue`]]);export{zt as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"./rolldown-runtime-C0FnF6B9.js";import{$r as e,Dn as t,E as n,En as r,Fn as i,H as a,Jn as o,K as s,Kn as c,L as l,Mn as u,Nn as d,On as f,Pr as p,Tn as m,Un as h,Xn as g,ar as _,fr as v,i as y,kt as b,nt as x,qr as S,r as C,sr as w,tt as T,wn as E,yr as D,zn as O}from"./element-plus-
|
|
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(()=>{})})}O(),v();var F=`npm install -g zen-gitsync --registry https://registry.npmjs.org/`,I=i({__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:n}){t();let r=e,i=n,a=D(null);_(()=>r.logs,async()=>{await h(),a.value&&(a.value.scrollTop=a.value.scrollHeight)});function o(){r.status!==`running`&&(r.status===`success`&&r.countdown>0&&i(`cancel`),i(`update:modelValue`,!1))}function s(){i(`retry`)}function c(){i(`restart`)}function l(){i(`cancel`),i(`update:modelValue`,!1)}async function u(){try{await navigator.clipboard.writeText(F),y.success(k(`@F13B4:已复制升级命令`))}catch{y.warning(k(`@F13B4:复制失败,请手动复制`))}}let d={MANUAL_COMMAND:F,props:r,emit:i,logEl:a,close:o,onRetry:s,onRestart:c,onLater:l,onCopyCommand:u,get Loading(){return b},get CircleCheck(){return T},get CircleClose(){return x},get $t(){return k}};return Object.defineProperty(d,"__isScriptSetup",{enumerable:!1,value:!0}),d}});O(),p();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(i,a,o,c,p,h){let _=s,v=l,y=n;return g(),r(y,{"model-value":o.modelValue,"onUpdate:modelValue":a[0]||=e=>c.emit(`update:modelValue`,e),title:c.$t(`@F13B4:升级`),width:`680px`,"close-on-click-modal":!1,"close-on-press-escape":!1,"show-close":o.status!==`running`,"append-to-body":``,onClose:c.close},{footer:w(()=>[o.status===`failed`?(g(),r(v,{key:0,type:`primary`,onClick:c.onRetry},{default:w(()=>[u(e(c.$t(`@F13B4:重试`)),1)]),_:1})):t(`v-if`,!0),o.status===`failed`?(g(),r(v,{key:1,onClick:c.onCopyCommand},{default:w(()=>[u(e(c.$t(`@F13B4:复制升级命令`)),1)]),_:1})):t(`v-if`,!0),o.status===`success`?(g(),r(v,{key:2,type:`primary`,onClick:c.onRestart},{default:w(()=>[u(e(c.$t(`@F13B4:立即重启并刷新`)),1)]),_:1})):t(`v-if`,!0),o.status===`success`?(g(),r(v,{key:3,onClick:c.onLater},{default:w(()=>[u(e(c.$t(`@F13B4:稍后手动重启`)),1)]),_:1})):t(`v-if`,!0),o.status===`running`?(g(),r(v,{key:4,disabled:``},{default:w(()=>[u(e(c.$t(`@F13B4:升级中`))+`... `,1)]),_:1})):t(`v-if`,!0)]),default:w(()=>[m(`div`,{class:S([`upgrade-status`,`is-${o.status}`])},[o.status===`running`?(g(),r(_,{key:0,class:`is-loading`},{default:w(()=>[d(c.Loading)]),_:1})):o.status===`success`?(g(),r(_,{key:1,color:`#67c23a`},{default:w(()=>[d(c.CircleCheck)]),_:1})):(g(),r(_,{key:2,color:`#f56c6c`},{default:w(()=>[d(c.CircleClose)]),_:1})),o.status===`running`?(g(),f(`span`,L,e(c.$t(`@F13B4:升级中`)),1)):o.status===`success`?(g(),f(`span`,R,e(c.$t(`@F13B4:升级完成`)),1)):(g(),f(`span`,z,e(c.$t(`@F13B4:升级失败`)),1))],2),o.status===`success`?(g(),f(`p`,B,[u(e(c.$t(`@F13B4:新版本已全局安装,需要重启服务才能生效`))+` `,1),o.countdown>0?(g(),f(`span`,V,e(c.$t(`@F13B4:{seconds} 秒后自动刷新`,{seconds:o.countdown})),1)):t(`v-if`,!0)])):t(`v-if`,!0),o.status===`failed`?(g(),f(`p`,H,[m(`span`,U,e(c.$t(`@F13B4:手动升级命令`)),1),m(`code`,{class:`upgrade-manual__cmd`},e(c.MANUAL_COMMAND))])):t(`v-if`,!0),m(`pre`,{ref:`logEl`,class:`upgrade-log`},e(o.logs||c.$t(`@F13B4:等待日志输出`)),513)]),_:1},8,[`model-value`,`title`,`show-close`])}var G=A(I,[[`render`,W],[`__scopeId`,`data-v-bc566bba`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/components/UpgradeDialog.vue`]]);O(),v();var K=`https://github.com/xz333221/zen-gitsync/releases`,q=5,J=`app-version-check`,Y=36e5,X=i({__name:`AppVersionBadge`,setup(e,{expose:t}){t();let n=`2.17.13`,r=D(n),i=E(()=>r.value||n),a=D(null),s=D(!1),l=D(``),u=D(`running`),d=D(0),f=null,p=D(!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 h(e){try{sessionStorage.setItem(J,JSON.stringify({at:Date.now(),data:e}))}catch{}}async function g(e=!1){let t=m();t&&(a.value=t);try{let t=await M();a.value=t,h(t),t.current&&(r.value=t.current),!e&&t.success&&t.hasUpdate&&y({type:`success`,message:k(`@F13B4:发现新版本 {version}`,{version:t.latest??``}),duration:4e3})}catch(t){e||y({type:`warning`,message:k(`@F13B4:检查更新失败 {error}`,{error:t?.message||``})})}}async function _(){if(a.value?.hasUpdate){try{await C.confirm(k(`@F13B4:确定要从 {current} 升级到 {latest} 吗?`,{current:a.value.current,latest:a.value.latest}),k(`@F13B4:升级`),{confirmButtonText:k(`@F13B4:确定升级`),cancelButtonText:k(`@F13B4:取消`),type:`info`})}catch{return}l.value=``,u.value=`running`,s.value=!0,await N(e=>{if(e.type===`done`){if(u.value=e.code===0?`success`:`failed`,e.code===0){try{sessionStorage.removeItem(J)}catch{}a.value?.latest&&(r.value=a.value.latest),v()}}else e.message&&(l.value+=e.message)})}}function v(){b(),d.value=q,f=setInterval(()=>{--d.value,d.value<=0&&(f&&=(clearInterval(f),null),S())},1e3)}function b(){f&&=(clearInterval(f),null),d.value=0}function x(){b()}async function S(){if(b(),!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];y({type:`warning`,message:n?k(n):k(`@F13B4:重启失败 {error}`,{error:t})}),p.value=!1}}}c(()=>{b()}),o(()=>{g(!0)});let w={buildVersion:n,releasesUrl:K,runtimeVersion:r,displayVersion:i,latestInfo:a,upgradeDialogVisible:s,upgradeLogs:l,upgradeStatus:u,AUTO_REFRESH_SECONDS:q,countdown:d,get countdownTimer(){return f},set countdownTimer(e){f=e},restartInFlight:p,CACHE_KEY:J,CACHE_TTL_MS:Y,readCache:m,writeCache:h,checkUpdate:g,handleUpgrade:_,startAutoRefreshCountdown:v,cancelAutoRefreshCountdown:b,handleCancelAutoRefresh:x,handleRestart:S,get $t(){return k},UpgradeDialog:G};return Object.defineProperty(w,"__isScriptSetup",{enumerable:!1,value:!0}),w}});O(),p();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,o,s,c){let l=a;return g(),f(`div`,Z,[t(` GitHub 链接 `),d(l,{content:o.$t(`@F13B4:在 GitHub 上查看源码`),placement:`top`,effect:`dark`,"show-after":300},{default:w(()=>[m(`a`,{href:`https://github.com/xz333221/zen-gitsync`,target:`_blank`,rel:`noopener noreferrer`,class:`badge-icon-link`,"aria-label":o.$t(`@F13B4:在 GitHub 上查看源码`)},[...r[1]||=[m(`svg`,{viewBox:`0 0 24 24`,width:`15`,height:`15`,"aria-hidden":`true`,fill:`currentColor`,xmlns:`http://www.w3.org/2000/svg`},[m(`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 链接 `),d(l,{content:o.$t(`@F13B4:在 npm 上查看包`),placement:`top`,effect:`dark`,"show-after":300},{default:w(()=>[m(`a`,{href:`https://www.npmjs.com/package/zen-gitsync`,target:`_blank`,rel:`noopener noreferrer`,class:`badge-icon-link badge-icon-link--npm`,"aria-label":o.$t(`@F13B4:在 npm 上查看包`)},[...r[2]||=[m(`svg`,{viewBox:`0 0 24 24`,width:`15`,height:`15`,"aria-hidden":`true`,fill:`currentColor`,xmlns:`http://www.w3.org/2000/svg`},[m(`path`,{d:`M2 2v20h20V2H2zm17.167 17.167H12.5v-10h-3.333v10H4.833V4.833h14.334v14.334z`})],-1)]],8,$)]),_:1},8,[`content`]),t(` 版本号 `),d(l,{content:o.$t(`@F13B4:查看更新`),placement:`top`,effect:`dark`,"show-after":300},{default:w(()=>[m(`a`,{href:o.releasesUrl,target:`_blank`,rel:`noopener noreferrer`,class:`version-link`},`v`+e(o.displayVersion),1)]),_:1},8,[`content`]),o.latestInfo?.hasUpdate?(g(),f(`button`,{key:0,type:`button`,class:`upgrade-btn`,title:o.$t(`@F13B4:发现新版本 {version},点击升级`,{version:o.latestInfo.latest??``}),"aria-label":o.$t(`@F13B4:发现新版本 {version},点击升级`,{version:o.latestInfo.latest??``}),onClick:o.handleUpgrade},[r[3]||=m(`span`,{class:`upgrade-btn__dot`,"aria-hidden":`true`},null,-1),m(`span`,te,e(o.$t(`@F13B4:升级`)),1),m(`span`,ne,`v`+e(o.latestInfo.latest),1)],8,ee)):t(`v-if`,!0),d(o.UpgradeDialog,{modelValue:o.upgradeDialogVisible,"onUpdate:modelValue":r[0]||=e=>o.upgradeDialogVisible=e,logs:o.upgradeLogs,status:o.upgradeStatus,countdown:o.countdown,onRetry:o.handleUpgrade,onRestart:o.handleRestart,onCancel:o.handleCancelAutoRefresh},null,8,[`modelValue`,`logs`,`status`,`countdown`])])}var ie=A(X,[[`render`,re],[`__scopeId`,`data-v-7e0300ec`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/components/AppVersionBadge.vue`]]);export{ie as default};
|
|
1
|
+
import"./rolldown-runtime-C0FnF6B9.js";import{$r as e,Dn as t,E as n,En as r,Fn as i,H as a,Jn as o,K as s,Kn as c,L as l,Mn as u,Nn as d,On as f,Pr as p,Tn as m,Un as h,Xn as g,ar as _,fr as v,i as y,kt as b,nt as x,qr as S,r as C,sr as w,tt as T,wn as E,yr as D,zn as O}from"./element-plus-DxBPQwL7.js";import{n as k,t as A}from"./_plugin-vue_export-helper-B1mHBne9.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(()=>{})})}O(),v();var F=`npm install -g zen-gitsync --registry https://registry.npmjs.org/`,I=i({__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:n}){t();let r=e,i=n,a=D(null);_(()=>r.logs,async()=>{await h(),a.value&&(a.value.scrollTop=a.value.scrollHeight)});function o(){r.status!==`running`&&(r.status===`success`&&r.countdown>0&&i(`cancel`),i(`update:modelValue`,!1))}function s(){i(`retry`)}function c(){i(`restart`)}function l(){i(`cancel`),i(`update:modelValue`,!1)}async function u(){try{await navigator.clipboard.writeText(F),y.success(k(`@F13B4:已复制升级命令`))}catch{y.warning(k(`@F13B4:复制失败,请手动复制`))}}let d={MANUAL_COMMAND:F,props:r,emit:i,logEl:a,close:o,onRetry:s,onRestart:c,onLater:l,onCopyCommand:u,get Loading(){return b},get CircleCheck(){return T},get CircleClose(){return x},get $t(){return k}};return Object.defineProperty(d,"__isScriptSetup",{enumerable:!1,value:!0}),d}});O(),p();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(i,a,o,c,p,h){let _=s,v=l,y=n;return g(),r(y,{"model-value":o.modelValue,"onUpdate:modelValue":a[0]||=e=>c.emit(`update:modelValue`,e),title:c.$t(`@F13B4:升级`),width:`680px`,"close-on-click-modal":!1,"close-on-press-escape":!1,"show-close":o.status!==`running`,"append-to-body":``,onClose:c.close},{footer:w(()=>[o.status===`failed`?(g(),r(v,{key:0,type:`primary`,onClick:c.onRetry},{default:w(()=>[u(e(c.$t(`@F13B4:重试`)),1)]),_:1})):t(`v-if`,!0),o.status===`failed`?(g(),r(v,{key:1,onClick:c.onCopyCommand},{default:w(()=>[u(e(c.$t(`@F13B4:复制升级命令`)),1)]),_:1})):t(`v-if`,!0),o.status===`success`?(g(),r(v,{key:2,type:`primary`,onClick:c.onRestart},{default:w(()=>[u(e(c.$t(`@F13B4:立即重启并刷新`)),1)]),_:1})):t(`v-if`,!0),o.status===`success`?(g(),r(v,{key:3,onClick:c.onLater},{default:w(()=>[u(e(c.$t(`@F13B4:稍后手动重启`)),1)]),_:1})):t(`v-if`,!0),o.status===`running`?(g(),r(v,{key:4,disabled:``},{default:w(()=>[u(e(c.$t(`@F13B4:升级中`))+`... `,1)]),_:1})):t(`v-if`,!0)]),default:w(()=>[m(`div`,{class:S([`upgrade-status`,`is-${o.status}`])},[o.status===`running`?(g(),r(_,{key:0,class:`is-loading`},{default:w(()=>[d(c.Loading)]),_:1})):o.status===`success`?(g(),r(_,{key:1,color:`#67c23a`},{default:w(()=>[d(c.CircleCheck)]),_:1})):(g(),r(_,{key:2,color:`#f56c6c`},{default:w(()=>[d(c.CircleClose)]),_:1})),o.status===`running`?(g(),f(`span`,L,e(c.$t(`@F13B4:升级中`)),1)):o.status===`success`?(g(),f(`span`,R,e(c.$t(`@F13B4:升级完成`)),1)):(g(),f(`span`,z,e(c.$t(`@F13B4:升级失败`)),1))],2),o.status===`success`?(g(),f(`p`,B,[u(e(c.$t(`@F13B4:新版本已全局安装,需要重启服务才能生效`))+` `,1),o.countdown>0?(g(),f(`span`,V,e(c.$t(`@F13B4:{seconds} 秒后自动刷新`,{seconds:o.countdown})),1)):t(`v-if`,!0)])):t(`v-if`,!0),o.status===`failed`?(g(),f(`p`,H,[m(`span`,U,e(c.$t(`@F13B4:手动升级命令`)),1),m(`code`,{class:`upgrade-manual__cmd`},e(c.MANUAL_COMMAND))])):t(`v-if`,!0),m(`pre`,{ref:`logEl`,class:`upgrade-log`},e(o.logs||c.$t(`@F13B4:等待日志输出`)),513)]),_:1},8,[`model-value`,`title`,`show-close`])}var G=A(I,[[`render`,W],[`__scopeId`,`data-v-bc566bba`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/components/UpgradeDialog.vue`]]);O(),v();var K=`https://github.com/xz333221/zen-gitsync/releases`,q=5,J=`app-version-check`,Y=36e5,X=i({__name:`AppVersionBadge`,setup(e,{expose:t}){t();let n=`2.17.15`,r=D(n),i=E(()=>r.value||n),a=D(null),s=D(!1),l=D(``),u=D(`running`),d=D(0),f=null,p=D(!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 h(e){try{sessionStorage.setItem(J,JSON.stringify({at:Date.now(),data:e}))}catch{}}async function g(e=!1){let t=m();t&&(a.value=t);try{let t=await M();a.value=t,h(t),t.current&&(r.value=t.current),!e&&t.success&&t.hasUpdate&&y({type:`success`,message:k(`@F13B4:发现新版本 {version}`,{version:t.latest??``}),duration:4e3})}catch(t){e||y({type:`warning`,message:k(`@F13B4:检查更新失败 {error}`,{error:t?.message||``})})}}async function _(){if(a.value?.hasUpdate){try{await C.confirm(k(`@F13B4:确定要从 {current} 升级到 {latest} 吗?`,{current:a.value.current,latest:a.value.latest}),k(`@F13B4:升级`),{confirmButtonText:k(`@F13B4:确定升级`),cancelButtonText:k(`@F13B4:取消`),type:`info`})}catch{return}l.value=``,u.value=`running`,s.value=!0,await N(e=>{if(e.type===`done`){if(u.value=e.code===0?`success`:`failed`,e.code===0){try{sessionStorage.removeItem(J)}catch{}a.value?.latest&&(r.value=a.value.latest),v()}}else e.message&&(l.value+=e.message)})}}function v(){b(),d.value=q,f=setInterval(()=>{--d.value,d.value<=0&&(f&&=(clearInterval(f),null),S())},1e3)}function b(){f&&=(clearInterval(f),null),d.value=0}function x(){b()}async function S(){if(b(),!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];y({type:`warning`,message:n?k(n):k(`@F13B4:重启失败 {error}`,{error:t})}),p.value=!1}}}c(()=>{b()}),o(()=>{g(!0)});let w={buildVersion:n,releasesUrl:K,runtimeVersion:r,displayVersion:i,latestInfo:a,upgradeDialogVisible:s,upgradeLogs:l,upgradeStatus:u,AUTO_REFRESH_SECONDS:q,countdown:d,get countdownTimer(){return f},set countdownTimer(e){f=e},restartInFlight:p,CACHE_KEY:J,CACHE_TTL_MS:Y,readCache:m,writeCache:h,checkUpdate:g,handleUpgrade:_,startAutoRefreshCountdown:v,cancelAutoRefreshCountdown:b,handleCancelAutoRefresh:x,handleRestart:S,get $t(){return k},UpgradeDialog:G};return Object.defineProperty(w,"__isScriptSetup",{enumerable:!1,value:!0}),w}});O(),p();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,o,s,c){let l=a;return g(),f(`div`,Z,[t(` GitHub 链接 `),d(l,{content:o.$t(`@F13B4:在 GitHub 上查看源码`),placement:`top`,effect:`dark`,"show-after":300},{default:w(()=>[m(`a`,{href:`https://github.com/xz333221/zen-gitsync`,target:`_blank`,rel:`noopener noreferrer`,class:`badge-icon-link`,"aria-label":o.$t(`@F13B4:在 GitHub 上查看源码`)},[...r[1]||=[m(`svg`,{viewBox:`0 0 24 24`,width:`15`,height:`15`,"aria-hidden":`true`,fill:`currentColor`,xmlns:`http://www.w3.org/2000/svg`},[m(`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 链接 `),d(l,{content:o.$t(`@F13B4:在 npm 上查看包`),placement:`top`,effect:`dark`,"show-after":300},{default:w(()=>[m(`a`,{href:`https://www.npmjs.com/package/zen-gitsync`,target:`_blank`,rel:`noopener noreferrer`,class:`badge-icon-link badge-icon-link--npm`,"aria-label":o.$t(`@F13B4:在 npm 上查看包`)},[...r[2]||=[m(`svg`,{viewBox:`0 0 24 24`,width:`15`,height:`15`,"aria-hidden":`true`,fill:`currentColor`,xmlns:`http://www.w3.org/2000/svg`},[m(`path`,{d:`M2 2v20h20V2H2zm17.167 17.167H12.5v-10h-3.333v10H4.833V4.833h14.334v14.334z`})],-1)]],8,$)]),_:1},8,[`content`]),t(` 版本号 `),d(l,{content:o.$t(`@F13B4:查看更新`),placement:`top`,effect:`dark`,"show-after":300},{default:w(()=>[m(`a`,{href:o.releasesUrl,target:`_blank`,rel:`noopener noreferrer`,class:`version-link`},`v`+e(o.displayVersion),1)]),_:1},8,[`content`]),o.latestInfo?.hasUpdate?(g(),f(`button`,{key:0,type:`button`,class:`upgrade-btn`,title:o.$t(`@F13B4:发现新版本 {version},点击升级`,{version:o.latestInfo.latest??``}),"aria-label":o.$t(`@F13B4:发现新版本 {version},点击升级`,{version:o.latestInfo.latest??``}),onClick:o.handleUpgrade},[r[3]||=m(`span`,{class:`upgrade-btn__dot`,"aria-hidden":`true`},null,-1),m(`span`,te,e(o.$t(`@F13B4:升级`)),1),m(`span`,ne,`v`+e(o.latestInfo.latest),1)],8,ee)):t(`v-if`,!0),d(o.UpgradeDialog,{modelValue:o.upgradeDialogVisible,"onUpdate:modelValue":r[0]||=e=>o.upgradeDialogVisible=e,logs:o.upgradeLogs,status:o.upgradeStatus,countdown:o.countdown,onRetry:o.handleUpgrade,onRestart:o.handleRestart,onCancel:o.handleCancelAutoRefresh},null,8,[`modelValue`,`logs`,`status`,`countdown`])])}var ie=A(X,[[`render`,re],[`__scopeId`,`data-v-7e0300ec`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/components/AppVersionBadge.vue`]]);export{ie as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./rolldown-runtime-C0FnF6B9.js";import{$r as e,Dn as t,En as n,F as r,Fn as i,K as a,Mt as o,Nn as s,On as c,P as l,Pr as u,Qn as d,Rt as f,Tn as p,U as m,V as h,Vt as g,W as _,Xn as v,_ as y,bn as b,et as x,fr as S,qr as C,sr as w,un as T,vn as E,wn as D,yr as O,zn as k}from"./element-plus-
|
|
1
|
+
import"./rolldown-runtime-C0FnF6B9.js";import{$r as e,Dn as t,En as n,F as r,Fn as i,K as a,Mt as o,Nn as s,On as c,P as l,Pr as u,Qn as d,Rt as f,Tn as p,U as m,V as h,Vt as g,W as _,Xn as v,_ as y,bn as b,et as x,fr as S,qr as C,sr as w,un as T,vn as E,wn as D,yr as O,zn as k}from"./element-plus-DxBPQwL7.js";import{n as A,t as j}from"./_plugin-vue_export-helper-B1mHBne9.js";import{t as M}from"./SvgIcon-yefEMV0-.js";import{t as N}from"./IconButton-DcOAqpq0.js";import{r as P}from"./gitStore-D5CWxPLv.js";import{t as F}from"./CommonDialog-B_qUsIGr.js";k(),S();var I=i({__name:`BranchSelector`,emits:[`branchChanged`],setup(e,{expose:t,emit:n}){t();let r=P(),i=n,a=O(!1),s=O(``),c=D(()=>{let e=s.value.trim().toLowerCase();return e?r.allBranches.filter(t=>t.toLowerCase().includes(e)):r.allBranches});async function l(e){if(e===r.currentBranch){a.value=!1;return}a.value=!1,await r.changeBranch(e)&&(i(`branchChanged`),r.refreshLog())}let u=O(!1),d=O(``),p=O(``);function m(){a.value=!1,p.value=r.currentBranch,u.value=!0}async function h(){await r.createBranch(d.value,p.value)&&(u.value=!1,d.value=``,i(`branchChanged`))}let _=O(!1);async function v(){if(!_.value){_.value=!0;try{await Promise.all([r.getCurrentBranch(!0),r.getBranchStatus(!0),r.getAllBranches()]),i(`branchChanged`),r.refreshLog()}finally{_.value=!1}}}let y={gitStore:r,emit:i,branchPopoverVisible:a,branchFilter:s,filteredBranches:c,selectBranch:l,createBranchDialogVisible:u,newBranchName:d,selectedBaseBranch:p,openCreateBranchDialog:m,createNewBranch:h,isRefreshingBranch:_,refreshCurrentBranch:v,get $t(){return A},get Plus(){return f},get Menu(){return o},get Check(){return x},get Refresh(){return g},CommonDialog:F,IconButton:N,SvgIcon:M};return Object.defineProperty(y,"__isScriptSetup",{enumerable:!1,value:!0}),y}});k(),u(),T();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(i,o,u,f,g,x){let S=a,T=h,D=y,O=_,k=l,A=r,j=m;return f.gitStore.currentBranch?(v(),c(`div`,L,[p(`div`,R,[t(` VSCode 风格分支按钮 + 弹出列表 `),s(D,{visible:f.branchPopoverVisible,"onUpdate:visible":o[1]||=e=>f.branchPopoverVisible=e,placement:`top-start`,width:260,trigger:`click`,"popper-class":`branch-popover`,"show-arrow":!1,onShow:o[2]||=e=>f.branchFilter=``},{reference:w(()=>[p(`button`,z,[s(f.SvgIcon,{"icon-class":`git-branch`,"class-name":`branch-btn-icon`}),p(`span`,B,e(f.gitStore.currentBranch),1),p(`span`,V,[s(S,null,{default:w(()=>[...o[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:w(()=>[p(`div`,H,[t(` 搜索框 `),p(`div`,U,[s(T,{modelValue:f.branchFilter,"onUpdate:modelValue":o[0]||=e=>f.branchFilter=e,placeholder:f.$t(`@F13B4:搜索或签出分支`),size:`small`,clearable:``,autofocus:``},null,8,[`modelValue`,`placeholder`])]),t(` 分支列表 `),p(`div`,W,[(v(!0),c(b,null,d(f.filteredBranches,t=>(v(),c(`div`,{key:t,class:C([`branch-item`,{"is-active":t===f.gitStore.currentBranch}]),onClick:e=>f.selectBranch(t)},[t===f.gitStore.currentBranch?(v(),n(S,{key:0,class:`branch-item-check`},{default:w(()=>[s(f.Check)]),_:1})):(v(),c(`span`,K)),s(f.SvgIcon,{"icon-class":`git-branch`,"class-name":`branch-item-icon`}),p(`span`,q,e(t),1)],10,G))),128)),f.filteredBranches.length===0?(v(),c(`div`,J,e(f.$t(`@F13B4:没有匹配的分支`)),1)):t(`v-if`,!0)]),t(` 底部:创建新分支 `),p(`div`,Y,[p(`button`,{class:`branch-create-btn`,onClick:f.openCreateBranchDialog},[s(S,null,{default:w(()=>[s(f.Plus)]),_:1}),p(`span`,null,e(f.$t(`@F13B4:创建新分支`)),1)])])])]),_:1},8,[`visible`]),t(` 刷新按钮 `),s(f.IconButton,{tooltip:f.$t(`@CMDCON:刷新`),onClick:f.refreshCurrentBranch},{default:w(()=>[s(S,{class:C({"is-loading":f.isRefreshingBranch})},{default:w(()=>[s(f.Refresh)]),_:1},8,[`class`])]),_:1},8,[`tooltip`])]),t(` 创建分支对话框 `),s(f.CommonDialog,{modelValue:f.createBranchDialogVisible,"onUpdate:modelValue":o[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:w(()=>[p(`div`,$,[p(`div`,ee,[p(`button`,{type:`button`,class:`dialog-cancel-btn`,onClick:o[5]||=e=>f.createBranchDialogVisible=!1},e(f.$t(`@F13B4:取消`)),1),p(`button`,{type:`button`,class:`dialog-confirm-btn`,onClick:f.createNewBranch,disabled:f.gitStore.isCreatingBranch},[f.gitStore.isCreatingBranch?(v(),n(S,{key:1,class:`is-loading`},{default:w(()=>[...o[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})):(v(),n(S,{key:0},{default:w(()=>[s(f.Check)]),_:1})),p(`span`,null,e(f.$t(`@F13B4:创建`)),1)],8,te)])])]),default:w(()=>[p(`div`,X,[s(j,{model:{newBranchName:f.newBranchName,selectedBaseBranch:f.selectedBaseBranch},"label-position":`top`},{default:w(()=>[s(O,null,{label:w(()=>[p(`div`,Z,[s(S,{class:`label-icon`},{default:w(()=>[s(f.Plus)]),_:1}),p(`span`,null,e(f.$t(`@F13B4:新分支名称`)),1)])]),default:w(()=>[s(T,{modelValue:f.newBranchName,"onUpdate:modelValue":o[3]||=e=>f.newBranchName=e,placeholder:f.$t(`@F13B4:请输入新分支名称`),class:`modern-input`,size:`large`,onKeyup:E(f.createNewBranch,[`enter`])},null,8,[`modelValue`,`placeholder`])]),_:1}),s(O,null,{label:w(()=>[p(`div`,Q,[s(S,{class:`label-icon`},{default:w(()=>[s(f.Menu)]),_:1}),p(`span`,null,e(f.$t(`@F13B4:基于分支`)),1)])]),default:w(()=>[s(A,{modelValue:f.selectedBaseBranch,"onUpdate:modelValue":o[4]||=e=>f.selectedBaseBranch=e,placeholder:f.$t(`@F13B4:选择基础分支`),class:`modern-select`,size:`large`,style:{width:`100%`}},{default:w(()=>[(v(!0),c(b,null,d(f.gitStore.allBranches,e=>(v(),n(k,{key:e,label:e,value:e},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`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/components/BranchSelector.vue`]]);export{re as default};
|