zen-gitsync 2.16.2 → 2.16.3

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zen-gitsync",
3
- "version": "2.16.2",
3
+ "version": "2.16.3",
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",
@@ -27,8 +27,8 @@
27
27
  // (格式化磁盘、删根目录、关机等系统级破坏操作)
28
28
  //
29
29
  // 视觉风格(termui.js):对标 Codex CLI / Claude Code / OpenCode —
30
- // 盒式输入框、ora 等待 spinner、✻ 思考灰斜体、⏺ 工具块 + 结果槽、
31
- // 正文逐行轻量 markdown(**bold** / `code` / # 标题 / ``` 围栏 / - 列表)
30
+ // 盒式输入框、ora 等待 spinner、✻ 思考(橙黄斜体)、⚙ 工具头(青) + 结果槽、
31
+ // 正文 ➤ 子弹头(绿)+ 逐行轻量 markdown(**bold** / `code` / # 标题 / ``` 围栏 / - 列表)
32
32
  //
33
33
  // 使用方式:
34
34
  // g ai 交互模式(REPL)
@@ -96,7 +96,7 @@ const STRINGS = {
96
96
  prompt: '❯ ',
97
97
  bannerModel: '模型',
98
98
  bannerCwd: '目录',
99
- thinkingLabel: '思考',
99
+ thinkingLabel: '思考',
100
100
  chars: '字符',
101
101
  imagePasting: '正在读取剪贴板图片…',
102
102
  imageAttached: (n, size) => `📎 图片 #${n} 已附加(${size}),将随下一条消息发送`,
@@ -136,7 +136,7 @@ const STRINGS = {
136
136
  prompt: '❯ ',
137
137
  bannerModel: 'Model',
138
138
  bannerCwd: 'CWD',
139
- thinkingLabel: 'Thinking',
139
+ thinkingLabel: 'Thinking',
140
140
  chars: 'chars',
141
141
  imagePasting: 'Reading clipboard image…',
142
142
  imageAttached: (n, size) => `📎 Image #${n} attached (${size}); sent with your next message`,
@@ -446,7 +446,7 @@ async function runAgentTurn(state, userText, t, images = []) {
446
446
  const stopSpinner = () => {
447
447
  if (!spinnerStopped) { spinner.stop(); spinnerStopped = true }
448
448
  }
449
- // 每次 LLM 调用一个 writer:思考灰斜体、正文 + 逐行 markdown
449
+ // 每次 LLM 调用一个 writer:思考(橙黄斜体)+ 正文 ➤ 子弹头 + 逐行 markdown
450
450
  const writer = createAssistantWriter({
451
451
  showThinking: state.showThinking,
452
452
  thinkingHeader: t.thinkingLabel,
@@ -808,7 +808,9 @@ export async function runAiAgent(argv = []) {
808
808
  const rl = readline.createInterface({
809
809
  input: process.stdin,
810
810
  output: process.stdout,
811
- prompt: chalk.cyan.bold(t.prompt),
811
+ // prompt: ❯ 用青色加粗;末尾追加 ANSI 亮白+加粗码,
812
+ // 让用户输入的文本继承亮白色高亮(黑底上最清晰)
813
+ prompt: chalk.cyan.bold(t.prompt) + '\x1b[1;97m',
812
814
  historySize: 200,
813
815
  })
814
816
  state.rl = rl // 供 /addmodel 等需要 rl.question 的斜杠命令复用
@@ -16,10 +16,10 @@
16
16
  //
17
17
  // - 盒式输入框(Codex composer 风格):╭───╮ + ❯ 提示符 + ╰───╯
18
18
  // - 等待 spinner(ora):首个 token 到达前持续转动
19
- // - 思考过程:✻ 思考 头 + 灰色斜体流式输出
20
- // - 工具调用块(Claude Code 风格):⏺ 工具头 + 智能参数摘要,
21
- // 结果用 ⎿/│ 缩进槽,按退出码/错误前缀着色
22
- // - 正文:⏺ 项目符号 + 逐行缓冲的轻量 markdown 渲染
19
+ // - 思考过程:✻ 思考 头 + 橙黄斜体流式输出
20
+ // - 工具调用块(Claude Code 风格):⚙ 工具头 + 智能参数摘要,
21
+ // 结果用 缩进槽,按退出码/错误前缀着色
22
+ // - 正文:➤ 子弹头 + 逐行缓冲的轻量 markdown 渲染
23
23
  // (**bold**、`code`、# 标题、``` 代码块、- 列表)
24
24
  //
25
25
  // 设计约束:
@@ -85,16 +85,18 @@ export function truncateDisplay(text, limit = DISPLAY_RESULT_LIMIT) {
85
85
  /** 启动横幅:模型 + 目录 + 快捷键提示,盒式自适应宽度 */
86
86
  export function printBanner({ title, modelLabel, baseURL, cwd, modelText, cwdText, tip }) {
87
87
  const lines = [
88
- chalk.green.bold(title),
89
- `${modelText}: ${chalk.cyan(modelLabel)}${baseURL ? ' ' + chalk.dim(baseURL) : ''}`,
90
- `${cwdText}: ${chalk.cyan(cwd)}`,
91
- chalk.dim(tip),
88
+ // greenBright 在黑底上比 green 更鲜亮,与 🤖 回答图标同色系
89
+ chalk.greenBright.bold(title),
90
+ `${modelText}: ${chalk.cyanBright(modelLabel)}${baseURL ? ' ' + chalk.hex('#a0aec0')(baseURL) : ''}`,
91
+ `${cwdText}: ${chalk.cyanBright(cwd)}`,
92
+ // dim 在黑底太暗,改用浅灰可读
93
+ chalk.hex('#a0aec0')(tip),
92
94
  ].join('\n')
93
95
  process.stdout.write(
94
96
  boxenAdaptive(lines, {
95
97
  padding: { top: 0, bottom: 0, left: 1, right: 1 },
96
98
  margin: { top: 1, bottom: 0, left: 0, right: 0 },
97
- borderColor: 'cyan',
99
+ borderColor: 'greenBright',
98
100
  borderStyle: 'round',
99
101
  }) + '\n'
100
102
  )
@@ -203,9 +205,10 @@ export function drawInputBottom(write = (s) => process.stdout.write(s)) {
203
205
 
204
206
  export function startSpinner(text) {
205
207
  const spinner = ora({
206
- text: chalk.dim(text),
208
+ // 琥珀色加粗,与思考内容同色系,dim 太浅看不清
209
+ text: chalk.hex('#e8a33d').bold(text),
207
210
  spinner: 'dots',
208
- color: 'cyan',
211
+ color: 'yellow',
209
212
  // ora 默认 discardStdin: true,内部用 stdin-discarder 在 spinner 运行时
210
213
  // 丢弃 stdin 输入。但 stdin-discarder 的 stop() 在 Windows 上有 bug:
211
214
  // start() 跳过 Windows,但 stop() 没有 Windows 检查,无条件执行
@@ -223,11 +226,14 @@ export function startSpinner(text) {
223
226
  }
224
227
 
225
228
  // ──────────────────────────────────────────────
226
- // 流式回复 writer:思考(灰斜体) + 正文( + 轻量 markdown)
229
+ // 流式回复 writer:思考(橙黄斜体) + 正文( 子弹头 + 轻量 markdown)
227
230
  // ──────────────────────────────────────────────
228
231
 
229
- /** 行内 markdown:`code` 优先提取防干扰,再处理 **bold** */
230
- function renderInline(line) {
232
+ /** 行内 markdown:`code` 优先提取防干扰,再处理 **bold**
233
+ * @param {string} resetFg - 行内 code 后需重置的前景色 ANSI 码(如 whiteBright 用 '\x1b[97m'),
234
+ * 避免 chalk.cyan 的 \x1b[39m 把外层 base 色清掉导致后续文字掉色
235
+ */
236
+ function renderInline(line, resetFg = '') {
231
237
  const spans = []
232
238
  // 先抠出 inline code,避免其中的 * 被 bold 规则误吃
233
239
  line = line.replace(/`([^`\n]+)`/g, (m, c) => {
@@ -235,7 +241,7 @@ function renderInline(line) {
235
241
  return `\u0000${spans.length - 1}\u0000`
236
242
  })
237
243
  line = line.replace(/\*\*([^*\n]+)\*\*/g, (m, c) => chalk.bold(c))
238
- line = line.replace(/\u0000(\d+)\u0000/g, (m, i) => chalk.cyan(spans[Number(i)]))
244
+ line = line.replace(/\u0000(\d+)\u0000/g, (m, i) => chalk.cyan(spans[Number(i)]) + resetFg)
239
245
  return line
240
246
  }
241
247
 
@@ -255,16 +261,21 @@ export function createAssistantWriter({
255
261
  let mode = null // null | 'thinking' | 'content'
256
262
  let lineBuf = '' // 正文行缓冲(逐行渲染,保证 ** 等标记完整)
257
263
  let inFence = false // ``` 代码块状态
258
- let contentLines = 0 // 已输出正文行数(首行带 子弹头)
264
+ let contentLines = 0 // 已输出正文行数(首行带 子弹头)
259
265
  let lastBlank = false // 上一行是空白行(连续空行合并,避免模型输出头部/分隔空行刷屏)
260
266
  let thinkAtLineStart = true // 思考流当前是否在行首(用于逐行缩进 + 计算与正文的分隔)
261
- // 后留 2 个空格,后续行 3 空格对齐 — 图标与文字之间别太挤
262
- const BULLET_FIRST = chalk.green('⏺') + ' '
267
+ // 后留 2 个空格,后续行 3 空格对齐 — 图标与文字之间别太挤
268
+ // 正文 🤖(亮绿):模型最终回复的视觉锚点;用亮绿 + 加粗图标,普通绿在深背景上偏暗
269
+ const BULLET_FIRST = chalk.bold(chalk.hex('#5eff8b')('🤖')) + ' '
263
270
  const BULLET_REST = ' '
271
+ // whiteBright ANSI 码:行内 code 的 \x1b[39m 会清掉外层色,用此恢复正文亮白色
272
+ const WB = '\x1b[97m'
264
273
  // 思考内容整体右移,与正文文字左缘对齐,视觉上成为独立子块
265
274
  const THINK_INDENT = ' '
266
275
  // 思考用橙黄色斜体(gray/dim 太浅看不清;橙黄既醒目又与正文白、工具青区分开)
267
276
  const thinkStyle = (s) => chalk.hex('#e8a33d').italic(s)
277
+ // 思考图标:🧠 大脑 — 紧贴最左(0 缩进),与工具头、正文对齐到同一左缘
278
+ const THINK_ICON = '🧠'
268
279
 
269
280
  const emitContentLine = (raw, withNewline = true) => {
270
281
  // 围栏标记行:切换状态,用一个淡淡的槽线代替裸 ```
@@ -295,7 +306,10 @@ export function createAssistantWriter({
295
306
  const bullet = contentLines === 0 ? BULLET_FIRST : BULLET_REST
296
307
  contentLines++
297
308
  const h = raw.match(/^(#{1,6})\s+(.*)$/)
298
- const body = h ? chalk.bold(renderInline(h[2])) : renderInline(raw)
309
+ // 正文用 whiteBright(亮白)比默认白更醒目;resetFg=WB 让行内 code 后恢复亮白
310
+ const body = h
311
+ ? chalk.bold.whiteBright(renderInline(h[2], WB))
312
+ : chalk.whiteBright(renderInline(raw, WB))
299
313
  write(bullet + body + (withNewline ? '\n' : ''))
300
314
  }
301
315
 
@@ -312,8 +326,9 @@ export function createAssistantWriter({
312
326
  if (mode !== 'thinking') {
313
327
  flushLineBuf()
314
328
  mode = 'thinking'
315
- // 段头前空一行与上文分隔;头部本身也缩进,和内容左缘对齐
316
- write('\n' + THINK_INDENT + thinkStyle(thinkingHeader) + '\n')
329
+ // 图标 🧠 靠最左(0 缩进),与 ⚙ 工具头、➤ 正文对齐同一左缘
330
+ // 段头前空一行与上文(spinner / 上一轮输出)分隔,视觉更清晰
331
+ write('\n' + THINK_ICON + ' ' + thinkStyle(chalk.bold(thinkingHeader)) + '\n')
317
332
  thinkAtLineStart = true
318
333
  }
319
334
  // 按换行切段,整段着色(避免逐字符 escape 刷屏);每逢行首补一层缩进,
@@ -334,12 +349,14 @@ export function createAssistantWriter({
334
349
  }
335
350
  },
336
351
 
337
- /** 正文段:⏺ 子弹头 + 逐行 markdown 渲染 */
352
+ /** 正文段:➤ 子弹头 + 逐行 markdown 渲染 */
338
353
  writeContent(text) {
339
354
  if (!text) return
340
355
  if (mode !== 'content') {
341
356
  // 思考→正文:补足换行 + 空一行,让思考块与正文之间有呼吸间隔(不再紧挨)
342
357
  if (mode === 'thinking') write((thinkAtLineStart ? '' : '\n') + '\n')
358
+ // 无思考段直接出正文:null→content 时在 🤖 上方加一空行,与 spinner 分隔
359
+ else if (mode === null) write('\n')
343
360
  mode = 'content'
344
361
  }
345
362
  lineBuf += text
@@ -391,32 +408,38 @@ export function summarizeToolArgs(name, args, { chars = '字符' } = {}) {
391
408
  }
392
409
  }
393
410
 
394
- /** 工具头:⏺ name 参数摘要(图标与文字之间 2 空格,别太挤;青色与正文绿色子弹头区分) */
411
+ /** 工具头:▶ name 参数摘要(青色三角表示"工具执行";name 加粗白色,摘要灰色,避免整块青色) */
395
412
  export function printToolHeader(name, summary, write = (s) => process.stdout.write(s)) {
396
- write('\n' + chalk.cyan('⏺') + ' ' + chalk.bold(name) + (summary ? ' ' + chalk.dim(summary) : '') + '\n')
413
+ // 保留青色作为工具执行的标识色;name 用白色加粗与下方结果区分;
414
+ // summary 用浅灰(#a0aec0)— dim 在黑底下太暗看不清,浅灰可读且仍比 name 低调
415
+ write('\n' + chalk.cyan('▶') + ' '
416
+ + chalk.bold.white(name)
417
+ + (summary ? ' ' + chalk.hex('#a0aec0')(summary) : '')
418
+ + '\n')
397
419
  }
398
420
 
399
421
  /**
400
422
  * 工具结果块:
401
- * └─ 首行
402
- * │ 后续行…
403
- * 退出码非 0 → 黄色;"错误/已拒绝"开头 → 红色;其余用青色(cyan,dim/gray 太浅看不清)。
404
- * (首行用 └─ 而不是 Claude 的 ⎿:box-drawing 字符在 Windows 终端字体里渲染更稳,
405
- * 且与输入框 ╭╰ 边框同一字符族,视觉更统一)
423
+ * │ 每行统一用 │ 槽线对齐(不做首行 └─ 拐角,看着更干净)
424
+ * 退出码非 0 → 琥珀色;"错误/已拒绝"开头 → 琥珀色;其余用柔和灰蓝(避免与工具头同色)。
425
+ *
426
+ * run_command 的结果里首行是 `$ <command>` 回显——这条信息已经出现在上方的
427
+ * `▶ run_command $ <summary>` 工具头里,这里再印一次就是重复。所以这里把首
428
+ * 行 `$ ...` 剥掉,同时复用它来识别退出码(退出码仍驱动错误着色)。
406
429
  */
407
430
  export function printToolResult(result, write = (s) => process.stdout.write(s)) {
408
431
  const text = truncateDisplay(result)
432
+ // 先把 "$ <command>\n" 这一行回显从展示里剥掉(退出码仍在第二行里识别)
433
+ const visible = text.replace(/^\$[^\n]*\n/, '')
409
434
  const exitMatch = text.match(/^\$[^\n]*\n\(exit (\d+)\)/)
410
435
  const exitCode = exitMatch ? Number(exitMatch[1]) : null
411
436
  const isError = exitCode !== null && exitCode !== 0
412
437
  || /^(错误|已拒绝|Error)/.test(text.trim())
413
- // 正文用 cyan(比 dim/gray 亮,能看清);错误保持黄色告警。槽线仍用 dim 当装饰导轨
414
- const colorize = isError ? chalk.yellow : chalk.cyan
415
- const lines = text.split('\n')
416
- const rendered = lines.map((l, i) => {
417
- const gutter = i === 0 ? chalk.dim(' └─ ') : chalk.dim('')
418
- return gutter + colorize(l)
419
- }).join('\n')
438
+ // 正文用柔和灰蓝(#94a3b8) 不再用青色,避免与工具头同色连成一片;
439
+ // 错误用琥珀色(#f0a020)比黄色更醒目
440
+ const colorize = isError ? chalk.hex('#f0a020') : chalk.hex('#94a3b8')
441
+ const lines = visible.split('\n')
442
+ const rendered = lines.map((l) => chalk.dim(' ') + colorize(l)).join('\n')
420
443
  write(rendered + '\n')
421
444
  }
422
445
 
@@ -102,13 +102,13 @@ test('writer: showThinking=false 时丢弃思考段', () => {
102
102
  assert.ok(text.includes('正文'))
103
103
  })
104
104
 
105
- test('writer: 正文首行 子弹头,后续行缩进对齐', () => {
105
+ test('writer: 正文首行 🤖 子弹头,后续行缩进对齐', () => {
106
106
  const c = collect()
107
107
  const w = createAssistantWriter({ write: c.write })
108
108
  w.writeContent('第一行\n第二行\n第三行')
109
109
  w.finish()
110
110
  const lines = c.lines()
111
- assert.ok(lines.some(l => l.startsWith(' 第一行')))
111
+ assert.ok(lines.some(l => l.startsWith('🤖 第一行')))
112
112
  assert.ok(lines.some(l => l.startsWith(' 第二行')))
113
113
  assert.ok(lines.some(l => l.startsWith(' 第三行')))
114
114
  })
@@ -184,7 +184,9 @@ test('writer: 头部空白行被吞掉,连续空白行合并(真实 MiniMax 输
184
184
  w.writeContent('答案\n\n\n\n下一段\n')
185
185
  w.finish()
186
186
  const lines = c.lines()
187
- assert.equal(lines[0], '⏺ 答案', `首行应为 ⏺ 答案,实际: ${lines[0]}`)
187
+ // null→content 自动在 🤖 上方加一空行,跳过空行找正文首行
188
+ const firstContent = lines.find(l => l !== '')
189
+ assert.equal(firstContent, '🤖 答案', `首行应为 🤖 答案,实际: ${JSON.stringify(lines)}`)
188
190
  // "答案"与"下一段"之间最多一个空行,且空行不带缩进
189
191
  const midBlank = lines.slice(1, lines.indexOf(' 下一段')).filter(l => l === '').length
190
192
  assert.ok(midBlank <= 1, `空行应被合并,实际行: ${JSON.stringify(lines)}`)
@@ -192,20 +194,20 @@ test('writer: 头部空白行被吞掉,连续空白行合并(真实 MiniMax 输
192
194
  })
193
195
 
194
196
  // ── 工具块 ──
195
- test('printToolHeader: + 名称 + 摘要', () => {
197
+ test('printToolHeader: + 名称(粗)+ 摘要(粗)', () => {
196
198
  const c = collect()
197
199
  printToolHeader('run_command', '$ npm test', c.write)
198
200
  const text = c.text()
199
- assert.ok(text.includes(' run_command'))
201
+ assert.ok(text.includes(' run_command'))
200
202
  assert.ok(text.includes('$ npm test'))
201
203
  })
202
204
 
203
- test('printToolResult: 首行 └─,后续行 │ 槽线', () => {
205
+ test('printToolResult: 全部行统一 │ 槽线(无 └─ 拐角)', () => {
204
206
  const c = collect()
205
207
  printToolResult('$ ls\n(exit 0)\nfile1\nfile2', c.write)
206
208
  const lines = c.lines()
207
- assert.ok(lines[0].startsWith(' └─ '), `首行应为 └─ 槽线,实际: ${lines[0]}`)
208
- assert.ok(lines.slice(1).every(l => l.startsWith('') || l === ''), '后续行应为 槽线')
209
+ assert.ok(lines.every(l => l.startsWith(' │ ') || l === ''), `每行都应为 槽线,实际: ${JSON.stringify(lines)}`)
210
+ assert.ok(!lines.some(l => l.includes('└─')), '不应出现 └─ 拐角字符')
209
211
  })
210
212
 
211
213
  test('printToolResult: 超长结果被截断并含省略标记', () => {
@@ -1,2 +1,2 @@
1
1
  import"./rolldown-runtime-DAXXjFlN.js";import{B as e,Cn as t,D as n,Et as r,Fn as i,G as a,Jn as o,Ln as s,Mn as c,Sn as l,Tn as u,Xn as d,Y as f,_n as p,_r as m,a as h,gn as g,hn as _,i as v,mn as y,mr as b,nt as x,rt as S,sr as C,vn as w,zn as T}from"./element-plus-DNnePjco.js";import{n as E,t as D}from"./_plugin-vue_export-helper-BQRl7WAH.js";async function O(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 k(){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 A(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 O(t,t=>{try{e(JSON.parse(t))}catch{}})}async function j(){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())};O(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(()=>{})})}var M=u({__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 i=e,a=n,s=C(null);o(()=>i.logs,async()=>{await c(),s.value&&(s.value.scrollTop=s.value.scrollHeight)});function l(){i.status!==`running`&&(i.status===`success`&&i.countdown>0&&a(`cancel`),a(`update:modelValue`,!1))}function u(){a(`retry`)}function d(){a(`restart`)}function f(){a(`cancel`),a(`update:modelValue`,!1)}let p={props:i,emit:a,logEl:s,close:l,onRetry:u,onRestart:d,onLater:f,get Loading(){return r},get CircleCheck(){return x},get CircleClose(){return S},get $t(){return E}};return Object.defineProperty(p,"__isScriptSetup",{enumerable:!1,value:!0}),p}}),N={key:3},P={key:4},F={key:5},I={key:0,class:`upgrade-hint`},L={key:0,class:`upgrade-countdown`};function R(r,i,a,o,s,c){let u=f,h=e,v=n;return T(),g(v,{"model-value":a.modelValue,"onUpdate:modelValue":i[0]||=e=>o.emit(`update:modelValue`,e),title:o.$t(`@F13B4:升级`),width:`680px`,"close-on-click-modal":!1,"close-on-press-escape":!1,"show-close":a.status!==`running`,"append-to-body":``,onClose:o.close},{footer:d(()=>[a.status===`failed`?(T(),g(h,{key:0,type:`primary`,onClick:o.onRetry},{default:d(()=>[l(m(o.$t(`@F13B4:重试`)),1)]),_:1})):p(`v-if`,!0),a.status===`success`?(T(),g(h,{key:1,type:`primary`,onClick:o.onRestart},{default:d(()=>[l(m(o.$t(`@F13B4:立即重启并刷新`)),1)]),_:1})):p(`v-if`,!0),a.status===`success`?(T(),g(h,{key:2,onClick:o.onLater},{default:d(()=>[l(m(o.$t(`@F13B4:稍后手动重启`)),1)]),_:1})):p(`v-if`,!0),a.status===`running`?(T(),g(h,{key:3,disabled:``},{default:d(()=>[l(m(o.$t(`@F13B4:升级中`))+`... `,1)]),_:1})):p(`v-if`,!0)]),default:d(()=>[_(`div`,{class:b([`upgrade-status`,`is-${a.status}`])},[a.status===`running`?(T(),g(u,{key:0,class:`is-loading`},{default:d(()=>[t(o.Loading)]),_:1})):a.status===`success`?(T(),g(u,{key:1,color:`#67c23a`},{default:d(()=>[t(o.CircleCheck)]),_:1})):(T(),g(u,{key:2,color:`#f56c6c`},{default:d(()=>[t(o.CircleClose)]),_:1})),a.status===`running`?(T(),w(`span`,N,m(o.$t(`@F13B4:升级中`)),1)):a.status===`success`?(T(),w(`span`,P,m(o.$t(`@F13B4:升级完成`)),1)):(T(),w(`span`,F,m(o.$t(`@F13B4:升级失败`)),1))],2),a.status===`success`?(T(),w(`p`,I,[l(m(o.$t(`@F13B4:新版本已全局安装,需要重启服务才能生效`))+` `,1),a.countdown>0?(T(),w(`span`,L,m(o.$t(`@F13B4:{seconds} 秒后自动刷新`,{seconds:a.countdown})),1)):p(`v-if`,!0)])):p(`v-if`,!0),_(`pre`,{ref:`logEl`,class:`upgrade-log`},m(a.logs||o.$t(`@F13B4:等待日志输出`)),513)]),_:1},8,[`model-value`,`title`,`show-close`])}var z=D(M,[[`render`,R],[`__scopeId`,`data-v-bc566bba`],[`__file`,`E:/workspace/github_workspace/zen-git/src/ui/client/src/components/UpgradeDialog.vue`]]),B=`https://github.com/xz333221/zen-gitsync/releases`,V=5,H=`app-version-check`,U=3600*1e3,W=u({__name:`AppVersionBadge`,setup(e,{expose:t}){t();let n=`2.16.2`,r=C(n),a=y(()=>r.value||n),o=C(null),c=C(!1),l=C(``),u=C(`running`),d=C(0),f=null,p=C(!1);function m(){try{let e=sessionStorage.getItem(H);if(!e)return null;let{at:t,data:n}=JSON.parse(e);return Date.now()-t>U?null:n}catch{return null}}function g(e){try{sessionStorage.setItem(H,JSON.stringify({at:Date.now(),data:e}))}catch{}}async function _(e=!1){let t=m();t&&(o.value=t);try{let t=await k();o.value=t,g(t),t.current&&(r.value=t.current),!e&&t.success&&t.hasUpdate&&h({type:`success`,message:E(`@F13B4:发现新版本 {version}`,{version:t.latest??``}),duration:4e3})}catch(t){e||h({type:`warning`,message:E(`@F13B4:检查更新失败 {error}`,{error:t?.message||``})})}}async function b(){if(o.value?.hasUpdate){try{await v.confirm(E(`@F13B4:确定要从 {current} 升级到 {latest} 吗?`,{current:o.value.current,latest:o.value.latest}),E(`@F13B4:升级`),{confirmButtonText:E(`@F13B4:确定升级`),cancelButtonText:E(`@F13B4:取消`),type:`info`})}catch{return}l.value=``,u.value=`running`,c.value=!0,await A(e=>{if(e.type===`done`){if(u.value=e.code===0?`success`:`failed`,e.code===0){try{sessionStorage.removeItem(H)}catch{}o.value?.latest&&(r.value=o.value.latest),x()}}else e.message&&(l.value+=e.message)})}}function x(){S(),d.value=V,f=setInterval(()=>{--d.value,d.value<=0&&(f&&=(clearInterval(f),null),T())},1e3)}function S(){f&&=(clearInterval(f),null),d.value=0}function w(){S()}async function T(){if(S(),!p.value){p.value=!0;try{let e=await j(),{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];h({type:`warning`,message:n?E(n):E(`@F13B4:重启失败 {error}`,{error:t})}),p.value=!1}}}i(()=>{S()}),s(()=>{_(!0)});let D={buildVersion:n,releasesUrl:B,runtimeVersion:r,displayVersion:a,latestInfo:o,upgradeDialogVisible:c,upgradeLogs:l,upgradeStatus:u,AUTO_REFRESH_SECONDS:V,countdown:d,get countdownTimer(){return f},set countdownTimer(e){f=e},restartInFlight:p,CACHE_KEY:H,CACHE_TTL_MS:U,readCache:m,writeCache:g,checkUpdate:_,handleUpgrade:b,startAutoRefreshCountdown:x,cancelAutoRefreshCountdown:S,handleCancelAutoRefresh:w,handleRestart:T,get $t(){return E},UpgradeDialog:z};return Object.defineProperty(D,"__isScriptSetup",{enumerable:!1,value:!0}),D}}),G={class:`app-version-badge`},K=[`aria-label`],q=[`aria-label`],J=[`title`,`aria-label`],Y={class:`upgrade-btn__label`},X={class:`upgrade-btn__version`};function Z(e,n,r,i,o,s){let c=a;return T(),w(`div`,G,[p(` GitHub 链接 `),t(c,{content:i.$t(`@F13B4:在 GitHub 上查看源码`),placement:`top`,effect:`dark`,"show-after":300},{default:d(()=>[_(`a`,{href:`https://github.com/xz333221/zen-gitsync`,target:`_blank`,rel:`noopener noreferrer`,class:`badge-icon-link`,"aria-label":i.$t(`@F13B4:在 GitHub 上查看源码`)},[...n[1]||=[_(`svg`,{viewBox:`0 0 24 24`,width:`15`,height:`15`,"aria-hidden":`true`,fill:`currentColor`,xmlns:`http://www.w3.org/2000/svg`},[_(`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,K)]),_:1},8,[`content`]),p(` NPM 链接 `),t(c,{content:i.$t(`@F13B4:在 npm 上查看包`),placement:`top`,effect:`dark`,"show-after":300},{default:d(()=>[_(`a`,{href:`https://www.npmjs.com/package/zen-gitsync`,target:`_blank`,rel:`noopener noreferrer`,class:`badge-icon-link badge-icon-link--npm`,"aria-label":i.$t(`@F13B4:在 npm 上查看包`)},[...n[2]||=[_(`svg`,{viewBox:`0 0 24 24`,width:`15`,height:`15`,"aria-hidden":`true`,fill:`currentColor`,xmlns:`http://www.w3.org/2000/svg`},[_(`path`,{d:`M2 2v20h20V2H2zm17.167 17.167H12.5v-10h-3.333v10H4.833V4.833h14.334v14.334z`})],-1)]],8,q)]),_:1},8,[`content`]),p(` 版本号 `),t(c,{content:i.$t(`@F13B4:查看更新`),placement:`top`,effect:`dark`,"show-after":300},{default:d(()=>[_(`a`,{href:i.releasesUrl,target:`_blank`,rel:`noopener noreferrer`,class:`version-link`},`v`+m(i.displayVersion),1)]),_:1},8,[`content`]),i.latestInfo?.hasUpdate?(T(),w(`button`,{key:0,type:`button`,class:`upgrade-btn`,title:i.$t(`@F13B4:发现新版本 {version},点击升级`,{version:i.latestInfo.latest??``}),"aria-label":i.$t(`@F13B4:发现新版本 {version},点击升级`,{version:i.latestInfo.latest??``}),onClick:i.handleUpgrade},[n[3]||=_(`span`,{class:`upgrade-btn__dot`,"aria-hidden":`true`},null,-1),_(`span`,Y,m(i.$t(`@F13B4:升级`)),1),_(`span`,X,`v`+m(i.latestInfo.latest),1)],8,J)):p(`v-if`,!0),t(i.UpgradeDialog,{modelValue:i.upgradeDialogVisible,"onUpdate:modelValue":n[0]||=e=>i.upgradeDialogVisible=e,logs:i.upgradeLogs,status:i.upgradeStatus,countdown:i.countdown,onRetry:i.handleUpgrade,onRestart:i.handleRestart,onCancel:i.handleCancelAutoRefresh},null,8,[`modelValue`,`logs`,`status`,`countdown`])])}var Q=D(W,[[`render`,Z],[`__scopeId`,`data-v-7e0300ec`],[`__file`,`E:/workspace/github_workspace/zen-git/src/ui/client/src/components/AppVersionBadge.vue`]]);export{Q as default};
2
+ `);i=o.pop()??``;for(let e of o)e.trim()&&t(e)}i.trim()&&t(i)}async function k(){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 A(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 O(t,t=>{try{e(JSON.parse(t))}catch{}})}async function j(){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())};O(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(()=>{})})}var M=u({__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 i=e,a=n,s=C(null);o(()=>i.logs,async()=>{await c(),s.value&&(s.value.scrollTop=s.value.scrollHeight)});function l(){i.status!==`running`&&(i.status===`success`&&i.countdown>0&&a(`cancel`),a(`update:modelValue`,!1))}function u(){a(`retry`)}function d(){a(`restart`)}function f(){a(`cancel`),a(`update:modelValue`,!1)}let p={props:i,emit:a,logEl:s,close:l,onRetry:u,onRestart:d,onLater:f,get Loading(){return r},get CircleCheck(){return x},get CircleClose(){return S},get $t(){return E}};return Object.defineProperty(p,"__isScriptSetup",{enumerable:!1,value:!0}),p}}),N={key:3},P={key:4},F={key:5},I={key:0,class:`upgrade-hint`},L={key:0,class:`upgrade-countdown`};function R(r,i,a,o,s,c){let u=f,h=e,v=n;return T(),g(v,{"model-value":a.modelValue,"onUpdate:modelValue":i[0]||=e=>o.emit(`update:modelValue`,e),title:o.$t(`@F13B4:升级`),width:`680px`,"close-on-click-modal":!1,"close-on-press-escape":!1,"show-close":a.status!==`running`,"append-to-body":``,onClose:o.close},{footer:d(()=>[a.status===`failed`?(T(),g(h,{key:0,type:`primary`,onClick:o.onRetry},{default:d(()=>[l(m(o.$t(`@F13B4:重试`)),1)]),_:1})):p(`v-if`,!0),a.status===`success`?(T(),g(h,{key:1,type:`primary`,onClick:o.onRestart},{default:d(()=>[l(m(o.$t(`@F13B4:立即重启并刷新`)),1)]),_:1})):p(`v-if`,!0),a.status===`success`?(T(),g(h,{key:2,onClick:o.onLater},{default:d(()=>[l(m(o.$t(`@F13B4:稍后手动重启`)),1)]),_:1})):p(`v-if`,!0),a.status===`running`?(T(),g(h,{key:3,disabled:``},{default:d(()=>[l(m(o.$t(`@F13B4:升级中`))+`... `,1)]),_:1})):p(`v-if`,!0)]),default:d(()=>[_(`div`,{class:b([`upgrade-status`,`is-${a.status}`])},[a.status===`running`?(T(),g(u,{key:0,class:`is-loading`},{default:d(()=>[t(o.Loading)]),_:1})):a.status===`success`?(T(),g(u,{key:1,color:`#67c23a`},{default:d(()=>[t(o.CircleCheck)]),_:1})):(T(),g(u,{key:2,color:`#f56c6c`},{default:d(()=>[t(o.CircleClose)]),_:1})),a.status===`running`?(T(),w(`span`,N,m(o.$t(`@F13B4:升级中`)),1)):a.status===`success`?(T(),w(`span`,P,m(o.$t(`@F13B4:升级完成`)),1)):(T(),w(`span`,F,m(o.$t(`@F13B4:升级失败`)),1))],2),a.status===`success`?(T(),w(`p`,I,[l(m(o.$t(`@F13B4:新版本已全局安装,需要重启服务才能生效`))+` `,1),a.countdown>0?(T(),w(`span`,L,m(o.$t(`@F13B4:{seconds} 秒后自动刷新`,{seconds:a.countdown})),1)):p(`v-if`,!0)])):p(`v-if`,!0),_(`pre`,{ref:`logEl`,class:`upgrade-log`},m(a.logs||o.$t(`@F13B4:等待日志输出`)),513)]),_:1},8,[`model-value`,`title`,`show-close`])}var z=D(M,[[`render`,R],[`__scopeId`,`data-v-bc566bba`],[`__file`,`E:/workspace/github_workspace/zen-git/src/ui/client/src/components/UpgradeDialog.vue`]]),B=`https://github.com/xz333221/zen-gitsync/releases`,V=5,H=`app-version-check`,U=3600*1e3,W=u({__name:`AppVersionBadge`,setup(e,{expose:t}){t();let n=`2.16.3`,r=C(n),a=y(()=>r.value||n),o=C(null),c=C(!1),l=C(``),u=C(`running`),d=C(0),f=null,p=C(!1);function m(){try{let e=sessionStorage.getItem(H);if(!e)return null;let{at:t,data:n}=JSON.parse(e);return Date.now()-t>U?null:n}catch{return null}}function g(e){try{sessionStorage.setItem(H,JSON.stringify({at:Date.now(),data:e}))}catch{}}async function _(e=!1){let t=m();t&&(o.value=t);try{let t=await k();o.value=t,g(t),t.current&&(r.value=t.current),!e&&t.success&&t.hasUpdate&&h({type:`success`,message:E(`@F13B4:发现新版本 {version}`,{version:t.latest??``}),duration:4e3})}catch(t){e||h({type:`warning`,message:E(`@F13B4:检查更新失败 {error}`,{error:t?.message||``})})}}async function b(){if(o.value?.hasUpdate){try{await v.confirm(E(`@F13B4:确定要从 {current} 升级到 {latest} 吗?`,{current:o.value.current,latest:o.value.latest}),E(`@F13B4:升级`),{confirmButtonText:E(`@F13B4:确定升级`),cancelButtonText:E(`@F13B4:取消`),type:`info`})}catch{return}l.value=``,u.value=`running`,c.value=!0,await A(e=>{if(e.type===`done`){if(u.value=e.code===0?`success`:`failed`,e.code===0){try{sessionStorage.removeItem(H)}catch{}o.value?.latest&&(r.value=o.value.latest),x()}}else e.message&&(l.value+=e.message)})}}function x(){S(),d.value=V,f=setInterval(()=>{--d.value,d.value<=0&&(f&&=(clearInterval(f),null),T())},1e3)}function S(){f&&=(clearInterval(f),null),d.value=0}function w(){S()}async function T(){if(S(),!p.value){p.value=!0;try{let e=await j(),{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];h({type:`warning`,message:n?E(n):E(`@F13B4:重启失败 {error}`,{error:t})}),p.value=!1}}}i(()=>{S()}),s(()=>{_(!0)});let D={buildVersion:n,releasesUrl:B,runtimeVersion:r,displayVersion:a,latestInfo:o,upgradeDialogVisible:c,upgradeLogs:l,upgradeStatus:u,AUTO_REFRESH_SECONDS:V,countdown:d,get countdownTimer(){return f},set countdownTimer(e){f=e},restartInFlight:p,CACHE_KEY:H,CACHE_TTL_MS:U,readCache:m,writeCache:g,checkUpdate:_,handleUpgrade:b,startAutoRefreshCountdown:x,cancelAutoRefreshCountdown:S,handleCancelAutoRefresh:w,handleRestart:T,get $t(){return E},UpgradeDialog:z};return Object.defineProperty(D,"__isScriptSetup",{enumerable:!1,value:!0}),D}}),G={class:`app-version-badge`},K=[`aria-label`],q=[`aria-label`],J=[`title`,`aria-label`],Y={class:`upgrade-btn__label`},X={class:`upgrade-btn__version`};function Z(e,n,r,i,o,s){let c=a;return T(),w(`div`,G,[p(` GitHub 链接 `),t(c,{content:i.$t(`@F13B4:在 GitHub 上查看源码`),placement:`top`,effect:`dark`,"show-after":300},{default:d(()=>[_(`a`,{href:`https://github.com/xz333221/zen-gitsync`,target:`_blank`,rel:`noopener noreferrer`,class:`badge-icon-link`,"aria-label":i.$t(`@F13B4:在 GitHub 上查看源码`)},[...n[1]||=[_(`svg`,{viewBox:`0 0 24 24`,width:`15`,height:`15`,"aria-hidden":`true`,fill:`currentColor`,xmlns:`http://www.w3.org/2000/svg`},[_(`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,K)]),_:1},8,[`content`]),p(` NPM 链接 `),t(c,{content:i.$t(`@F13B4:在 npm 上查看包`),placement:`top`,effect:`dark`,"show-after":300},{default:d(()=>[_(`a`,{href:`https://www.npmjs.com/package/zen-gitsync`,target:`_blank`,rel:`noopener noreferrer`,class:`badge-icon-link badge-icon-link--npm`,"aria-label":i.$t(`@F13B4:在 npm 上查看包`)},[...n[2]||=[_(`svg`,{viewBox:`0 0 24 24`,width:`15`,height:`15`,"aria-hidden":`true`,fill:`currentColor`,xmlns:`http://www.w3.org/2000/svg`},[_(`path`,{d:`M2 2v20h20V2H2zm17.167 17.167H12.5v-10h-3.333v10H4.833V4.833h14.334v14.334z`})],-1)]],8,q)]),_:1},8,[`content`]),p(` 版本号 `),t(c,{content:i.$t(`@F13B4:查看更新`),placement:`top`,effect:`dark`,"show-after":300},{default:d(()=>[_(`a`,{href:i.releasesUrl,target:`_blank`,rel:`noopener noreferrer`,class:`version-link`},`v`+m(i.displayVersion),1)]),_:1},8,[`content`]),i.latestInfo?.hasUpdate?(T(),w(`button`,{key:0,type:`button`,class:`upgrade-btn`,title:i.$t(`@F13B4:发现新版本 {version},点击升级`,{version:i.latestInfo.latest??``}),"aria-label":i.$t(`@F13B4:发现新版本 {version},点击升级`,{version:i.latestInfo.latest??``}),onClick:i.handleUpgrade},[n[3]||=_(`span`,{class:`upgrade-btn__dot`,"aria-hidden":`true`},null,-1),_(`span`,Y,m(i.$t(`@F13B4:升级`)),1),_(`span`,X,`v`+m(i.latestInfo.latest),1)],8,J)):p(`v-if`,!0),t(i.UpgradeDialog,{modelValue:i.upgradeDialogVisible,"onUpdate:modelValue":n[0]||=e=>i.upgradeDialogVisible=e,logs:i.upgradeLogs,status:i.upgradeStatus,countdown:i.countdown,onRetry:i.handleUpgrade,onRestart:i.handleRestart,onCancel:i.handleCancelAutoRefresh},null,8,[`modelValue`,`logs`,`status`,`countdown`])])}var Q=D(W,[[`render`,Z],[`__scopeId`,`data-v-7e0300ec`],[`__file`,`E:/workspace/github_workspace/zen-git/src/ui/client/src/components/AppVersionBadge.vue`]]);export{Q as default};
@@ -1 +1 @@
1
- import"./rolldown-runtime-DAXXjFlN.js";import{Cn as e,K as t,L as n,Lt as r,Pt as i,R as a,Tn as o,Vn as s,W as c,Xn as l,Y as u,_n as d,_r as f,cn as p,gn as m,hn as h,kt as g,mn as _,mr as v,q as y,r as b,sr as x,tt as S,un as C,vn as w,zn as T}from"./element-plus-DNnePjco.js";import{n as E,t as D}from"./_plugin-vue_export-helper-BQRl7WAH.js";import{t as O}from"./SvgIcon-BqWp2WS8.js";import{n as k,t as A}from"./CommonDialog-BA4xg5l3.js";import{y as j}from"./index-Br2VZQBT.js";var M=o({__name:`BranchSelector`,emits:[`branchChanged`],setup(e,{expose:t,emit:n}){t();let a=j(),o=n,s=x(!1),c=x(``),l=_(()=>{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=x(!1),f=x(``),p=x(``);function m(){s.value=!1,p.value=a.currentBranch,d.value=!0}async function h(){await a.createBranch(f.value,p.value)&&(d.value=!1,f.value=``,o(`branchChanged`))}let v=x(!1);async function y(){if(!v.value){v.value=!0;try{await Promise.all([a.getCurrentBranch(!0),a.getBranchStatus(!0),a.getAllBranches()]),o(`branchChanged`),a.refreshLog()}finally{v.value=!1}}}let b={gitStore:a,emit:o,branchPopoverVisible:s,branchFilter:c,filteredBranches:l,selectBranch:u,createBranchDialogVisible:d,newBranchName:f,selectedBaseBranch:p,openCreateBranchDialog:m,createNewBranch:h,isRefreshingBranch:v,refreshCurrentBranch:y,get $t(){return E},get Plus(){return i},get Menu(){return g},get Check(){return S},get Refresh(){return r},CommonDialog:A,IconButton:k,SvgIcon:O};return Object.defineProperty(b,"__isScriptSetup",{enumerable:!1,value:!0}),b}}),N={key:0,class:`branch-info`},P={class:`branch-wrapper`},F={class:`branch-btn`},I={class:`branch-btn-name`},L={class:`branch-btn-caret`},R={class:`branch-popover-inner`},z={class:`branch-search`},B={class:`branch-list`},V=[`onClick`],H={key:1,class:`branch-item-check-placeholder`},U={class:`branch-item-name`},W={key:0,class:`branch-empty`},G={class:`branch-popover-footer`},K={class:`create-branch-content`},q={class:`form-label`},J={class:`form-label`},Y={class:`dialog-footer`},X={class:`footer-actions`},Z=[`disabled`];function Q(r,i,o,g,_,x){let S=u,E=c,D=b,O=y,k=n,A=a,j=t;return g.gitStore.currentBranch?(T(),w(`div`,N,[h(`div`,P,[d(` VSCode 风格分支按钮 + 弹出列表 `),e(D,{visible:g.branchPopoverVisible,"onUpdate:visible":i[1]||=e=>g.branchPopoverVisible=e,placement:`top-start`,width:260,trigger:`click`,"popper-class":`branch-popover`,"show-arrow":!1,onShow:i[2]||=e=>g.branchFilter=``},{reference:l(()=>[h(`button`,F,[e(g.SvgIcon,{"icon-class":`git-branch`,"class-name":`branch-btn-icon`}),h(`span`,I,f(g.gitStore.currentBranch),1),h(`span`,L,[e(S,null,{default:l(()=>[...i[7]||=[h(`svg`,{viewBox:`0 0 1024 1024`,xmlns:`http://www.w3.org/2000/svg`},[h(`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:l(()=>[h(`div`,R,[d(` 搜索框 `),h(`div`,z,[e(E,{modelValue:g.branchFilter,"onUpdate:modelValue":i[0]||=e=>g.branchFilter=e,placeholder:g.$t(`@F13B4:搜索或签出分支`),size:`small`,clearable:``,autofocus:``},null,8,[`modelValue`,`placeholder`])]),d(` 分支列表 `),h(`div`,B,[(T(!0),w(C,null,s(g.filteredBranches,t=>(T(),w(`div`,{key:t,class:v([`branch-item`,{"is-active":t===g.gitStore.currentBranch}]),onClick:e=>g.selectBranch(t)},[t===g.gitStore.currentBranch?(T(),m(S,{key:0,class:`branch-item-check`},{default:l(()=>[e(g.Check)]),_:1})):(T(),w(`span`,H)),e(g.SvgIcon,{"icon-class":`git-branch`,"class-name":`branch-item-icon`}),h(`span`,U,f(t),1)],10,V))),128)),g.filteredBranches.length===0?(T(),w(`div`,W,f(g.$t(`@F13B4:没有匹配的分支`)),1)):d(`v-if`,!0)]),d(` 底部:创建新分支 `),h(`div`,G,[h(`button`,{class:`branch-create-btn`,onClick:g.openCreateBranchDialog},[e(S,null,{default:l(()=>[e(g.Plus)]),_:1}),h(`span`,null,f(g.$t(`@F13B4:创建新分支`)),1)])])])]),_:1},8,[`visible`]),d(` 刷新按钮 `),e(g.IconButton,{tooltip:g.$t(`@CMDCON:刷新`),onClick:g.refreshCurrentBranch},{default:l(()=>[e(S,{class:v({"is-loading":g.isRefreshingBranch})},{default:l(()=>[e(g.Refresh)]),_:1},8,[`class`])]),_:1},8,[`tooltip`])]),d(` 创建分支对话框 `),e(g.CommonDialog,{modelValue:g.createBranchDialogVisible,"onUpdate:modelValue":i[6]||=e=>g.createBranchDialogVisible=e,title:g.$t(`@F13B4:创建新分支`),size:`small`,"destroy-on-close":!0,"append-to-body":!0,"custom-class":`create-branch-dialog`},{footer:l(()=>[h(`div`,Y,[h(`div`,X,[h(`button`,{type:`button`,class:`dialog-cancel-btn`,onClick:i[5]||=e=>g.createBranchDialogVisible=!1},f(g.$t(`@F13B4:取消`)),1),h(`button`,{type:`button`,class:`dialog-confirm-btn`,onClick:g.createNewBranch,disabled:g.gitStore.isCreatingBranch},[g.gitStore.isCreatingBranch?(T(),m(S,{key:1,class:`is-loading`},{default:l(()=>[...i[8]||=[h(`svg`,{viewBox:`0 0 1024 1024`,xmlns:`http://www.w3.org/2000/svg`},[h(`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})):(T(),m(S,{key:0},{default:l(()=>[e(g.Check)]),_:1})),h(`span`,null,f(g.$t(`@F13B4:创建`)),1)],8,Z)])])]),default:l(()=>[h(`div`,K,[e(j,{model:{newBranchName:g.newBranchName,selectedBaseBranch:g.selectedBaseBranch},"label-position":`top`},{default:l(()=>[e(O,null,{label:l(()=>[h(`div`,q,[e(S,{class:`label-icon`},{default:l(()=>[e(g.Plus)]),_:1}),h(`span`,null,f(g.$t(`@F13B4:新分支名称`)),1)])]),default:l(()=>[e(E,{modelValue:g.newBranchName,"onUpdate:modelValue":i[3]||=e=>g.newBranchName=e,placeholder:g.$t(`@F13B4:请输入新分支名称`),class:`modern-input`,size:`large`,onKeyup:p(g.createNewBranch,[`enter`])},null,8,[`modelValue`,`placeholder`])]),_:1}),e(O,null,{label:l(()=>[h(`div`,J,[e(S,{class:`label-icon`},{default:l(()=>[e(g.Menu)]),_:1}),h(`span`,null,f(g.$t(`@F13B4:基于分支`)),1)])]),default:l(()=>[e(A,{modelValue:g.selectedBaseBranch,"onUpdate:modelValue":i[4]||=e=>g.selectedBaseBranch=e,placeholder:g.$t(`@F13B4:选择基础分支`),class:`modern-select`,size:`large`,style:{width:`100%`}},{default:l(()=>[(T(!0),w(C,null,s(g.gitStore.allBranches,e=>(T(),m(k,{key:e,label:e,value:e},null,8,[`label`,`value`]))),128))]),_:1},8,[`modelValue`,`placeholder`])]),_:1})]),_:1},8,[`model`])])]),_:1},8,[`modelValue`,`title`])])):d(`v-if`,!0)}var $=D(M,[[`render`,Q],[`__scopeId`,`data-v-9548a76f`],[`__file`,`E:/workspace/github_workspace/zen-git/src/ui/client/src/components/BranchSelector.vue`]]);export{$ as default};
1
+ import"./rolldown-runtime-DAXXjFlN.js";import{Cn as e,K as t,L as n,Lt as r,Pt as i,R as a,Tn as o,Vn as s,W as c,Xn as l,Y as u,_n as d,_r as f,cn as p,gn as m,hn as h,kt as g,mn as _,mr as v,q as y,r as b,sr as x,tt as S,un as C,vn as w,zn as T}from"./element-plus-DNnePjco.js";import{n as E,t as D}from"./_plugin-vue_export-helper-BQRl7WAH.js";import{t as O}from"./SvgIcon-BqWp2WS8.js";import{n as k,t as A}from"./CommonDialog-BA4xg5l3.js";import{y as j}from"./index-Dh9-lDzZ.js";var M=o({__name:`BranchSelector`,emits:[`branchChanged`],setup(e,{expose:t,emit:n}){t();let a=j(),o=n,s=x(!1),c=x(``),l=_(()=>{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=x(!1),f=x(``),p=x(``);function m(){s.value=!1,p.value=a.currentBranch,d.value=!0}async function h(){await a.createBranch(f.value,p.value)&&(d.value=!1,f.value=``,o(`branchChanged`))}let v=x(!1);async function y(){if(!v.value){v.value=!0;try{await Promise.all([a.getCurrentBranch(!0),a.getBranchStatus(!0),a.getAllBranches()]),o(`branchChanged`),a.refreshLog()}finally{v.value=!1}}}let b={gitStore:a,emit:o,branchPopoverVisible:s,branchFilter:c,filteredBranches:l,selectBranch:u,createBranchDialogVisible:d,newBranchName:f,selectedBaseBranch:p,openCreateBranchDialog:m,createNewBranch:h,isRefreshingBranch:v,refreshCurrentBranch:y,get $t(){return E},get Plus(){return i},get Menu(){return g},get Check(){return S},get Refresh(){return r},CommonDialog:A,IconButton:k,SvgIcon:O};return Object.defineProperty(b,"__isScriptSetup",{enumerable:!1,value:!0}),b}}),N={key:0,class:`branch-info`},P={class:`branch-wrapper`},F={class:`branch-btn`},I={class:`branch-btn-name`},L={class:`branch-btn-caret`},R={class:`branch-popover-inner`},z={class:`branch-search`},B={class:`branch-list`},V=[`onClick`],H={key:1,class:`branch-item-check-placeholder`},U={class:`branch-item-name`},W={key:0,class:`branch-empty`},G={class:`branch-popover-footer`},K={class:`create-branch-content`},q={class:`form-label`},J={class:`form-label`},Y={class:`dialog-footer`},X={class:`footer-actions`},Z=[`disabled`];function Q(r,i,o,g,_,x){let S=u,E=c,D=b,O=y,k=n,A=a,j=t;return g.gitStore.currentBranch?(T(),w(`div`,N,[h(`div`,P,[d(` VSCode 风格分支按钮 + 弹出列表 `),e(D,{visible:g.branchPopoverVisible,"onUpdate:visible":i[1]||=e=>g.branchPopoverVisible=e,placement:`top-start`,width:260,trigger:`click`,"popper-class":`branch-popover`,"show-arrow":!1,onShow:i[2]||=e=>g.branchFilter=``},{reference:l(()=>[h(`button`,F,[e(g.SvgIcon,{"icon-class":`git-branch`,"class-name":`branch-btn-icon`}),h(`span`,I,f(g.gitStore.currentBranch),1),h(`span`,L,[e(S,null,{default:l(()=>[...i[7]||=[h(`svg`,{viewBox:`0 0 1024 1024`,xmlns:`http://www.w3.org/2000/svg`},[h(`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:l(()=>[h(`div`,R,[d(` 搜索框 `),h(`div`,z,[e(E,{modelValue:g.branchFilter,"onUpdate:modelValue":i[0]||=e=>g.branchFilter=e,placeholder:g.$t(`@F13B4:搜索或签出分支`),size:`small`,clearable:``,autofocus:``},null,8,[`modelValue`,`placeholder`])]),d(` 分支列表 `),h(`div`,B,[(T(!0),w(C,null,s(g.filteredBranches,t=>(T(),w(`div`,{key:t,class:v([`branch-item`,{"is-active":t===g.gitStore.currentBranch}]),onClick:e=>g.selectBranch(t)},[t===g.gitStore.currentBranch?(T(),m(S,{key:0,class:`branch-item-check`},{default:l(()=>[e(g.Check)]),_:1})):(T(),w(`span`,H)),e(g.SvgIcon,{"icon-class":`git-branch`,"class-name":`branch-item-icon`}),h(`span`,U,f(t),1)],10,V))),128)),g.filteredBranches.length===0?(T(),w(`div`,W,f(g.$t(`@F13B4:没有匹配的分支`)),1)):d(`v-if`,!0)]),d(` 底部:创建新分支 `),h(`div`,G,[h(`button`,{class:`branch-create-btn`,onClick:g.openCreateBranchDialog},[e(S,null,{default:l(()=>[e(g.Plus)]),_:1}),h(`span`,null,f(g.$t(`@F13B4:创建新分支`)),1)])])])]),_:1},8,[`visible`]),d(` 刷新按钮 `),e(g.IconButton,{tooltip:g.$t(`@CMDCON:刷新`),onClick:g.refreshCurrentBranch},{default:l(()=>[e(S,{class:v({"is-loading":g.isRefreshingBranch})},{default:l(()=>[e(g.Refresh)]),_:1},8,[`class`])]),_:1},8,[`tooltip`])]),d(` 创建分支对话框 `),e(g.CommonDialog,{modelValue:g.createBranchDialogVisible,"onUpdate:modelValue":i[6]||=e=>g.createBranchDialogVisible=e,title:g.$t(`@F13B4:创建新分支`),size:`small`,"destroy-on-close":!0,"append-to-body":!0,"custom-class":`create-branch-dialog`},{footer:l(()=>[h(`div`,Y,[h(`div`,X,[h(`button`,{type:`button`,class:`dialog-cancel-btn`,onClick:i[5]||=e=>g.createBranchDialogVisible=!1},f(g.$t(`@F13B4:取消`)),1),h(`button`,{type:`button`,class:`dialog-confirm-btn`,onClick:g.createNewBranch,disabled:g.gitStore.isCreatingBranch},[g.gitStore.isCreatingBranch?(T(),m(S,{key:1,class:`is-loading`},{default:l(()=>[...i[8]||=[h(`svg`,{viewBox:`0 0 1024 1024`,xmlns:`http://www.w3.org/2000/svg`},[h(`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})):(T(),m(S,{key:0},{default:l(()=>[e(g.Check)]),_:1})),h(`span`,null,f(g.$t(`@F13B4:创建`)),1)],8,Z)])])]),default:l(()=>[h(`div`,K,[e(j,{model:{newBranchName:g.newBranchName,selectedBaseBranch:g.selectedBaseBranch},"label-position":`top`},{default:l(()=>[e(O,null,{label:l(()=>[h(`div`,q,[e(S,{class:`label-icon`},{default:l(()=>[e(g.Plus)]),_:1}),h(`span`,null,f(g.$t(`@F13B4:新分支名称`)),1)])]),default:l(()=>[e(E,{modelValue:g.newBranchName,"onUpdate:modelValue":i[3]||=e=>g.newBranchName=e,placeholder:g.$t(`@F13B4:请输入新分支名称`),class:`modern-input`,size:`large`,onKeyup:p(g.createNewBranch,[`enter`])},null,8,[`modelValue`,`placeholder`])]),_:1}),e(O,null,{label:l(()=>[h(`div`,J,[e(S,{class:`label-icon`},{default:l(()=>[e(g.Menu)]),_:1}),h(`span`,null,f(g.$t(`@F13B4:基于分支`)),1)])]),default:l(()=>[e(A,{modelValue:g.selectedBaseBranch,"onUpdate:modelValue":i[4]||=e=>g.selectedBaseBranch=e,placeholder:g.$t(`@F13B4:选择基础分支`),class:`modern-select`,size:`large`,style:{width:`100%`}},{default:l(()=>[(T(!0),w(C,null,s(g.gitStore.allBranches,e=>(T(),m(k,{key:e,label:e,value:e},null,8,[`label`,`value`]))),128))]),_:1},8,[`modelValue`,`placeholder`])]),_:1})]),_:1},8,[`model`])])]),_:1},8,[`modelValue`,`title`])])):d(`v-if`,!0)}var $=D(M,[[`render`,Q],[`__scopeId`,`data-v-9548a76f`],[`__file`,`E:/workspace/github_workspace/zen-git/src/ui/client/src/components/BranchSelector.vue`]]);export{$ as default};