zen-gitsync 2.13.22 → 2.13.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/package.json +1 -1
  2. package/scripts/README_COLOR_CONVERTER.md +196 -196
  3. package/scripts/README_FONTSIZE_CONVERTER.md +278 -278
  4. package/scripts/README_SPACING_CONVERTER.md +126 -126
  5. package/scripts/README_STYLE_VARS.md +180 -180
  6. package/src/ui/public/assets/{AppVersionBadge-CS59-kD5.js → AppVersionBadge-BUS8w2f8.js} +2 -2
  7. package/src/ui/public/assets/{BranchSelector-DulCErgN.js → BranchSelector-Dm7nENer.js} +1 -1
  8. package/src/ui/public/assets/{CommandConsole-H1j4BsHx.js → CommandConsole-C1W9ZQkE.js} +2 -2
  9. package/src/ui/public/assets/{CommitForm-DIdLEAZ_.js → CommitForm-C76W1ZZH.js} +1 -1
  10. package/src/ui/public/assets/{CustomCommandManager-Cm5yU0TM.js → CustomCommandManager-JKx8JYqn.js} +1 -1
  11. package/src/ui/public/assets/{EditorView-CTvDExIi.js → EditorView-CriUYDvi.js} +0 -0
  12. package/src/ui/public/assets/{FileDiffViewer-C7Cosx8a.js → FileDiffViewer-DNWsiIGt.js} +1 -1
  13. package/src/ui/public/assets/{FlowExecutionViewer-BeGTXBVV.js → FlowExecutionViewer-CTDh2bCD.js} +1 -1
  14. package/src/ui/public/assets/{FlowOrchestrationWorkspace-CuqAZCaM.js → FlowOrchestrationWorkspace-Chah2aGN.js} +1 -1
  15. package/src/ui/public/assets/{GitStatus-DBDjyLJD.js → GitStatus-DP-DQsiS.js} +1 -1
  16. package/src/ui/public/assets/{ImagePreview-C8eIs5yL.js → ImagePreview-D8klNa6F.js} +1 -1
  17. package/src/ui/public/assets/{LogList-YCJ_gVWr.js → LogList-Z76_5USQ.js} +1 -1
  18. package/src/ui/public/assets/{ProjectStartupButton-gWSO3HCJ.js → ProjectStartupButton-C5oF4unq.js} +1 -1
  19. package/src/ui/public/assets/{RemoteRepoCard-9iWOAx2g.js → RemoteRepoCard-B-fGjb8Y.js} +1 -1
  20. package/src/ui/public/assets/{ResetToRemoteButton-BckRJ_lM.js → ResetToRemoteButton-BixSoEVs.js} +1 -1
  21. package/src/ui/public/assets/{SourceMapView-DWBowIx1.js → SourceMapView-C9HZiJ9N.js} +1 -1
  22. package/src/ui/public/assets/{TemplateManager-DiKpGMhi.js → TemplateManager-C7SuKq0f.js} +1 -1
  23. package/src/ui/public/assets/{UserInputNode-CU11vBBn.js → UserInputNode-CYy0UpzR.js} +1 -1
  24. package/src/ui/public/assets/WorkbenchView-A9Oik707.js +12 -0
  25. package/src/ui/public/assets/WorkbenchView-DvML7yIv.css +1 -0
  26. package/src/ui/public/assets/{_plugin-vue_export-helper-vLPduyLG.js → _plugin-vue_export-helper-BfbhkIv4.js} +2 -2
  27. package/src/ui/public/assets/{index-BxxqloTb.js → index-DPSGvy34.js} +3 -3
  28. package/src/ui/public/favicon.svg +75 -75
  29. package/src/ui/public/index.html +19 -19
  30. package/src/ui/public/logo.svg +74 -74
  31. package/src/ui/server/routes/workbench.js +160 -23
  32. package/src/ui/public/assets/WorkbenchView-BsVMwobR.js +0 -12
  33. package/src/ui/public/assets/WorkbenchView-DslIMLgz.css +0 -1
@@ -388,8 +388,70 @@ async function listDirTree(projectPath, maxDepth = 2, maxEntries = 400) {
388
388
  return lines.join('\n');
389
389
  }
390
390
 
391
+ // 剥离 LLM 输出的 思考块、```json``` 代码块围栏,以及首尾说明文字。
392
+ // 原贪婪正则 /({[\s\S]*})/ 会把 思考块(内含未配对花括号或字符串)一起吞进 JSON.parse,
393
+ // 在 DeepSeek 等会输出 推理链的模型上偶发 "Unterminated string in JSON"。
394
+ function stripThinkingBlocks(content) {
395
+ let s = String(content || '');
396
+ // 1) 显式 思考块(成对标签)
397
+ s = s.replace(/<think(?:ing)?>[\s\S]*?<\/think(?:ing)?>/gi, '');
398
+ // 2) 某些 provider 流式结尾会留下裸 <think>...</think> 之外的残段(无结束标签时被截断)
399
+ s = s.replace(/<think(?:ing)?>[\s\S]*$/gi, '');
400
+ // 3) ```json ... ``` 代码块围栏(保留内部 JSON)
401
+ s = s.replace(/```json\s*/gi, '').replace(/```/g, '');
402
+ return s;
403
+ }
404
+
405
+ // 在剥离 思考块 的文本里定位第一个「平衡花括号对象」的起点/终点。
406
+ // 跳过字符串内的 {/}(含转义)以及 Jinja {{ }} 模板占位符;
407
+ // 同时只在「JSON 特征显著」的 { 处起算 —— 即该 { 之后不远处出现 " 字符串。
408
+ // 这能避免把 LLM 思考文本里的裸 { ... }(如 "see { views, stores }")误当 JSON 起点。
409
+ function extractFirstJsonObject(content) {
410
+ const s = String(content || '');
411
+ let depth = 0;
412
+ let inStr = false;
413
+ let escape = false;
414
+ let start = -1;
415
+ for (let i = 0; i < s.length; i++) {
416
+ const ch = s[i];
417
+ if (inStr) {
418
+ if (escape) { escape = false; continue; }
419
+ if (ch === '\\') { escape = true; continue; }
420
+ if (ch === '"') { inStr = false; }
421
+ continue;
422
+ }
423
+ if (ch === '"') { inStr = true; continue; }
424
+ // 跳过 Jinja {{ }} 占位符(提示词模板常用,勿当 JSON)
425
+ if (ch === '{' && s[i + 1] === '{') { i++; continue; }
426
+ if (ch === '}' && s[i - 1] === '}') { continue; }
427
+ if (ch === '{') {
428
+ if (depth === 0) {
429
+ // 启发式判断「这看起来像 JSON 起点」:
430
+ // 1. { 之前紧邻「真正的语义字符」(字母/数字/中文/下划线) → 不是 JSON 起点(散文里的花括号)
431
+ // 但接受 . , ; : 等句末标点(LLM 经常以「总结:{...}」直接开头 JSON)
432
+ // 2. { 之后跳过空白第一个字符必须是 " 或 }(空对象)
433
+ const before = i > 0 ? s[i - 1] : '';
434
+ if (/[A-Za-z0-9_一-龥]/.test(before)) continue;
435
+ let j = i + 1;
436
+ while (j < s.length && /\s/.test(s[j])) j++;
437
+ const firstNonWs = s[j];
438
+ if (firstNonWs !== '"' && firstNonWs !== '}') continue;
439
+ start = i;
440
+ }
441
+ depth++;
442
+ } else if (ch === '}') {
443
+ if (depth > 0) depth--;
444
+ if (depth === 0 && start !== -1) {
445
+ return s.slice(start, i + 1);
446
+ }
447
+ }
448
+ }
449
+ // 兜底:找不到平衡对象时返回原文(让上层 JSON.parse 报清晰错误)
450
+ return s;
451
+ }
452
+
391
453
  async function callLlmJson(model, prompt, opts = {}) {
392
- const { maxTokens = 1500, timeoutMs = 60000, images = [] } = opts;
454
+ const { timeoutMs = 60000, images = [] } = opts;
393
455
  const { default: fetch } = await import('node-fetch').catch(() => ({ default: globalThis.fetch }));
394
456
  const url = `${String(model.baseURL || '').replace(/\/$/, '')}/chat/completions`;
395
457
  const headers = { 'Content-Type': 'application/json' };
@@ -410,7 +472,6 @@ async function callLlmJson(model, prompt, opts = {}) {
410
472
  const body = JSON.stringify({
411
473
  model: model.model,
412
474
  messages: [{ role: 'user', content: userContent }],
413
- max_tokens: maxTokens,
414
475
  temperature: 0.4,
415
476
  response_format: { type: 'json_object' },
416
477
  stream: false,
@@ -422,18 +483,37 @@ async function callLlmJson(model, prompt, opts = {}) {
422
483
  const resp = await fetch(url, { method: 'POST', headers, body, signal: controller.signal });
423
484
  const data = await resp.json().catch(() => ({}));
424
485
  if (!resp.ok) throw new Error(data?.error?.message || `HTTP ${resp.status}`);
425
- const content = data?.choices?.[0]?.message?.content || '{}';
486
+ const content = data?.choices?.[0]?.message?.content || '';
487
+ if (!content.trim()) {
488
+ throw new Error('LLM 返回内容为空');
489
+ }
426
490
  try {
427
- const m = content.match(/```json\s*([\s\S]*?)```/) || content.match(/({[\s\S]*})/);
428
- return JSON.parse(m ? m[1] : content);
429
- } catch {
430
- return {};
491
+ const cleaned = stripThinkingBlocks(content);
492
+ return JSON.parse(extractFirstJsonObject(cleaned));
493
+ } catch (err) {
494
+ const snippet = content.length > 500 ? content.slice(0, 500) + '…' : content;
495
+ throw new Error(`LLM 返回非 JSON 或被截断:${err.message};原始内容片段:${snippet}`);
431
496
  }
432
497
  } finally {
433
498
  clearTimeout(timer);
434
499
  }
435
500
  }
436
501
 
502
+ async function callLlmJsonWithRetry(model, prompt, opts = {}, retries = 1) {
503
+ let lastErr;
504
+ for (let i = 0; i <= retries; i++) {
505
+ try {
506
+ return await callLlmJson(model, prompt, opts);
507
+ } catch (err) {
508
+ lastErr = err;
509
+ if (i < retries) {
510
+ await new Promise(r => setTimeout(r, 800 * (i + 1)));
511
+ }
512
+ }
513
+ }
514
+ throw lastErr;
515
+ }
516
+
437
517
  /**
438
518
  * 流式调用 OpenAI 兼容 LLM。每收到一个 chunk 调 onDelta 回调。
439
519
  * onDelta 接收 { thinking?: string, content?: string },二选一。
@@ -1118,13 +1198,21 @@ async function runTaskQueue(task, repoPath, branch, opts) {
1118
1198
  const priorOutputs = fromIndex > 0
1119
1199
  ? await collectPriorOutputsUpTo(task, fromIndex)
1120
1200
  : []
1201
+ // 连续模式(默认):任意 sub 终态非 done(cancelled / error)→ 整批停,后续 sub 保持 todo。
1202
+ // AI 拆出来的 sub 一般前后强依赖(前一步产出是后一步输入),出错就停下来让用户决策。
1203
+ // 关闭后回退旧行为:单个 sub 失败不影响后续 sub 继续跑。
1204
+ const sequential = task.sequential !== false
1121
1205
  for (let i = fromIndex; i < task.subtasks.length; i++) {
1122
1206
  const sub = task.subtasks[i]
1123
1207
  if (sub.status === 'done') continue;
1124
- await runSingleSubtask(task, sub, repoPath, branch, priorOutputs)
1208
+ const outcome = await runSingleSubtask(task, sub, repoPath, branch, priorOutputs)
1125
1209
  // 逐 sub 落盘:之前只在队列跑完才 persistTaskAfterRun,中途崩溃会丢已完成
1126
1210
  // sub 的状态。runSingleSubtask 已经把 sub.status 改完,这里补一次落盘。
1127
1211
  await persistTaskAfterRun(task)
1212
+ if (sequential && outcome !== 'done') {
1213
+ // cancelled / error → 后续 sub 全部保持 todo,不再继续
1214
+ break
1215
+ }
1128
1216
  }
1129
1217
  }
1130
1218
 
@@ -1325,7 +1413,12 @@ ${prompt}`
1325
1413
  job.exitCode = 130; // 128 + SIGINT(2),约定俗成的"用户取消"退出码
1326
1414
  job.status = 'cancelled';
1327
1415
  job.error = '用户已停止执行';
1328
- // sub 不改状态——cancelled job 维度,同 task 后续 sub 仍可继续执行
1416
+ // 同步把闭包里的 sub 也置 cancelled(cancel 接口的 syncSubToCancelled 改了磁盘 task
1417
+ // 引用,但 runSingleSubtask 形参里的 sub 是另一份内存引用)。否则 finally publish sub:update
1418
+ // 会用 status='running' 覆盖掉前端已渲染的 cancelled 状态,导致 UI 反复跳回 running。
1419
+ // 同时 sequential=true 时 runTaskQueue 会看到 outcome='cancelled',break 不再跑后续 sub。
1420
+ sub.status = 'cancelled';
1421
+ if (!sub.error) sub.error = '用户已停止执行';
1329
1422
  } else {
1330
1423
  job.exitCode = 0;
1331
1424
  job.status = 'done';
@@ -1359,6 +1452,36 @@ ${prompt}`
1359
1452
  console.warn('[workbench] flushJobsSaveNow failed (job id=' + job.id + ', status=' + job.status + '):', err && err.message || err)
1360
1453
  }
1361
1454
  }
1455
+ // 把 sub 的终态返回给 runTaskQueue,用于「连续模式」判断要不要 break 整批队列
1456
+ return job.status // 'done' | 'cancelled' | 'error'
1457
+ }
1458
+
1459
+ /**
1460
+ * 把被取消的 sub 同步置 'cancelled' 并落盘。
1461
+ * cancelJob 路径专用:前端 taskIsRunning/sub.is-running 都看 sub.status,不改就会出现
1462
+ * "主任务黄点 + sub running 动效 + 右侧执行完成"三处不一致。
1463
+ *
1464
+ * 简单任务的虚拟 subId 不在 tasks.json 里(task.subtasks 是 complex 才有),所以这里
1465
+ * 找不到 sub 时静默返回;简单任务的 running 状态由 job 数组单独维护(见 taskIsRunning)。
1466
+ *
1467
+ * @returns {{ taskId: string, sub: object } | null} 找到并更新时返回新 sub,否则 null
1468
+ */
1469
+ async function syncSubToCancelled(job) {
1470
+ if (!job || !job.taskId || !job.subId) return null
1471
+ const data = await readJson(TASKS_FILE, { tasks: [] })
1472
+ const task = (data.tasks || []).find(x => x.id === job.taskId)
1473
+ if (!task || !Array.isArray(task.subtasks)) return null
1474
+ const sub = task.subtasks.find(s => s && s.id === job.subId)
1475
+ if (!sub) return null
1476
+ if (sub.status === 'cancelled') return { taskId: task.id, sub } // 已置过,幂等返回
1477
+ sub.status = 'cancelled'
1478
+ sub.error = '用户已停止执行'
1479
+ sub.errorAt = nowIso()
1480
+ task.updatedAt = nowIso()
1481
+ await writeJson(TASKS_FILE, data)
1482
+ publish('sub:update', { taskId: task.id, sub })
1483
+ publish('task:update', task)
1484
+ return { taskId: task.id, sub }
1362
1485
  }
1363
1486
 
1364
1487
  /** 把 task.subtasks 写回 tasks.json,并广播 task:update。runTaskQueue 和"单 sub 执行"共用。 */
@@ -1488,7 +1611,7 @@ export function registerWorkbenchRoutes({ app, getCurrentProjectPath, getProject
1488
1611
  }
1489
1612
 
1490
1613
  const projectName = path.basename(projectPath);
1491
- const LLM_OPTS = { maxTokens: 16000, timeoutMs: 1200000 };
1614
+ const LLM_OPTS = { timeoutMs: 1200000 };
1492
1615
 
1493
1616
  // ── 第一阶段:基于可编辑指令 + 根目录概览,生成「可复用的提示词模板」 ──
1494
1617
  const overviewBlock = subProjects.map(sp =>
@@ -1522,7 +1645,7 @@ ${subProjects.map(sp => {
1522
1645
  "template": "可复用的提示词模板,长度不限,请充分覆盖 {{task.title}} / {{task.desc}} / {{sub.title}} / {{sub.desc}} / {{repo.path}} / {{branch}} 这 6 个变量的用法与上下文"
1523
1646
  }`;
1524
1647
 
1525
- const first = await callLlmJson(model, firstPrompt, LLM_OPTS);
1648
+ const first = await callLlmJsonWithRetry(model, firstPrompt, LLM_OPTS);
1526
1649
  const templateName = String(first.name || '').trim() || `${projectName}架构说明`;
1527
1650
  const template = String(first.template || '').trim();
1528
1651
 
@@ -1553,11 +1676,15 @@ ${sp.readme || '(无)'}
1553
1676
  {
1554
1677
  "summary": "该子项目的架构说明,长度不限,模型自行决定篇幅与详尽程度,能写多详细就多详细"
1555
1678
  }`;
1556
- const r = await callLlmJson(model, subPrompt, LLM_OPTS);
1679
+ const r = await callLlmJsonWithRetry(model, subPrompt, LLM_OPTS);
1557
1680
  return { name: sp.name, root: sp.root, summary: String(r.summary || '').trim() };
1558
1681
  }
1559
1682
 
1560
- const subSummaries = await Promise.all(subProjects.map(summarizeOneSub));
1683
+ // 串行执行,避免并发触发 provider 限流(429)导致整批失败
1684
+ const subSummaries = [];
1685
+ for (const sp of subProjects) {
1686
+ subSummaries.push(await summarizeOneSub(sp));
1687
+ }
1561
1688
 
1562
1689
  // ── 第三阶段:仅多子项目时合并(单子项目直接拿它的 summary) ──
1563
1690
  let finalSummary = '';
@@ -1578,7 +1705,7 @@ ${sp.readme || '(无)'}
1578
1705
  ## 子项目说明
1579
1706
  ${subSummaries.map((s, i) => `\n### [${i + 1}] ${s.name} (${s.root})\n${s.summary || '(空)'}`).join('\n')}`;
1580
1707
 
1581
- const merged = await callLlmJson(model, mergePrompt, LLM_OPTS);
1708
+ const merged = await callLlmJsonWithRetry(model, mergePrompt, LLM_OPTS);
1582
1709
  finalSummary = String(merged.summary || '').trim()
1583
1710
  || subSummaries.map(s => `### ${s.name}\n${s.summary}`).join('\n\n');
1584
1711
  finalName = String(merged.name || '').trim() || templateName;
@@ -1588,13 +1715,9 @@ ${subSummaries.map((s, i) => `\n### [${i + 1}] ${s.name} (${s.root})\n${s.summar
1588
1715
  finalName = `${projectName}架构说明`;
1589
1716
 
1590
1717
  if (!finalSummary) {
1591
- // 兜底:仅返回模板
1592
- return res.json({
1593
- success: true,
1594
- name: finalName,
1595
- template,
1596
- result: '',
1597
- content: template
1718
+ return res.status(502).json({
1719
+ success: false,
1720
+ error: '模型返回为空,请稍后重试'
1598
1721
  });
1599
1722
  }
1600
1723
 
@@ -2276,11 +2399,14 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
2276
2399
 
2277
2400
  app.post('/api/workbench/tasks', async (req, res) => {
2278
2401
  try {
2279
- const { id, title, desc, promptId, subtasks, type: rawType, simpleOverride } = req.body || {};
2402
+ const { id, title, desc, promptId, subtasks, type: rawType, simpleOverride, sequential: rawSequential } = req.body || {};
2280
2403
  // title 非必填:允许空字符串,UI 层会用"未命名任务"占位
2281
2404
  const safeTitle = typeof title === 'string' ? title.trim() : '';
2282
2405
  // type 归一化:仅接受 'simple' | 'complex',缺省/未知一律按 complex
2283
2406
  const taskType = rawType === 'simple' ? 'simple' : 'complex';
2407
+ // sequential 归一化:仅接受 boolean,缺省/非布尔一律 true(连续模式),
2408
+ // 旧任务没字段时也是 true,保留连续默认行为
2409
+ const sequential = rawSequential === false ? false : true;
2284
2410
  const safeOverride = typeof simpleOverride === 'string' ? simpleOverride.slice(0, 8000) : '';
2285
2411
  const data = await readJson(TASKS_FILE, { tasks: [] });
2286
2412
  const tasks = data.tasks || [];
@@ -2296,6 +2422,8 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
2296
2422
  desc: desc || '',
2297
2423
  promptId: promptId || null,
2298
2424
  type: taskType,
2425
+ // 复杂任务可显式关闭连续模式;简单任务无意义,固定 true
2426
+ sequential: taskType === 'complex' ? sequential : true,
2299
2427
  simpleOverride: taskType === 'simple' ? safeOverride : '',
2300
2428
  subtasks: Array.isArray(subtasks) ? subtasks.map(s => ({
2301
2429
  id: s.id || genId(),
@@ -2329,6 +2457,8 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
2329
2457
  desc: desc || '',
2330
2458
  promptId: promptId || null,
2331
2459
  type: taskType,
2460
+ // 新建任务:简单任务固定 true,复杂任务用传入值(默认 true)
2461
+ sequential: taskType === 'complex' ? sequential : true,
2332
2462
  simpleOverride: taskType === 'simple' ? safeOverride : '',
2333
2463
  projectPath: currentProjectPath || '',
2334
2464
  subtasks: Array.isArray(subtasks) ? subtasks.map(s => ({
@@ -2530,7 +2660,11 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
2530
2660
  // - 找到正在运行的 job,调 child.kill() 终止 claude 进程
2531
2661
  // - Windows 下用 taskkill /T /F 杀进程树(claude 进程可能 fork 出子进程)
2532
2662
  // - 加入 cancelledJobs 集合,runTaskQueue 退出循环后会把 job 标为 'cancelled'
2533
- // - 只影响这一个 sub;同 task 后续 sub 仍按队列顺序继续执行
2663
+ // - 同步把 sub.status 改为 'cancelled' 并 publish sub:update,
2664
+ // 否则前端 sub 列表/任务头黄点会一直显示 running(sub.status 没动)。
2665
+ // 历史这里只改 job.status 导致 UI 误显示「执行中」。
2666
+ // - 只影响这一个 sub;同 task 后续 sub 在 sequential=false 时继续执行,
2667
+ // sequential=true 时由 runTaskQueue 自然 break(见 runSingleSubtask 的 cancelled 分支)
2534
2668
  app.post('/api/workbench/jobs/:id/cancel', (req, res) => {
2535
2669
  const job = jobs.get(req.params.id)
2536
2670
  if (!job) {
@@ -2545,6 +2679,9 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
2545
2679
  job.error = '用户已停止执行'
2546
2680
  job.endedAt = nowIso()
2547
2681
  publish('job:update', { ...job }) // 用浅拷贝避免序列化 child 引用
2682
+ // 同步把 sub 也置 cancelled,否则 taskIsRunning(sub.status==='running') 一直 true
2683
+ // → 左侧任务头黄点 + 右侧 sub 列表 running 动效都不消失
2684
+ const subInfo = syncSubToCancelled(job)
2548
2685
  // 终态:fire-and-forget 同步落盘,cancel 是显式操作,要保证不丢
2549
2686
  flushJobsSaveNow().catch(err => console.warn('[workbench] jobs save failed:', err.message))
2550
2687
  const child = job.child
@@ -1,12 +0,0 @@
1
- import"./rolldown-runtime-CMxvf4Kt.js";import{A as e,B as t,Cn as n,D as r,E as i,En as a,Et as o,F as s,Fn as c,In as l,It as u,J as d,K as f,L as p,Ln as m,Lt as h,Nn as g,Nt as _,Ot as v,Pt as y,Qn as b,R as x,Sn as S,Tt as ee,Vn as C,W as te,Wn as w,X as T,Y as ne,Yn as E,Z as re,Zn as D,_n as O,_r as ie,a as k,at as A,b as j,cn as ae,cr as M,ct as N,dn as P,dt as oe,et as F,f as se,gn as I,gt as ce,hn as L,hr as R,i as z,ir as le,it as ue,k as de,l as B,ln as fe,lt as pe,mr as V,o as me,on as he,or as ge,ot as _e,p as ve,pn as ye,pt as be,q as xe,r as Se,rt as Ce,sn as we,un as H,vn as U,vr as W,wn as G,x as K,y as q,yn as J,yt as Te,zn as Y}from"./element-plus-CJjFCgLP.js";import{r as Ee}from"./vendor-0YbzMuxw.js";import{n as X,t as Z}from"./_plugin-vue_export-helper-vLPduyLG.js";import{n as De}from"./index-BxxqloTb.js";var Oe={class:`ai-split-direct-pane`},ke={key:0,class:`ai-split-status`},Ae={key:1,class:`ai-split-status`},je={key:1},Me={key:2},Ne={key:2,class:`ai-split-status is-error`},Pe={key:3,class:`ai-split-idle`},Fe={class:`ai-split-idle__title`},Ie={class:`ai-split-idle__desc`},Le={class:`ai-split-prompt-actions`},Re={key:0,class:`ai-split-prompt-editor`},ze={class:`ai-split-prompt-editor__actions`},Be={key:1,class:`ai-split-pre`},Ve={class:`ai-split-subhead`},He={class:`ai-split-user-actions`},Ue={key:3,class:`ai-split-pre`},We={key:0,class:`ai-split-tab-count`},Ge={class:`ai-split-pre ai-split-pre--think`},Ke={key:0,class:`ai-split-tab-count`},qe={class:`ai-split-parse-error__detail`},Je={class:`ai-split-parse-error__hint`},Q={class:`ai-split-parse-error__actions`},Ye={key:1,class:`ai-split-raw-toolbar`},Xe={class:`ai-split-raw-tip`},Ze={key:0,class:`ai-split-tab-count`},Qe={key:0,class:`ai-split-empty`},$e={key:1,class:`ai-split-list`},et={class:`ai-split-list__no`},tt={class:`ai-split-list__body`},nt={class:`ai-split-list__title`},rt={class:`ai-split-list__desc`},it={key:5,class:`ai-split-footer-hint`},at={class:`ai-split-direct-footer`},ot=Z(a({__name:`AISplitDirectPane`,props:{title:{},desc:{},taskId:{},promptId:{}},emits:[`confirm`],setup(e,{emit:r}){let i=e,a=r,s=M(`idle`),c=M(`prompt`),l=M(``),f=M(``),p=M(``),m=M(``),h=M(``),g=M([]),_=M(``),v=M(``),y=M(``),b=null,x=0,ee=L(()=>p.value.length),w=L(()=>m.value.length),T=L(()=>s.value===`result`&&g.value.length>0),re=L(()=>s.value===`running`),ie=L(()=>s.value===`preview`),A=M(``),j=M(!1);function ae(){b&&=(b.abort(),null)}function N(){ae(),s.value=`idle`,c.value=`prompt`,l.value=``,f.value=``,A.value=``,p.value=``,m.value=``,h.value=``,g.value=[],_.value=``,v.value=``,y.value=``}async function oe(){if(!i.title.trim()){k.warning(X(`@WORKBENCH:请先填写任务标题`));return}N(),s.value=`preview`,c.value=`prompt`,j.value=!0;try{let e=await fetch(`/api/workbench/tasks/ai-split-preview`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({title:i.title,desc:i.desc,taskId:i.taskId||``,promptId:i.promptId||``})}).then(e=>e.json());if(!e.success){s.value=`error`,_.value=e.error||X(`@WORKBENCH:生成预览失败`);return}l.value=e.system||``,f.value=e.user||``,A.value=e.user||``}catch(e){s.value=`error`,_.value=e?.message||String(e)}finally{j.value=!1}}async function F(){if(!A.value.trim()){k.warning(X(`@WORKBENCH:提示词不能为空`));return}let e=++x;ae(),p.value=``,m.value=``,h.value=``,g.value=[],v.value=``,y.value=``,_.value=``,s.value=`running`,c.value=`thinking`,f.value=A.value,b=new AbortController;let t=b;try{let n=await fetch(`/api/workbench/tasks/ai-split-subtasks`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`text/event-stream`},body:JSON.stringify({title:i.title,desc:i.desc,taskId:i.taskId||``,promptId:i.promptId||``,customUserBlock:A.value}),signal:t.signal});if(e!==x)return;if(!n.ok||!n.body){let e=await n.text().catch(()=>``);throw Error(e||`HTTP ${n.status}`)}let r=n.body.getReader(),a=new TextDecoder(`utf-8`),o=``,u=null;for(;;){let{value:t,done:n}=await r.read();if(e!==x)return;if(n)break;o+=a.decode(t,{stream:!0});let i=o.split(`
2
- `);o=i.pop()??``;for(let e of i){let t=e.trim();if(!t.startsWith(`data:`))continue;let n=t.slice(5).trim();if(!n)continue;let r;try{r=JSON.parse(n)}catch{continue}switch(r.type){case`meta`:l.value=r.prompt?.system||l.value;break;case`thinking`:p.value+=String(r.delta||``);break;case`content`:m.value+=String(r.delta||``);break;case`done`:u=r;break;case`error`:throw Error(r.error||`AI 拆分失败`)}}}if(e!==x)return;if(!u)throw Error(X(`@WORKBENCH:AI 未返回结果`));g.value=Array.isArray(u.subtasks)?u.subtasks:[],h.value=u.raw||m.value,v.value=String(u.parseError||``),y.value=String(u.parseStage||``),p.value||=X(`@WORKBENCH:(当前模型未返回独立的思考内容,可切换到「原始结果」查看完整输出)`),s.value=`result`,c.value=g.value.length>0?`confirm`:`raw`}catch(n){if(e!==x)return;if(n?.name===`AbortError`||t.signal.aborted){s.value=`preview`,c.value=`prompt`;return}s.value=`error`,_.value=n?.message||String(n)}finally{e===x&&(b=null)}}function ce(){T.value&&a(`confirm`,g.value.slice())}function R(){A.value.trim()?F():oe()}function z(){b&&(b.abort(),b=null,k.info(X(`@WORKBENCH:已停止拆分`)))}let le=M(!1);async function ue(){if(!m.value.trim()){k.warning(X(`@WORKBENCH:原始结果为空,无法解析`));return}le.value=!0;try{let e=await fetch(`/api/workbench/tasks/parse-subtasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({raw:m.value})}).then(e=>e.json());if(!e.success){k.error(e.error||X(`@WORKBENCH:解析失败`));return}g.value=Array.isArray(e.subtasks)?e.subtasks:[],v.value=String(e.parseError||``),y.value=String(e.parseStage||``),h.value=m.value,g.value.length>0?(k.success(X(`@WORKBENCH:解析成功,已识别 {n} 个子任务`,{n:g.value.length})),c.value=`confirm`):k.warning(X(`@WORKBENCH:仍未解析到子任务,请继续修改原始结果`))}catch(e){k.error(X(`@WORKBENCH:解析失败: `)+(e?.message||e))}finally{le.value=!1}}E(()=>i.taskId,()=>{N()});let de=M(!1),B=M(``),fe=M(!1);function pe(){B.value=l.value,de.value=!0}async function me(){if(!B.value.trim()){k.warning(X(`@WORKBENCH:指令内容不能为空`));return}fe.value=!0;try{let e=await fetch(`/api/workbench/tasks/ai-subtask-instruction`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({instruction:B.value})}).then(e=>e.json());e.success?(k.success(X(`@WORKBENCH:已保存指令`)),de.value=!1,oe()):k.error(e.error||X(`@WORKBENCH:保存失败`))}catch(e){k.error(X(`@WORKBENCH:保存失败: `)+(e?.message||e))}finally{fe.value=!1}}function he(){de.value=!1}return(e,r)=>{let i=ne,a=t,h=te,y=se,b=d,x=ve;return Y(),J(`div`,Oe,[re.value?(Y(),J(`div`,ke,[G(i,{class:`is-loading`},{default:D(()=>[G(V(o))]),_:1}),I(`span`,null,W(V(X)(`@WORKBENCH:AI 正在拆分…`)),1),G(a,{size:`small`,link:``,type:`danger`,class:`ai-split-status__stop`,onClick:z},{default:D(()=>[n(W(V(X)(`@WORKBENCH:停止拆分`)),1)]),_:1})])):ie.value?(Y(),J(`div`,Ae,[j.value?(Y(),O(i,{key:0,class:`is-loading`},{default:D(()=>[G(V(o))]),_:1})):U(``,!0),j.value?(Y(),J(`span`,je,W(V(X)(`@WORKBENCH:正在生成提示词预览…`)),1)):(Y(),J(`span`,Me,W(V(X)(`@WORKBENCH:提示词已就绪,可在下方编辑后点「发送给 AI」开始拆分`)),1))])):s.value===`error`?(Y(),J(`div`,Ne,[G(i,{color:`#f56c6c`},{default:D(()=>[G(V(Ce))]),_:1}),I(`span`,null,W(_.value),1)])):s.value===`idle`?(Y(),J(`div`,Pe,[r[5]||=S(`<div class="ai-split-idle__icon" aria-hidden="true" data-v-85bcc687><svg viewBox="0 0 24 24" width="36" height="36" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" data-v-85bcc687><path d="M12 3v3" data-v-85bcc687></path><path d="M12 18v3" data-v-85bcc687></path><path d="M3 12h3" data-v-85bcc687></path><path d="M18 12h3" data-v-85bcc687></path><path d="M5.6 5.6l2.1 2.1" data-v-85bcc687></path><path d="M16.3 16.3l2.1 2.1" data-v-85bcc687></path><path d="M5.6 18.4l2.1-2.1" data-v-85bcc687></path><path d="M16.3 7.7l2.1-2.1" data-v-85bcc687></path><circle cx="12" cy="12" r="4" data-v-85bcc687></circle></svg></div>`,1),I(`div`,Fe,W(V(X)(`@WORKBENCH:准备用 AI 拆分任务`)),1),I(`div`,Ie,W(V(X)(`@WORKBENCH:点击下方按钮开始生成。生成期间可切换到「思考 / 原始结果」实时查看模型输出。`)),1),G(a,{type:`primary`,icon:V(u),onClick:oe},{default:D(()=>[n(W(V(X)(`@WORKBENCH:开始拆分`)),1)]),_:1},8,[`icon`])])):U(``,!0),s.value===`idle`?U(``,!0):(Y(),O(x,{key:4,modelValue:c.value,"onUpdate:modelValue":r[4]||=e=>c.value=e,class:`ai-split-tabs`},{default:D(()=>[G(y,{label:V(X)(`@WORKBENCH:提示词`),name:`prompt`},{default:D(()=>[I(`div`,Le,[G(a,{size:`small`,disabled:re.value,onClick:pe},{default:D(()=>[n(W(V(X)(`@WORKBENCH:编辑指令`)),1)]),_:1},8,[`disabled`])]),de.value?(Y(),J(`div`,Re,[G(h,{modelValue:B.value,"onUpdate:modelValue":r[0]||=e=>B.value=e,type:`textarea`,rows:12,placeholder:V(X)(`@WORKBENCH:指令内容`)},null,8,[`modelValue`,`placeholder`]),I(`div`,ze,[G(a,{size:`small`,onClick:he},{default:D(()=>[n(W(V(X)(`@WORKBENCH:取消`)),1)]),_:1}),G(a,{size:`small`,type:`primary`,loading:fe.value,onClick:me},{default:D(()=>[n(W(V(X)(`@WORKBENCH:保存并重跑`)),1)]),_:1},8,[`loading`])])])):(Y(),J(`pre`,Be,W(l.value||`(等待 LLM 启动…)`),1)),I(`h4`,Ve,W(V(X)(`@WORKBENCH:用户提示词(拼装后)`)),1),ie.value?(Y(),J(P,{key:2},[G(h,{modelValue:A.value,"onUpdate:modelValue":r[1]||=e=>A.value=e,type:`textarea`,rows:16,placeholder:V(X)(`@WORKBENCH:正在生成预览…`),readonly:j.value,class:`ai-split-user-editor`,resize:`none`},null,8,[`modelValue`,`placeholder`,`readonly`]),I(`div`,He,[G(a,{size:`small`,disabled:j.value,onClick:N},{default:D(()=>[n(W(V(X)(`@WORKBENCH:取消`)),1)]),_:1},8,[`disabled`]),G(a,{type:`primary`,icon:V(u),disabled:j.value||!A.value.trim(),onClick:F},{default:D(()=>[n(W(V(X)(`@WORKBENCH:发送给 AI`)),1)]),_:1},8,[`icon`,`disabled`])])],64)):(Y(),J(`pre`,Ue,W(f.value||`(等待 LLM 启动…)`),1))]),_:1},8,[`label`]),G(y,{name:`thinking`},{label:D(()=>[I(`span`,null,[n(W(V(X)(`@WORKBENCH:思考`))+` `,1),ee.value>0?(Y(),J(`span`,We,`(`+W(ee.value)+`)`,1)):U(``,!0)])]),default:D(()=>[I(`pre`,Ge,W(p.value||V(X)(`@WORKBENCH:(暂无输出)`)),1)]),_:1}),G(y,{name:`raw`},{label:D(()=>[I(`span`,null,[n(W(V(X)(`@WORKBENCH:原始结果`))+` `,1),w.value>0?(Y(),J(`span`,Ke,`(`+W(w.value)+`)`,1)):U(``,!0)])]),default:D(()=>[v.value&&s.value===`result`?(Y(),O(b,{key:0,type:`warning`,"show-icon":``,closable:!1,class:`ai-split-parse-error`},{title:D(()=>[n(W(V(X)(`@WORKBENCH:模型返回内容解析失败,无法识别为有效的子任务 JSON`)),1)]),default:D(()=>[I(`div`,qe,W(v.value),1),I(`div`,Je,W(V(X)(`@WORKBENCH:常见原因:desc 内夹杂了 ASCII 双引号、出现尾随逗号,或输出被截断。可在下方文本框中手动修改后点「重新解析」,或重新生成。`)),1),I(`div`,Q,[G(a,{size:`small`,type:`primary`,loading:le.value,onClick:ue},{default:D(()=>[n(W(V(X)(`@WORKBENCH:重新解析`)),1)]),_:1},8,[`loading`]),G(a,{size:`small`,onClick:R},{default:D(()=>[n(W(V(X)(`@WORKBENCH:重新生成`)),1)]),_:1}),G(a,{size:`small`,onClick:r[2]||=e=>c.value=`prompt`},{default:D(()=>[n(W(V(X)(`@WORKBENCH:去编辑指令`)),1)]),_:1})])]),_:1})):U(``,!0),s.value===`result`||m.value?(Y(),J(`div`,Ye,[I(`span`,Xe,W(V(X)(`@WORKBENCH:可直接编辑下方文本,修正后点「重新解析」即可入库`)),1),G(a,{size:`small`,type:`primary`,loading:le.value,disabled:!m.value.trim(),onClick:ue},{default:D(()=>[n(W(V(X)(`@WORKBENCH:重新解析`)),1)]),_:1},8,[`loading`,`disabled`])])):U(``,!0),G(h,{modelValue:m.value,"onUpdate:modelValue":r[3]||=e=>m.value=e,type:`textarea`,rows:14,placeholder:V(X)(`@WORKBENCH:(暂无输出)`),readonly:re.value,class:`ai-split-raw-editor`,resize:`none`},null,8,[`modelValue`,`placeholder`,`readonly`])]),_:1}),G(y,{name:`confirm`,disabled:g.value.length===0},{label:D(()=>[I(`span`,null,[n(W(V(X)(`@WORKBENCH:确认入库`))+` `,1),g.value.length>0?(Y(),J(`span`,Ze,`(`+W(g.value.length)+`)`,1)):U(``,!0)])]),default:D(()=>[g.value.length===0?(Y(),J(`div`,Qe,W(V(X)(`@WORKBENCH:(暂无子任务)`)),1)):(Y(),J(`ul`,$e,[(Y(!0),J(P,null,C(g.value,(e,t)=>(Y(),J(`li`,{key:t,class:`ai-split-list__item`},[I(`div`,et,W(t+1),1),I(`div`,tt,[I(`div`,nt,W(e.title),1),I(`div`,rt,W(e.desc),1)])]))),128))]))]),_:1},8,[`disabled`])]),_:1},8,[`modelValue`])),v.value&&s.value===`result`&&g.value.length===0?(Y(),J(`div`,it,[G(i,{color:`#e6a23c`},{default:D(()=>[G(V(Ce))]),_:1}),I(`span`,null,W(V(X)(`@WORKBENCH:解析失败,未能从模型输出中提取出子任务 — 请查看「原始结果」`)),1)])):U(``,!0),I(`div`,at,[s.value===`error`||s.value===`result`&&v.value&&g.value.length===0?(Y(),O(a,{key:0,onClick:R},{default:D(()=>[n(W(V(X)(`@WORKBENCH:重新生成`)),1)]),_:1})):U(``,!0),s.value===`result`&&g.value.length>0?(Y(),O(a,{key:1,onClick:R},{default:D(()=>[n(W(V(X)(`@WORKBENCH:重新拆分`)),1)]),_:1})):U(``,!0),G(a,{type:`primary`,disabled:!T.value,onClick:ce},{default:D(()=>[n(W(V(X)(`@WORKBENCH:确认入库`))+` (`+W(g.value.length)+`) `,1)]),_:1},8,[`disabled`])])])}}}),[[`__scopeId`,`data-v-85bcc687`]]),st={class:`ai-chat-pane`},ct={key:0,class:`ai-chat-streaming-banner`},lt={key:1,class:`ai-chat-empty`},ut={class:`ai-chat-empty__title`},dt={class:`ai-chat-empty__desc`},ft={key:0,class:`ai-chat-bubble user`},pt={class:`ai-chat-content`},mt={key:1,class:`ai-chat-bubble assistant`},ht={class:`ai-chat-pre ai-chat-pre--think`},gt={key:1,class:`ai-chat-content-text`},_t={key:2,class:`ai-chat-subtasks`},vt={class:`ai-chat-subtasks__head`},yt={class:`ai-chat-subtasks__count`},bt={class:`ai-chat-list`},xt={class:`ai-chat-list__no`},St={class:`ai-chat-list__body`},Ct={class:`ai-chat-list__title`},wt={class:`ai-chat-list__desc`},Tt={class:`ai-chat-parse-error__detail`},Et={class:`ai-chat-pre`},Dt={key:5,class:`ai-chat-turn__actions`},Ot={class:`ai-chat-input`},kt={class:`ai-chat-input__actions`},At={key:0,class:`ai-chat-history__loading`},jt={key:1,class:`ai-chat-history__empty`},Mt={key:2,class:`ai-chat-history__list`},Nt={class:`ai-chat-history__title`},Pt={class:`ai-chat-history__meta`},Ft={class:`ai-chat-history__actions`},It=Z(a({__name:`AISplitChatPane`,props:{title:{},desc:{},taskId:{},promptId:{},initialSessionId:{}},emits:[`confirm`],setup(r,{emit:a}){let s=r,c=a,l=M(`idle`),d=M(``),f=M([]),p=M(``),m=M(``),_=null,v=0,y=M(null),b=L(()=>l.value===`streaming`),x=L(()=>{if(!b.value)return``;let e=[...f.value].reverse().find(e=>e.role===`assistant`);return e?e.content?X(`@WORKBENCH:AI 正在输出…`):e.thinking?X(`@WORKBENCH:AI 正在思考… (已思考 {n} 字)`,{n:e.thinking.length}):X(`@WORKBENCH:AI 正在思考…`):X(`@WORKBENCH:AI 正在思考…`)}),S=M(!1),ee=M(!1),w=M([]);function T(){y.value&&(y.value.scrollTop=y.value.scrollHeight)}async function E(){let e=p.value.trim();if(!e||b.value)return;if(!d.value&&!s.title.trim()){k.warning(X(`@WORKBENCH:请先填写任务标题`));return}let t=++v;_=new AbortController;let n=_,r={role:`user`,content:e};f.value.push(r),p.value=``;let i={role:`assistant`,content:``,thinking:``};f.value.push(i),l.value=`streaming`,await g(),T();try{let r=await fetch(`/api/workbench/tasks/ai-chat-split`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`text/event-stream`},body:JSON.stringify({sessionId:d.value,title:s.title,desc:s.desc,taskId:s.taskId||``,promptId:s.promptId||``,userMessage:e}),signal:n.signal});if(t!==v)return;if(!r.ok||!r.body){let e=await r.text().catch(()=>``);throw Error(e||`HTTP ${r.status}`)}let a=r.body.getReader(),o=new TextDecoder(`utf-8`),c=``,u=null,p=!1;for(;;){let{value:e,done:n}=await a.read();if(t!==v)return;if(n)break;c+=o.decode(e,{stream:!0});let r=c.split(`
3
- `);c=r.pop()??``;for(let e of r){let t=e.trim();if(!t.startsWith(`data:`))continue;let n=t.slice(5).trim();if(!n)continue;let r;try{r=JSON.parse(n)}catch{continue}switch(r.type){case`meta`:r.sessionId&&(d.value=r.sessionId);break;case`user_echo`:p=!0;break;case`thinking`:i.thinking=(i.thinking||``)+String(r.delta||``);break;case`content`:i.content+=String(r.delta||``);break;case`done`:u=r;break;case`error`:throw Error(r.error||`对话拆分失败`)}}f.value=[...f.value],await g(),T()}if(t!==v)return;if(!p&&!u)throw Error(X(`@WORKBENCH:AI 未返回结果`));u&&(i.subtasks=Array.isArray(u.subtasks)?u.subtasks:[],i.raw=String(u.raw||i.content),i.parseError=String(u.parseError||``),i.parseStage=String(u.parseStage||``)),f.value=[...f.value],await g(),T(),l.value=`idle`}catch(e){if(t!==v)return;if(e?.name===`AbortError`||n.signal.aborted){i.content=(i.content||``)+`
4
-
5
- [已停止]`,f.value=[...f.value],l.value=`idle`;return}l.value=`error`,m.value=e?.message||String(e),k.error(m.value)}finally{t===v&&(_=null)}}function re(){_&&=(_.abort(),null)}function ie(){if(b.value){k.warning(X(`@WORKBENCH:请先停止当前生成`));return}f.value=[],d.value=``,m.value=``,l.value=`idle`}function j(e){if(!e.subtasks||e.subtasks.length===0){k.warning(X(`@WORKBENCH:当前没有可应用的子任务`));return}c(`confirm`,e.subtasks.slice())}async function ae(){S.value=!0,ee.value=!0;try{let e=await fetch(`/api/workbench/tasks/ai-chat-sessions`).then(e=>e.json());if(!e.success){k.error(e.error||X(`@WORKBENCH:加载历史会话失败`));return}w.value=Array.isArray(e.sessions)?e.sessions:[]}catch(e){k.error(X(`@WORKBENCH:加载历史会话失败: `)+(e?.message||e))}finally{ee.value=!1}}async function N(e){if(S.value=!1,b.value){k.warning(X(`@WORKBENCH:请先停止当前生成`));return}try{let t=await fetch(`/api/workbench/tasks/ai-chat-sessions/${encodeURIComponent(e)}`).then(e=>e.json());if(!t.success){k.error(t.error||X(`@WORKBENCH:加载历史会话失败`));return}let n=t.session;d.value=n.sessionId;let r=(n.messages||[]).filter(e=>e.role===`user`||e.role===`assistant`).map(e=>({role:e.role,content:e.content||``,thinking:``,subtasks:void 0,raw:void 0,parseError:``,parseStage:``})),i=[...r].reverse().find(e=>e.role===`assistant`);i&&Array.isArray(n.latestSubtasks)&&(i.subtasks=n.latestSubtasks,i.raw=n.latestRaw,i.parseStage=n.latestParseStage),f.value=r,l.value=`idle`,k.success(X(`@WORKBENCH:已恢复历史会话`)),await g(),T()}catch(e){k.error(X(`@WORKBENCH:加载历史会话失败: `)+(e?.message||e))}}async function oe(e){try{await z.confirm(X(`@WORKBENCH:确认删除该会话`),X(`@WORKBENCH:删除后无法恢复`),{type:`warning`})}catch{return}try{let t=await fetch(`/api/workbench/tasks/ai-chat-sessions/${encodeURIComponent(e)}`,{method:`DELETE`}).then(e=>e.json());if(!t.success){k.error(t.error||X(`@WORKBENCH:删除失败`));return}w.value=w.value.filter(t=>t.sessionId!==e),k.success(X(`@WORKBENCH:已删除`))}catch(e){k.error(X(`@WORKBENCH:删除失败: `)+(e?.message||e))}}function se(e){if(!e)return``;try{let t=new Date(e);if(Number.isNaN(t.getTime()))return e;let n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}`}catch{return e}}function ce(e){return e?e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`:`0 B`}return s.initialSessionId&&N(s.initialSessionId),(r,a)=>{let s=ne,c=e,l=de,d=t,m=te,g=i;return Y(),J(`div`,st,[I(`div`,{ref_key:`streamEl`,ref:y,class:`ai-chat-stream`},[b.value?(Y(),J(`div`,ct,[G(s,{class:`is-loading`},{default:D(()=>[G(V(o))]),_:1}),I(`span`,null,W(x.value),1)])):U(``,!0),f.value.length===0&&!b.value?(Y(),J(`div`,lt,[G(s,{size:32,color:`#909399`},{default:D(()=>[G(V(F))]),_:1}),I(`div`,ut,W(V(X)(`@WORKBENCH:开始与 AI 对话拆分`)),1),I(`div`,dt,W(V(X)(`@WORKBENCH:输入你想让 AI 怎么拆分或调整(Enter 发送,Shift+Enter 换行)`)),1)])):U(``,!0),(Y(!0),J(P,null,C(f.value,(e,t)=>(Y(),J(`div`,{key:t,class:R([`ai-chat-turn`,`ai-chat-turn--${e.role}`])},[e.role===`user`?(Y(),J(`div`,ft,[I(`pre`,pt,W(e.content),1)])):(Y(),J(`div`,mt,[e.thinking?(Y(),O(l,{key:0,class:`ai-chat-collapse`},{default:D(()=>[G(c,{title:V(X)(`@WORKBENCH:思考过程`)+` (${e.thinking.length})`,name:`think`},{default:D(()=>[I(`pre`,ht,W(e.thinking),1)]),_:2},1032,[`title`])]),_:2},1024)):U(``,!0),e.content?(Y(),J(`div`,gt,W(e.content),1)):U(``,!0),e.subtasks&&e.subtasks.length>0?(Y(),J(`div`,_t,[I(`div`,vt,[I(`span`,yt,W(V(X)(`@WORKBENCH:识别到 {n} 个子任务`,{n:e.subtasks.length})),1)]),I(`ul`,bt,[(Y(!0),J(P,null,C(e.subtasks,(e,t)=>(Y(),J(`li`,{key:t,class:`ai-chat-list__item`},[I(`div`,xt,W(t+1),1),I(`div`,St,[I(`div`,Ct,W(e.title),1),I(`div`,wt,W(e.desc),1)])]))),128))])])):U(``,!0),e.parseError&&(!e.subtasks||e.subtasks.length===0)?(Y(),O(l,{key:3,class:`ai-chat-collapse`},{default:D(()=>[G(c,{title:V(X)(`@WORKBENCH:查看解析详情`),name:`diag`},{default:D(()=>[I(`div`,Tt,W(e.parseError),1)]),_:2},1032,[`title`])]),_:2},1024)):U(``,!0),e.raw&&e.raw!==e.content?(Y(),O(l,{key:4,class:`ai-chat-collapse`},{default:D(()=>[G(c,{title:V(X)(`@WORKBENCH:查看原始 LLM 输出`),name:`raw`},{default:D(()=>[I(`pre`,Et,W(e.raw),1)]),_:2},1032,[`title`])]),_:2},1024)):U(``,!0),e.subtasks&&e.subtasks.length>0?(Y(),J(`div`,Dt,[G(d,{type:`primary`,size:`small`,icon:V(u),onClick:t=>j(e)},{default:D(()=>[n(W(V(X)(`@WORKBENCH:应用本轮`))+` (`+W(e.subtasks.length)+`) `,1)]),_:2},1032,[`icon`,`onClick`])])):U(``,!0)]))],2))),128))],512),I(`div`,Ot,[G(m,{modelValue:p.value,"onUpdate:modelValue":a[0]||=e=>p.value=e,type:`textarea`,rows:3,disabled:b.value,placeholder:V(X)(`@WORKBENCH:输入你想让 AI 怎么拆分或调整(Enter 发送,Shift+Enter 换行)`),onKeydown:fe(H(E,[`exact`,`prevent`]),[`enter`])},null,8,[`modelValue`,`disabled`,`placeholder`,`onKeydown`]),I(`div`,kt,[b.value?(Y(),O(d,{key:0,type:`danger`,icon:V(Ce),onClick:re},{default:D(()=>[n(W(V(X)(`@WORKBENCH:停止`)),1)]),_:1},8,[`icon`])):(Y(),O(d,{key:1,type:`primary`,icon:V(u),disabled:!p.value.trim(),onClick:E},{default:D(()=>[n(W(V(X)(`@WORKBENCH:发送`)),1)]),_:1},8,[`icon`,`disabled`])),G(d,{disabled:b.value,icon:V(h),onClick:ie},{default:D(()=>[n(W(V(X)(`@WORKBENCH:清空对话`)),1)]),_:1},8,[`disabled`,`icon`]),G(d,{disabled:b.value,icon:V(A),onClick:ae},{default:D(()=>[n(W(V(X)(`@WORKBENCH:历史会话`)),1)]),_:1},8,[`disabled`,`icon`])])]),G(g,{modelValue:S.value,"onUpdate:modelValue":a[1]||=e=>S.value=e,title:V(X)(`@WORKBENCH:历史会话`),direction:`rtl`,size:`420px`},{default:D(()=>[ee.value?(Y(),J(`div`,At,[G(s,{class:`is-loading`},{default:D(()=>[G(V(o))]),_:1})])):w.value.length===0?(Y(),J(`div`,jt,W(V(X)(`@WORKBENCH:暂无历史会话`)),1)):(Y(),J(`ul`,Mt,[(Y(!0),J(P,null,C(w.value,e=>(Y(),J(`li`,{key:e.sessionId,class:`ai-chat-history__item`},[I(`div`,Nt,W(e.title||`(无标题)`),1),I(`div`,Pt,[I(`span`,null,W(se(e.updatedAt)),1),a[2]||=I(`span`,null,`·`,-1),I(`span`,null,W(e.messageCount)+` 条消息`,1),a[3]||=I(`span`,null,`·`,-1),I(`span`,null,W(e.latestSubtaskCount)+` 个子任务`,1),a[4]||=I(`span`,null,`·`,-1),I(`span`,null,W(ce(e.size)),1)]),I(`div`,Ft,[G(d,{size:`small`,type:`primary`,onClick:t=>N(e.sessionId)},{default:D(()=>[n(W(V(X)(`@WORKBENCH:恢复`)),1)]),_:1},8,[`onClick`]),G(d,{size:`small`,type:`danger`,onClick:t=>oe(e.sessionId)},{default:D(()=>[n(W(V(X)(`@WORKBENCH:删除`)),1)]),_:1},8,[`onClick`])])]))),128))]))]),_:1},8,[`modelValue`,`title`])])}}}),[[`__scopeId`,`data-v-e5b87036`]]),Lt={class:`ai-split-mode-bar`},Rt=Z(a({__name:`AISplitDialog`,props:{modelValue:{type:Boolean},title:{},desc:{},taskId:{},promptId:{}},emits:[`update:modelValue`,`confirm`],setup(e,{emit:t}){let n=e,i=t,a=M(`direct`),o=L(()=>[{label:X(`@WORKBENCH:直接拆分`),value:`direct`},{label:X(`@WORKBENCH:对话拆分`),value:`chat`}]);function s(e){i(`confirm`,e),i(`update:modelValue`,!1)}return E(()=>n.modelValue,e=>{e&&(a.value=`direct`)}),(t,n)=>{let c=B,l=r;return Y(),O(l,{"model-value":e.modelValue,"onUpdate:modelValue":n[1]||=e=>i(`update:modelValue`,e),title:V(X)(`@WORKBENCH:AI 拆分任务`),width:`800px`,"close-on-click-modal":!1,"close-on-press-escape":!0,"show-close":!0},{default:D(()=>[I(`div`,Lt,[G(c,{modelValue:a.value,"onUpdate:modelValue":n[0]||=e=>a.value=e,options:o.value,block:!1},null,8,[`modelValue`,`options`])]),a.value===`direct`?(Y(),O(ot,{key:0,title:e.title,desc:e.desc,"task-id":e.taskId,"prompt-id":e.promptId,onConfirm:s},null,8,[`title`,`desc`,`task-id`,`prompt-id`])):(Y(),O(It,{key:1,title:e.title,desc:e.desc,"task-id":e.taskId,"prompt-id":e.promptId,onConfirm:s},null,8,[`title`,`desc`,`task-id`,`prompt-id`]))]),_:1},8,[`model-value`,`title`])}}}),[[`__scopeId`,`data-v-2732cf4b`]]),zt={class:`wb-attachments__head`},Bt={class:`wb-attachments__label`},Vt={class:`wb-attachments__count`},Ht=[`disabled`],Ut={key:0,class:`wb-attachments__paste-hint`},Wt={key:1,class:`wb-attachments__list`},Gt=[`title`,`onClick`,`onContextmenu`],Kt=[`src`,`alt`],qt={key:1},Jt={class:`wb-attachment__meta`},$=[`title`],Yt=[`onClick`,`title`],Xt=Z(a({__name:`AttachmentZone`,props:{attachments:{},isImage:{type:Function},humanSize:{type:Function},isUploading:{type:Boolean},isPasteHover:{type:Boolean},maxCount:{},onPick:{type:Function},onRemove:{type:Function}},emits:[`paste`,`drop`,`dragover`,`dragenter`,`dragleave`],setup(e,{emit:t}){let r=e,i=t,a=L(()=>r.attachments.filter(e=>r.isImage(e))),o=L(()=>a.value.map(e=>`/api/workbench/attachments/${e.id}/raw`)),s=M(0),l=M(!1);function u(e){if(r.isImage(e)){let t=a.value.findIndex(t=>t.id===e.id);s.value=t>=0?t:0,l.value=!0}else window.open(`/api/workbench/attachments/${e.id}/raw`,`_blank`,`noopener`)}function d(){l.value=!1}let f=M({visible:!1,x:0,y:0,att:null}),p=M(!1);function m(e,t){if(!r.isImage(e))return;t.preventDefault();let n=window.innerWidth-180,i=window.innerHeight-120;f.value={visible:!0,x:Math.min(t.clientX,n),y:Math.min(t.clientY,i),att:e}}function h(){f.value.visible&&(f.value.visible=!1)}async function g(){let e=f.value.att;if(!(!e||p.value)){if(h(),!navigator.clipboard||typeof ClipboardItem>`u`){k({type:`warning`,message:X(`@WORKBENCH:当前浏览器不支持复制图片`)});return}p.value=!0;try{let t=await fetch(`/api/workbench/attachments/${e.id}/raw`,{credentials:`same-origin`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.blob(),r=[`image/png`,`image/jpeg`,`image/webp`,`image/gif`].includes(n.type)?n.type:`image/png`,i=new ClipboardItem({[r]:n});await navigator.clipboard.write([i]),k({type:`success`,message:X(`@WORKBENCH:图片已复制到剪贴板`),duration:1800})}catch(e){k({type:`error`,message:X(`@WORKBENCH:复制失败 {error}`,{error:e?.message||``})})}finally{p.value=!1}}}return typeof window<`u`&&(window.addEventListener(`click`,h),window.addEventListener(`scroll`,h,!0),window.addEventListener(`blur`,h)),c(()=>{typeof window>`u`||(window.removeEventListener(`click`,h),window.removeEventListener(`scroll`,h,!0),window.removeEventListener(`blur`,h))}),(t,r)=>(Y(),J(P,null,[I(`div`,{class:R([`wb-attachments`,{"is-paste-hover":e.isPasteHover}]),onPaste:r[1]||=e=>i(`paste`,e),onDrop:r[2]||=H(e=>i(`drop`,e),[`prevent`]),onDragover:r[3]||=H(e=>i(`dragover`,e),[`prevent`]),onDragenter:r[4]||=H(e=>i(`dragenter`,e),[`prevent`]),onDragleave:r[5]||=e=>i(`dragleave`,e)},[I(`div`,zt,[I(`span`,Bt,[n(W(V(X)(`@WORKBENCH:附件`))+` `,1),I(`span`,Vt,W(e.attachments.length)+` / `+W(e.maxCount),1)]),I(`button`,{class:`wb-attachments__add wb-soft-btn`,disabled:e.isUploading||e.attachments.length>=e.maxCount,onClick:r[0]||=(...t)=>e.onPick&&e.onPick(...t)},W(e.isUploading?V(X)(`@WORKBENCH:上传中…`):V(X)(`@WORKBENCH:添加附件`)),9,Ht)]),e.isPasteHover?(Y(),J(`div`,Ut,W(V(X)(`@WORKBENCH:粘贴图片以快速添加`)),1)):U(``,!0),e.attachments.length>0?(Y(),J(`ul`,Wt,[(Y(!0),J(P,null,C(e.attachments,t=>(Y(),J(`li`,{key:t.id,class:`wb-attachment`},[I(`button`,{type:`button`,class:`wb-attachment__preview`,title:V(X)(`@WORKBENCH:点击预览`),onClick:e=>u(t),onContextmenu:e=>m(t,e)},[I(`div`,{class:R([`wb-attachment__icon`,{"wb-attachment__icon--img":e.isImage(t)}])},[e.isImage(t)?(Y(),J(`img`,{key:0,src:`/api/workbench/attachments/${t.id}/raw`,alt:t.originalName,loading:`lazy`},null,8,Kt)):(Y(),J(`span`,qt,W(t.ext.toUpperCase()),1))],2),I(`div`,Jt,[I(`div`,{class:`wb-attachment__name`,title:`${t.originalName} (${e.humanSize(t.size)})`},W(t.originalName),9,$)])],40,Gt),I(`button`,{class:`wb-attachment__del`,onClick:H(n=>e.onRemove(t),[`stop`]),title:V(X)(`@WORKBENCH:删除`)},`×`,8,Yt)]))),128))])):U(``,!0)],34),(Y(),O(ye,{to:`body`},[l.value&&o.value.length>0?(Y(),O(V(K),{key:0,"url-list":o.value,"initial-index":s.value,"hide-on-click-modal":!0,onClose:d},null,8,[`url-list`,`initial-index`])):U(``,!0)])),(Y(),O(ye,{to:`body`},[f.value.visible&&f.value.att&&e.isImage(f.value.att)?(Y(),J(`ul`,{key:0,class:`wb-ctx-menu`,style:ie({top:f.value.y+`px`,left:f.value.x+`px`}),onContextmenu:r[6]||=H(()=>{},[`prevent`])},[I(`li`,{class:R([`wb-ctx-menu__item`,{"is-disabled":p.value}]),onClick:g},[r[7]||=I(`span`,{class:`wb-ctx-menu__icon`,"aria-hidden":`true`},[I(`svg`,{viewBox:`0 0 24 24`,width:`14`,height:`14`,fill:`none`,stroke:`currentColor`,"stroke-width":`1.8`,"stroke-linecap":`round`,"stroke-linejoin":`round`},[I(`rect`,{x:`9`,y:`9`,width:`11`,height:`11`,rx:`2`}),I(`path`,{d:`M5 15V5a2 2 0 0 1 2-2h10`})])],-1),I(`span`,null,W(V(X)(`@WORKBENCH:复制图片`)),1)],2)],36)):U(``,!0)]))],64))}}),[[`__scopeId`,`data-v-9e1ed466`]]),Zt=[`aria-expanded`],Qt={class:`wb-log-summary__left`},$t={key:0,class:`wb-log-summary__status wb-log-summary__status--running`},en={class:`wb-log-summary__label`},tn={key:0,class:`wb-log-summary__elapsed`},nn={key:1,class:`wb-log-summary__status wb-log-summary__status--pending`},rn={class:`wb-log-summary__label`},an={key:2,class:`wb-log-summary__status wb-log-summary__status--done`},on={key:0,class:`wb-log-summary__icon`},sn={key:1,class:`wb-log-summary__icon`},cn={class:`wb-log-summary__label`},ln={key:2,class:`wb-log-summary__elapsed`},un={key:3},dn={class:`wb-log-summary__right`},fn={class:`wb-log-summary__meta`},pn=[`title`],mn={class:`wb-log-details__body`},hn=[`open`],gn={class:`wb-log-section__summary`},_n={class:`wb-log-section__tag wb-log-section__tag--user`},vn={class:`wb-log-section__count`},yn=[`title`],bn={class:`wb-log-section__pre wb-log-section__pre--user`},xn=[`open`],Sn={class:`wb-log-section__summary`},Cn={class:`wb-log-section__tag wb-log-section__tag--think`},wn={class:`wb-log-section__count`},Tn=[`title`],En={class:`wb-log-section__pre wb-log-section__pre--think`},Dn=[`aria-expanded`,`title`],On={class:`wb-log-pre__label`},kn={class:`wb-log-pre__meta`},An=[`title`],jn=[`title`,`disabled`],Mn={key:1,class:`wb-log-pre__empty`},Nn={key:1,class:`wb-log-fullscreen__empty`},Pn=64*1024,Fn=60,In=Z(a({__name:`JobLogDetails`,props:{job:{}},setup(e){let t=e,n=M(!0);function i(){n.value=!n.value}function a(){let e=t.job.output||``;return e?e.length<=Pn?e:`${X(`@WORKBENCH:…(前文已截断)`)}\n${e.slice(-65536)}`:``}function o(){let e=t.job.thinking||``;return e?e.length<=Pn?e:`${X(`@WORKBENCH:…(前文已截断)`)}\n${e.slice(-65536)}`:``}async function s(e){try{if(navigator?.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}try{let t=document.createElement(`textarea`);t.value=e,t.style.position=`fixed`,t.style.opacity=`0`,t.style.left=`-9999px`,document.body.appendChild(t),t.select();let n=document.execCommand(`copy`);return document.body.removeChild(t),n}catch{return!1}}async function c(e){let n=t.job[e]||``;if(!n){k.warning(X(`@WORKBENCH:暂无内容可复制`));return}await s(n)?k.success(X(`@WORKBENCH:已复制到剪贴板`)):k.error(X(`@WORKBENCH:复制失败`))}async function l(){let e=[];if(t.job.prompt&&e.push(`## ${X(`@WORKBENCH:用户提示词`)}\n\n${t.job.prompt}`),t.job.thinking&&e.push(`## ${X(`@WORKBENCH:Claude 思考`)}\n\n${t.job.thinking}`),t.job.output&&e.push(`## ${X(`@WORKBENCH:模型返回`)}\n\n${t.job.output}`),!e.length){k.warning(X(`@WORKBENCH:暂无内容可复制`));return}await s(e.join(`
6
-
7
- ---
8
-
9
- `))?k.success(X(`@WORKBENCH:已复制到剪贴板`)):k.error(X(`@WORKBENCH:复制失败`))}let u=L(()=>a()),d=L(()=>t.job.status===`running`||t.job.status===`pending`),f=L(()=>{let e=t.job.status;return e===`done`||e===`error`||e===`cancelled`}),p=M(0),h=null;function _(){v(),h=setInterval(()=>{let e=u.value.length;if(e===0){p.value=0,v();return}let t=Math.max(1,Math.ceil(Fn/30));p.value<e&&(p.value=Math.min(e,p.value+t)),p.value>=e&&v()},33)}function v(){h&&=(clearInterval(h),null)}E(()=>[t.job.output?.length||0,t.job.status],([e,t])=>{t===`done`||t===`error`||t===`cancelled`?(v(),p.value=e):p.value<e&&!h&&_()},{immediate:!0}),m(()=>v());let y=L(()=>u.value.slice(0,p.value)),x=L(()=>(t.job.output||``).slice(0,p.value)),S=L(()=>p.value>=(t.job.output||``).length),ee=M(null);E(()=>t.job.status,(e,t)=>{e===`running`&&t!==`running`&&(ee.value=ee.value??Date.now())});let C=L(()=>{if(!ee.value)return``;let e=ee.value,n=t.job.endedAt?new Date(t.job.endedAt).getTime():Date.now(),r=Math.max(0,Math.floor((n-e)/1e3));return r<60?`${r}s`:`${Math.floor(r/60)}分${(r%60).toString().padStart(2,`0`)}秒`}),te=M(null),w=!1,T=M(!1);function ne(){if(w)return;if((t.job.output||``).length>0){T.value=!1;return}let e=t.job.status;e===`running`||e===`pending`?T.value=(t.job.thinking||``).length>0:T.value=!1}function re(e){let t=e.target;w=!0,T.value=t.open}E(()=>t.job.status,(e,t)=>{!(t===`running`||t===`pending`)&&(e===`running`||e===`pending`)&&(w=!1),ne()}),E(()=>(t.job.thinking||``).length,()=>ne(),{immediate:!0}),E(()=>(t.job.output||``).length,()=>ne());let ie=!1,A=M(!0);function j(e){let t=e.target;ie=!0,A.value=t.open}E(()=>t.job.status,(e,t)=>{!(t===`running`||t===`pending`)&&(e===`running`||e===`pending`)?(ie=!1,A.value=!0):ie||(A.value=!0)});let N=M(!0);function P(){N.value=!N.value}E(()=>t.job.status,(e,t)=>{!(t===`running`||t===`pending`)&&(e===`running`||e===`pending`)&&(N.value=!0)}),E(()=>(t.job.output||``).length,async()=>{n.value||N.value&&(await g(),te.value&&(te.value.scrollTop=te.value.scrollHeight))});let oe=M(!1),F=L(()=>!!(t.job.output&&t.job.output.length)),se=M(null);E(oe,async e=>{e&&(await g(),se.value&&(se.value.scrollTop=se.value.scrollHeight))}),E(()=>(t.job.output||``).length,async()=>{oe.value&&(await g(),se.value&&(se.value.scrollTop=se.value.scrollHeight))});function ce(){}return(t,a)=>{let s=r;return Y(),J(`div`,{class:R([`wb-log-details`,{"is-running":d.value,"is-pending":e.job.status===`pending`,"is-finished":f.value}])},[I(`div`,{class:`wb-log-summary`,onClick:i,role:`button`,"aria-expanded":!n.value},[I(`span`,Qt,[e.job.status===`running`?(Y(),J(`span`,$t,[I(`span`,en,W(V(X)(`@WORKBENCH:正在执行…`)),1),a[5]||=I(`span`,{class:`wb-log-dots`,"aria-hidden":`true`},[I(`span`,{class:`wb-log-dots__dot`}),I(`span`,{class:`wb-log-dots__dot`}),I(`span`,{class:`wb-log-dots__dot`})],-1),C.value?(Y(),J(`span`,tn,W(C.value),1)):U(``,!0)])):e.job.status===`pending`?(Y(),J(`span`,nn,[I(`span`,rn,W(V(X)(`@WORKBENCH:排队中…`)),1),a[6]||=I(`span`,{class:`wb-log-dots`,"aria-hidden":`true`},[I(`span`,{class:`wb-log-dots__dot`}),I(`span`,{class:`wb-log-dots__dot`}),I(`span`,{class:`wb-log-dots__dot`})],-1)])):f.value?(Y(),J(`span`,an,[e.job.status===`error`?(Y(),J(`span`,on,`✗`)):(Y(),J(`span`,sn,`✓`)),I(`span`,cn,W(e.job.status===`error`?V(X)(`@WORKBENCH:执行出错`):V(X)(`@WORKBENCH:执行完成`)),1),C.value?(Y(),J(`span`,ln,W(C.value),1)):U(``,!0)])):(Y(),J(`span`,un,W(V(X)(`@WORKBENCH:查看执行日志`)),1))]),I(`span`,dn,[I(`span`,fn,W((e.job.output||``).length)+` `+W(V(X)(`@WORKBENCH:字符`)),1),I(`button`,{type:`button`,class:`wb-log-copy`,title:V(X)(`@WORKBENCH:复制全部(含提示词与输出)`),onClick:H(l,[`stop`])},` ⧉ `+W(V(X)(`@WORKBENCH:复制全部`)),9,pn)])],8,Zt),b(I(`div`,mn,[e.job.prompt?(Y(),J(`details`,{key:0,class:`wb-log-section`,open:A.value,onToggle:j},[I(`summary`,gn,[I(`span`,_n,W(V(X)(`@WORKBENCH:用户提示词`)),1),I(`span`,vn,W((e.job.prompt||``).length)+` `+W(V(X)(`@WORKBENCH:字符`)),1),I(`button`,{type:`button`,class:`wb-log-copy wb-log-copy--sm`,title:V(X)(`@WORKBENCH:复制用户提示词`),onClick:a[0]||=H(e=>c(`prompt`),[`stop`])},` ⧉ `+W(V(X)(`@WORKBENCH:复制`)),9,yn)]),I(`pre`,bn,W(e.job.prompt),1)],40,hn)):U(``,!0),e.job.thinking?(Y(),J(`details`,{key:1,class:`wb-log-section`,open:T.value,onToggle:re},[I(`summary`,Sn,[I(`span`,Cn,W(V(X)(`@WORKBENCH:Claude 思考`)),1),I(`span`,wn,W((e.job.thinking||``).length)+` `+W(V(X)(`@WORKBENCH:字符`)),1),I(`button`,{type:`button`,class:`wb-log-copy wb-copy--sm`,title:V(X)(`@WORKBENCH:复制思考内容`),onClick:a[1]||=H(e=>c(`thinking`),[`stop`])},` ⧉ `+W(V(X)(`@WORKBENCH:复制`)),9,Tn)]),I(`pre`,En,W(o()),1)],40,xn)):U(``,!0),I(`div`,{class:`wb-log-pre__head`,role:`button`,"aria-expanded":N.value,title:N.value?V(X)(`@WORKBENCH:收起`):V(X)(`@WORKBENCH:展开`),onClick:P},[I(`span`,{class:R([`wb-log-pre__toggle-icon`,{"is-expanded":N.value}]),"aria-hidden":`true`},`▸`,2),I(`span`,On,W(V(X)(`@WORKBENCH:模型返回`)),1),I(`span`,kn,W((e.job.output||``).length)+` `+W(V(X)(`@WORKBENCH:字符`)),1),I(`button`,{type:`button`,class:`wb-log-copy wb-log-copy--sm`,title:V(X)(`@WORKBENCH:复制模型返回`),onClick:a[2]||=H(e=>c(`output`),[`stop`])},` ⧉ `+W(V(X)(`@WORKBENCH:复制`)),9,An),I(`button`,{type:`button`,class:`wb-log-copy wb-log-copy--sm`,title:V(X)(`@WORKBENCH:全屏查看模型返回`),disabled:!F.value,onClick:a[3]||=H(e=>oe.value=!0,[`stop`])},` ⛶ `+W(V(X)(`@WORKBENCH:全屏`)),9,jn)],8,Dn),b(I(`div`,{ref_key:`preRef`,ref:te,class:`wb-log-pre`},[F.value?(Y(),O(V(Ee),{key:0,content:y.value,final:S.value,typewriter:!1,class:`wb-log-pre__render`},null,8,[`content`,`final`])):(Y(),J(`div`,Mn,W(V(X)(`@WORKBENCH:(暂无输出)`)),1))],512),[[ae,N.value]]),G(s,{modelValue:oe.value,"onUpdate:modelValue":a[4]||=e=>oe.value=e,title:V(X)(`@WORKBENCH:模型返回 - 全屏查看`),fullscreen:``,"close-on-click-modal":!1,class:`wb-log-fullscreen-dialog`,onClosed:ce},{default:D(()=>[I(`div`,{ref_key:`fullscreenContainerRef`,ref:se,class:`wb-log-fullscreen`},[F.value?(Y(),O(V(Ee),{key:0,content:x.value,final:S.value,typewriter:!1,class:`wb-log-fullscreen__render`},null,8,[`content`,`final`])):(Y(),J(`div`,Nn,W(V(X)(`@WORKBENCH:(暂无输出)`)),1))],512)]),_:1},8,[`modelValue`,`title`])],512),[[ae,!n.value]])],2)}}}),[[`__scopeId`,`data-v-74f27a55`]]);function Ln(e){switch(e){case`todo`:return X(`@WORKBENCH:待执行`);case`running`:return X(`@WORKBENCH:执行中`);case`done`:return X(`@WORKBENCH:已完成`);case`error`:return X(`@WORKBENCH:出错`);case`cancelled`:return X(`@WORKBENCH:已取消`);case`pending`:return X(`@WORKBENCH:排队中`);default:return e}}function Rn(e){switch(e){case`running`:return`var(--color-primary)`;case`done`:return`#22c55e`;case`error`:return`#ef4444`;case`cancelled`:return`#9ca3af`;case`pending`:return`#f59e0b`;default:return`var(--text-tertiary)`}}var zn={class:`exec-logs`},Bn={class:`exec-logs__head`},Vn={class:`exec-logs__title-block`},Hn={class:`exec-logs__stats`},Un={class:`exec-logs__head-actions`},Wn={class:`exec-logs__config`},Gn={class:`exec-logs__config-label`},Kn={class:`exec-logs__config-field`},qn={class:`exec-logs__config-name`},Jn={class:`exec-logs__config-field`},Yn={class:`exec-logs__config-name`},Xn={class:`exec-logs__filter`},Zn={key:0,class:`exec-logs__batch-meta`},Qn={key:0,class:`exec-logs__batch`},$n={class:`exec-logs__list`},er={key:0,class:`exec-logs__empty`},tr={class:`exec-logs__empty-art`,"aria-hidden":`true`},nr={class:`exec-logs__empty-title`},rr={class:`exec-logs__empty-hint`},ir={class:`exec-card__head`},ar=[`title`],or={class:`exec-card__meta`},sr={key:0,class:`exec-card__task`},cr={key:1,class:`exec-card__time`},lr={key:2,class:`exec-card__exit`},ur=[`title`,`onClick`],dr={key:0,class:`exec-card__error`},fr={key:1,class:`exec-logs__pager`},pr=50,mr=Z(a({__name:`ExecutionLogManager`,setup(e){function r(e){return e instanceof Error?e.message:String(e)}let i=M([]),a=M(0),o=ge({count:0,sizeMB:0,byStatus:{}}),c=M(!1),u=M(new Set),d=ge({q:``,status:``,page:1}),f=M({maxCount:500,maxSizeMB:256}),m=ge({maxCount:500,maxSizeMB:256}),g=M(!1),_=[{value:`pending`,label:X(`@WORKBENCH:排队中`)},{value:`running`,label:X(`@WORKBENCH:执行中`)},{value:`done`,label:X(`@WORKBENCH:已完成`)},{value:`error`,label:X(`@WORKBENCH:出错`)},{value:`cancelled`,label:X(`@WORKBENCH:已取消`)}],v=L(()=>i.value.length>0&&i.value.every(e=>u.value.has(e.id))),y=L(()=>i.value.some(e=>u.value.has(e.id))&&!v.value);async function S(){c.value=!0;try{let e=new URLSearchParams;d.q&&e.set(`q`,d.q),d.status&&e.set(`status`,d.status),e.set(`limit`,String(pr)),e.set(`offset`,String((d.page-1)*pr));let t=await fetch(`/api/workbench/jobs/list?${e.toString()}`).then(e=>e.json());if(!t.success)throw Error(t.error||`list failed`);i.value=t.jobs,a.value=t.total,o.count=t.stats.count,o.sizeMB=t.stats.sizeMB,o.byStatus=t.stats.byStatus;let n=new Set(i.value.map(e=>e.id));for(let e of Array.from(u.value))n.has(e)||u.value.delete(e)}catch(e){k.error(X(`@WORKBENCH:加载失败`)+`: `+r(e))}finally{c.value=!1}}async function ee(){try{let e=await fetch(`/api/workbench/jobs/config`).then(e=>e.json());e.success&&(f.value=e.config,m.maxCount=e.config.maxCount,m.maxSizeMB=e.config.maxSizeMB)}catch{}}async function w(){g.value=!0;try{let e=await fetch(`/api/workbench/jobs/config`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({maxCount:m.maxCount,maxSizeMB:m.maxSizeMB})}).then(e=>e.json());if(!e.success)throw Error(e.error||`save failed`);f.value=e.config,k.success(X(`@WORKBENCH:已保存策略`)),await S()}catch(e){k.error(X(`@WORKBENCH:保存失败`)+`: `+r(e))}finally{g.value=!1}}function T(){d.page=1,S()}function E(){d.q=``,d.status=``,d.page=1,S()}function re(e,t){t?u.value.add(e):u.value.delete(e),u.value=new Set(u.value)}function O(e){if(e)for(let e of i.value)u.value.add(e.id);else for(let e of i.value)u.value.delete(e.id);u.value=new Set(u.value)}async function A(e){try{await z.confirm(X(`@WORKBENCH:确定要删除所选的 {count} 条日志吗?`,{count:1}),X(`@WORKBENCH:删除`),{type:`warning`})}catch{return}try{let t=await fetch(`/api/workbench/jobs/${e}`,{method:`DELETE`}).then(e=>e.json());if(!t.success)throw Error(t.error||`delete failed`);u.value.delete(e),u.value=new Set(u.value),await S()}catch(e){k.error(X(`@WORKBENCH:保存失败`)+`: `+r(e))}}async function ae(){let e=Array.from(u.value);if(e.length!==0){try{await z.confirm(X(`@WORKBENCH:确定要删除所选的 {count} 条日志吗?`,{count:e.length}),X(`@WORKBENCH:批量删除`),{type:`warning`})}catch{return}try{let t=await fetch(`/api/workbench/jobs/batch-delete`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({ids:e})}).then(e=>e.json());if(!t.success)throw Error(t.error||`batch delete failed`);k.success(X(`@WORKBENCH:成功删除 {count} 条`,{count:t.removed||e.length})),u.value=new Set,await S()}catch(e){k.error(X(`@WORKBENCH:保存失败`)+`: `+r(e))}}}async function N(){let e=o.count;if(e!==0){try{await z.confirm(X(`@WORKBENCH:确定要清空所有 {count} 条执行日志吗?此操作不可恢复。`,{count:e}),X(`@WORKBENCH:清空全部`),{type:`warning`,confirmButtonText:X(`@WORKBENCH:清空全部`)})}catch{return}try{let t=await fetch(`/api/workbench/jobs/clear`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({confirm:!0})}).then(e=>e.json());if(!t.success)throw Error(t.error||`clear failed`);k.success(X(`@WORKBENCH:成功删除 {count} 条`,{count:t.removed||e})),u.value=new Set,await S()}catch(e){k.error(X(`@WORKBENCH:保存失败`)+`: `+r(e))}}}function oe(e,t){if(!e)return``;let n=new Date(e).getTime(),r=t?new Date(t).getTime():Date.now(),i=Math.max(0,r-n);return i<1e3?`${i}ms`:i<6e4?`${(i/1e3).toFixed(1)}s`:i<36e5?`${Math.floor(i/6e4)}m ${Math.floor(i%6e4/1e3)}s`:`${Math.floor(i/36e5)}h ${Math.floor(i%36e5/6e4)}m`}return l(()=>{S(),ee()}),(e,r)=>{let l=t,f=j,ee=te,k=p,M=x,F=s,se=ne,ce=q,L=me;return Y(),J(`div`,zn,[I(`header`,Bn,[I(`div`,Vn,[I(`span`,Hn,W(V(X)(`@WORKBENCH:共 {count} 条,占 {size} MB`,{count:o.count,size:o.sizeMB})),1)]),I(`div`,Un,[G(l,{icon:V(h),size:`small`,loading:c.value,onClick:S},{default:D(()=>[n(W(V(X)(`@WORKBENCH:刷新`)),1)]),_:1},8,[`icon`,`loading`]),G(l,{type:`danger`,plain:``,size:`small`,disabled:o.count===0,onClick:N},{default:D(()=>[n(W(V(X)(`@WORKBENCH:清空全部`)),1)]),_:1},8,[`disabled`])])]),I(`div`,Wn,[I(`span`,Gn,W(V(X)(`@WORKBENCH:保存策略`)),1),I(`span`,Kn,[I(`span`,qn,W(V(X)(`@WORKBENCH:最大条数`)),1),G(f,{modelValue:m.maxCount,"onUpdate:modelValue":r[0]||=e=>m.maxCount=e,min:0,max:1e4,step:50,size:`small`,"controls-position":`right`,style:{width:`130px`}},null,8,[`modelValue`])]),I(`span`,Jn,[I(`span`,Yn,W(V(X)(`@WORKBENCH:最大体积 (MB)`)),1),G(f,{modelValue:m.maxSizeMB,"onUpdate:modelValue":r[1]||=e=>m.maxSizeMB=e,min:0,max:10240,step:32,size:`small`,"controls-position":`right`,style:{width:`140px`}},null,8,[`modelValue`])]),G(l,{type:`primary`,size:`small`,loading:g.value,onClick:w},{default:D(()=>[n(W(V(X)(`@WORKBENCH:保存策略`)),1)]),_:1},8,[`loading`])]),I(`div`,Xn,[G(ee,{modelValue:d.q,"onUpdate:modelValue":r[2]||=e=>d.q=e,placeholder:V(X)(`@WORKBENCH:搜索标题 / 任务`),clearable:``,size:`small`,style:{width:`240px`},onKeyup:fe(T,[`enter`]),onClear:T},null,8,[`modelValue`,`placeholder`]),G(M,{modelValue:d.status,"onUpdate:modelValue":r[3]||=e=>d.status=e,placeholder:V(X)(`@WORKBENCH:全部状态`),clearable:``,size:`small`,style:{width:`130px`},onChange:T},{default:D(()=>[(Y(),J(P,null,C(_,e=>G(k,{key:e.value,label:e.label,value:e.value},null,8,[`label`,`value`])),64))]),_:1},8,[`modelValue`,`placeholder`]),G(l,{size:`small`,onClick:E},{default:D(()=>[n(W(V(X)(`@WORKBENCH:重置`)),1)]),_:1}),r[5]||=I(`span`,{class:`exec-logs__filter-spacer`},null,-1),u.value.size>0?(Y(),J(`span`,Zn,W(V(X)(`@WORKBENCH:已选择 {count} 项`,{count:u.value.size})),1)):U(``,!0)]),u.value.size>0?(Y(),J(`div`,Qn,[G(F,{"model-value":v.value,indeterminate:y.value,onChange:O},{default:D(()=>[n(W(v.value?V(X)(`@WORKBENCH:取消全选`):V(X)(`@WORKBENCH:全选`)),1)]),_:1},8,[`model-value`,`indeterminate`]),G(l,{type:`danger`,size:`small`,onClick:ae},{default:D(()=>[n(W(V(X)(`@WORKBENCH:批量删除`)),1)]),_:1})])):U(``,!0),b((Y(),J(`div`,$n,[!c.value&&i.value.length===0?(Y(),J(`div`,er,[I(`div`,tr,[G(se,null,{default:D(()=>[G(V(be))]),_:1})]),I(`div`,nr,W(V(X)(`@WORKBENCH:暂无执行日志`)),1),I(`div`,rr,W(V(X)(`@WORKBENCH:点击「执行任务」开始一次执行,日志会出现在这里。`)),1)])):U(``,!0),(Y(!0),J(P,null,C(i.value,e=>(Y(),J(`article`,{key:e.id,class:R([`exec-card`,{"is-selected":u.value.has(e.id)}])},[I(`header`,ir,[G(F,{"model-value":u.value.has(e.id),onChange:t=>re(e.id,t)},null,8,[`model-value`,`onChange`]),I(`span`,{class:`exec-card__status`,style:ie({color:V(Rn)(e.status),borderColor:V(Rn)(e.status)})},W(V(Ln)(e.status)),5),I(`span`,{class:`exec-card__title`,title:e.title||V(X)(`@WORKBENCH:无标题`)},W(e.title||V(X)(`@WORKBENCH:无标题`)),9,ar),r[6]||=I(`span`,{class:`exec-card__spacer`},null,-1),I(`span`,or,[e.taskTitle?(Y(),J(`span`,sr,`📁 `+W(e.taskTitle),1)):U(``,!0),e.startedAt?(Y(),J(`span`,cr,`⏱ `+W(oe(e.startedAt,e.endedAt)),1)):U(``,!0),e.exitCode===null?U(``,!0):(Y(),J(`span`,lr,`exit `+W(e.exitCode),1))]),I(`button`,{type:`button`,class:`exec-card__del`,title:V(X)(`@WORKBENCH:删除`),onClick:t=>A(e.id)},`×`,8,ur)]),e.error?(Y(),J(`p`,dr,`⚠ `+W(e.error),1)):U(``,!0),G(In,{job:e},null,8,[`job`])],2))),128))])),[[L,c.value]]),a.value>pr?(Y(),J(`footer`,fr,[G(ce,{"current-page":d.page,"onUpdate:currentPage":r[4]||=e=>d.page=e,"page-size":pr,total:a.value,layout:`prev, pager, next, total`,background:``,small:``,onCurrentChange:S},null,8,[`current-page`,`total`])])):U(``,!0)])}}}),[[`__scopeId`,`data-v-174a9b87`]]),hr={class:`workbench`},gr={class:`workbench__editor-row`},_r={class:`wb-sidebar`},vr={class:`wb-section`},yr={class:`wb-section__head`},br={class:`wb-section__tag`},xr={class:`wb-section__title`},Sr={class:`wb-pill wb-section__count`},Cr=[`disabled`],wr={class:`wb-task-list`},Tr=[`aria-expanded`,`title`,`onClick`,`onKeydown`],Er=[`title`],Dr={class:`wb-pill wb-task-group__count`},Or=[`data-icon`,`onClick`],kr=[`data-icon`],Ar={class:`wb-task-item__body`},jr=[`title`],Mr={class:`wb-task-item__meta`},Nr=[`title`],Pr={class:`wb-pill wb-task-item__num`},Fr=[`title`],Ir={class:`wb-pill wb-task-item__num`},Lr=[`title`],Rr=[`title`,`aria-label`],zr=[`title`],Br=[`title`],Vr=[`onClick`,`title`,`aria-label`],Hr={key:0,class:`wb-empty wb-empty--rich`},Ur={class:`wb-empty__art`,"aria-hidden":`true`},Wr={class:`wb-empty__title`},Gr={class:`wb-empty__hint`},Kr={class:`wb-empty__cta`},qr={class:`wb-section`},Jr={class:`wb-section__head`},Yr={class:`wb-section__tag wb-section__tag--accent`},Xr={class:`wb-section__title`},Zr={class:`wb-pill wb-section__count`},Qr=[`title`,`aria-label`],$r={class:`wb-prompt-list`},ei={class:`wb-prompt-item__icon`},ti=[`onClick`,`title`],ni=[`title`],ri=[`onClick`,`title`,`aria-label`],ii={key:0,class:`wb-empty wb-empty--compact`},ai={class:`wb-split`},oi={key:0,class:`wb-placeholder`},si={class:`wb-split__header`},ci=[`placeholder`],li=[`title`],ui={key:0,class:`wb-meta-save__dot`},di={key:1,class:`wb-meta-save__check`},fi={key:2,class:`wb-meta-save__bang`},pi={key:3,class:`wb-meta-save__dot`},mi={value:null},hi=[`value`],gi=[`aria-label`],_i=[`aria-selected`],vi=[`aria-selected`],yi=[`disabled`,`title`],bi=[`title`,`aria-label`],xi=[`title`,`aria-label`],Si=[`open`],Ci={class:`wb-task-desc__summary`},wi={class:`wb-task-desc__label`},Ti={key:0,class:`wb-task-desc__tag`},Ei={key:0},Di={key:1,class:`wb-task-desc__tag-attachment`},Oi=[`placeholder`],ki={key:0,class:`wb-exec-list`},Ai={class:`wb-exec-list__header`},ji={class:`wb-exec-list__title`},Mi={class:`wb-split__sub-actions`},Ni={key:0,class:`wb-dirty-badge`},Pi={class:`wb-exec-sub-list`},Fi=[`onClick`],Ii={class:`wb-exec-sub-item__row1`},Li=[`title`],Ri={class:`wb-sub-error`},zi={class:`wb-sub-error__head`},Bi={class:`wb-sub-error__title`},Vi={key:0,class:`wb-sub-error__time`},Hi={class:`wb-sub-error__msg`},Ui={class:`wb-sub-error__actions`},Wi=[`title`],Gi=[`title`],Ki={key:2,class:`wb-exec-sub-item__dirty-dot`,title:`未保存`},qi={class:`wb-exec-sub-item__row2`},Ji={key:0,class:`wb-sub-item__pid`},Yi={class:`wb-exec-sub-item__actions`},Xi=[`title`,`onClick`],Zi=[`title`,`onClick`],Qi=[`title`,`onClick`],$i=[`title`,`disabled`,`onClick`],ea=[`title`,`disabled`,`onClick`],ta={key:0,class:`wb-empty wb-empty--rich`},na={class:`wb-empty__art`,"aria-hidden":`true`},ra={class:`wb-empty__title`},ia={class:`wb-empty__cta`},aa={class:`wb-exec-detail`},oa={key:0,class:`wb-placeholder`},sa={class:`wb-exec-detail__head`},ca=[`placeholder`],la=[`title`],ua=[`placeholder`],da={class:`wb-form-item__label wb-simple__override-summary`},fa=[`title`],pa=[`disabled`],ma=[`placeholder`],ha={key:0,class:`wb-simple__continue`},ga=[`placeholder`],_a={class:`wb-simple__continue-actions`},va={style:{display:`flex`,gap:`8px`,"align-items":`center`}},ya=`__simple`,ba=`__no_project__`,xa=`wb.collapsedGroupPaths.v1`,Sa=`wb.seenGroupPaths.v1`,Ca=`.png,.jpg,.jpeg,.gif,.webp,.bmp,.svg,.pdf,.txt,.md,.csv,.json,.log`,wa=5*1024*1024,Ta=Z(a({__name:`WorkbenchView`,setup(e){let i=M([]),a=M([]),o=M([]),s=M(!1),u=M(null),d=L(()=>a.value.find(e=>e.id===u.value)||null),p=L(()=>d.value?.type===`simple`),m=M(null),h=L(()=>!d.value||p.value||!m.value?null:d.value.subtasks.find(e=>e.id===m.value)||null),x=M(new Map),S=M({title:``,desc:``,promptId:null,simpleOverride:``});function A(){let e=new Map;if(d.value)for(let t of d.value.subtasks)e.set(t.id,{id:t.id,title:t.title,desc:t.desc,promptOverride:t.promptOverride});x.value=e,d.value?S.value={title:d.value.title,desc:d.value.desc,promptId:d.value.promptId,simpleOverride:d.value.simpleOverride||``}:S.value={title:``,desc:``,promptId:null,simpleOverride:``}}let j=L(()=>{let e=new Set;if(!d.value)return e;for(let t of d.value.subtasks){let n=x.value.get(t.id);if(!n){e.add(t.id);continue}(n.title!==t.title||n.desc!==t.desc||n.promptOverride!==t.promptOverride)&&e.add(t.id)}return e}),ae=L(()=>j.value.size>0),F=M(`idle`),se=M(0),de=null,B=L(()=>{if(!d.value)return!1;let e=d.value;return S.value.title!==e.title||S.value.desc!==e.desc||S.value.promptId!==e.promptId||S.value.simpleOverride!==(e.simpleOverride||``)});function me(){de!==null&&(clearTimeout(de),de=null)}async function ve(){if(!d.value)return!1;if(!B.value)return!0;if(F.value=`saving`,await kt(!1))return se.value=Date.now(),F.value=`saved`,setTimeout(()=>{F.value===`saved`&&Date.now()-se.value>=4e3&&(F.value=`idle`)},4e3),!0;F.value=`error`;let e=Date.now();return setTimeout(()=>{F.value===`error`&&Date.now()-e>=4e3&&(F.value=`idle`)},4e3),!1}E(()=>d.value?{id:d.value.id,title:d.value.title,desc:d.value.desc,promptId:d.value.promptId,simpleOverride:d.value.simpleOverride||``}:null,(e,t)=>{!e||!t||e.id!==t.id||(de!==null&&clearTimeout(de),de=window.setTimeout(()=>{ve()},1500))},{deep:!0}),E(u,async(e,t)=>{me(),d.value&&B.value&&await ve()}),E(u,()=>{jt.value=!1});function ye(e){try{let t=new Blob([JSON.stringify(e)],{type:`application/json`});navigator.sendBeacon?.(`/api/workbench/tasks`,t)}catch{}}function Ce(){d.value&&B.value&&ye(d.value)}let K=ge({visible:!1,editing:null,name:``,content:``,aiLoading:!1}),q=ge({visible:!1,text:``,loading:!1,saving:!1}),Ee=M(!1),Z=null,Oe=De();function ke(){Oe.setRunning(o.value.filter(e=>e.status===`running`).length)}function Ae(e){return o.value.find(t=>t.subId===e)||null}function je(e,t){if(e===`hello`){o.value=t.jobs||[],ke();return}if(e===`job:update`){let e=t,n=o.value.findIndex(t=>t.id===e.id);n>=0?o.value[n]=e:o.value.push(e),ke();return}if(e===`job:thinking-delta`||e===`job:output-delta`){let n=e===`job:thinking-delta`?`thinking`:`output`,r=t?.delta||``;if(!r)return;let i=o.value.findIndex(e=>e.id===t.id);if(i<0)return;let a=o.value[i][n]||``;o.value[i][n]=a+r;return}if(e===`sub:update`){let e=a.value.find(e=>e.id===t.taskId);if(e){let n=e.subtasks.findIndex(e=>e.id===t.sub.id);n>=0&&(e.subtasks[n]=t.sub)}}if(e===`task:update`){let e=a.value.findIndex(e=>e.id===t.id);e>=0&&(a.value[e]=t)}e===`task:error`&&k.error(t.error||X(`@WORKBENCH:执行出错`))}let Me=[{key:`image`,patterns:[/图\s*片/,/上\s*传/,/upload/i,/image/i,/screenshot/i,/截图/,/附件/,/attachment/i]},{key:`icon`,patterns:[/图\s*标/,/icon/i,/svg/i]},{key:`test`,patterns:[/测\s*试/,/test/i,/spec/i,/\bqa\b/i]},{key:`ui`,patterns:[/ui\s*优\s*化/,/样\s*式/,/style/i,/css/i,/界面/,/视\s*觉/,/design/i]}];async function Ne(e){try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(e),!0}catch{}try{let t=document.createElement(`textarea`);t.value=e,t.style.position=`fixed`,t.style.left=`-9999px`,document.body.appendChild(t),t.select();let n=document.execCommand(`copy`);return document.body.removeChild(t),n}catch{return!1}}function Pe(e){if(!e)return``;let t=new Date(e);if(Number.isNaN(t.getTime()))return``;let n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`}async function Fe(e){let t=await Ne(`[${e.title||X(`@WORKBENCH:未命名子任务`)}]\n${e.error||``}`);k[t?`success`:`error`](X(t?`@WORKBENCH:已复制错误信息`:`@WORKBENCH:复制失败`))}function Ie(e){m.value=e.id,s.value=!0}function Le(e){let t=(e||``).trim();if(!t)return`doc`;for(let e of Me)if(e.patterns.some(e=>e.test(t)))return e.key;return`doc`}let Re={icon:le(be),image:le(_),test:le(ce),ui:le(v),doc:le(be),idea:le(v)};function ze(e){return Re[Le(e.title)]}function Be(e){if(!e)return[];let t=`${e.id}${ya}`;return o.value.filter(e=>e.subId===t||e.subId.startsWith(`${t}__r`)).sort((e,t)=>{let n=e.startedAt||``,r=t.startedAt||``;return n&&r?n.localeCompare(r):n?-1:+!!r})}function Ve(e){if(!e)return null;let t=Be(e);return t.length>0?t[t.length-1]:null}function He(e){return e?e.status===`pending`||e.status===`running`?`running`:e.status===`done`?`done`:e.status===`cancelled`?`cancelled`:`error`:`idle`}function Ue(e){return Array.isArray(e.attachments)?e.attachments.length:0}function We(e){return Array.isArray(e.subtasks)?e.subtasks.length:0}function Ge(e){return Array.isArray(e.subtasks)?e.subtasks.filter(e=>e&&e.status===`done`).length:0}function Ke(e){if(Array.isArray(e.subtasks)&&e.subtasks.some(e=>e&&e.status===`running`))return!0;let t=`${e.id}__simple`,n=o.value.find(e=>e.subId===t||e.subId.startsWith(`${t}__r`));return!!(n&&(n.status===`running`||n.status===`pending`))}async function qe(){i.value=(await fetch(`/api/workbench/prompts`).then(e=>e.json()).catch(()=>({prompts:[]}))).prompts||[]}async function Je(){a.value=(await fetch(`/api/workbench/tasks`).then(e=>e.json()).catch(()=>({tasks:[]}))).tasks||[],!u.value&&a.value.length>0&&(u.value=a.value[0].id),A()}let Q=M({path:``,name:``});async function Ye(){let e=await fetch(`/api/workbench/current-project`).then(e=>e.json()).catch(()=>({}));e&&typeof e.projectPath==`string`&&(Q.value={path:e.projectPath,name:e.projectName||``})}function Xe(e){try{let t=localStorage.getItem(e);if(!t)return new Set;let n=JSON.parse(t);return new Set(Array.isArray(n)?n.filter(e=>typeof e==`string`):[])}catch{return new Set}}function Ze(e,t){try{localStorage.setItem(e,JSON.stringify(Array.from(t)))}catch{}}let Qe=M(Xe(xa)),$e=M(Xe(Sa));E(Qe,e=>Ze(xa,e),{deep:!1}),E($e,e=>Ze(Sa,e),{deep:!1});function et(e){return Qe.value.has(e)}function tt(e){Qe.value.has(e)?Qe.value.delete(e):Qe.value.add(e),Qe.value=new Set(Qe.value);let t=new Set($e.value);t.add(e),$e.value=t}let nt=L(()=>{let e=a.value,t=new Map;for(let n of e){let e=(n.projectPath||``).trim()||ba;t.has(e)||t.set(e,[]),t.get(e).push(n)}let n=Q.value.path,r=Array.from(t.keys()).sort((e,t)=>e===n?-1:t===n||e===ba?1:t===ba?-1:e.localeCompare(t));return{groups:r.map(e=>({path:e,label:e===ba?X(`@WORKBENCH:未关联项目`):e,tasks:t.get(e)})),hasMultiple:r.length>1}});function rt(e){if(!e||e===ba)return e;let t=e.split(/[\\/]/).filter(Boolean);return t.length<=1?e:t.slice(-2).join(`/`)}E(()=>nt.value.groups.map(e=>e.path),e=>{let t=Q.value.path,n=new Set(Qe.value),r=new Set($e.value),i=!1;for(let a of e)r.has(a)||(r.add(a),a!==t&&(n.add(a),i=!0));i&&(Qe.value=n),$e.value=r},{immediate:!0});async function it(){o.value=(await fetch(`/api/workbench/jobs`).then(e=>e.json()).catch(()=>({jobs:[]}))).jobs||[],ke()}async function at(e){try{let t=await fetch(`/api/workbench/jobs/by-task/${encodeURIComponent(e)}`,{method:`DELETE`}).then(e=>e.json());return t?.success?(o.value=o.value.filter(t=>t.taskId!==e),ke(),t.removed||0):(console.warn(`[clearJobsByTask] failed:`,t?.error),0)}catch(e){return console.warn(`[clearJobsByTask] error:`,e),0}}async function ot(e){try{let t=await fetch(`/api/workbench/jobs/by-task/${encodeURIComponent(e)}?keepDone=true`,{method:`DELETE`}).then(e=>e.json());if(!t?.success)return console.warn(`[clearNonDoneJobsByTask] failed:`,t?.error),0;let n=new Set(t.ids||[]);return o.value=o.value.filter(t=>!(t.taskId===e&&n.has(t.id))),ke(),t.removed||0}catch(e){return console.warn(`[clearNonDoneJobsByTask] error:`,e),0}}async function st(){if(!d.value)return;let e=d.value,t=Array.isArray(e.subtasks)?e.subtasks:[],n=t.filter(e=>e.status===`done`).length,r=t.filter(e=>e.status===`error`).length,i=t.filter(e=>e.status===`running`).length,a=o.value.filter(t=>t.taskId===e.id),s=n+r===0?X(`@WORKBENCH:当前任务还没有执行内容,确认仍要清空?`):X(`@WORKBENCH:将清空 {n} 个已执行/失败的子任务和 {m} 条执行记录,任务拆分/描述/附件保留。`,{n:n+r,m:a.length});try{await z.confirm(s,X(`@WORKBENCH:清空执行内容`),{confirmButtonText:X(`@WORKBENCH:清空`),cancelButtonText:X(`@WORKBENCH:取消`),type:`warning`})}catch{return}if(i>0){k.warning(X(`@WORKBENCH:有 {n} 个子任务正在执行,请先停止`,{n:i}));return}let c=await fetch(`/api/workbench/tasks/${encodeURIComponent(e.id)}/clear-execution`,{method:`POST`,headers:{"Content-Type":`application/json`}}).then(e=>e.json()).catch(e=>({success:!1,error:e?.message||String(e)}));if(c?.success){if(Array.isArray(e.subtasks))for(let t of e.subtasks)t.status=`todo`,t.error&&delete t.error;o.value=o.value.filter(t=>t.taskId!==e.id),ke(),k.success(c.message||X(`@WORKBENCH:已清空执行内容`))}else k.error(c?.error||X(`@WORKBENCH:清空失败`))}async function ct(){if(!d.value)return;let e=d.value,t=Array.isArray(e.subtasks)?e.subtasks.length:0;if(t===0){k.warning(X(`@WORKBENCH:当前任务没有子任务`));return}if(o.value.find(t=>t.taskId===e.id&&(t.status===`running`||t.status===`pending`))){k.warning(X(`@WORKBENCH:有子任务正在执行,请先停止`));return}try{await z.confirm(X(`@WORKBENCH:将删除 {n} 个子任务,任务描述/附件/标题保留,确认?`,{n:t}),X(`@WORKBENCH:清空子任务`),{confirmButtonText:X(`@WORKBENCH:清空`),cancelButtonText:X(`@WORKBENCH:取消`),type:`warning`})}catch{return}let n=await fetch(`/api/workbench/tasks/${encodeURIComponent(e.id)}/clear-subtasks`,{method:`POST`,headers:{"Content-Type":`application/json`}}).then(e=>e.json()).catch(e=>({success:!1,error:e?.message||String(e)}));n?.success?(e.subtasks=[],m.value=null,j.value.clear(),x.value.clear(),o.value=o.value.filter(t=>t.taskId!==e.id),ke(),k.success(n.message||X(`@WORKBENCH:已清空子任务`))):k.error(n?.error||X(`@WORKBENCH:清空失败`))}function lt(){Z&&=(Z.close(),null),Z=new EventSource(`/api/workbench/events`),Z.onmessage=e=>{try{let t=JSON.parse(e.data);je(t.event,t.payload)}catch{}},Z.onerror=()=>{Z&&=(Z.close(),null),setTimeout(lt,3e3)}}function ut(){K.editing=null,K.name=``,K.content=``,K.aiLoading=!1,K.visible=!0}function dt(e){K.editing=e,K.name=e.name,K.content=e.content,K.aiLoading=!1,K.visible=!0}async function ft(){if(!K.aiLoading){K.aiLoading=!0;try{let e=await fetch(`/api/workbench/prompts/ai-generate`,{method:`POST`}).then(e=>e.json());e.success?(K.name=e.name||K.name,K.content=e.result||``,k.success(X(`@WORKBENCH:已生成,可继续编辑`))):k.error(e.error||X(`@WORKBENCH:生成失败`))}catch(e){k.error(X(`@WORKBENCH:网络错误: `)+(e&&e.message||e))}finally{K.aiLoading=!1}}}async function pt(){q.visible=!0,q.loading=!0;try{let e=await fetch(`/api/workbench/prompts/ai-instruction`).then(e=>e.json());e.success?q.text=e.instruction||``:k.error(e.error||X(`@WORKBENCH:读取指令失败`))}catch(e){k.error(X(`@WORKBENCH:读取指令失败`)+`: `+(e&&e.message||e))}finally{q.loading=!1}}async function mt(){if(!q.text.trim()){k.warning(X(`@WORKBENCH:指令内容不能为空`));return}q.saving=!0;try{let e=await fetch(`/api/workbench/prompts/ai-instruction`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({instruction:q.text})}).then(e=>e.json());e.success?(k.success(X(`@WORKBENCH:已保存指令`)),q.visible=!1):k.error(e.error||X(`@WORKBENCH:保存失败`))}catch(e){k.error(X(`@WORKBENCH:网络错误: `)+(e&&e.message||e))}finally{q.saving=!1}}async function ht(){if(!K.name.trim()||!K.content.trim()){k.warning(X(`@WORKBENCH:名称和内容不能为空`));return}let e={id:K.editing?.id,name:K.name.trim(),content:K.content},t=await fetch(`/api/workbench/prompts`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)}).then(e=>e.json());t.success?(k.success(X(`@WORKBENCH:已保存`)),K.visible=!1,qe()):k.error(t.error||X(`@WORKBENCH:保存失败`))}async function gt(e){await z.confirm(X(`@WORKBENCH:删除提示词「{name}」?`,{name:e.name}),X(`@WORKBENCH:确认`),{type:`warning`}),await fetch(`/api/workbench/prompts/${e.id}`,{method:`DELETE`}),qe();for(let t of a.value)t.promptId===e.id&&(t.promptId=null,await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)}));Je()}let _t=M(!1),vt=M(null);async function yt(){if(_t.value)return;_t.value=!0;let e={title:``,desc:``,promptId:null,type:`simple`,simpleOverride:``,subtasks:[]};Q.value.path&&(e.projectPath=Q.value.path);try{let t=await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)}).then(e=>e.json());if(!t.success){k.error(t.error||X(`@WORKBENCH:保存失败`));return}me(),d.value&&B.value&&await ve(),await Je(),t.task?.id&&(u.value=t.task.id,A(),k.success(X(`@WORKBENCH:已新建任务`)),await g(),vt.value?.focus())}finally{_t.value=!1}}async function bt(e,t){if(e.type===t)return;let n=e.type===`complex`&&t===`simple`&&(e.subtasks?.length??0)>0;if(n)try{await z.confirm(X(`@WORKBENCH:任务「{title}」当前有 {n} 个子任务,切换为简单任务后会清空这些子任务,确认继续?`,{title:e.title,n:e.subtasks.length}),X(`@WORKBENCH:切换任务类型`),{type:`warning`,confirmButtonText:X(`@WORKBENCH:切换并清空`),cancelButtonText:X(`@WORKBENCH:取消`)})}catch{return}let r={id:e.id,title:e.title,desc:e.desc,promptId:e.promptId,type:t,simpleOverride:e.simpleOverride||``,subtasks:n?[]:e.subtasks||[]},i=await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(r)}).then(e=>e.json());if(!i.success){k.error(i.error||X(`@WORKBENCH:保存失败`));return}await Je(),k.success(X(t===`simple`?`@WORKBENCH:已切换为简单任务`:`@WORKBENCH:已切换为复杂任务`))}async function xt(e){d.value&&await bt(d.value,e)}async function St(e){await z.confirm(X(`@WORKBENCH:删除任务「{title}」及其所有子任务?`,{title:e.title}),X(`@WORKBENCH:确认`),{type:`warning`}),await fetch(`/api/workbench/tasks/${e.id}`,{method:`DELETE`}),u.value===e.id&&(u.value=null),Je()}async function Ct(e){u.value!==e.id&&(me(),d.value&&B.value&&await ve(),u.value=e.id,A())}E(()=>d.value,e=>{if(!e||e.type===`simple`){m.value=null;return}m.value=e.subtasks.find(e=>e.status===`running`)?.id||e.subtasks[0]?.id||null},{immediate:!0}),E(()=>d.value?.subtasks?.length,()=>{!d.value||p.value||(!m.value||!d.value.subtasks.find(e=>e.id===m.value))&&(m.value=d.value.subtasks[0]?.id||null)}),E(()=>d.value?.subtasks?.map(e=>({id:e.id,status:e.status}))||[],()=>{if(!d.value||p.value)return;let e=d.value.subtasks,t=e.find(e=>e.id===m.value);if(!t||t.status!==`running`){let t=e.find(e=>e.status===`running`);t&&t.id!==m.value&&(m.value=t.id)}});let wt=M(new Set);function Tt(e){return wt.value.has(e)}function Et(e,t){t?wt.value.add(e):wt.value.delete(e),wt.value=new Set(wt.value)}async function Dt(){if(!d.value)return;let e={id:`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,title:X(`@WORKBENCH:新子任务`),desc:``,status:`todo`,promptOverride:``};d.value.subtasks.push(e),Et(e.id,!0);try{await kt(!1)}finally{Et(e.id,!1)}}async function Ot(e){if(d.value){d.value.subtasks=d.value.subtasks.filter(t=>t.id!==e.id),Et(e.id,!0);try{await kt(!1)}finally{Et(e.id,!1)}}}async function kt(e){if(!d.value)return!1;let t=await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(d.value)}).then(e=>e.json());return t.success?(e&&k.success(X(`@WORKBENCH:已保存拆分`)),await Je(),!0):(k.error(t.error||X(`@WORKBENCH:保存失败`)),!1)}async function At(){await kt(!0)}let jt=M(!1);function Mt(){if(d.value){if(!(d.value.title||``).trim()){k.warning(X(`@WORKBENCH:请先填写任务标题`));return}jt.value=!0}}function Nt(e){if(d.value){for(let t of e)d.value.subtasks.push({id:`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,title:t.title,desc:t.desc||``,status:`todo`,promptOverride:``,attachments:[]});k.success(X(`@WORKBENCH:已生成 {n} 个子任务,请审阅后保存`,{n:e.length}))}}async function Pt(e){if(e.type===`simple`)return Ft(e);if(!e.subtasks||e.subtasks.length===0){k.warning(X(`@WORKBENCH:请先拆分任务`));return}if(d.value&&d.value.id===e.id){let t=a.value.find(t=>t.id===e.id);if((!t||t.title!==d.value.title||t.desc!==d.value.desc||JSON.stringify(t.subtasks)!==JSON.stringify(d.value.subtasks)||t.promptId!==d.value.promptId)&&!await kt(!1))return}let t=e.subtasks.filter(e=>e.status===`done`);if(t.length>0){let n=`close`;try{await z.confirm(X(`@WORKBENCH:该任务有 {n} 个子任务已 done,如何处理?`,{n:t.length})+`
10
-
11
- `+X(`@WORKBENCH:点"确定"将重置全部 done 为 todo,从头跑一遍(会消耗 token)`)+`
12
- `+X(`@WORKBENCH:点"取消"将保留 done 状态,只跑未完成的 sub`),X(`@WORKBENCH:检测到已完成子任务`),{confirmButtonText:X(`@WORKBENCH:重置全部并重跑`),cancelButtonText:X(`@WORKBENCH:只跑未完成`),type:`warning`,distinguishCancelAndClose:!0,showClose:!0}),n=`confirm`}catch(e){n=e===`cancel`?`cancel`:`close`}if(n===`close`)return;if(n===`confirm`){let t=await fetch(`/api/workbench/tasks/${encodeURIComponent(e.id)}/clear-execution`,{method:`POST`,headers:{"Content-Type":`application/json`}}).then(e=>e.json()).catch(e=>({success:!1,error:e?.message||String(e)}));if(!t?.success){k.error(t?.error||X(`@WORKBENCH:清空失败`));return}if(Array.isArray(e.subtasks))for(let t of e.subtasks)t.status=`todo`,t.error&&delete t.error;o.value=o.value.filter(t=>t.taskId!==e.id),ke(),k.success(t.message||X(`@WORKBENCH:已重置,准备从头执行`))}}await ot(e.id);let n=await fetch(`/api/workbench/tasks/${e.id}/run`,{method:`POST`}).then(e=>e.json());n.success?k.success(n.message||X(`@WORKBENCH:已加入执行队列`)):k.error(n.error||X(`@WORKBENCH:执行失败`))}async function Ft(e){if(d.value&&d.value.id===e.id){let t=a.value.find(t=>t.id===e.id);if((!t||t.title!==d.value.title||t.desc!==d.value.desc||t.promptId!==d.value.promptId||(t.simpleOverride||``)!==(d.value.simpleOverride||``))&&!await kt(!1))return}await at(e.id);let t=await fetch(`/api/workbench/tasks/${e.id}/run-simple`,{method:`POST`}).then(e=>e.json());t.success?k.success(t.message||X(`@WORKBENCH:已加入执行队列`)):k.error(t.error||X(`@WORKBENCH:执行失败`))}async function It(e,t){let n=Be(e).slice(-1)[0];if(!n){k.error(X(`@WORKBENCH:没有可续接的会话`));return}let r=await fetch(`/api/workbench/jobs/${n.id}/continue`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({userMessage:t})}).then(e=>e.json()).catch(e=>({success:!1,error:e?.message||String(e)}));r.success?k.success(r.message||X(`@WORKBENCH:已加入续接队列`)):k.error(r.error||X(`@WORKBENCH:续接失败`))}let Lt=ge({});async function zt(e){try{await z.confirm(X(`@WORKBENCH:退出后将清空本次对话的全部轮次,确认?`),X(`@WORKBENCH:退出执行`),{confirmButtonText:X(`@WORKBENCH:退出`),cancelButtonText:X(`@WORKBENCH:取消`),type:`warning`})}catch{return}await at(e.id),delete Lt[e.id]}async function Bt(e){let t=(Lt[e.id]||``).trim();t&&(await It(e,t),Lt[e.id]=``)}async function Vt(e){if(!d.value)return;let t=d.value,n=Ae(e.id);if(n&&(n.status===`running`||n.status===`pending`)){k.warning(X(`@WORKBENCH:该子任务正在执行中`));return}let r=a.value.find(e=>e.id===t.id);if((!r||r.title!==t.title||r.desc!==t.desc||JSON.stringify(r.subtasks)!==JSON.stringify(t.subtasks)||r.promptId!==t.promptId)&&!await kt(!1))return;let i=await fetch(`/api/workbench/subtasks/${e.id}/run`,{method:`POST`}).then(e=>e.json()).catch(e=>({success:!1,error:e?.message||String(e)}));i.success?k.success(i.message||X(`@WORKBENCH:已开始执行子任务`)):k.error(i.error||X(`@WORKBENCH:执行失败`))}function Ht(e){if(e.status===`done`)return!1;let t=Ae(e.id);return!(t&&(t.status===`running`||t.status===`pending`))}function Ut(e){if(!Ht(e)||!d.value)return!1;let t=d.value.subtasks||[],n=t.findIndex(t=>t.id===e.id);return!(n<0||n===t.length-1)}async function Wt(e){if(!d.value)return;let t=d.value,n=(t.subtasks||[]).findIndex(t=>t.id===e.id);if(n<0)return;let r=a.value.find(e=>e.id===t.id);if((!r||r.title!==t.title||r.desc!==t.desc||JSON.stringify(r.subtasks)!==JSON.stringify(t.subtasks)||r.promptId!==t.promptId)&&!await kt(!1))return;let i=await fetch(`/api/workbench/tasks/${t.id}/run-from`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({startSubIndex:n})}).then(e=>e.json()).catch(e=>({success:!1,error:e?.message||String(e)}));i.success?k.success(i.message||X(`@WORKBENCH:已从此处开始执行`)):k.error(i.error||X(`@WORKBENCH:执行失败`))}async function Gt(e){if(d.value&&!Tt(e.id)){Et(e.id,!0);try{let t=x.value.get(e.id);t&&x.value.set(e.id,{...t,status:`todo`}),e.status=`todo`,await kt(!1)}finally{Et(e.id,!1)}}}async function Kt(e){try{await z.confirm(X(`@WORKBENCH:确认停止执行?已输出的内容会保留。`),X(`@WORKBENCH:停止执行`),{confirmButtonText:X(`@WORKBENCH:停止`),cancelButtonText:X(`@WORKBENCH:取消`),type:`warning`})}catch{return}let t=await fetch(`/api/workbench/jobs/${e.id}/cancel`,{method:`POST`}).then(e=>e.json()).catch(e=>({success:!1,error:e?.message||String(e)}));t.success?k.success(X(`@WORKBENCH:已发送停止信号`)):k.error(t.error||X(`@WORKBENCH:停止失败`))}l(async()=>{await Promise.all([qe(),Je(),Ye(),it()]),lt(),window.addEventListener(`beforeunload`,Ce)}),c(()=>{Z&&=(Z.close(),null),window.removeEventListener(`beforeunload`,Ce),d.value&&B.value&&ye(d.value)});let qt=new Set([`image/png`,`image/jpeg`,`image/jpg`,`image/gif`,`image/webp`,`image/bmp`,`image/svg+xml`,`application/pdf`,`text/plain`,`text/markdown`,`text/x-markdown`,`text/csv`,`application/json`,`text/json`,`text/x-log`]),Jt=M({}),$=M(null);function Yt(e){return!!Jt.value[e]}function Zt(e,t){if(e instanceof File)return e;let n=e.type||`application/octet-stream`;return new File([e],t,{type:n})}function Qt(e){return e.kind===`task`?`task-${e.task?.id??``}`:`sub-${e.sub.id}`}function $t(e){let t=e.kind===`task`?e.task?.attachments:e.sub.attachments;return Array.isArray(t)?t:[]}function en(e,t){e.kind===`task`?e.task&&(e.task.attachments=t):e.sub.attachments=t}function tn(e){return e.kind===`task`?`/api/workbench/tasks/${e.task?.id??``}/attachments`:`/api/workbench/subtasks/${e.sub.id}/attachments`}function nn(e,t){return e.kind===`task`?`/api/workbench/tasks/${e.task?.id??``}/attachments/${t}`:`/api/workbench/subtasks/${e.sub.id}/attachments/${t}`}function rn(e,t){if(!e.clipboardData)return;let n=Array.from(e.clipboardData.items).filter(e=>e.kind===`file`&&e.type.startsWith(`image/`));if(n.length>0){e.preventDefault();for(let e of n){let n=e.getAsFile();if(!n)continue;let r=(n.type.split(`/`)[1]||`png`).replace(`jpeg`,`jpg`);on(t,Zt(n,`paste-${new Date().toISOString().replace(/[:.]/g,`-`)}.${r}`))}return}let r=Array.from(e.clipboardData.items).filter(e=>e.kind===`file`&&!e.type.startsWith(`image/`));if(r.length>0){e.preventDefault();for(let e of r){let n=e.getAsFile();n&&on(t,Zt(n,n.name||`pasted-file`))}}}function an(e,t){$.value=null,Array.from(e.dataTransfer?.files||[]).forEach(e=>on(t,e))}async function on(e,t){if(t.size>wa){k.error(`「${t.name}」${X(`@WORKBENCH:超过 5MB 限制`)}`);return}if(!qt.has(t.type)&&!t.name.match(/\.(png|jpg|jpeg|gif|webp|bmp|svg|pdf|txt|md|markdown|csv|json|log)$/i)){k.error(`${X(`@WORKBENCH:不支持的文件类型`)}(${t.name})`);return}let n=$t(e);if(n.length>=9){k.error(X(`@WORKBENCH:单个任务最多 9 个附件`));return}if(n.find(e=>e.originalName===t.name&&e.size===t.size)){k.info(`${t.name} ${X(`@WORKBENCH:已存在,已复用`)}`);return}let r=Qt(e);Jt.value[r]=!0;try{let n=await fetch(tn(e),{method:`POST`,headers:{"Content-Type":`application/octet-stream`,"X-Original-Name":t.name,"X-Mime-Type":t.type||`application/octet-stream`},body:t}).then(e=>e.json());if(n.success){let r=$t(e);r.push(n.attachment),en(e,r),k.success(`${X(`@WORKBENCH:已添加:`)}${t.name}`)}else k.error(n.error||X(`@WORKBENCH:上传失败`))}catch(e){k.error(X(`@WORKBENCH:上传失败`)+`:`+(e&&e.message||e))}finally{Jt.value[r]=!1}}async function sn(e,t){try{await z.confirm(X(`@WORKBENCH:删除附件「{name}」?`,{name:t.originalName}),X(`@WORKBENCH:确认`),{type:`warning`})}catch{return}let n=await fetch(nn(e,t.id),{method:`DELETE`}).then(e=>e.json());n.success?(en(e,$t(e).filter(e=>e.id!==t.id)),k.success(X(`@WORKBENCH:已删除`))):k.error(n.error||X(`@WORKBENCH:删除失败`))}function cn(e){let t=document.createElement(`input`);t.type=`file`,t.accept=Ca,t.multiple=!0,t.onchange=()=>{Array.from(t.files||[]).forEach(t=>on(e,t))},t.click()}let ln=new Set([`png`,`jpg`,`jpeg`,`gif`,`webp`,`bmp`,`svg`]);function un(e){return ln.has(String(e.ext||``).toLowerCase())}function dn(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`}return(e,o)=>{let c=ne,l=t,g=Se,x=r,S=te,E=xe,k=f;return Y(),J(`div`,hr,[I(`div`,gr,[I(`aside`,_r,[I(`section`,vr,[I(`header`,yr,[I(`span`,br,W(V(X)(`@WORKBENCH:任务`)),1),I(`h3`,xr,W(V(X)(`@WORKBENCH:任务列表`)),1),I(`span`,Sr,W(a.value.length),1)]),I(`button`,{class:`wb-new-btn`,disabled:_t.value,onClick:yt},[G(c,{class:`wb-new-btn__icon`},{default:D(()=>[G(V(y))]),_:1}),I(`span`,null,W(V(X)(`@WORKBENCH:新建任务`)),1),o[39]||=I(`span`,{class:`wb-new-btn__shortcut`},`N`,-1)],8,Cr),I(`ul`,wr,[(Y(!0),J(P,null,C(nt.value.groups,e=>(Y(),J(P,{key:e.path},[nt.value.hasMultiple?(Y(),J(`li`,{key:0,class:R([`wb-task-group__head`,{"is-current":e.path===Q.value.path,"is-collapsed":et(e.path)}]),role:`button`,tabindex:`0`,"aria-expanded":!et(e.path),title:et(e.path)?V(X)(`@WORKBENCH:展开`):V(X)(`@WORKBENCH:收起`),onClick:t=>tt(e.path),onKeydown:[fe(H(t=>tt(e.path),[`prevent`]),[`enter`]),fe(H(t=>tt(e.path),[`prevent`]),[`space`])]},[G(c,{class:`wb-task-group__caret`},{default:D(()=>[(Y(),O(w(et(e.path)?V(re):V(T))))]),_:2},1024),G(c,{class:`wb-task-group__icon`},{default:D(()=>[G(V(Te))]),_:1}),I(`span`,{class:`wb-task-group__name`,title:e.path===Q.value.path?Q.value.path:e.label},W(e.path===Q.value.path?Q.value.name:rt(e.label)),9,Er),I(`span`,Dr,W(e.tasks.length),1)],42,Tr)):U(``,!0),et(e.path)?U(``,!0):(Y(!0),J(P,{key:1},C(e.tasks,e=>(Y(),J(`li`,{key:e.id,class:R([`wb-task-item`,{active:e.id===u.value,"has-attachment":Ue(e)>0,"is-other-project":e.projectPath&&e.projectPath!==Q.value.path,"is-running":Ke(e)}]),"data-icon":Le(e.title),onClick:t=>Ct(e)},[I(`div`,{class:`wb-task-item__avatar`,"data-icon":Le(e.title)},[G(c,null,{default:D(()=>[(Y(),O(w(ze(e))))]),_:2},1024)],8,kr),I(`div`,Ar,[I(`div`,{class:`wb-task-item__title`,title:e.title},W(e.title||V(X)(`@WORKBENCH:未命名任务`)),9,jr),I(`div`,Mr,[We(e)>0?(Y(),J(`span`,{key:0,class:R([`wb-task-item__meta-item`,{"wb-task-item__meta-item--running":Ke(e)}]),title:V(X)(`@WORKBENCH:个子任务`)},[G(c,{class:`wb-task-item__meta-icon`},{default:D(()=>[G(V(ee))]),_:1}),I(`span`,Pr,W(Ge(e))+`/`+W(We(e)),1)],10,Nr)):U(``,!0),Ue(e)>0?(Y(),J(`span`,{key:1,class:`wb-task-item__meta-item`,title:V(X)(`@WORKBENCH:附件`)},[G(c,{class:`wb-task-item__meta-icon`},{default:D(()=>[G(V(_))]),_:1}),I(`span`,Ir,W(Ue(e)),1)],8,Fr)):U(``,!0),e.promptId?(Y(),J(`span`,{key:2,class:`wb-task-item__meta-item wb-task-item__meta-item--accent`,title:V(X)(`@WORKBENCH:已绑定预置提示词`)},[G(c,{class:`wb-task-item__meta-icon`},{default:D(()=>[G(V(v))]),_:1})],8,Lr)):U(``,!0),I(`button`,{type:`button`,class:R([`wb-task-item__meta-item wb-task-item__type-toggle`,e.type===`simple`?`wb-task-item__meta-item--simple`:`wb-task-item__meta-item--complex`]),title:e.type===`simple`?V(X)(`@WORKBENCH:简单任务 - 点击切换为复杂任务`):V(X)(`@WORKBENCH:复杂任务 - 点击切换为简单任务`),"aria-label":e.type===`simple`?V(X)(`@WORKBENCH:切换为复杂任务`):V(X)(`@WORKBENCH:切换为简单任务`)},W(e.type===`simple`?V(X)(`@WORKBENCH:简单`):V(X)(`@WORKBENCH:复杂`)),11,Rr),e.projectPath&&e.projectPath!==Q.value.path?(Y(),J(`span`,{key:3,class:`wb-task-item__meta-item wb-task-item__meta-item--project`,title:e.projectPath},W(rt(e.projectPath)),9,zr)):U(``,!0)])]),Ke(e)?(Y(),J(`span`,{key:0,class:`wb-task-item__running-dot`,title:V(X)(`@WORKBENCH:执行中`),"aria-hidden":`true`},null,8,Br)):U(``,!0),I(`button`,{class:`wb-task-item__del`,onClick:H(t=>St(e),[`stop`]),title:V(X)(`@WORKBENCH:删除`),"aria-label":V(X)(`@WORKBENCH:删除`)},[G(c,null,{default:D(()=>[G(V(_e))]),_:1})],8,Vr)],10,Or))),128))],64))),128)),a.value.length===0?(Y(),J(`li`,Hr,[I(`div`,Ur,[G(c,null,{default:D(()=>[G(V(oe))]),_:1})]),I(`div`,Wr,W(V(X)(`@WORKBENCH:暂无任务`)),1),I(`div`,Gr,W(V(X)(`@WORKBENCH:点击上方按钮新建`)),1),I(`div`,Kr,[G(l,{type:`primary`,size:`small`,icon:V(y),loading:_t.value,onClick:yt},{default:D(()=>[n(W(V(X)(`@WORKBENCH:新建任务`)),1)]),_:1},8,[`icon`,`loading`])])])):U(``,!0)])]),I(`section`,qr,[I(`header`,Jr,[I(`span`,Yr,W(V(X)(`@WORKBENCH:提示`)),1),I(`h3`,Xr,W(V(X)(`@WORKBENCH:预置提示词`)),1),I(`span`,Zr,W(i.value.length),1),I(`button`,{class:`wb-section__action`,onClick:ut,title:V(X)(`@WORKBENCH:新建提示词`),"aria-label":V(X)(`@WORKBENCH:新建提示词`)},[G(c,null,{default:D(()=>[G(V(y))]),_:1})],8,Qr)]),I(`ul`,$r,[(Y(!0),J(P,null,C(i.value,e=>(Y(),J(`li`,{key:e.id,class:`wb-prompt-item`},[I(`div`,ei,[G(c,null,{default:D(()=>[G(V(v))]),_:1})]),I(`span`,{class:`wb-prompt-item__name`,onClick:t=>dt(e),title:e.content},W(e.name),9,ti),Q.value.name?(Y(),J(`span`,{key:0,class:`wb-prompt-item__project`,title:V(X)(`@WORKBENCH:适用于当前项目`)+`:`+Q.value.path},W(Q.value.name),9,ni)):U(``,!0),I(`button`,{class:`wb-prompt-item__del`,onClick:t=>gt(e),title:V(X)(`@WORKBENCH:删除`),"aria-label":V(X)(`@WORKBENCH:删除`)},[G(c,null,{default:D(()=>[G(V(_e))]),_:1})],8,ri)]))),128)),i.value.length===0?(Y(),J(`li`,ii,W(V(X)(`@WORKBENCH:暂无提示词`)),1)):U(``,!0)])])]),I(`section`,ai,[d.value?(Y(),J(P,{key:1},[I(`div`,si,[b(I(`input`,{ref_key:`titleInputRef`,ref:vt,class:`wb-input wb-input--title`,"onUpdate:modelValue":o[0]||=e=>d.value.title=e,placeholder:V(X)(`@WORKBENCH:任务标题`)},null,8,ci),[[we,d.value.title]]),F.value!==`idle`||B.value?(Y(),J(`span`,{key:0,class:R([`wb-meta-save`,{"is-saving":F.value===`saving`,"is-saved":F.value===`saved`,"is-error":F.value===`error`,"is-dirty":B.value&&F.value===`idle`}]),title:F.value===`saving`?V(X)(`@WORKBENCH:保存中…`):F.value===`error`?V(X)(`@WORKBENCH:保存失败`):F.value===`saved`?V(X)(`@WORKBENCH:已保存`):``},[F.value===`saving`?(Y(),J(`span`,ui)):F.value===`saved`?(Y(),J(`span`,di,`✓`)):F.value===`error`?(Y(),J(`span`,fi,`!`)):(Y(),J(`span`,pi)),n(` `+W(F.value===`saving`?V(X)(`@WORKBENCH:保存中…`):F.value===`saved`?V(X)(`@WORKBENCH:已保存`):F.value===`error`?V(X)(`@WORKBENCH:保存失败`):V(X)(`@WORKBENCH:有未保存的更改`)),1)],10,li)):U(``,!0),b(I(`select`,{class:`wb-select`,"onUpdate:modelValue":o[1]||=e=>d.value.promptId=e},[I(`option`,mi,W(V(X)(`@WORKBENCH:不绑定预置提示词`)),1),(Y(!0),J(P,null,C(i.value,e=>(Y(),J(`option`,{key:e.id,value:e.id},W(e.name),9,hi))),128))],512),[[he,d.value.promptId]]),I(`div`,{class:`wb-mode-switch`,role:`tablist`,"aria-label":V(X)(`@WORKBENCH:任务类型`)},[I(`button`,{type:`button`,role:`tab`,class:R([`wb-mode-switch__btn`,{"is-active":!p.value}]),"aria-selected":!p.value,onClick:o[2]||=e=>xt(`complex`)},W(V(X)(`@WORKBENCH:复杂`)),11,_i),I(`button`,{type:`button`,role:`tab`,class:R([`wb-mode-switch__btn`,{"is-active":p.value}]),"aria-selected":p.value,onClick:o[3]||=e=>xt(`simple`)},W(V(X)(`@WORKBENCH:简单`)),11,vi),I(`span`,{class:R([`wb-mode-switch__indicator`,{"is-right":p.value}]),"aria-hidden":`true`},null,2)],8,gi),p.value?U(``,!0):(Y(),J(`button`,{key:1,type:`button`,class:`wb-ai-split-btn`,disabled:!d.value.title||!d.value.title.trim(),title:V(X)(`@WORKBENCH:AI 拆分`),onClick:Mt},[o[40]||=I(`svg`,{class:`wb-ai-split-btn__icon`,viewBox:`0 0 16 16`,width:`14`,height:`14`,"aria-hidden":`true`},[I(`path`,{d:`M8 1.5l1.6 3.4 3.4 1.6-3.4 1.6L8 11.5 6.4 8.1 3 6.5l3.4-1.6L8 1.5zM2.5 9.5l.8 1.6 1.6.8-1.6.8-.8 1.6-.8-1.6L.1 11.9l1.6-.8.8-1.6zm11 0l.8 1.6 1.6.8-1.6.8-.8 1.6-.8-1.6-1.6-.8 1.6-.8.8-1.6z`,fill:`currentColor`})],-1),I(`span`,null,W(V(X)(`@WORKBENCH:AI 拆分`)),1)],8,yi)),G(l,{type:`primary`,loading:!1,onClick:o[4]||=e=>Pt(d.value)},{default:D(()=>[n(W(p.value?V(X)(`@WORKBENCH:执行`):V(X)(`@WORKBENCH:执行任务`)),1)]),_:1}),I(`button`,{type:`button`,class:`wb-logs-inline-btn wb-logs-inline-btn--danger`,title:V(X)(`@WORKBENCH:清空当前任务的所有执行内容`),"aria-label":V(X)(`@WORKBENCH:清空当前任务的所有执行内容`),onClick:st},[G(c,{class:`wb-logs-inline-btn__icon`},{default:D(()=>[G(V(pe))]),_:1}),I(`span`,null,W(V(X)(`@WORKBENCH:清空执行`)),1)],8,bi),I(`button`,{type:`button`,class:`wb-logs-inline-btn`,title:V(X)(`@WORKBENCH:执行日志`),"aria-label":V(X)(`@WORKBENCH:执行日志`),onClick:o[5]||=e=>s.value=!0},[G(c,{class:`wb-logs-inline-btn__icon`},{default:D(()=>[G(V(be))]),_:1}),I(`span`,null,W(V(X)(`@WORKBENCH:执行日志`)),1)],8,xi)]),I(`details`,{class:`wb-task-desc`,open:Ee.value,onToggle:o[13]||=e=>Ee.value=e.target.open},[I(`summary`,Ci,[G(c,{class:`wb-task-desc__caret`},{default:D(()=>[(Y(),O(w(Ee.value?V(T):V(re))))]),_:1}),I(`span`,wi,W(V(X)(`@WORKBENCH:任务描述(可选)`)),1),d.value.desc&&d.value.desc.length>0||d.value.attachments&&d.value.attachments.length>0?(Y(),J(`span`,Ti,[d.value.desc&&d.value.desc.length>0?(Y(),J(`span`,Ei,W(V(X)(`@WORKBENCH:已填写`)),1)):U(``,!0),d.value.attachments&&d.value.attachments.length>0?(Y(),J(`span`,Di,W(d.value.attachments.length),1)):U(``,!0)])):U(``,!0)]),b(I(`textarea`,{class:`wb-textarea`,"onUpdate:modelValue":o[6]||=e=>d.value.desc=e,placeholder:V(X)(`@WORKBENCH:任务描述(可选)`),rows:`2`,onPaste:o[7]||=e=>rn(e,{kind:`task`,task:d.value})},null,40,Oi),[[we,d.value.desc]]),G(Xt,{attachments:d.value.attachments||[],"is-image":un,"human-size":dn,"is-uploading":Yt(`task-`+d.value.id),"is-paste-hover":$.value===`task-`+d.value.id,"max-count":9,"on-pick":()=>cn({kind:`task`,task:d.value}),"on-remove":e=>sn({kind:`task`,task:d.value},e),onPaste:o[8]||=e=>rn(e,{kind:`task`,task:d.value}),onDrop:o[9]||=H(e=>an(e,{kind:`task`,task:d.value}),[`prevent`]),onDragover:o[10]||=H(e=>$.value=`task-`+d.value.id,[`prevent`]),onDragenter:o[11]||=H(e=>$.value=`task-`+d.value.id,[`prevent`]),onDragleave:o[12]||=e=>$.value=$.value===`task-`+d.value.id?null:$.value},null,8,[`attachments`,`is-uploading`,`is-paste-hover`,`on-pick`,`on-remove`])],40,Si),I(`div`,{class:R([`wb-execution-body`,{"wb-execution-body--simple":p.value}])},[p.value?U(``,!0):(Y(),J(`div`,ki,[I(`div`,Ai,[I(`h4`,ji,W(V(X)(`@WORKBENCH:子任务拆分`)),1),I(`div`,Mi,[G(l,{size:`small`,plain:``,icon:V(y),disabled:d.value.subtasks.length===0,onClick:Dt},{default:D(()=>[n(W(V(X)(`@WORKBENCH:添加子任务`)),1)]),_:1},8,[`icon`,`disabled`]),G(l,{size:`small`,type:ae.value?`primary`:`default`,disabled:d.value.subtasks.length===0,onClick:At},{default:D(()=>[n(W(V(X)(`@WORKBENCH:保存拆分`))+` `,1),ae.value?(Y(),J(`span`,Ni,W(j.value.size),1)):U(``,!0)]),_:1},8,[`type`,`disabled`]),G(l,{size:`small`,type:`danger`,plain:``,icon:V(pe),disabled:!d.value.subtasks||d.value.subtasks.length===0,title:V(X)(`@WORKBENCH:只清空子任务,任务描述/附件/标题保留`),onClick:ct},{default:D(()=>[n(W(V(X)(`@WORKBENCH:清空子任务`)),1)]),_:1},8,[`icon`,`disabled`,`title`])])]),I(`ul`,Pi,[(Y(!0),J(P,null,C(d.value.subtasks,e=>(Y(),J(`li`,{key:e.id,class:R([`wb-exec-sub-item`,{"is-selected":m.value===e.id,"is-running":e.status===`running`,"is-done":e.status===`done`,"is-dirty":j.value.has(e.id),"is-persisting":Tt(e.id)}]),onClick:t=>m.value=e.id},[I(`div`,Ii,[e.status===`error`&&e.error?(Y(),O(g,{key:0,placement:`right-start`,width:420,trigger:`hover`,"show-after":120,"popper-class":`wb-sub-error-popover`},{reference:D(()=>[I(`span`,{class:`wb-sub-item__status wb-sub-item__status--dot wb-sub-item__status--clickable`,style:ie({background:V(Rn)(e.status)}),title:V(X)(`@WORKBENCH:点击查看错误详情`)},[...o[41]||=[I(`span`,{class:`wb-simple__status-dot`,"aria-hidden":`true`},null,-1)]],12,Li)]),default:D(()=>[I(`div`,Ri,[I(`div`,zi,[G(c,{class:`wb-sub-error__icon`},{default:D(()=>[G(V(ue))]),_:1}),I(`span`,Bi,W(V(X)(`@WORKBENCH:执行出错`)),1),e.errorAt?(Y(),J(`span`,Vi,W(Pe(e.errorAt)),1)):U(``,!0)]),I(`pre`,Hi,W(e.error),1),I(`div`,Ui,[G(l,{size:`small`,icon:V(N),onClick:t=>Fe(e)},{default:D(()=>[n(W(V(X)(`@WORKBENCH:复制错误信息`)),1)]),_:1},8,[`icon`,`onClick`]),G(l,{size:`small`,type:`primary`,onClick:t=>Ie(e)},{default:D(()=>[n(W(V(X)(`@WORKBENCH:查看执行日志`)),1)]),_:1},8,[`onClick`])])])]),_:2},1024)):(Y(),J(`span`,{key:1,class:`wb-sub-item__status wb-sub-item__status--dot`,style:ie({background:V(Rn)(e.status)}),title:V(X)(`@WORKBENCH:任务完成状态`)},[...o[42]||=[I(`span`,{class:`wb-simple__status-dot`,"aria-hidden":`true`},null,-1)]],12,Wi)),I(`span`,{class:`wb-exec-sub-item__title`,title:e.title},W(e.title||V(X)(`@WORKBENCH:未命名子任务`)),9,Gi),j.value.has(e.id)?(Y(),J(`span`,Ki)):U(``,!0)]),I(`div`,qi,[Ae(e.id)?(Y(),J(`span`,Ji,`PID: `+W(Ae(e.id)?.pid),1)):U(``,!0),I(`span`,Yi,[Ht(e)?(Y(),J(`button`,{key:0,class:`wb-exec-sub-btn wb-exec-sub-btn--run`,title:V(X)(`@WORKBENCH:单独执行此子任务`),onClick:H(t=>Vt(e),[`stop`])},W(V(X)(`@WORKBENCH:执行`)),9,Xi)):U(``,!0),Ut(e)?(Y(),J(`button`,{key:1,class:`wb-exec-sub-btn wb-exec-sub-btn--run-from`,title:V(X)(`@WORKBENCH:从此处执行后续子任务`),onClick:H(t=>Wt(e),[`stop`])},W(V(X)(`@WORKBENCH:从此处开始`)),9,Zi)):U(``,!0),Ae(e.id)&&(Ae(e.id)?.status===`running`||Ae(e.id)?.status===`pending`)?(Y(),J(`button`,{key:2,class:`wb-exec-sub-btn wb-exec-sub-btn--stop`,title:V(X)(`@WORKBENCH:停止执行`),onClick:H(t=>Kt(Ae(e.id)),[`stop`])},W(V(X)(`@WORKBENCH:停止`)),9,Qi)):U(``,!0),e.status===`done`?(Y(),J(`button`,{key:3,class:`wb-exec-sub-btn wb-exec-sub-btn--undo`,title:V(X)(`@WORKBENCH:取消完成`),disabled:Tt(e.id),onClick:H(t=>Gt(e),[`stop`])},W(V(X)(`@WORKBENCH:取消完成`)),9,$i)):U(``,!0),I(`button`,{class:`wb-exec-sub-btn wb-exec-sub-btn--del`,title:V(X)(`@WORKBENCH:删除`),disabled:Tt(e.id),onClick:H(t=>Ot(e),[`stop`])},`×`,8,ea)])])],10,Fi))),128)),d.value.subtasks.length===0?(Y(),J(`li`,ta,[I(`div`,na,[G(c,null,{default:D(()=>[G(V(ee))]),_:1})]),I(`div`,ra,W(V(X)(`@WORKBENCH:拆分任务,逐项执行`)),1),I(`div`,ia,[G(l,{type:`primary`,size:`small`,icon:V(y),onClick:Dt},{default:D(()=>[n(W(V(X)(`@WORKBENCH:添加子任务`)),1)]),_:1},8,[`icon`])])])):U(``,!0)])])),I(`div`,aa,[p.value?(Y(),J(P,{key:1},[I(`details`,{class:R([`wb-simple__override`,{"has-content":!!(d.value.simpleOverride&&d.value.simpleOverride.trim())}])},[I(`summary`,da,[G(c,{class:`wb-simple__override-caret`},{default:D(()=>[G(V(re))]),_:1}),I(`span`,null,W(V(X)(`@WORKBENCH:覆盖预置提示词(可选)`)),1),d.value.simpleOverride&&d.value.simpleOverride.trim()?(Y(),J(`span`,{key:0,class:`wb-simple__override-tag`,title:V(X)(`@WORKBENCH:已填写覆盖内容`)},W(V(X)(`@WORKBENCH:已填写`)),9,fa)):U(``,!0),He(Ve(d.value))===`running`&&Ve(d.value)?(Y(),J(`button`,{key:1,class:`wb-simple__stop`,disabled:Tt(Ve(d.value).id),onClick:o[24]||=H(e=>Kt(Ve(d.value)),[`stop`])},W(V(X)(`@WORKBENCH:停止`)),9,pa)):U(``,!0)]),b(I(`textarea`,{class:`wb-textarea`,"onUpdate:modelValue":o[25]||=e=>d.value.simpleOverride=e,placeholder:V(X)(`@WORKBENCH:留空则使用上方选定的「预置提示词」模板;可用变量同子任务:{{task.title}} {{task.desc}} {{repo.path}} {{branch}}`),rows:`6`},null,8,ma),[[we,d.value.simpleOverride]])],2),(Y(!0),J(P,null,C(Be(d.value),e=>(Y(),O(In,{key:e.id,job:e},null,8,[`job`]))),128)),Ve(d.value)&&[`done`,`error`,`cancelled`].includes(He(Ve(d.value)))?(Y(),J(`div`,ha,[b(I(`textarea`,{class:`wb-textarea wb-simple__continue-input`,"onUpdate:modelValue":o[26]||=e=>Lt[d.value.id]=e,placeholder:V(X)(`@WORKBENCH:输入后续问题继续对话…(Ctrl+Enter 发送)`),rows:`3`,onKeydown:o[27]||=fe(H(e=>Bt(d.value),[`ctrl`,`prevent`]),[`enter`])},null,40,ga),[[we,Lt[d.value.id]]]),I(`div`,_a,[G(l,{onClick:o[28]||=e=>zt(d.value)},{default:D(()=>[n(W(V(X)(`@WORKBENCH:退出`)),1)]),_:1}),G(l,{type:`primary`,disabled:!(Lt[d.value.id]||``).trim(),onClick:o[29]||=e=>Bt(d.value)},{default:D(()=>[n(W(V(X)(`@WORKBENCH:发送`)),1)]),_:1},8,[`disabled`])])])):U(``,!0)],64)):(Y(),J(P,{key:0},[h.value?(Y(),J(P,{key:1},[I(`div`,sa,[b(I(`input`,{class:`wb-input`,"onUpdate:modelValue":o[14]||=e=>h.value.title=e,placeholder:V(X)(`@WORKBENCH:子任务标题`),onClick:o[15]||=H(()=>{},[`stop`]),onPaste:o[16]||=e=>rn(e,{kind:`sub`,task:d.value,sub:h.value})},null,40,ca),[[we,h.value.title]]),j.value.has(h.value.id)?(Y(),J(`span`,{key:0,class:`wb-sub-item__dirty`,title:V(X)(`@WORKBENCH:有未保存的更改`)},W(V(X)(`@WORKBENCH:未保存`)),9,la)):U(``,!0)]),b(I(`textarea`,{class:`wb-textarea wb-textarea--sm`,"onUpdate:modelValue":o[17]||=e=>h.value.desc=e,placeholder:V(X)(`@WORKBENCH:子任务描述 / 独立提示词覆盖`),rows:`3`,onPaste:o[18]||=e=>rn(e,{kind:`sub`,task:d.value,sub:h.value})},null,40,ua),[[we,h.value.desc]]),Ae(h.value.id)?(Y(),O(In,{key:0,job:Ae(h.value.id)},null,8,[`job`])):U(``,!0),G(Xt,{attachments:h.value.attachments||[],"is-image":un,"human-size":dn,"is-uploading":Yt(`sub-`+h.value.id),"is-paste-hover":$.value===h.value.id,"max-count":9,"on-pick":()=>cn({kind:`sub`,task:d.value,sub:h.value}),"on-remove":e=>sn({kind:`sub`,task:d.value,sub:h.value},e),onPaste:o[19]||=e=>rn(e,{kind:`sub`,task:d.value,sub:h.value}),onDrop:o[20]||=H(e=>an(e,{kind:`sub`,task:d.value,sub:h.value}),[`prevent`]),onDragover:o[21]||=H(e=>$.value=h.value.id,[`prevent`]),onDragenter:o[22]||=H(e=>$.value=h.value.id,[`prevent`]),onDragleave:o[23]||=e=>$.value=$.value===h.value.id?null:$.value},null,8,[`attachments`,`is-uploading`,`is-paste-hover`,`on-pick`,`on-remove`])],64)):(Y(),J(`div`,oa,[I(`p`,null,W(d.value.subtasks.length===0?V(X)(`@WORKBENCH:手动添加子任务,或让 AI 帮你自动拆分`):V(X)(`@WORKBENCH:左侧选择子任务查看详情`)),1)]))],64))])],2)],64)):(Y(),J(`div`,oi,[I(`p`,null,W(V(X)(`@WORKBENCH:左侧选择任务,或新建一个任务开始`)),1)]))])]),G(x,{modelValue:s.value,"onUpdate:modelValue":o[30]||=e=>s.value=e,title:V(X)(`@WORKBENCH:执行日志`),width:`1080px`,"close-on-click-modal":!1,top:`6vh`,class:`wb-logs-dialog`},{default:D(()=>[G(mr)]),_:1},8,[`modelValue`,`title`]),G(x,{modelValue:K.visible,"onUpdate:modelValue":o[34]||=e=>K.visible=e,title:K.editing?V(X)(`@WORKBENCH:编辑提示词`):V(X)(`@WORKBENCH:新建提示词`),width:`640px`},{footer:D(()=>[G(l,{onClick:o[33]||=e=>K.visible=!1},{default:D(()=>[n(W(V(X)(`@WORKBENCH:取消`)),1)]),_:1}),G(l,{type:`primary`,onClick:ht},{default:D(()=>[n(W(V(X)(`@WORKBENCH:保存`)),1)]),_:1})]),default:D(()=>[G(k,{"label-position":`top`},{default:D(()=>[G(E,{label:V(X)(`@WORKBENCH:名称`)},{default:D(()=>[G(S,{modelValue:K.name,"onUpdate:modelValue":o[31]||=e=>K.name=e,placeholder:V(X)(`@WORKBENCH:如:代码审查 / 写测试`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`]),G(E,null,{default:D(()=>[I(`div`,va,[G(l,{type:`primary`,plain:``,loading:K.aiLoading,onClick:ft},{default:D(()=>[n(W(V(X)(`@WORKBENCH:AI 生成项目架构说明`)),1)]),_:1},8,[`loading`]),G(l,{onClick:pt},{default:D(()=>[n(W(V(X)(`@WORKBENCH:编辑指令`)),1)]),_:1})])]),_:1}),G(E,{label:V(X)(`@WORKBENCH:内容`)},{default:D(()=>[G(S,{modelValue:K.content,"onUpdate:modelValue":o[32]||=e=>K.content=e,type:`textarea`,rows:10,placeholder:V(X)(`@WORKBENCH:可用变量:`)+`{{task.title}} {{task.desc}} {{sub.title}} {{sub.desc}} {{repo.path}} {{branch}}`},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])]),_:1})]),_:1},8,[`modelValue`,`title`]),G(x,{modelValue:q.visible,"onUpdate:modelValue":o[37]||=e=>q.visible=e,title:V(X)(`@WORKBENCH:编辑生成指令`),width:`720px`,"append-to-body":``},{footer:D(()=>[G(l,{onClick:o[36]||=e=>q.visible=!1},{default:D(()=>[n(W(V(X)(`@WORKBENCH:取消`)),1)]),_:1}),G(l,{type:`primary`,loading:q.saving,onClick:mt},{default:D(()=>[n(W(V(X)(`@WORKBENCH:保存`)),1)]),_:1},8,[`loading`])]),default:D(()=>[G(k,{"label-position":`top`},{default:D(()=>[G(E,{label:V(X)(`@WORKBENCH:指令内容`)},{default:D(()=>[G(S,{modelValue:q.text,"onUpdate:modelValue":o[35]||=e=>q.text=e,type:`textarea`,rows:18,placeholder:V(X)(`@WORKBENCH:指令内容`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])]),_:1})]),_:1},8,[`modelValue`,`title`]),d.value?(Y(),O(Rt,{key:0,modelValue:jt.value,"onUpdate:modelValue":o[38]||=e=>jt.value=e,title:d.value.title,desc:d.value.desc,"task-id":d.value.id,"prompt-id":d.value.promptId,onConfirm:Nt},null,8,[`modelValue`,`title`,`desc`,`task-id`,`prompt-id`])):U(``,!0)])}}}),[[`__scopeId`,`data-v-1ae5d369`]]);export{Ta as default};