zen-gitsync 2.13.18 → 2.13.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/ui/public/assets/{AppVersionBadge-CB05za9z.js → AppVersionBadge-DxwoTl4I.js} +2 -2
- package/src/ui/public/assets/{BranchSelector-D_4ZN-yW.js → BranchSelector-DYvaaEnf.js} +1 -1
- package/src/ui/public/assets/{CommandConsole-DnlEYvxJ.js → CommandConsole-C1E2g0yB.js} +2 -2
- package/src/ui/public/assets/{CommitForm-D1fzmTVM.js → CommitForm-WflPXJyB.js} +1 -1
- package/src/ui/public/assets/{CustomCommandManager-DqbDslM5.js → CustomCommandManager-CbRHolL0.js} +1 -1
- package/src/ui/public/assets/{EditorView-DyUPi7oi.js → EditorView-Lw0FPIlg.js} +0 -0
- package/src/ui/public/assets/{FileDiffViewer-DqHNm1Db.js → FileDiffViewer-ByoOW_11.js} +1 -1
- package/src/ui/public/assets/{FlowExecutionViewer-Ctoxm9hD.js → FlowExecutionViewer-wEk25Mzj.js} +1 -1
- package/src/ui/public/assets/{FlowOrchestrationWorkspace-D-e_cp10.js → FlowOrchestrationWorkspace-KfJga9TA.js} +1 -1
- package/src/ui/public/assets/{GitStatus-C0G0_pfB.js → GitStatus-BWLw1CQX.js} +1 -1
- package/src/ui/public/assets/{ImagePreview-IGNG85_Z.js → ImagePreview-JVKert7x.js} +1 -1
- package/src/ui/public/assets/{LogList-Drugd5s2.js → LogList-BYebS-YM.js} +1 -1
- package/src/ui/public/assets/{ProjectStartupButton-DgYOZGWj.js → ProjectStartupButton-BUhFIIaP.js} +1 -1
- package/src/ui/public/assets/{RemoteRepoCard-CqKjbqCc.js → RemoteRepoCard-BbEd_aLC.js} +1 -1
- package/src/ui/public/assets/{ResetToRemoteButton-Dquw8Q8M.js → ResetToRemoteButton-DN6cQL7W.js} +1 -1
- package/src/ui/public/assets/{SourceMapView-BK4SE8Sk.js → SourceMapView-DjQyejIE.js} +1 -1
- package/src/ui/public/assets/{TemplateManager-BeB5DnzM.js → TemplateManager-B1NninL9.js} +1 -1
- package/src/ui/public/assets/{UserInputNode-DGj443LF.js → UserInputNode-9Pr89y85.js} +1 -1
- package/src/ui/public/assets/WorkbenchView-BE7Ybbm0.css +1 -0
- package/src/ui/public/assets/WorkbenchView-BQ37IdMh.js +12 -0
- package/src/ui/public/assets/{_plugin-vue_export-helper-7JKb0AkH.js → _plugin-vue_export-helper-TrrjpmI9.js} +2 -2
- package/src/ui/public/assets/{index-CVkvp_5b.css → index-B3sS0q3V.css} +1 -1
- package/src/ui/public/assets/{index-gT8ZUxDS.js → index-DWsDwBpN.js} +3 -3
- package/src/ui/public/index.html +3 -3
- package/src/ui/server/routes/workbench.js +89 -25
- package/src/ui/public/assets/WorkbenchView-B2O2Ya-O.js +0 -9
- package/src/ui/public/assets/WorkbenchView-BqOJlWXm.css +0 -1
package/src/ui/public/index.html
CHANGED
|
@@ -10,17 +10,17 @@
|
|
|
10
10
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
11
11
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
12
12
|
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,400&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
13
|
-
<script type="module" crossorigin src="/assets/index-
|
|
13
|
+
<script type="module" crossorigin src="/assets/index-DWsDwBpN.js"></script>
|
|
14
14
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-CMxvf4Kt.js">
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/monaco-DC7mqInI.js">
|
|
16
16
|
<link rel="modulepreload" crossorigin href="/assets/element-plus-CJjFCgLP.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/vendor-0YbzMuxw.js">
|
|
18
|
-
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-
|
|
18
|
+
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-TrrjpmI9.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="/assets/socket-io-z4n873W1.js">
|
|
20
20
|
<link rel="stylesheet" crossorigin href="/assets/monaco-UXx6YYK1.css">
|
|
21
21
|
<link rel="stylesheet" crossorigin href="/assets/element-plus-D36sOm0a.css">
|
|
22
22
|
<link rel="stylesheet" crossorigin href="/assets/vendor-DNI_idR2.css">
|
|
23
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
23
|
+
<link rel="stylesheet" crossorigin href="/assets/index-B3sS0q3V.css">
|
|
24
24
|
</head>
|
|
25
25
|
<body>
|
|
26
26
|
<div id="app"></div>
|
|
@@ -1018,8 +1018,9 @@ function launchClaudeInNewWindow(cwd, promptText, resumeSessionId) {
|
|
|
1018
1018
|
args.push('--resume', String(resumeSessionId));
|
|
1019
1019
|
}
|
|
1020
1020
|
args.push(
|
|
1021
|
-
|
|
1022
|
-
|
|
1021
|
+
// -p '-' 让 claude CLI 从 stdin 读取 prompt —— 避免 Windows 命令行 32K 长度上限
|
|
1022
|
+
// (spawn argv 会拼成 cmdline 给 CreateProcess,长 prompt 直接 ENAMETOOLONG)
|
|
1023
|
+
'-p', '-',
|
|
1023
1024
|
'--output-format', 'stream-json',
|
|
1024
1025
|
'--verbose',
|
|
1025
1026
|
'--permission-mode', 'bypassPermissions',
|
|
@@ -1047,7 +1048,7 @@ function launchClaudeInNewWindow(cwd, promptText, resumeSessionId) {
|
|
|
1047
1048
|
spawnedExe = claudeExe;
|
|
1048
1049
|
child = spawn(claudeExe, args, {
|
|
1049
1050
|
cwd,
|
|
1050
|
-
stdio: ['
|
|
1051
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
1051
1052
|
windowsHide: false,
|
|
1052
1053
|
env: { ...process.env, LANG: 'zh_CN.UTF-8' }
|
|
1053
1054
|
});
|
|
@@ -1057,7 +1058,7 @@ function launchClaudeInNewWindow(cwd, promptText, resumeSessionId) {
|
|
|
1057
1058
|
child = spawn('claude', args, {
|
|
1058
1059
|
cwd,
|
|
1059
1060
|
detached: true,
|
|
1060
|
-
stdio: ['
|
|
1061
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
1061
1062
|
env: { ...process.env, LANG: 'zh_CN.UTF-8' }
|
|
1062
1063
|
});
|
|
1063
1064
|
}
|
|
@@ -1065,6 +1066,19 @@ function launchClaudeInNewWindow(cwd, promptText, resumeSessionId) {
|
|
|
1065
1066
|
child.on('spawn', () => {
|
|
1066
1067
|
// unref 让 claude 独立于父进程事件循环;返回 child 引用让调用方继续读 stdout。
|
|
1067
1068
|
child.unref();
|
|
1069
|
+
// 长 prompt 通过 stdin 喂入(避开 Windows CreateProcess 32K 命令行上限)。
|
|
1070
|
+
// 必须在 spawn 事件回调里 write,而不是 resolve 前同步 write——因为 spawn
|
|
1071
|
+
// 返回时 child.stdin 句柄可能尚未绑定到真正的 pipe fd。
|
|
1072
|
+
// write 完成后必须 end(),否则 claude CLI 会一直阻塞在读 stdin 上 → hang。
|
|
1073
|
+
try {
|
|
1074
|
+
child.stdin.write(promptText, () => {
|
|
1075
|
+
try { child.stdin.end() } catch { /* 子进程已关闭,忽略 */ }
|
|
1076
|
+
});
|
|
1077
|
+
} catch (err) {
|
|
1078
|
+
// stdin 写入失败不要让 spawn 整体 reject —— 让 child 自然以错误状态收尾,
|
|
1079
|
+
// 后面的 stdout/stderr 监听会捕获到 LLM 端反馈。
|
|
1080
|
+
console.warn('[workbench] stdin write failed:', err && err.message || err);
|
|
1081
|
+
}
|
|
1068
1082
|
resolve({ pid: child.pid, child });
|
|
1069
1083
|
});
|
|
1070
1084
|
});
|
|
@@ -1077,11 +1091,10 @@ function launchClaudeInNewWindow(cwd, promptText, resumeSessionId) {
|
|
|
1077
1091
|
* 这样后续 sub 仍能拿到前序上下文(跟单 sub 执行的语义保持一致)。
|
|
1078
1092
|
*/
|
|
1079
1093
|
async function runTaskQueue(task, repoPath, branch, opts) {
|
|
1080
|
-
// 前序上下文:跑完一个 sub 后把它"完成态"
|
|
1094
|
+
// 前序上下文:跑完一个 sub 后把它"完成态"输出存到这里,下一个 sub 启动时
|
|
1081
1095
|
// 拼到 prompt 头部,让 Claude 知道前面做了什么、产出了什么。
|
|
1082
|
-
//
|
|
1083
|
-
//
|
|
1084
|
-
const MAX_PREV_OUTPUT_CHARS = 2000
|
|
1096
|
+
// 现在 LLM 都是百万 token 上下文窗口,完整透传 raw output,不做截断——
|
|
1097
|
+
// 关键产物(生成的代码块、JSON、结论)在中间被砍掉反而会让后续 sub 失去依据。
|
|
1085
1098
|
const requested = Number(opts && opts.fromIndex)
|
|
1086
1099
|
const fromIndex = Number.isInteger(requested) && requested >= 0 && requested < task.subtasks.length
|
|
1087
1100
|
? requested
|
|
@@ -1121,7 +1134,6 @@ async function runTaskQueue(task, repoPath, branch, opts) {
|
|
|
1121
1134
|
async function runSingleSubtask(task, sub, repoPath, branch, priorOutputs, options) {
|
|
1122
1135
|
const opts = options || {}
|
|
1123
1136
|
const resumeSessionId = opts.resumeSessionId || null
|
|
1124
|
-
const MAX_PREV_OUTPUT_CHARS = 2000
|
|
1125
1137
|
const promptTemplate = sub.promptOverride || (task.promptId
|
|
1126
1138
|
? (await readJson(PROMPTS_FILE, { prompts: [] })).prompts.find(p => p.id === task.promptId)?.content
|
|
1127
1139
|
: null) || '';
|
|
@@ -1135,12 +1147,11 @@ async function runSingleSubtask(task, sub, repoPath, branch, priorOutputs, optio
|
|
|
1135
1147
|
const parts = [interpolated, sub.title, sub.desc].filter(s => s && s.trim());
|
|
1136
1148
|
let prompt = parts.join('\n\n');
|
|
1137
1149
|
|
|
1138
|
-
// ── 前序上下文:把前几个 done
|
|
1150
|
+
// ── 前序上下文:把前几个 done 子任务的输出完整拼到 prompt 头部 ──
|
|
1151
|
+
// 完整透传,不做字符截断;只在输出真为空时跳过该条。
|
|
1139
1152
|
if (priorOutputs && priorOutputs.length > 0) {
|
|
1140
1153
|
const prevBlock = priorOutputs.map((p, i) => {
|
|
1141
|
-
|
|
1142
|
-
const truncated = (p.output || '').length > MAX_PREV_OUTPUT_CHARS ? '\n…(前文已截断)' : ''
|
|
1143
|
-
return `### [${i + 1}] ${p.title}\n${text}${truncated}`
|
|
1154
|
+
return `### [${i + 1}] ${p.title}\n${p.output || ''}`
|
|
1144
1155
|
}).join('\n\n')
|
|
1145
1156
|
prompt = `以下是同一任务下已经完成的前序子任务输出(仅作上下文参考,请基于这些结论继续当前子任务,无需重复执行它们):
|
|
1146
1157
|
|
|
@@ -1309,16 +1320,30 @@ ${prompt}`
|
|
|
1309
1320
|
if (priorOutputs) priorOutputs.push({ title: sub.title, output: job.output || '' })
|
|
1310
1321
|
}
|
|
1311
1322
|
} catch (err) {
|
|
1312
|
-
|
|
1323
|
+
const errMsg = err && err.message ? err.message : String(err);
|
|
1324
|
+
job.error = errMsg;
|
|
1313
1325
|
job.status = 'error';
|
|
1314
1326
|
sub.status = 'error';
|
|
1327
|
+
sub.error = errMsg;
|
|
1328
|
+
sub.errorAt = nowIso();
|
|
1315
1329
|
} finally {
|
|
1316
1330
|
// 移除 child 引用——避免后续被 SSE 序列化到前端
|
|
1317
1331
|
delete job.child
|
|
1318
1332
|
publish('job:update', job);
|
|
1319
1333
|
publish('sub:update', { taskId: task.id, sub });
|
|
1320
|
-
// 终态:
|
|
1321
|
-
|
|
1334
|
+
// 终态:await 同步落盘,确保 done/cancelled/error 全部立即归档。
|
|
1335
|
+
// 历史上这里用 fire-and-forget(`.catch(err => ...)`) → runSingleSubtask 返回时
|
|
1336
|
+
// flushJobsSaveNow 还在写盘 microtask 里 → runTaskQueue 进入下一个 sub →
|
|
1337
|
+
// 如果用户此时调了 clearJobsByTask / 切页面 / 后端退出 → 写盘未完成就丢 job
|
|
1338
|
+
// (但 sub.status=done 已经被 publish 出去 → 磁盘状态 = "sub done 但无 job",
|
|
1339
|
+
// 跟用户截图里的"6 个 done 但 jobs.json 全空"现象吻合)。
|
|
1340
|
+
// 改 await 后:runSingleSubtask 返回时,本 sub 的 job 已经落盘 → 安全。
|
|
1341
|
+
// 出错也只是 log warn,不会抛出影响后续 sub 的执行。
|
|
1342
|
+
try {
|
|
1343
|
+
await flushJobsSaveNow()
|
|
1344
|
+
} catch (err) {
|
|
1345
|
+
console.warn('[workbench] flushJobsSaveNow failed (job id=' + job.id + ', status=' + job.status + '):', err && err.message || err)
|
|
1346
|
+
}
|
|
1322
1347
|
}
|
|
1323
1348
|
}
|
|
1324
1349
|
|
|
@@ -1327,7 +1352,19 @@ async function persistTaskAfterRun(task) {
|
|
|
1327
1352
|
const data = await readJson(TASKS_FILE, { tasks: [] });
|
|
1328
1353
|
const t = data.tasks.find(x => x.id === task.id);
|
|
1329
1354
|
if (t) {
|
|
1330
|
-
|
|
1355
|
+
// 仅同步 status 之外的 error/errorAt 字段,避免覆盖用户编辑过的 title/desc 等。
|
|
1356
|
+
// 历史 subtasks 持久化只写 status → 失败信息丢,hover "执行出错" 标签看不到原因。
|
|
1357
|
+
const newMap = new Map(task.subtasks.map(s => [s.id, s]));
|
|
1358
|
+
t.subtasks = (t.subtasks || []).map(old => {
|
|
1359
|
+
const fresh = newMap.get(old.id);
|
|
1360
|
+
if (!fresh) return old;
|
|
1361
|
+
return {
|
|
1362
|
+
...old,
|
|
1363
|
+
status: fresh.status ?? old.status,
|
|
1364
|
+
error: fresh.error ?? old.error,
|
|
1365
|
+
errorAt: fresh.errorAt ?? old.errorAt,
|
|
1366
|
+
};
|
|
1367
|
+
});
|
|
1331
1368
|
t.updatedAt = nowIso();
|
|
1332
1369
|
await writeJson(TASKS_FILE, data);
|
|
1333
1370
|
publish('task:update', t);
|
|
@@ -1349,20 +1386,17 @@ async function collectPriorOutputs(task, targetSub) {
|
|
|
1349
1386
|
* runTaskQueue 在 fromIndex>0 时调这个,让"从此处开始"也能拼上前序 done sub 的结论。
|
|
1350
1387
|
*/
|
|
1351
1388
|
async function collectPriorOutputsUpTo(task, endIdx) {
|
|
1352
|
-
const MAX_PREV_OUTPUT_CHARS = 2000
|
|
1353
1389
|
const prior = []
|
|
1354
1390
|
for (let i = 0; i < endIdx; i++) {
|
|
1355
1391
|
const s = task.subtasks[i]
|
|
1356
1392
|
if (s.status !== 'done') continue
|
|
1357
1393
|
// 从 jobs 列表里找最近一个属于这个 sub 且 status=done 的 job,
|
|
1358
|
-
// 取其 output 作为"
|
|
1394
|
+
// 取其 output 作为"前序上下文"。完整透传,不做字符截断。
|
|
1359
1395
|
const job = snapshotJobs()
|
|
1360
1396
|
.filter(j => j.subId === s.id && j.status === 'done')
|
|
1361
1397
|
.sort((a, b) => (b.endedAt || '').localeCompare(a.endedAt || ''))[0]
|
|
1362
1398
|
if (!job) continue
|
|
1363
|
-
|
|
1364
|
-
const truncated = (job.output || '').length > MAX_PREV_OUTPUT_CHARS ? '\n…(前文已截断)' : ''
|
|
1365
|
-
prior.push({ title: s.title, output: text + truncated })
|
|
1399
|
+
prior.push({ title: s.title, output: job.output || '' })
|
|
1366
1400
|
}
|
|
1367
1401
|
return prior
|
|
1368
1402
|
}
|
|
@@ -2252,6 +2286,9 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
|
|
|
2252
2286
|
desc: s.desc || '',
|
|
2253
2287
|
status: s.status || 'todo',
|
|
2254
2288
|
promptOverride: s.promptOverride || '',
|
|
2289
|
+
// 保留失败信息:编辑已 error 的 sub 时不能丢 context,否则 hover popover 看不到原因
|
|
2290
|
+
error: typeof s.error === 'string' ? s.error : undefined,
|
|
2291
|
+
errorAt: typeof s.errorAt === 'string' ? s.errorAt : undefined,
|
|
2255
2292
|
// 保留附件元数据(仅保留基础字段,丢弃客户端临时字段)
|
|
2256
2293
|
attachments: Array.isArray(s.attachments) ? s.attachments.map(a => ({
|
|
2257
2294
|
id: a.id,
|
|
@@ -2283,6 +2320,8 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
|
|
|
2283
2320
|
desc: s.desc || '',
|
|
2284
2321
|
status: s.status || 'todo',
|
|
2285
2322
|
promptOverride: s.promptOverride || '',
|
|
2323
|
+
error: typeof s.error === 'string' ? s.error : undefined,
|
|
2324
|
+
errorAt: typeof s.errorAt === 'string' ? s.errorAt : undefined,
|
|
2286
2325
|
attachments: Array.isArray(s.attachments) ? s.attachments : []
|
|
2287
2326
|
})) : [],
|
|
2288
2327
|
status: 'todo',
|
|
@@ -2448,8 +2487,24 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
|
|
|
2448
2487
|
});
|
|
2449
2488
|
|
|
2450
2489
|
// ── 进程状态查询(兜底,SSE 断了也能拉) ────────────────────────────
|
|
2451
|
-
|
|
2452
|
-
|
|
2490
|
+
// 合并内存 jobs Map(当前进程的活跃 job)+ jobs.json 落盘历史。
|
|
2491
|
+
// 之前只走 snapshotJobs():进程重启后内存清空,新开页签就看不到旧 job 的输出。
|
|
2492
|
+
// WorkbenchView 在 onMounted 调一次,靠这个接口把历史 job 重新塞回 jobs.value,
|
|
2493
|
+
// 才能用 jobOf(subId) 找到对应记录渲染 JobLogDetails。
|
|
2494
|
+
// 文件里的字段已经是落盘时 serialize 过的精简形态,跟 snapshotJobs() 同 schema,
|
|
2495
|
+
// 直接合并即可,不需要再走 serializeJob 补 taskTitle/subTitle(WorkbenchView 不用)。
|
|
2496
|
+
app.get('/api/workbench/jobs', async (_req, res) => {
|
|
2497
|
+
try {
|
|
2498
|
+
const data = await readJson(JOBS_FILE, { version: 1, jobs: [] })
|
|
2499
|
+
const fileJobs = (data && Array.isArray(data.jobs)) ? data.jobs : []
|
|
2500
|
+
const fileIds = new Set(fileJobs.map(j => j.id))
|
|
2501
|
+
// 内存里 running/pending 或刚起还没刷盘的,文件里没的,必须补
|
|
2502
|
+
const liveOnly = snapshotJobs().filter(j => !fileIds.has(j.id))
|
|
2503
|
+
res.json({ success: true, jobs: [...fileJobs, ...liveOnly] })
|
|
2504
|
+
} catch (err) {
|
|
2505
|
+
// 读取失败兜底:只返内存的,UI 至少能看到当前活跃 job
|
|
2506
|
+
res.json({ success: true, jobs: snapshotJobs() })
|
|
2507
|
+
}
|
|
2453
2508
|
});
|
|
2454
2509
|
|
|
2455
2510
|
// ── 取消正在执行的 job ───────────────────────────────────────────
|
|
@@ -2704,21 +2759,30 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
|
|
|
2704
2759
|
// 重新执行任务前清空该 task 下的所有旧 job(内存 + 文件双写)。
|
|
2705
2760
|
// 不清活跃的 running/pending,避免误杀正在跑的实例;前端启动新 run 时
|
|
2706
2761
|
// 应确认旧任务已结束,或在活跃态时拒绝调用本接口。
|
|
2762
|
+
// ?keepDone=true 时只清 non-done 的 job(保留 done 历史的日志),用于
|
|
2763
|
+
// "只跑未完成" 场景——避免偷偷清掉 done sub 的日志,让前端 jobOf(subId)
|
|
2764
|
+
// 在新页签上还能找到。
|
|
2707
2765
|
app.delete('/api/workbench/jobs/by-task/:taskId', async (req, res) => {
|
|
2708
2766
|
try {
|
|
2709
2767
|
const taskId = req.params.taskId
|
|
2710
2768
|
if (!taskId) return res.status(400).json({ success: false, error: '缺少 taskId' })
|
|
2769
|
+
const keepDone = String(req.query.keepDone || '').toLowerCase() === 'true'
|
|
2711
2770
|
const ids = []
|
|
2712
2771
|
for (const j of jobs.values()) {
|
|
2713
2772
|
if (j.taskId !== taskId) continue
|
|
2714
2773
|
if (j.status === 'running' || j.status === 'pending') continue
|
|
2774
|
+
if (keepDone && j.status === 'done') continue
|
|
2715
2775
|
jobs.delete(j.id)
|
|
2716
2776
|
ids.push(j.id)
|
|
2717
2777
|
}
|
|
2718
2778
|
const data = await readJson(JOBS_FILE, { version: 1, jobs: [] })
|
|
2719
2779
|
if (data && Array.isArray(data.jobs)) {
|
|
2720
2780
|
const before = data.jobs.length
|
|
2721
|
-
data.jobs = data.jobs.filter(j =>
|
|
2781
|
+
data.jobs = data.jobs.filter(j => {
|
|
2782
|
+
if (j.taskId !== taskId) return true
|
|
2783
|
+
if (keepDone && j.status === 'done') return true
|
|
2784
|
+
return !ids.includes(j.id)
|
|
2785
|
+
})
|
|
2722
2786
|
const removed = before - data.jobs.length
|
|
2723
2787
|
if (removed > 0) await writeJson(JOBS_FILE, data)
|
|
2724
2788
|
return res.json({ success: true, removed: ids.length + removed, ids })
|
|
@@ -1,9 +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,N as g,Nn as _,Nt as v,Ot as y,P as b,Pt as x,Qn as S,R as ee,Sn as C,Tt as w,Vn as T,W as te,Wn as ne,X as re,Y as ie,Yn as E,Z as D,Zn as O,_n as k,_r as A,a as j,at as M,b as N,cn as ae,cr as P,dn as F,dt as oe,et as se,f as I,gn as L,gt as ce,hn as R,hr as z,i as B,ir as le,k as ue,l as de,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,rt as Se,sn as Ce,un as H,vn as U,vr as W,wn as G,x as we,y as K,yn as q,yt as Te,zn as J}from"./element-plus-CJjFCgLP.js";import{r as Y}from"./vendor-0YbzMuxw.js";import{n as X,t as Ee}from"./_plugin-vue_export-helper-7JKb0AkH.js";import{n as De}from"./index-gT8ZUxDS.js";var Z={class:`ai-split-direct-pane`},Oe={key:0,class:`ai-split-status`},ke={key:1,class:`ai-split-status`},Ae={key:1},je={key:2},Me={key:2,class:`ai-split-status is-error`},Ne={key:3,class:`ai-split-idle`},Pe={class:`ai-split-idle__title`},Fe={class:`ai-split-idle__desc`},Ie={class:`ai-split-prompt-actions`},Le={key:0,class:`ai-split-prompt-editor`},Re={class:`ai-split-prompt-editor__actions`},ze={key:1,class:`ai-split-pre`},Be={class:`ai-split-subhead`},Ve={class:`ai-split-user-actions`},He={key:3,class:`ai-split-pre`},Ue={key:0,class:`ai-split-tab-count`},We={class:`ai-split-pre ai-split-pre--think`},Ge={key:0,class:`ai-split-tab-count`},Q={class:`ai-split-parse-error__detail`},Ke={class:`ai-split-parse-error__hint`},qe={class:`ai-split-parse-error__actions`},Je={key:1,class:`ai-split-raw-toolbar`},Ye={class:`ai-split-raw-tip`},Xe={key:0,class:`ai-split-tab-count`},Ze={key:0,class:`ai-split-empty`},Qe={key:1,class:`ai-split-list`},$e={class:`ai-split-list__no`},et={class:`ai-split-list__body`},tt={class:`ai-split-list__title`},nt={class:`ai-split-list__desc`},rt={key:5,class:`ai-split-footer-hint`},it={class:`ai-split-direct-footer`},at=Ee(a({__name:`AISplitDirectPane`,props:{title:{},desc:{},taskId:{},promptId:{}},emits:[`confirm`],setup(e,{emit:r}){let i=e,a=r,s=P(`idle`),c=P(`prompt`),l=P(``),f=P(``),p=P(``),m=P(``),h=P(``),g=P([]),_=P(``),v=P(``),y=P(``),b=null,x=0,S=R(()=>p.value.length),ee=R(()=>m.value.length),w=R(()=>s.value===`result`&&g.value.length>0),ne=R(()=>s.value===`running`),re=R(()=>s.value===`preview`),D=P(``),A=P(!1);function M(){b&&=(b.abort(),null)}function N(){M(),s.value=`idle`,c.value=`prompt`,l.value=``,f.value=``,D.value=``,p.value=``,m.value=``,h.value=``,g.value=[],_.value=``,v.value=``,y.value=``}async function ae(){if(!i.title.trim()){j.warning(X(`@WORKBENCH:请先填写任务标题`));return}N(),s.value=`preview`,c.value=`prompt`,A.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||``,D.value=e.user||``}catch(e){s.value=`error`,_.value=e?.message||String(e)}finally{A.value=!1}}async function oe(){if(!D.value.trim()){j.warning(X(`@WORKBENCH:提示词不能为空`));return}let e=++x;M(),p.value=``,m.value=``,h.value=``,g.value=[],v.value=``,y.value=``,_.value=``,s.value=`running`,c.value=`thinking`,f.value=D.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:D.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 se(){w.value&&a(`confirm`,g.value.slice())}function ce(){D.value.trim()?oe():ae()}function z(){b&&(b.abort(),b=null,j.info(X(`@WORKBENCH:已停止拆分`)))}let B=P(!1);async function le(){if(!m.value.trim()){j.warning(X(`@WORKBENCH:原始结果为空,无法解析`));return}B.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){j.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?(j.success(X(`@WORKBENCH:解析成功,已识别 {n} 个子任务`,{n:g.value.length})),c.value=`confirm`):j.warning(X(`@WORKBENCH:仍未解析到子任务,请继续修改原始结果`))}catch(e){j.error(X(`@WORKBENCH:解析失败: `)+(e?.message||e))}finally{B.value=!1}}E(()=>i.taskId,()=>{N()});let ue=P(!1),de=P(``),fe=P(!1);function pe(){de.value=l.value,ue.value=!0}async function me(){if(!de.value.trim()){j.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:de.value})}).then(e=>e.json());e.success?(j.success(X(`@WORKBENCH:已保存指令`)),ue.value=!1,ae()):j.error(e.error||X(`@WORKBENCH:保存失败`))}catch(e){j.error(X(`@WORKBENCH:保存失败: `)+(e?.message||e))}finally{fe.value=!1}}function he(){ue.value=!1}return(e,r)=>{let i=ie,a=t,h=te,y=I,b=d,x=ve;return J(),q(`div`,Z,[ne.value?(J(),q(`div`,Oe,[G(i,{class:`is-loading`},{default:O(()=>[G(V(o))]),_:1}),L(`span`,null,W(V(X)(`@WORKBENCH:AI 正在拆分…`)),1),G(a,{size:`small`,link:``,type:`danger`,class:`ai-split-status__stop`,onClick:z},{default:O(()=>[n(W(V(X)(`@WORKBENCH:停止拆分`)),1)]),_:1})])):re.value?(J(),q(`div`,ke,[A.value?(J(),k(i,{key:0,class:`is-loading`},{default:O(()=>[G(V(o))]),_:1})):U(``,!0),A.value?(J(),q(`span`,Ae,W(V(X)(`@WORKBENCH:正在生成提示词预览…`)),1)):(J(),q(`span`,je,W(V(X)(`@WORKBENCH:提示词已就绪,可在下方编辑后点「发送给 AI」开始拆分`)),1))])):s.value===`error`?(J(),q(`div`,Me,[G(i,{color:`#f56c6c`},{default:O(()=>[G(V(Se))]),_:1}),L(`span`,null,W(_.value),1)])):s.value===`idle`?(J(),q(`div`,Ne,[r[5]||=C(`<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),L(`div`,Pe,W(V(X)(`@WORKBENCH:准备用 AI 拆分任务`)),1),L(`div`,Fe,W(V(X)(`@WORKBENCH:点击下方按钮开始生成。生成期间可切换到「思考 / 原始结果」实时查看模型输出。`)),1),G(a,{type:`primary`,icon:V(u),onClick:ae},{default:O(()=>[n(W(V(X)(`@WORKBENCH:开始拆分`)),1)]),_:1},8,[`icon`])])):U(``,!0),s.value===`idle`?U(``,!0):(J(),k(x,{key:4,modelValue:c.value,"onUpdate:modelValue":r[4]||=e=>c.value=e,class:`ai-split-tabs`},{default:O(()=>[G(y,{label:V(X)(`@WORKBENCH:提示词`),name:`prompt`},{default:O(()=>[L(`div`,Ie,[G(a,{size:`small`,disabled:ne.value,onClick:pe},{default:O(()=>[n(W(V(X)(`@WORKBENCH:编辑指令`)),1)]),_:1},8,[`disabled`])]),ue.value?(J(),q(`div`,Le,[G(h,{modelValue:de.value,"onUpdate:modelValue":r[0]||=e=>de.value=e,type:`textarea`,rows:12,placeholder:V(X)(`@WORKBENCH:指令内容`)},null,8,[`modelValue`,`placeholder`]),L(`div`,Re,[G(a,{size:`small`,onClick:he},{default:O(()=>[n(W(V(X)(`@WORKBENCH:取消`)),1)]),_:1}),G(a,{size:`small`,type:`primary`,loading:fe.value,onClick:me},{default:O(()=>[n(W(V(X)(`@WORKBENCH:保存并重跑`)),1)]),_:1},8,[`loading`])])])):(J(),q(`pre`,ze,W(l.value||`(等待 LLM 启动…)`),1)),L(`h4`,Be,W(V(X)(`@WORKBENCH:用户提示词(拼装后)`)),1),re.value?(J(),q(F,{key:2},[G(h,{modelValue:D.value,"onUpdate:modelValue":r[1]||=e=>D.value=e,type:`textarea`,rows:16,placeholder:V(X)(`@WORKBENCH:正在生成预览…`),readonly:A.value,class:`ai-split-user-editor`,resize:`none`},null,8,[`modelValue`,`placeholder`,`readonly`]),L(`div`,Ve,[G(a,{size:`small`,disabled:A.value,onClick:N},{default:O(()=>[n(W(V(X)(`@WORKBENCH:取消`)),1)]),_:1},8,[`disabled`]),G(a,{type:`primary`,icon:V(u),disabled:A.value||!D.value.trim(),onClick:oe},{default:O(()=>[n(W(V(X)(`@WORKBENCH:发送给 AI`)),1)]),_:1},8,[`icon`,`disabled`])])],64)):(J(),q(`pre`,He,W(f.value||`(等待 LLM 启动…)`),1))]),_:1},8,[`label`]),G(y,{name:`thinking`},{label:O(()=>[L(`span`,null,[n(W(V(X)(`@WORKBENCH:思考`))+` `,1),S.value>0?(J(),q(`span`,Ue,`(`+W(S.value)+`)`,1)):U(``,!0)])]),default:O(()=>[L(`pre`,We,W(p.value||V(X)(`@WORKBENCH:(暂无输出)`)),1)]),_:1}),G(y,{name:`raw`},{label:O(()=>[L(`span`,null,[n(W(V(X)(`@WORKBENCH:原始结果`))+` `,1),ee.value>0?(J(),q(`span`,Ge,`(`+W(ee.value)+`)`,1)):U(``,!0)])]),default:O(()=>[v.value&&s.value===`result`?(J(),k(b,{key:0,type:`warning`,"show-icon":``,closable:!1,class:`ai-split-parse-error`},{title:O(()=>[n(W(V(X)(`@WORKBENCH:模型返回内容解析失败,无法识别为有效的子任务 JSON`)),1)]),default:O(()=>[L(`div`,Q,W(v.value),1),L(`div`,Ke,W(V(X)(`@WORKBENCH:常见原因:desc 内夹杂了 ASCII 双引号、出现尾随逗号,或输出被截断。可在下方文本框中手动修改后点「重新解析」,或重新生成。`)),1),L(`div`,qe,[G(a,{size:`small`,type:`primary`,loading:B.value,onClick:le},{default:O(()=>[n(W(V(X)(`@WORKBENCH:重新解析`)),1)]),_:1},8,[`loading`]),G(a,{size:`small`,onClick:ce},{default:O(()=>[n(W(V(X)(`@WORKBENCH:重新生成`)),1)]),_:1}),G(a,{size:`small`,onClick:r[2]||=e=>c.value=`prompt`},{default:O(()=>[n(W(V(X)(`@WORKBENCH:去编辑指令`)),1)]),_:1})])]),_:1})):U(``,!0),s.value===`result`||m.value?(J(),q(`div`,Je,[L(`span`,Ye,W(V(X)(`@WORKBENCH:可直接编辑下方文本,修正后点「重新解析」即可入库`)),1),G(a,{size:`small`,type:`primary`,loading:B.value,disabled:!m.value.trim(),onClick:le},{default:O(()=>[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:ne.value,class:`ai-split-raw-editor`,resize:`none`},null,8,[`modelValue`,`placeholder`,`readonly`])]),_:1}),G(y,{name:`confirm`,disabled:g.value.length===0},{label:O(()=>[L(`span`,null,[n(W(V(X)(`@WORKBENCH:确认入库`))+` `,1),g.value.length>0?(J(),q(`span`,Xe,`(`+W(g.value.length)+`)`,1)):U(``,!0)])]),default:O(()=>[g.value.length===0?(J(),q(`div`,Ze,W(V(X)(`@WORKBENCH:(暂无子任务)`)),1)):(J(),q(`ul`,Qe,[(J(!0),q(F,null,T(g.value,(e,t)=>(J(),q(`li`,{key:t,class:`ai-split-list__item`},[L(`div`,$e,W(t+1),1),L(`div`,et,[L(`div`,tt,W(e.title),1),L(`div`,nt,W(e.desc),1)])]))),128))]))]),_:1},8,[`disabled`])]),_:1},8,[`modelValue`])),v.value&&s.value===`result`&&g.value.length===0?(J(),q(`div`,rt,[G(i,{color:`#e6a23c`},{default:O(()=>[G(V(Se))]),_:1}),L(`span`,null,W(V(X)(`@WORKBENCH:解析失败,未能从模型输出中提取出子任务 — 请查看「原始结果」`)),1)])):U(``,!0),L(`div`,it,[s.value===`error`||s.value===`result`&&v.value&&g.value.length===0?(J(),k(a,{key:0,onClick:ce},{default:O(()=>[n(W(V(X)(`@WORKBENCH:重新生成`)),1)]),_:1})):U(``,!0),s.value===`result`&&g.value.length>0?(J(),k(a,{key:1,onClick:ce},{default:O(()=>[n(W(V(X)(`@WORKBENCH:重新拆分`)),1)]),_:1})):U(``,!0),G(a,{type:`primary`,disabled:!w.value,onClick:se},{default:O(()=>[n(W(V(X)(`@WORKBENCH:确认入库`))+` (`+W(g.value.length)+`) `,1)]),_:1},8,[`disabled`])])])}}}),[[`__scopeId`,`data-v-85bcc687`]]),ot={class:`ai-chat-pane`},st={key:0,class:`ai-chat-streaming-banner`},ct={key:1,class:`ai-chat-empty`},lt={class:`ai-chat-empty__title`},ut={class:`ai-chat-empty__desc`},dt={key:0,class:`ai-chat-bubble user`},ft={class:`ai-chat-content`},pt={key:1,class:`ai-chat-bubble assistant`},mt={class:`ai-chat-pre ai-chat-pre--think`},ht={key:1,class:`ai-chat-content-text`},gt={key:2,class:`ai-chat-subtasks`},_t={class:`ai-chat-subtasks__head`},vt={class:`ai-chat-subtasks__count`},yt={class:`ai-chat-list`},bt={class:`ai-chat-list__no`},xt={class:`ai-chat-list__body`},St={class:`ai-chat-list__title`},Ct={class:`ai-chat-list__desc`},wt={class:`ai-chat-parse-error__detail`},Tt={class:`ai-chat-pre`},Et={key:5,class:`ai-chat-turn__actions`},Dt={class:`ai-chat-input`},Ot={class:`ai-chat-input__actions`},kt={key:0,class:`ai-chat-history__loading`},At={key:1,class:`ai-chat-history__empty`},jt={key:2,class:`ai-chat-history__list`},Mt={class:`ai-chat-history__title`},Nt={class:`ai-chat-history__meta`},Pt={class:`ai-chat-history__actions`},Ft=Ee(a({__name:`AISplitChatPane`,props:{title:{},desc:{},taskId:{},promptId:{},initialSessionId:{}},emits:[`confirm`],setup(r,{emit:a}){let s=r,c=a,l=P(`idle`),d=P(``),f=P([]),p=P(``),m=P(``),g=null,v=0,y=P(null),b=R(()=>l.value===`streaming`),x=R(()=>{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=P(!1),ee=P(!1),C=P([]);function w(){y.value&&(y.value.scrollTop=y.value.scrollHeight)}async function ne(){let e=p.value.trim();if(!e||b.value)return;if(!d.value&&!s.title.trim()){j.warning(X(`@WORKBENCH:请先填写任务标题`));return}let t=++v;g=new AbortController;let n=g,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 _(),w();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 _(),w()}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 _(),w(),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),j.error(m.value)}finally{t===v&&(g=null)}}function re(){g&&=(g.abort(),null)}function E(){if(b.value){j.warning(X(`@WORKBENCH:请先停止当前生成`));return}f.value=[],d.value=``,m.value=``,l.value=`idle`}function D(e){if(!e.subtasks||e.subtasks.length===0){j.warning(X(`@WORKBENCH:当前没有可应用的子任务`));return}c(`confirm`,e.subtasks.slice())}async function A(){S.value=!0,ee.value=!0;try{let e=await fetch(`/api/workbench/tasks/ai-chat-sessions`).then(e=>e.json());if(!e.success){j.error(e.error||X(`@WORKBENCH:加载历史会话失败`));return}C.value=Array.isArray(e.sessions)?e.sessions:[]}catch(e){j.error(X(`@WORKBENCH:加载历史会话失败: `)+(e?.message||e))}finally{ee.value=!1}}async function N(e){if(S.value=!1,b.value){j.warning(X(`@WORKBENCH:请先停止当前生成`));return}try{let t=await fetch(`/api/workbench/tasks/ai-chat-sessions/${encodeURIComponent(e)}`).then(e=>e.json());if(!t.success){j.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`,j.success(X(`@WORKBENCH:已恢复历史会话`)),await _(),w()}catch(e){j.error(X(`@WORKBENCH:加载历史会话失败: `)+(e?.message||e))}}async function ae(e){try{await B.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){j.error(t.error||X(`@WORKBENCH:删除失败`));return}C.value=C.value.filter(t=>t.sessionId!==e),j.success(X(`@WORKBENCH:已删除`))}catch(e){j.error(X(`@WORKBENCH:删除失败: `)+(e?.message||e))}}function oe(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 I(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=ie,c=e,l=ue,d=t,m=te,g=i;return J(),q(`div`,ot,[L(`div`,{ref_key:`streamEl`,ref:y,class:`ai-chat-stream`},[b.value?(J(),q(`div`,st,[G(s,{class:`is-loading`},{default:O(()=>[G(V(o))]),_:1}),L(`span`,null,W(x.value),1)])):U(``,!0),f.value.length===0&&!b.value?(J(),q(`div`,ct,[G(s,{size:32,color:`#909399`},{default:O(()=>[G(V(se))]),_:1}),L(`div`,lt,W(V(X)(`@WORKBENCH:开始与 AI 对话拆分`)),1),L(`div`,ut,W(V(X)(`@WORKBENCH:输入你想让 AI 怎么拆分或调整(Enter 发送,Shift+Enter 换行)`)),1)])):U(``,!0),(J(!0),q(F,null,T(f.value,(e,t)=>(J(),q(`div`,{key:t,class:z([`ai-chat-turn`,`ai-chat-turn--${e.role}`])},[e.role===`user`?(J(),q(`div`,dt,[L(`pre`,ft,W(e.content),1)])):(J(),q(`div`,pt,[e.thinking?(J(),k(l,{key:0,class:`ai-chat-collapse`},{default:O(()=>[G(c,{title:V(X)(`@WORKBENCH:思考过程`)+` (${e.thinking.length})`,name:`think`},{default:O(()=>[L(`pre`,mt,W(e.thinking),1)]),_:2},1032,[`title`])]),_:2},1024)):U(``,!0),e.content?(J(),q(`div`,ht,W(e.content),1)):U(``,!0),e.subtasks&&e.subtasks.length>0?(J(),q(`div`,gt,[L(`div`,_t,[L(`span`,vt,W(V(X)(`@WORKBENCH:识别到 {n} 个子任务`,{n:e.subtasks.length})),1)]),L(`ul`,yt,[(J(!0),q(F,null,T(e.subtasks,(e,t)=>(J(),q(`li`,{key:t,class:`ai-chat-list__item`},[L(`div`,bt,W(t+1),1),L(`div`,xt,[L(`div`,St,W(e.title),1),L(`div`,Ct,W(e.desc),1)])]))),128))])])):U(``,!0),e.parseError&&(!e.subtasks||e.subtasks.length===0)?(J(),k(l,{key:3,class:`ai-chat-collapse`},{default:O(()=>[G(c,{title:V(X)(`@WORKBENCH:查看解析详情`),name:`diag`},{default:O(()=>[L(`div`,wt,W(e.parseError),1)]),_:2},1032,[`title`])]),_:2},1024)):U(``,!0),e.raw&&e.raw!==e.content?(J(),k(l,{key:4,class:`ai-chat-collapse`},{default:O(()=>[G(c,{title:V(X)(`@WORKBENCH:查看原始 LLM 输出`),name:`raw`},{default:O(()=>[L(`pre`,Tt,W(e.raw),1)]),_:2},1032,[`title`])]),_:2},1024)):U(``,!0),e.subtasks&&e.subtasks.length>0?(J(),q(`div`,Et,[G(d,{type:`primary`,size:`small`,icon:V(u),onClick:t=>D(e)},{default:O(()=>[n(W(V(X)(`@WORKBENCH:应用本轮`))+` (`+W(e.subtasks.length)+`) `,1)]),_:2},1032,[`icon`,`onClick`])])):U(``,!0)]))],2))),128))],512),L(`div`,Dt,[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(ne,[`exact`,`prevent`]),[`enter`])},null,8,[`modelValue`,`disabled`,`placeholder`,`onKeydown`]),L(`div`,Ot,[b.value?(J(),k(d,{key:0,type:`danger`,icon:V(Se),onClick:re},{default:O(()=>[n(W(V(X)(`@WORKBENCH:停止`)),1)]),_:1},8,[`icon`])):(J(),k(d,{key:1,type:`primary`,icon:V(u),disabled:!p.value.trim(),onClick:ne},{default:O(()=>[n(W(V(X)(`@WORKBENCH:发送`)),1)]),_:1},8,[`icon`,`disabled`])),G(d,{disabled:b.value,icon:V(h),onClick:E},{default:O(()=>[n(W(V(X)(`@WORKBENCH:清空对话`)),1)]),_:1},8,[`disabled`,`icon`]),G(d,{disabled:b.value,icon:V(M),onClick:A},{default:O(()=>[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:O(()=>[ee.value?(J(),q(`div`,kt,[G(s,{class:`is-loading`},{default:O(()=>[G(V(o))]),_:1})])):C.value.length===0?(J(),q(`div`,At,W(V(X)(`@WORKBENCH:暂无历史会话`)),1)):(J(),q(`ul`,jt,[(J(!0),q(F,null,T(C.value,e=>(J(),q(`li`,{key:e.sessionId,class:`ai-chat-history__item`},[L(`div`,Mt,W(e.title||`(无标题)`),1),L(`div`,Nt,[L(`span`,null,W(oe(e.updatedAt)),1),a[2]||=L(`span`,null,`·`,-1),L(`span`,null,W(e.messageCount)+` 条消息`,1),a[3]||=L(`span`,null,`·`,-1),L(`span`,null,W(e.latestSubtaskCount)+` 个子任务`,1),a[4]||=L(`span`,null,`·`,-1),L(`span`,null,W(I(e.size)),1)]),L(`div`,Pt,[G(d,{size:`small`,type:`primary`,onClick:t=>N(e.sessionId)},{default:O(()=>[n(W(V(X)(`@WORKBENCH:恢复`)),1)]),_:1},8,[`onClick`]),G(d,{size:`small`,type:`danger`,onClick:t=>ae(e.sessionId)},{default:O(()=>[n(W(V(X)(`@WORKBENCH:删除`)),1)]),_:1},8,[`onClick`])])]))),128))]))]),_:1},8,[`modelValue`,`title`])])}}}),[[`__scopeId`,`data-v-e5b87036`]]),It={class:`ai-split-mode-bar`},Lt=Ee(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=P(`direct`),o=R(()=>[{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=de,l=r;return J(),k(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:O(()=>[L(`div`,It,[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`?(J(),k(at,{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`])):(J(),k(Ft,{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`]]),Rt={class:`wb-attachments__head`},zt={class:`wb-attachments__label`},Bt={class:`wb-attachments__count`},$=[`disabled`],Vt={key:0,class:`wb-attachments__paste-hint`},Ht={key:1,class:`wb-attachments__list`},Ut=[`title`,`onClick`,`onContextmenu`],Wt=[`src`,`alt`],Gt={key:1},Kt={class:`wb-attachment__meta`},qt=[`title`],Jt=[`onClick`,`title`],Yt=Ee(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=R(()=>r.attachments.filter(e=>r.isImage(e))),o=R(()=>a.value.map(e=>`/api/workbench/attachments/${e.id}/raw`)),s=P(0),l=P(!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=P({visible:!1,x:0,y:0,att:null}),p=P(!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`){j({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]),j({type:`success`,message:X(`@WORKBENCH:图片已复制到剪贴板`),duration:1800})}catch(e){j({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)=>(J(),q(F,null,[L(`div`,{class:z([`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)},[L(`div`,Rt,[L(`span`,zt,[n(W(V(X)(`@WORKBENCH:附件`))+` `,1),L(`span`,Bt,W(e.attachments.length)+` / `+W(e.maxCount),1)]),L(`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,$)]),e.isPasteHover?(J(),q(`div`,Vt,W(V(X)(`@WORKBENCH:粘贴图片以快速添加`)),1)):U(``,!0),e.attachments.length>0?(J(),q(`ul`,Ht,[(J(!0),q(F,null,T(e.attachments,t=>(J(),q(`li`,{key:t.id,class:`wb-attachment`},[L(`button`,{type:`button`,class:`wb-attachment__preview`,title:V(X)(`@WORKBENCH:点击预览`),onClick:e=>u(t),onContextmenu:e=>m(t,e)},[L(`div`,{class:z([`wb-attachment__icon`,{"wb-attachment__icon--img":e.isImage(t)}])},[e.isImage(t)?(J(),q(`img`,{key:0,src:`/api/workbench/attachments/${t.id}/raw`,alt:t.originalName,loading:`lazy`},null,8,Wt)):(J(),q(`span`,Gt,W(t.ext.toUpperCase()),1))],2),L(`div`,Kt,[L(`div`,{class:`wb-attachment__name`,title:`${t.originalName} (${e.humanSize(t.size)})`},W(t.originalName),9,qt)])],40,Ut),L(`button`,{class:`wb-attachment__del`,onClick:H(n=>e.onRemove(t),[`stop`]),title:V(X)(`@WORKBENCH:删除`)},`×`,8,Jt)]))),128))])):U(``,!0)],34),(J(),k(ye,{to:`body`},[l.value&&o.value.length>0?(J(),k(V(we),{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)])),(J(),k(ye,{to:`body`},[f.value.visible&&f.value.att&&e.isImage(f.value.att)?(J(),q(`ul`,{key:0,class:`wb-ctx-menu`,style:A({top:f.value.y+`px`,left:f.value.x+`px`}),onContextmenu:r[6]||=H(()=>{},[`prevent`])},[L(`li`,{class:z([`wb-ctx-menu__item`,{"is-disabled":p.value}]),onClick:g},[r[7]||=L(`span`,{class:`wb-ctx-menu__icon`,"aria-hidden":`true`},[L(`svg`,{viewBox:`0 0 24 24`,width:`14`,height:`14`,fill:`none`,stroke:`currentColor`,"stroke-width":`1.8`,"stroke-linecap":`round`,"stroke-linejoin":`round`},[L(`rect`,{x:`9`,y:`9`,width:`11`,height:`11`,rx:`2`}),L(`path`,{d:`M5 15V5a2 2 0 0 1 2-2h10`})])],-1),L(`span`,null,W(V(X)(`@WORKBENCH:复制图片`)),1)],2)],36)):U(``,!0)]))],64))}}),[[`__scopeId`,`data-v-9e1ed466`]]),Xt=[`aria-expanded`],Zt={class:`wb-log-summary__left`},Qt={key:0,class:`wb-log-summary__status wb-log-summary__status--running`},$t={class:`wb-log-summary__label`},en={key:0,class:`wb-log-summary__elapsed`},tn={key:1,class:`wb-log-summary__status wb-log-summary__status--pending`},nn={class:`wb-log-summary__label`},rn={key:2,class:`wb-log-summary__status wb-log-summary__status--done`},an={key:0,class:`wb-log-summary__icon`},on={key:1,class:`wb-log-summary__icon`},sn={class:`wb-log-summary__label`},cn={key:2,class:`wb-log-summary__elapsed`},ln={key:3},un={class:`wb-log-summary__right`},dn={class:`wb-log-summary__meta`},fn=[`title`],pn={class:`wb-log-details__body`},mn=[`open`],hn={class:`wb-log-section__summary`},gn={class:`wb-log-section__tag wb-log-section__tag--user`},_n={class:`wb-log-section__count`},vn=[`title`],yn={class:`wb-log-section__pre wb-log-section__pre--user`},bn=[`open`],xn={class:`wb-log-section__summary`},Sn={class:`wb-log-section__tag wb-log-section__tag--think`},Cn={class:`wb-log-section__count`},wn=[`title`],Tn={class:`wb-log-section__pre wb-log-section__pre--think`},En={class:`wb-log-pre__head`},Dn={class:`wb-log-pre__label`},On={class:`wb-log-pre__meta`},kn=[`title`],An=[`title`,`disabled`],jn={key:1,class:`wb-log-pre__empty`},Mn={key:1,class:`wb-log-fullscreen__empty`},Nn=64*1024,Pn=60,Fn=Ee(a({__name:`JobLogDetails`,props:{job:{}},setup(e){let t=e,n=P(!1);function i(){n.value=!n.value}function a(){let e=t.job.output||``;return e?e.length<=Nn?e:`${X(`@WORKBENCH:…(前文已截断)`)}\n${e.slice(-65536)}`:``}async function o(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 s(e){let n=t.job[e]||``;if(!n){j.warning(X(`@WORKBENCH:暂无内容可复制`));return}await o(n)?j.success(X(`@WORKBENCH:已复制到剪贴板`)):j.error(X(`@WORKBENCH:复制失败`))}async function c(){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){j.warning(X(`@WORKBENCH:暂无内容可复制`));return}await o(e.join(`
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
`))?j.success(X(`@WORKBENCH:已复制到剪贴板`)):j.error(X(`@WORKBENCH:复制失败`))}let l=R(()=>a()),u=R(()=>t.job.status===`running`||t.job.status===`pending`),d=R(()=>{let e=t.job.status;return e===`done`||e===`error`||e===`cancelled`}),f=P(0),p=null;function h(){g(),p=setInterval(()=>{let e=l.value.length;if(e===0){f.value=0,g();return}let t=Math.max(1,Math.ceil(Pn/30));f.value<e&&(f.value=Math.min(e,f.value+t)),f.value>=e&&g()},33)}function g(){p&&=(clearInterval(p),null)}E(()=>[t.job.output?.length||0,t.job.status],([e,t])=>{t===`done`||t===`error`||t===`cancelled`?(g(),f.value=e):f.value<e&&!p&&h()},{immediate:!0}),m(()=>g());let v=R(()=>l.value.slice(0,f.value)),y=R(()=>(t.job.output||``).slice(0,f.value)),b=R(()=>f.value>=(t.job.output||``).length),x=P(null);E(()=>t.job.status,(e,t)=>{e===`running`&&t!==`running`&&(x.value=x.value??Date.now())});let ee=R(()=>{if(!x.value)return``;let e=x.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`)}秒`}),C=P(null),w=!1,T=P(!1);function te(){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 ne(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),te()}),E(()=>(t.job.thinking||``).length,()=>te(),{immediate:!0}),E(()=>(t.job.output||``).length,()=>te());let re=!1,ie=P(!0);function D(e){let t=e.target;re=!0,ie.value=t.open}E(()=>t.job.status,(e,t)=>{!(t===`running`||t===`pending`)&&(e===`running`||e===`pending`)?(re=!1,ie.value=!0):re||(ie.value=!0)}),E(()=>(t.job.output||``).length,async()=>{n.value||(await _(),C.value&&(C.value.scrollTop=C.value.scrollHeight))});let A=P(!1),M=R(()=>!!(t.job.output&&t.job.output.length)),N=P(null);E(A,async e=>{e&&(await _(),N.value&&(N.value.scrollTop=N.value.scrollHeight))}),E(()=>(t.job.output||``).length,async()=>{A.value&&(await _(),N.value&&(N.value.scrollTop=N.value.scrollHeight))});function F(){}return(t,a)=>{let o=r;return J(),q(`div`,{class:z([`wb-log-details`,{"is-running":u.value,"is-pending":e.job.status===`pending`,"is-finished":d.value}])},[L(`div`,{class:`wb-log-summary`,onClick:i,role:`button`,"aria-expanded":!n.value},[L(`span`,Zt,[e.job.status===`running`?(J(),q(`span`,Qt,[L(`span`,$t,W(V(X)(`@WORKBENCH:正在执行…`)),1),a[5]||=L(`span`,{class:`wb-log-dots`,"aria-hidden":`true`},[L(`span`,{class:`wb-log-dots__dot`}),L(`span`,{class:`wb-log-dots__dot`}),L(`span`,{class:`wb-log-dots__dot`})],-1),ee.value?(J(),q(`span`,en,W(ee.value),1)):U(``,!0)])):e.job.status===`pending`?(J(),q(`span`,tn,[L(`span`,nn,W(V(X)(`@WORKBENCH:排队中…`)),1),a[6]||=L(`span`,{class:`wb-log-dots`,"aria-hidden":`true`},[L(`span`,{class:`wb-log-dots__dot`}),L(`span`,{class:`wb-log-dots__dot`}),L(`span`,{class:`wb-log-dots__dot`})],-1)])):d.value?(J(),q(`span`,rn,[e.job.status===`error`?(J(),q(`span`,an,`✗`)):(J(),q(`span`,on,`✓`)),L(`span`,sn,W(e.job.status===`error`?V(X)(`@WORKBENCH:执行出错`):V(X)(`@WORKBENCH:执行完成`)),1),ee.value?(J(),q(`span`,cn,W(ee.value),1)):U(``,!0)])):(J(),q(`span`,ln,W(V(X)(`@WORKBENCH:查看执行日志`)),1))]),L(`span`,un,[L(`span`,dn,W((e.job.output||``).length)+` `+W(V(X)(`@WORKBENCH:字符`)),1),L(`button`,{type:`button`,class:`wb-log-copy`,title:V(X)(`@WORKBENCH:复制全部(含提示词与输出)`),onClick:H(c,[`stop`])},` ⧉ `+W(V(X)(`@WORKBENCH:复制全部`)),9,fn)])],8,Xt),S(L(`div`,pn,[e.job.prompt?(J(),q(`details`,{key:0,class:`wb-log-section`,open:ie.value,onToggle:D},[L(`summary`,hn,[L(`span`,gn,W(V(X)(`@WORKBENCH:用户提示词`)),1),L(`span`,_n,W((e.job.prompt||``).length)+` `+W(V(X)(`@WORKBENCH:字符`)),1),L(`button`,{type:`button`,class:`wb-log-copy wb-log-copy--sm`,title:V(X)(`@WORKBENCH:复制用户提示词`),onClick:a[0]||=H(e=>s(`prompt`),[`stop`])},` ⧉ `+W(V(X)(`@WORKBENCH:复制`)),9,vn)]),L(`pre`,yn,W(e.job.prompt),1)],40,mn)):U(``,!0),e.job.thinking?(J(),q(`details`,{key:1,class:`wb-log-section`,open:T.value,onToggle:ne},[L(`summary`,xn,[L(`span`,Sn,W(V(X)(`@WORKBENCH:Claude 思考`)),1),L(`span`,Cn,W((e.job.thinking||``).length)+` `+W(V(X)(`@WORKBENCH:字符`)),1),L(`button`,{type:`button`,class:`wb-log-copy wb-copy--sm`,title:V(X)(`@WORKBENCH:复制思考内容`),onClick:a[1]||=H(e=>s(`thinking`),[`stop`])},` ⧉ `+W(V(X)(`@WORKBENCH:复制`)),9,wn)]),L(`pre`,Tn,W(e.job.thinking),1)],40,bn)):U(``,!0),L(`div`,En,[L(`span`,Dn,W(V(X)(`@WORKBENCH:模型返回`)),1),L(`span`,On,W((e.job.output||``).length)+` `+W(V(X)(`@WORKBENCH:字符`)),1),L(`button`,{type:`button`,class:`wb-log-copy wb-log-copy--sm`,title:V(X)(`@WORKBENCH:复制模型返回`),onClick:a[2]||=H(e=>s(`output`),[`stop`])},` ⧉ `+W(V(X)(`@WORKBENCH:复制`)),9,kn),L(`button`,{type:`button`,class:`wb-log-copy wb-log-copy--sm`,title:V(X)(`@WORKBENCH:全屏查看模型返回`),disabled:!M.value,onClick:a[3]||=H(e=>A.value=!0,[`stop`])},` ⛶ `+W(V(X)(`@WORKBENCH:全屏`)),9,An)]),L(`div`,{ref_key:`preRef`,ref:C,class:`wb-log-pre`},[M.value?(J(),k(V(Y),{key:0,content:v.value,final:b.value,typewriter:!1,class:`wb-log-pre__render`},null,8,[`content`,`final`])):(J(),q(`div`,jn,W(V(X)(`@WORKBENCH:(暂无输出)`)),1))],512),G(o,{modelValue:A.value,"onUpdate:modelValue":a[4]||=e=>A.value=e,title:V(X)(`@WORKBENCH:模型返回 - 全屏查看`),fullscreen:``,"close-on-click-modal":!1,class:`wb-log-fullscreen-dialog`,onClosed:F},{default:O(()=>[L(`div`,{ref_key:`fullscreenContainerRef`,ref:N,class:`wb-log-fullscreen`},[M.value?(J(),k(V(Y),{key:0,content:y.value,final:b.value,typewriter:!1,class:`wb-log-fullscreen__render`},null,8,[`content`,`final`])):(J(),q(`div`,Mn,W(V(X)(`@WORKBENCH:(暂无输出)`)),1))],512)]),_:1},8,[`modelValue`,`title`])],512),[[ae,!n.value]])],2)}}}),[[`__scopeId`,`data-v-424fafaf`]]);function In(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 Ln(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 Rn={class:`exec-logs`},zn={class:`exec-logs__head`},Bn={class:`exec-logs__title-block`},Vn={class:`exec-logs__stats`},Hn={class:`exec-logs__head-actions`},Un={class:`exec-logs__config`},Wn={class:`exec-logs__config-label`},Gn={class:`exec-logs__config-field`},Kn={class:`exec-logs__config-name`},qn={class:`exec-logs__config-field`},Jn={class:`exec-logs__config-name`},Yn={class:`exec-logs__filter`},Xn={key:0,class:`exec-logs__batch-meta`},Zn={key:0,class:`exec-logs__batch`},Qn={class:`exec-logs__list`},$n={key:0,class:`exec-logs__empty`},er={class:`exec-logs__empty-art`,"aria-hidden":`true`},tr={class:`exec-logs__empty-title`},nr={class:`exec-logs__empty-hint`},rr={class:`exec-card__head`},ir=[`title`],ar={class:`exec-card__meta`},or={key:0,class:`exec-card__task`},sr={key:1,class:`exec-card__time`},cr={key:2,class:`exec-card__exit`},lr=[`title`,`onClick`],ur={key:0,class:`exec-card__error`},dr={key:1,class:`exec-logs__pager`},fr=50,pr=Ee(a({__name:`ExecutionLogManager`,setup(e){function r(e){return e instanceof Error?e.message:String(e)}let i=P([]),a=P(0),o=ge({count:0,sizeMB:0,byStatus:{}}),c=P(!1),u=P(new Set),d=ge({q:``,status:``,page:1}),f=P({maxCount:500,maxSizeMB:256}),m=ge({maxCount:500,maxSizeMB:256}),g=P(!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=R(()=>i.value.length>0&&i.value.every(e=>u.value.has(e.id))),y=R(()=>i.value.some(e=>u.value.has(e.id))&&!v.value);async function b(){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(fr)),e.set(`offset`,String((d.page-1)*fr));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){j.error(X(`@WORKBENCH:加载失败`)+`: `+r(e))}finally{c.value=!1}}async function x(){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 C(){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,j.success(X(`@WORKBENCH:已保存策略`)),await b()}catch(e){j.error(X(`@WORKBENCH:保存失败`)+`: `+r(e))}finally{g.value=!1}}function w(){d.page=1,b()}function ne(){d.q=``,d.status=``,d.page=1,b()}function re(e,t){t?u.value.add(e):u.value.delete(e),u.value=new Set(u.value)}function E(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 D(e){try{await B.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 b()}catch(e){j.error(X(`@WORKBENCH:保存失败`)+`: `+r(e))}}async function k(){let e=Array.from(u.value);if(e.length!==0){try{await B.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`);j.success(X(`@WORKBENCH:成功删除 {count} 条`,{count:t.removed||e.length})),u.value=new Set,await b()}catch(e){j.error(X(`@WORKBENCH:保存失败`)+`: `+r(e))}}}async function M(){let e=o.count;if(e!==0){try{await B.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`);j.success(X(`@WORKBENCH:成功删除 {count} 条`,{count:t.removed||e})),u.value=new Set,await b()}catch(e){j.error(X(`@WORKBENCH:保存失败`)+`: `+r(e))}}}function ae(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(()=>{b(),x()}),(e,r)=>{let l=t,f=N,x=te,j=p,P=ee,oe=s,se=ie,I=K,ce=me;return J(),q(`div`,Rn,[L(`header`,zn,[L(`div`,Bn,[L(`span`,Vn,W(V(X)(`@WORKBENCH:共 {count} 条,占 {size} MB`,{count:o.count,size:o.sizeMB})),1)]),L(`div`,Hn,[G(l,{icon:V(h),size:`small`,loading:c.value,onClick:b},{default:O(()=>[n(W(V(X)(`@WORKBENCH:刷新`)),1)]),_:1},8,[`icon`,`loading`]),G(l,{type:`danger`,plain:``,size:`small`,disabled:o.count===0,onClick:M},{default:O(()=>[n(W(V(X)(`@WORKBENCH:清空全部`)),1)]),_:1},8,[`disabled`])])]),L(`div`,Un,[L(`span`,Wn,W(V(X)(`@WORKBENCH:保存策略`)),1),L(`span`,Gn,[L(`span`,Kn,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`])]),L(`span`,qn,[L(`span`,Jn,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:C},{default:O(()=>[n(W(V(X)(`@WORKBENCH:保存策略`)),1)]),_:1},8,[`loading`])]),L(`div`,Yn,[G(x,{modelValue:d.q,"onUpdate:modelValue":r[2]||=e=>d.q=e,placeholder:V(X)(`@WORKBENCH:搜索标题 / 任务`),clearable:``,size:`small`,style:{width:`240px`},onKeyup:fe(w,[`enter`]),onClear:w},null,8,[`modelValue`,`placeholder`]),G(P,{modelValue:d.status,"onUpdate:modelValue":r[3]||=e=>d.status=e,placeholder:V(X)(`@WORKBENCH:全部状态`),clearable:``,size:`small`,style:{width:`130px`},onChange:w},{default:O(()=>[(J(),q(F,null,T(_,e=>G(j,{key:e.value,label:e.label,value:e.value},null,8,[`label`,`value`])),64))]),_:1},8,[`modelValue`,`placeholder`]),G(l,{size:`small`,onClick:ne},{default:O(()=>[n(W(V(X)(`@WORKBENCH:重置`)),1)]),_:1}),r[5]||=L(`span`,{class:`exec-logs__filter-spacer`},null,-1),u.value.size>0?(J(),q(`span`,Xn,W(V(X)(`@WORKBENCH:已选择 {count} 项`,{count:u.value.size})),1)):U(``,!0)]),u.value.size>0?(J(),q(`div`,Zn,[G(oe,{"model-value":v.value,indeterminate:y.value,onChange:E},{default:O(()=>[n(W(v.value?V(X)(`@WORKBENCH:取消全选`):V(X)(`@WORKBENCH:全选`)),1)]),_:1},8,[`model-value`,`indeterminate`]),G(l,{type:`danger`,size:`small`,onClick:k},{default:O(()=>[n(W(V(X)(`@WORKBENCH:批量删除`)),1)]),_:1})])):U(``,!0),S((J(),q(`div`,Qn,[!c.value&&i.value.length===0?(J(),q(`div`,$n,[L(`div`,er,[G(se,null,{default:O(()=>[G(V(be))]),_:1})]),L(`div`,tr,W(V(X)(`@WORKBENCH:暂无执行日志`)),1),L(`div`,nr,W(V(X)(`@WORKBENCH:点击「执行任务」开始一次执行,日志会出现在这里。`)),1)])):U(``,!0),(J(!0),q(F,null,T(i.value,e=>(J(),q(`article`,{key:e.id,class:z([`exec-card`,{"is-selected":u.value.has(e.id)}])},[L(`header`,rr,[G(oe,{"model-value":u.value.has(e.id),onChange:t=>re(e.id,t)},null,8,[`model-value`,`onChange`]),L(`span`,{class:`exec-card__status`,style:A({color:V(Ln)(e.status),borderColor:V(Ln)(e.status)})},W(V(In)(e.status)),5),L(`span`,{class:`exec-card__title`,title:e.title||V(X)(`@WORKBENCH:无标题`)},W(e.title||V(X)(`@WORKBENCH:无标题`)),9,ir),r[6]||=L(`span`,{class:`exec-card__spacer`},null,-1),L(`span`,ar,[e.taskTitle?(J(),q(`span`,or,`📁 `+W(e.taskTitle),1)):U(``,!0),e.startedAt?(J(),q(`span`,sr,`⏱ `+W(ae(e.startedAt,e.endedAt)),1)):U(``,!0),e.exitCode===null?U(``,!0):(J(),q(`span`,cr,`exit `+W(e.exitCode),1))]),L(`button`,{type:`button`,class:`exec-card__del`,title:V(X)(`@WORKBENCH:删除`),onClick:t=>D(e.id)},`×`,8,lr)]),e.error?(J(),q(`p`,ur,`⚠ `+W(e.error),1)):U(``,!0),G(Fn,{job:e},null,8,[`job`])],2))),128))])),[[ce,c.value]]),a.value>fr?(J(),q(`footer`,dr,[G(I,{"current-page":d.page,"onUpdate:currentPage":r[4]||=e=>d.page=e,"page-size":fr,total:a.value,layout:`prev, pager, next, total`,background:``,small:``,onCurrentChange:b},null,8,[`current-page`,`total`])])):U(``,!0)])}}}),[[`__scopeId`,`data-v-174a9b87`]]),mr={class:`workbench`},hr={class:`workbench__editor-row`},gr={class:`wb-sidebar`},_r={class:`wb-section`},vr={class:`wb-section__head`},yr={class:`wb-section__tag`},br={class:`wb-section__title`},xr={class:`wb-pill wb-section__count`},Sr={class:`wb-task-list`},Cr=[`aria-expanded`,`title`,`onClick`,`onKeydown`],wr=[`title`],Tr={class:`wb-pill wb-task-group__count`},Er=[`data-icon`,`onClick`],Dr=[`data-icon`],Or={class:`wb-task-item__body`},kr=[`title`],Ar={class:`wb-task-item__meta`},jr=[`title`],Mr={class:`wb-pill wb-task-item__num`},Nr=[`title`],Pr={class:`wb-pill wb-task-item__num`},Fr=[`title`],Ir=[`title`,`aria-label`],Lr=[`title`],Rr=[`title`],zr=[`onClick`,`title`,`aria-label`],Br={key:0,class:`wb-empty wb-empty--rich`},Vr={class:`wb-empty__art`,"aria-hidden":`true`},Hr={class:`wb-empty__title`},Ur={class:`wb-empty__hint`},Wr={class:`wb-empty__cta`},Gr={class:`wb-section`},Kr={class:`wb-section__head`},qr={class:`wb-section__tag wb-section__tag--accent`},Jr={class:`wb-section__title`},Yr={class:`wb-pill wb-section__count`},Xr=[`title`,`aria-label`],Zr={class:`wb-prompt-list`},Qr={class:`wb-prompt-item__icon`},$r=[`onClick`,`title`],ei=[`title`],ti=[`onClick`,`title`,`aria-label`],ni={key:0,class:`wb-empty wb-empty--compact`},ri={class:`wb-split`},ii={key:0,class:`wb-placeholder`},ai={class:`wb-split__header`},oi=[`placeholder`],si=[`title`],ci={key:0,class:`wb-meta-save__dot`},li={key:1,class:`wb-meta-save__check`},ui={key:2,class:`wb-meta-save__bang`},di={key:3,class:`wb-meta-save__dot`},fi={value:null},pi=[`value`],mi=[`aria-label`],hi=[`aria-selected`],gi=[`aria-selected`],_i=[`disabled`,`title`],vi=[`title`,`aria-label`],yi=[`title`,`aria-label`],bi=[`open`],xi={class:`wb-task-desc__summary`},Si={class:`wb-task-desc__label`},Ci={key:0,class:`wb-task-desc__tag`},wi={key:0},Ti={key:1,class:`wb-task-desc__tag-attachment`},Ei=[`placeholder`],Di={key:0,class:`wb-exec-list`},Oi={class:`wb-exec-list__header`},ki={class:`wb-exec-list__title`},Ai={class:`wb-split__sub-actions`},ji={key:0,class:`wb-dirty-badge`},Mi={class:`wb-exec-sub-list`},Ni=[`onClick`],Pi={class:`wb-exec-sub-item__row1`},Fi=[`title`],Ii=[`title`],Li={key:0,class:`wb-exec-sub-item__dirty-dot`,title:`未保存`},Ri={class:`wb-exec-sub-item__row2`},zi={key:0,class:`wb-sub-item__pid`},Bi={class:`wb-exec-sub-item__actions`},Vi=[`title`,`onClick`],Hi=[`title`,`onClick`],Ui=[`title`,`onClick`],Wi=[`title`,`disabled`,`onClick`],Gi=[`title`,`disabled`,`onClick`],Ki={key:0,class:`wb-empty wb-empty--rich`},qi={class:`wb-empty__art`,"aria-hidden":`true`},Ji={class:`wb-empty__title`},Yi={class:`wb-empty__cta`},Xi={class:`wb-exec-detail`},Zi={key:0,class:`wb-placeholder`},Qi={class:`wb-exec-detail__head`},$i=[`placeholder`],ea=[`title`],ta=[`placeholder`],na={class:`wb-form-item__label wb-simple__override-summary`},ra=[`title`],ia=[`disabled`],aa=[`placeholder`],oa={key:0,class:`wb-simple__continue`},sa=[`placeholder`],ca={class:`wb-simple__continue-actions`},la={style:{display:`flex`,gap:`8px`,"align-items":`center`}},ua=`__simple`,da=`__no_project__`,fa=`.png,.jpg,.jpeg,.gif,.webp,.bmp,.svg,.pdf,.txt,.md,.csv,.json,.log`,pa=5*1024*1024,ma=Ee(a({__name:`WorkbenchView`,setup(e){let i=P([]),a=P([]),o=P([]),s=P(!1),u=P(null),d=R(()=>a.value.find(e=>e.id===u.value)||null),m=R(()=>d.value?.type===`simple`),h=P(null),_=R(()=>!d.value||m.value||!h.value?null:d.value.subtasks.find(e=>e.id===h.value)||null),C=P(new Map),M=P({title:``,desc:``,promptId:null,simpleOverride:``});function N(){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});C.value=e,d.value?M.value={title:d.value.title,desc:d.value.desc,promptId:d.value.promptId,simpleOverride:d.value.simpleOverride||``}:M.value={title:``,desc:``,promptId:null,simpleOverride:``}}let ae=R(()=>{let e=new Set;if(!d.value)return e;for(let t of d.value.subtasks){let n=C.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}),se=R(()=>ae.value.size>0),I=P(`idle`),ue=P(0),de=null,me=R(()=>{if(!d.value)return!1;let e=d.value;return M.value.title!==e.title||M.value.desc!==e.desc||M.value.promptId!==e.promptId||M.value.simpleOverride!==(e.simpleOverride||``)});function ve(){de!==null&&(clearTimeout(de),de=null)}async function ye(){if(!d.value)return!1;if(!me.value)return!0;if(I.value=`saving`,await xt(!1))return ue.value=Date.now(),I.value=`saved`,setTimeout(()=>{I.value===`saved`&&Date.now()-ue.value>=4e3&&(I.value=`idle`)},4e3),!0;I.value=`error`;let e=Date.now();return setTimeout(()=>{I.value===`error`&&Date.now()-e>=4e3&&(I.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(()=>{ye()},1500))},{deep:!0}),E(u,async(e,t)=>{ve(),d.value&&me.value&&await ye()}),E(u,()=>{Ct.value=!1});function Se(e){try{let t=new Blob([JSON.stringify(e)],{type:`application/json`});navigator.sendBeacon?.(`/api/workbench/tasks`,t)}catch{}}function we(){d.value&&me.value&&Se(d.value)}let K=ge({visible:!1,editing:null,name:``,content:``,aiLoading:!1}),Y=ge({visible:!1,text:``,loading:!1,saving:!1}),Ee=P(!1),Z=ge({visible:!1,editing:null,title:``,desc:``,promptId:null,type:`complex`,simpleOverride:``}),Oe=null,ke=De();function Ae(){ke.setRunning(o.value.filter(e=>e.status===`running`).length)}function je(e){return o.value.find(t=>t.subId===e)||null}function Me(e,t){if(e===`hello`){o.value=t.jobs||[],Ae();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),Ae();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`&&j.error(t.error||X(`@WORKBENCH:执行出错`))}let Ne=[{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]}];function Pe(e){let t=(e||``).trim();if(!t)return`doc`;for(let e of Ne)if(e.patterns.some(e=>e.test(t)))return e.key;return`doc`}let Fe={icon:le(be),image:le(v),test:le(ce),ui:le(y),doc:le(be),idea:le(y)};function Ie(e){return Fe[Pe(e.title)]}function Le(e){if(!e)return[];let t=`${e.id}${ua}`;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 Re(e){if(!e)return null;let t=Le(e);return t.length>0?t[t.length-1]:null}function ze(e){return e?e.status===`pending`||e.status===`running`?`running`:e.status===`done`?`done`:e.status===`cancelled`?`cancelled`:`error`:`idle`}function Be(e){return Array.isArray(e.attachments)?e.attachments.length:0}function Ve(e){return Array.isArray(e.subtasks)?e.subtasks.length:0}function He(e){return Array.isArray(e.subtasks)?e.subtasks.filter(e=>e&&e.status===`done`).length:0}function Ue(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 We(){i.value=(await fetch(`/api/workbench/prompts`).then(e=>e.json()).catch(()=>({prompts:[]}))).prompts||[]}async function Ge(){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),N()}let Q=P({path:``,name:``});async function Ke(){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||``})}let qe=P(new Set);function Je(e){return qe.value.has(e)}function Ye(e){qe.value.has(e)?qe.value.delete(e):qe.value.add(e),qe.value=new Set(qe.value)}let Xe=R(()=>{let e=a.value,t=new Map;for(let n of e){let e=(n.projectPath||``).trim()||da;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===da?1:t===da?-1:e.localeCompare(t));return{groups:r.map(e=>({path:e,label:e===da?X(`@WORKBENCH:未关联项目`):e,tasks:t.get(e)})),hasMultiple:r.length>1}});function Ze(e){if(!e||e===da)return e;let t=e.split(/[\\/]/).filter(Boolean);return t.length<=1?e:t.slice(-2).join(`/`)}E(()=>Xe.value.groups.map(e=>e.path),e=>{let t=Q.value.path,n=new Set(qe.value),r=!1;for(let i of e)i!==t&&!n.has(i)&&(n.add(i),r=!0);r&&(qe.value=n)},{immediate:!0});async function Qe(){o.value=(await fetch(`/api/workbench/jobs`).then(e=>e.json()).catch(()=>({jobs:[]}))).jobs||[],Ae()}async function $e(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),Ae(),t.removed||0):(console.warn(`[clearJobsByTask] failed:`,t?.error),0)}catch(e){return console.warn(`[clearJobsByTask] error:`,e),0}}async function et(){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 B.confirm(s,X(`@WORKBENCH:清空执行内容`),{confirmButtonText:X(`@WORKBENCH:清空`),cancelButtonText:X(`@WORKBENCH:取消`),type:`warning`})}catch{return}if(i>0){j.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),Ae(),j.success(c.message||X(`@WORKBENCH:已清空执行内容`))}else j.error(c?.error||X(`@WORKBENCH:清空失败`))}async function tt(){if(!d.value)return;let e=d.value,t=Array.isArray(e.subtasks)?e.subtasks.length:0;if(t===0){j.warning(X(`@WORKBENCH:当前任务没有子任务`));return}if(o.value.find(t=>t.taskId===e.id&&(t.status===`running`||t.status===`pending`))){j.warning(X(`@WORKBENCH:有子任务正在执行,请先停止`));return}try{await B.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=[],h.value=null,ae.value.clear(),C.value.clear(),o.value=o.value.filter(t=>t.taskId!==e.id),Ae(),j.success(n.message||X(`@WORKBENCH:已清空子任务`))):j.error(n?.error||X(`@WORKBENCH:清空失败`))}function nt(){Oe&&=(Oe.close(),null),Oe=new EventSource(`/api/workbench/events`),Oe.onmessage=e=>{try{let t=JSON.parse(e.data);Me(t.event,t.payload)}catch{}},Oe.onerror=()=>{Oe&&=(Oe.close(),null),setTimeout(nt,3e3)}}function rt(){K.editing=null,K.name=``,K.content=``,K.aiLoading=!1,K.visible=!0}function it(e){K.editing=e,K.name=e.name,K.content=e.content,K.aiLoading=!1,K.visible=!0}async function at(){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||``,j.success(X(`@WORKBENCH:已生成,可继续编辑`))):j.error(e.error||X(`@WORKBENCH:生成失败`))}catch(e){j.error(X(`@WORKBENCH:网络错误: `)+(e&&e.message||e))}finally{K.aiLoading=!1}}}async function ot(){Y.visible=!0,Y.loading=!0;try{let e=await fetch(`/api/workbench/prompts/ai-instruction`).then(e=>e.json());e.success?Y.text=e.instruction||``:j.error(e.error||X(`@WORKBENCH:读取指令失败`))}catch(e){j.error(X(`@WORKBENCH:读取指令失败`)+`: `+(e&&e.message||e))}finally{Y.loading=!1}}async function st(){if(!Y.text.trim()){j.warning(X(`@WORKBENCH:指令内容不能为空`));return}Y.saving=!0;try{let e=await fetch(`/api/workbench/prompts/ai-instruction`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({instruction:Y.text})}).then(e=>e.json());e.success?(j.success(X(`@WORKBENCH:已保存指令`)),Y.visible=!1):j.error(e.error||X(`@WORKBENCH:保存失败`))}catch(e){j.error(X(`@WORKBENCH:网络错误: `)+(e&&e.message||e))}finally{Y.saving=!1}}async function ct(){if(!K.name.trim()||!K.content.trim()){j.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?(j.success(X(`@WORKBENCH:已保存`)),K.visible=!1,We()):j.error(t.error||X(`@WORKBENCH:保存失败`))}async function lt(e){await B.confirm(X(`@WORKBENCH:删除提示词「{name}」?`,{name:e.name}),X(`@WORKBENCH:确认`),{type:`warning`}),await fetch(`/api/workbench/prompts/${e.id}`,{method:`DELETE`}),We();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)}));Ge()}function ut(){Z.editing=null,Z.title=``,Z.desc=``,Z.promptId=null,Z.type=`simple`,Z.simpleOverride=``,Z.visible=!0}async function dt(){let e={id:Z.editing?.id,title:Z.title.trim(),desc:Z.desc,promptId:Z.promptId,type:Z.type,simpleOverride:Z.type===`simple`?Z.simpleOverride:``,subtasks:Z.editing?.subtasks||[]};!Z.editing?.id&&Q.value.path&&(e.projectPath=Q.value.path);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){j.success(X(`@WORKBENCH:已保存`));let e=!Z.editing?.id;Z.visible=!1,await Ge(),e&&t.task?.id?(u.value=t.task.id,N()):u.value||=t.task.id}else j.error(t.error||X(`@WORKBENCH:保存失败`))}async function ft(e,t){if(e.type===t)return;let n=e.type===`complex`&&t===`simple`&&(e.subtasks?.length??0)>0;if(n)try{await B.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){j.error(i.error||X(`@WORKBENCH:保存失败`));return}await Ge(),j.success(X(t===`simple`?`@WORKBENCH:已切换为简单任务`:`@WORKBENCH:已切换为复杂任务`))}async function pt(e){d.value&&await ft(d.value,e)}async function mt(e){await B.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),Ge()}async function ht(e){u.value!==e.id&&(ve(),d.value&&me.value&&await ye(),u.value=e.id,N())}E(()=>d.value,e=>{if(!e||e.type===`simple`){h.value=null;return}h.value=e.subtasks.find(e=>e.status===`running`)?.id||e.subtasks[0]?.id||null},{immediate:!0}),E(()=>d.value?.subtasks?.length,()=>{!d.value||m.value||(!h.value||!d.value.subtasks.find(e=>e.id===h.value))&&(h.value=d.value.subtasks[0]?.id||null)}),E(()=>d.value?.subtasks?.map(e=>({id:e.id,status:e.status}))||[],()=>{if(!d.value||m.value)return;let e=d.value.subtasks,t=e.find(e=>e.id===h.value);if(!t||t.status!==`running`){let t=e.find(e=>e.status===`running`);t&&t.id!==h.value&&(h.value=t.id)}});let gt=P(new Set);function _t(e){return gt.value.has(e)}function vt(e,t){t?gt.value.add(e):gt.value.delete(e),gt.value=new Set(gt.value)}async function yt(){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),vt(e.id,!0);try{await xt(!1)}finally{vt(e.id,!1)}}async function bt(e){if(d.value){d.value.subtasks=d.value.subtasks.filter(t=>t.id!==e.id),vt(e.id,!0);try{await xt(!1)}finally{vt(e.id,!1)}}}async function xt(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&&j.success(X(`@WORKBENCH:已保存拆分`)),await Ge(),!0):(j.error(t.error||X(`@WORKBENCH:保存失败`)),!1)}async function St(){await xt(!0)}let Ct=P(!1);function wt(){if(d.value){if(!(d.value.title||``).trim()){j.warning(X(`@WORKBENCH:请先填写任务标题`));return}Ct.value=!0}}function Tt(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:[]});j.success(X(`@WORKBENCH:已生成 {n} 个子任务,请审阅后保存`,{n:e.length}))}}async function Et(e){if(e.type===`simple`)return Dt(e);if(!e.subtasks||e.subtasks.length===0){j.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 xt(!1))return}await $e(e.id);let t=await fetch(`/api/workbench/tasks/${e.id}/run`,{method:`POST`}).then(e=>e.json());t.success?j.success(t.message||X(`@WORKBENCH:已加入执行队列`)):j.error(t.error||X(`@WORKBENCH:执行失败`))}async function Dt(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 xt(!1))return}await $e(e.id);let t=await fetch(`/api/workbench/tasks/${e.id}/run-simple`,{method:`POST`}).then(e=>e.json());t.success?j.success(t.message||X(`@WORKBENCH:已加入执行队列`)):j.error(t.error||X(`@WORKBENCH:执行失败`))}async function Ot(e,t){let n=Le(e).slice(-1)[0];if(!n){j.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?j.success(r.message||X(`@WORKBENCH:已加入续接队列`)):j.error(r.error||X(`@WORKBENCH:续接失败`))}let kt=ge({});async function At(e){try{await B.confirm(X(`@WORKBENCH:退出后将清空本次对话的全部轮次,确认?`),X(`@WORKBENCH:退出执行`),{confirmButtonText:X(`@WORKBENCH:退出`),cancelButtonText:X(`@WORKBENCH:取消`),type:`warning`})}catch{return}await $e(e.id),delete kt[e.id]}async function jt(e){let t=(kt[e.id]||``).trim();t&&(await Ot(e,t),kt[e.id]=``)}async function Mt(e){if(!d.value)return;let t=d.value,n=je(e.id);if(n&&(n.status===`running`||n.status===`pending`)){j.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 xt(!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?j.success(i.message||X(`@WORKBENCH:已开始执行子任务`)):j.error(i.error||X(`@WORKBENCH:执行失败`))}function Nt(e){if(e.status===`done`)return!1;let t=je(e.id);return!(t&&(t.status===`running`||t.status===`pending`))}function Pt(e){if(!Nt(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 Ft(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 xt(!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?j.success(i.message||X(`@WORKBENCH:已从此处开始执行`)):j.error(i.error||X(`@WORKBENCH:执行失败`))}async function It(e){if(d.value&&!_t(e.id)){vt(e.id,!0);try{let t=C.value.get(e.id);t&&C.value.set(e.id,{...t,status:`todo`}),e.status=`todo`,await xt(!1)}finally{vt(e.id,!1)}}}async function Rt(e){try{await B.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?j.success(X(`@WORKBENCH:已发送停止信号`)):j.error(t.error||X(`@WORKBENCH:停止失败`))}l(async()=>{await Promise.all([We(),Ge(),Ke(),Qe()]),nt(),window.addEventListener(`beforeunload`,we)}),c(()=>{Oe&&=(Oe.close(),null),window.removeEventListener(`beforeunload`,we),d.value&&me.value&&Se(d.value)});let zt=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`]),Bt=P({}),$=P(null);function Vt(e){return!!Bt.value[e]}function Ht(e,t){if(e instanceof File)return e;let n=e.type||`application/octet-stream`;return new File([e],t,{type:n})}function Ut(e){return e.kind===`task`?`task-${e.task?.id??``}`:`sub-${e.sub.id}`}function Wt(e){let t=e.kind===`task`?e.task?.attachments:e.sub.attachments;return Array.isArray(t)?t:[]}function Gt(e,t){e.kind===`task`?e.task&&(e.task.attachments=t):e.sub.attachments=t}function Kt(e){return e.kind===`task`?`/api/workbench/tasks/${e.task?.id??``}/attachments`:`/api/workbench/subtasks/${e.sub.id}/attachments`}function qt(e,t){return e.kind===`task`?`/api/workbench/tasks/${e.task?.id??``}/attachments/${t}`:`/api/workbench/subtasks/${e.sub.id}/attachments/${t}`}function Jt(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`);Zt(t,Ht(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&&Zt(t,Ht(n,n.name||`pasted-file`))}}}function Xt(e,t){$.value=null,Array.from(e.dataTransfer?.files||[]).forEach(e=>Zt(t,e))}async function Zt(e,t){if(t.size>pa){j.error(`「${t.name}」${X(`@WORKBENCH:超过 5MB 限制`)}`);return}if(!zt.has(t.type)&&!t.name.match(/\.(png|jpg|jpeg|gif|webp|bmp|svg|pdf|txt|md|markdown|csv|json|log)$/i)){j.error(`${X(`@WORKBENCH:不支持的文件类型`)}(${t.name})`);return}let n=Wt(e);if(n.length>=9){j.error(X(`@WORKBENCH:单个任务最多 9 个附件`));return}if(n.find(e=>e.originalName===t.name&&e.size===t.size)){j.info(`${t.name} ${X(`@WORKBENCH:已存在,已复用`)}`);return}let r=Ut(e);Bt.value[r]=!0;try{let n=await fetch(Kt(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=Wt(e);r.push(n.attachment),Gt(e,r),j.success(`${X(`@WORKBENCH:已添加:`)}${t.name}`)}else j.error(n.error||X(`@WORKBENCH:上传失败`))}catch(e){j.error(X(`@WORKBENCH:上传失败`)+`:`+(e&&e.message||e))}finally{Bt.value[r]=!1}}async function Qt(e,t){try{await B.confirm(X(`@WORKBENCH:删除附件「{name}」?`,{name:t.originalName}),X(`@WORKBENCH:确认`),{type:`warning`})}catch{return}let n=await fetch(qt(e,t.id),{method:`DELETE`}).then(e=>e.json());n.success?(Gt(e,Wt(e).filter(e=>e.id!==t.id)),j.success(X(`@WORKBENCH:已删除`))):j.error(n.error||X(`@WORKBENCH:删除失败`))}function $t(e){let t=document.createElement(`input`);t.type=`file`,t.accept=fa,t.multiple=!0,t.onchange=()=>{Array.from(t.files||[]).forEach(t=>Zt(e,t))},t.click()}let en=new Set([`png`,`jpg`,`jpeg`,`gif`,`webp`,`bmp`,`svg`]);function tn(e){return en.has(String(e.ext||``).toLowerCase())}function nn(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=ie,l=t,C=r,E=te,j=xe,M=f,N=g,P=b,ce=p,R=ee;return J(),q(`div`,mr,[L(`div`,hr,[L(`aside`,gr,[L(`section`,_r,[L(`header`,vr,[L(`span`,yr,W(V(X)(`@WORKBENCH:任务`)),1),L(`h3`,br,W(V(X)(`@WORKBENCH:任务列表`)),1),L(`span`,xr,W(a.value.length),1)]),L(`button`,{class:`wb-new-btn`,onClick:ut},[G(c,{class:`wb-new-btn__icon`},{default:O(()=>[G(V(x))]),_:1}),L(`span`,null,W(V(X)(`@WORKBENCH:新建任务`)),1),o[47]||=L(`span`,{class:`wb-new-btn__shortcut`},`N`,-1)]),L(`ul`,Sr,[(J(!0),q(F,null,T(Xe.value.groups,e=>(J(),q(F,{key:e.path},[Xe.value.hasMultiple?(J(),q(`li`,{key:0,class:z([`wb-task-group__head`,{"is-current":e.path===Q.value.path,"is-collapsed":Je(e.path)}]),role:`button`,tabindex:`0`,"aria-expanded":!Je(e.path),title:Je(e.path)?V(X)(`@WORKBENCH:展开`):V(X)(`@WORKBENCH:收起`),onClick:t=>Ye(e.path),onKeydown:[fe(H(t=>Ye(e.path),[`prevent`]),[`enter`]),fe(H(t=>Ye(e.path),[`prevent`]),[`space`])]},[G(c,{class:`wb-task-group__caret`},{default:O(()=>[(J(),k(ne(Je(e.path)?V(D):V(re))))]),_:2},1024),G(c,{class:`wb-task-group__icon`},{default:O(()=>[G(V(Te))]),_:1}),L(`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:Ze(e.label)),9,wr),L(`span`,Tr,W(e.tasks.length),1)],42,Cr)):U(``,!0),Je(e.path)?U(``,!0):(J(!0),q(F,{key:1},T(e.tasks,e=>(J(),q(`li`,{key:e.id,class:z([`wb-task-item`,{active:e.id===u.value,"has-attachment":Be(e)>0,"is-other-project":e.projectPath&&e.projectPath!==Q.value.path,"is-running":Ue(e)}]),"data-icon":Pe(e.title),onClick:t=>ht(e)},[L(`div`,{class:`wb-task-item__avatar`,"data-icon":Pe(e.title)},[G(c,null,{default:O(()=>[(J(),k(ne(Ie(e))))]),_:2},1024)],8,Dr),L(`div`,Or,[L(`div`,{class:`wb-task-item__title`,title:e.title},W(e.title||V(X)(`@WORKBENCH:未命名任务`)),9,kr),L(`div`,Ar,[Ve(e)>0?(J(),q(`span`,{key:0,class:z([`wb-task-item__meta-item`,{"wb-task-item__meta-item--running":Ue(e)}]),title:V(X)(`@WORKBENCH:个子任务`)},[G(c,{class:`wb-task-item__meta-icon`},{default:O(()=>[G(V(w))]),_:1}),L(`span`,Mr,W(He(e))+`/`+W(Ve(e)),1)],10,jr)):U(``,!0),Be(e)>0?(J(),q(`span`,{key:1,class:`wb-task-item__meta-item`,title:V(X)(`@WORKBENCH:附件`)},[G(c,{class:`wb-task-item__meta-icon`},{default:O(()=>[G(V(v))]),_:1}),L(`span`,Pr,W(Be(e)),1)],8,Nr)):U(``,!0),e.promptId?(J(),q(`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:O(()=>[G(V(y))]),_:1})],8,Fr)):U(``,!0),L(`button`,{type:`button`,class:z([`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,Ir),e.projectPath&&e.projectPath!==Q.value.path?(J(),q(`span`,{key:3,class:`wb-task-item__meta-item wb-task-item__meta-item--project`,title:e.projectPath},W(Ze(e.projectPath)),9,Lr)):U(``,!0)])]),Ue(e)?(J(),q(`span`,{key:0,class:`wb-task-item__running-dot`,title:V(X)(`@WORKBENCH:执行中`),"aria-hidden":`true`},null,8,Rr)):U(``,!0),L(`button`,{class:`wb-task-item__del`,onClick:H(t=>mt(e),[`stop`]),title:V(X)(`@WORKBENCH:删除`),"aria-label":V(X)(`@WORKBENCH:删除`)},[G(c,null,{default:O(()=>[G(V(_e))]),_:1})],8,zr)],10,Er))),128))],64))),128)),a.value.length===0?(J(),q(`li`,Br,[L(`div`,Vr,[G(c,null,{default:O(()=>[G(V(oe))]),_:1})]),L(`div`,Hr,W(V(X)(`@WORKBENCH:暂无任务`)),1),L(`div`,Ur,W(V(X)(`@WORKBENCH:点击上方按钮新建`)),1),L(`div`,Wr,[G(l,{type:`primary`,size:`small`,icon:V(x),onClick:ut},{default:O(()=>[n(W(V(X)(`@WORKBENCH:新建任务`)),1)]),_:1},8,[`icon`])])])):U(``,!0)])]),L(`section`,Gr,[L(`header`,Kr,[L(`span`,qr,W(V(X)(`@WORKBENCH:提示`)),1),L(`h3`,Jr,W(V(X)(`@WORKBENCH:预置提示词`)),1),L(`span`,Yr,W(i.value.length),1),L(`button`,{class:`wb-section__action`,onClick:rt,title:V(X)(`@WORKBENCH:新建提示词`),"aria-label":V(X)(`@WORKBENCH:新建提示词`)},[G(c,null,{default:O(()=>[G(V(x))]),_:1})],8,Xr)]),L(`ul`,Zr,[(J(!0),q(F,null,T(i.value,e=>(J(),q(`li`,{key:e.id,class:`wb-prompt-item`},[L(`div`,Qr,[G(c,null,{default:O(()=>[G(V(y))]),_:1})]),L(`span`,{class:`wb-prompt-item__name`,onClick:t=>it(e),title:e.content},W(e.name),9,$r),Q.value.name?(J(),q(`span`,{key:0,class:`wb-prompt-item__project`,title:V(X)(`@WORKBENCH:适用于当前项目`)+`:`+Q.value.path},W(Q.value.name),9,ei)):U(``,!0),L(`button`,{class:`wb-prompt-item__del`,onClick:t=>lt(e),title:V(X)(`@WORKBENCH:删除`),"aria-label":V(X)(`@WORKBENCH:删除`)},[G(c,null,{default:O(()=>[G(V(_e))]),_:1})],8,ti)]))),128)),i.value.length===0?(J(),q(`li`,ni,W(V(X)(`@WORKBENCH:暂无提示词`)),1)):U(``,!0)])])]),L(`section`,ri,[d.value?(J(),q(F,{key:1},[L(`div`,ai,[S(L(`input`,{class:`wb-input wb-input--title`,"onUpdate:modelValue":o[0]||=e=>d.value.title=e,placeholder:V(X)(`@WORKBENCH:任务标题`)},null,8,oi),[[Ce,d.value.title]]),I.value!==`idle`||me.value?(J(),q(`span`,{key:0,class:z([`wb-meta-save`,{"is-saving":I.value===`saving`,"is-saved":I.value===`saved`,"is-error":I.value===`error`,"is-dirty":me.value&&I.value===`idle`}]),title:I.value===`saving`?V(X)(`@WORKBENCH:保存中…`):I.value===`error`?V(X)(`@WORKBENCH:保存失败`):I.value===`saved`?V(X)(`@WORKBENCH:已保存`):``},[I.value===`saving`?(J(),q(`span`,ci)):I.value===`saved`?(J(),q(`span`,li,`✓`)):I.value===`error`?(J(),q(`span`,ui,`!`)):(J(),q(`span`,di)),n(` `+W(I.value===`saving`?V(X)(`@WORKBENCH:保存中…`):I.value===`saved`?V(X)(`@WORKBENCH:已保存`):I.value===`error`?V(X)(`@WORKBENCH:保存失败`):V(X)(`@WORKBENCH:有未保存的更改`)),1)],10,si)):U(``,!0),S(L(`select`,{class:`wb-select`,"onUpdate:modelValue":o[1]||=e=>d.value.promptId=e},[L(`option`,fi,W(V(X)(`@WORKBENCH:不绑定预置提示词`)),1),(J(!0),q(F,null,T(i.value,e=>(J(),q(`option`,{key:e.id,value:e.id},W(e.name),9,pi))),128))],512),[[he,d.value.promptId]]),L(`div`,{class:`wb-mode-switch`,role:`tablist`,"aria-label":V(X)(`@WORKBENCH:任务类型`)},[L(`button`,{type:`button`,role:`tab`,class:z([`wb-mode-switch__btn`,{"is-active":!m.value}]),"aria-selected":!m.value,onClick:o[2]||=e=>pt(`complex`)},W(V(X)(`@WORKBENCH:复杂`)),11,hi),L(`button`,{type:`button`,role:`tab`,class:z([`wb-mode-switch__btn`,{"is-active":m.value}]),"aria-selected":m.value,onClick:o[3]||=e=>pt(`simple`)},W(V(X)(`@WORKBENCH:简单`)),11,gi),L(`span`,{class:z([`wb-mode-switch__indicator`,{"is-right":m.value}]),"aria-hidden":`true`},null,2)],8,mi),m.value?U(``,!0):(J(),q(`button`,{key:1,type:`button`,class:`wb-ai-split-btn`,disabled:!d.value.title||!d.value.title.trim(),title:V(X)(`@WORKBENCH:AI 拆分`),onClick:wt},[o[48]||=L(`svg`,{class:`wb-ai-split-btn__icon`,viewBox:`0 0 16 16`,width:`14`,height:`14`,"aria-hidden":`true`},[L(`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),L(`span`,null,W(V(X)(`@WORKBENCH:AI 拆分`)),1)],8,_i)),G(l,{type:`primary`,loading:!1,onClick:o[4]||=e=>Et(d.value)},{default:O(()=>[n(W(m.value?V(X)(`@WORKBENCH:执行`):V(X)(`@WORKBENCH:执行任务`)),1)]),_:1}),L(`button`,{type:`button`,class:`wb-logs-inline-btn wb-logs-inline-btn--danger`,title:V(X)(`@WORKBENCH:清空当前任务的所有执行内容`),"aria-label":V(X)(`@WORKBENCH:清空当前任务的所有执行内容`),onClick:et},[G(c,{class:`wb-logs-inline-btn__icon`},{default:O(()=>[G(V(pe))]),_:1}),L(`span`,null,W(V(X)(`@WORKBENCH:清空执行`)),1)],8,vi),L(`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:O(()=>[G(V(be))]),_:1}),L(`span`,null,W(V(X)(`@WORKBENCH:执行日志`)),1)],8,yi)]),L(`details`,{class:`wb-task-desc`,open:Ee.value,onToggle:o[13]||=e=>Ee.value=e.target.open},[L(`summary`,xi,[G(c,{class:`wb-task-desc__caret`},{default:O(()=>[(J(),k(ne(Ee.value?V(re):V(D))))]),_:1}),L(`span`,Si,W(V(X)(`@WORKBENCH:任务描述(可选)`)),1),d.value.desc&&d.value.desc.length>0||d.value.attachments&&d.value.attachments.length>0?(J(),q(`span`,Ci,[d.value.desc&&d.value.desc.length>0?(J(),q(`span`,wi,W(V(X)(`@WORKBENCH:已填写`)),1)):U(``,!0),d.value.attachments&&d.value.attachments.length>0?(J(),q(`span`,Ti,W(d.value.attachments.length),1)):U(``,!0)])):U(``,!0)]),S(L(`textarea`,{class:`wb-textarea`,"onUpdate:modelValue":o[6]||=e=>d.value.desc=e,placeholder:V(X)(`@WORKBENCH:任务描述(可选)`),rows:`2`,onPaste:o[7]||=e=>Jt(e,{kind:`task`,task:d.value})},null,40,Ei),[[Ce,d.value.desc]]),G(Yt,{attachments:d.value.attachments||[],"is-image":tn,"human-size":nn,"is-uploading":Vt(`task-`+d.value.id),"is-paste-hover":$.value===`task-`+d.value.id,"max-count":9,"on-pick":()=>$t({kind:`task`,task:d.value}),"on-remove":e=>Qt({kind:`task`,task:d.value},e),onPaste:o[8]||=e=>Jt(e,{kind:`task`,task:d.value}),onDrop:o[9]||=H(e=>Xt(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,bi),L(`div`,{class:z([`wb-execution-body`,{"wb-execution-body--simple":m.value}])},[m.value?U(``,!0):(J(),q(`div`,Di,[L(`div`,Oi,[L(`h4`,ki,W(V(X)(`@WORKBENCH:子任务拆分`)),1),L(`div`,Ai,[G(l,{size:`small`,plain:``,icon:V(x),disabled:d.value.subtasks.length===0,onClick:yt},{default:O(()=>[n(W(V(X)(`@WORKBENCH:添加子任务`)),1)]),_:1},8,[`icon`,`disabled`]),G(l,{size:`small`,type:se.value?`primary`:`default`,disabled:d.value.subtasks.length===0,onClick:St},{default:O(()=>[n(W(V(X)(`@WORKBENCH:保存拆分`))+` `,1),se.value?(J(),q(`span`,ji,W(ae.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:tt},{default:O(()=>[n(W(V(X)(`@WORKBENCH:清空子任务`)),1)]),_:1},8,[`icon`,`disabled`,`title`])])]),L(`ul`,Mi,[(J(!0),q(F,null,T(d.value.subtasks,e=>(J(),q(`li`,{key:e.id,class:z([`wb-exec-sub-item`,{"is-selected":h.value===e.id,"is-running":e.status===`running`,"is-done":e.status===`done`,"is-dirty":ae.value.has(e.id),"is-persisting":_t(e.id)}]),onClick:t=>h.value=e.id},[L(`div`,Pi,[L(`span`,{class:`wb-sub-item__status wb-sub-item__status--dot`,style:A({background:V(Ln)(e.status)}),title:V(X)(`@WORKBENCH:任务完成状态`)},[...o[49]||=[L(`span`,{class:`wb-simple__status-dot`,"aria-hidden":`true`},null,-1)]],12,Fi),L(`span`,{class:`wb-exec-sub-item__title`,title:e.title},W(e.title||V(X)(`@WORKBENCH:未命名子任务`)),9,Ii),ae.value.has(e.id)?(J(),q(`span`,Li)):U(``,!0)]),L(`div`,Ri,[je(e.id)?(J(),q(`span`,zi,`PID: `+W(je(e.id)?.pid),1)):U(``,!0),L(`span`,Bi,[Nt(e)?(J(),q(`button`,{key:0,class:`wb-exec-sub-btn wb-exec-sub-btn--run`,title:V(X)(`@WORKBENCH:单独执行此子任务`),onClick:H(t=>Mt(e),[`stop`])},W(V(X)(`@WORKBENCH:执行`)),9,Vi)):U(``,!0),Pt(e)?(J(),q(`button`,{key:1,class:`wb-exec-sub-btn wb-exec-sub-btn--run-from`,title:V(X)(`@WORKBENCH:从此处执行后续子任务`),onClick:H(t=>Ft(e),[`stop`])},W(V(X)(`@WORKBENCH:从此处开始`)),9,Hi)):U(``,!0),je(e.id)&&(je(e.id)?.status===`running`||je(e.id)?.status===`pending`)?(J(),q(`button`,{key:2,class:`wb-exec-sub-btn wb-exec-sub-btn--stop`,title:V(X)(`@WORKBENCH:停止执行`),onClick:H(t=>Rt(je(e.id)),[`stop`])},W(V(X)(`@WORKBENCH:停止`)),9,Ui)):U(``,!0),e.status===`done`?(J(),q(`button`,{key:3,class:`wb-exec-sub-btn wb-exec-sub-btn--undo`,title:V(X)(`@WORKBENCH:取消完成`),disabled:_t(e.id),onClick:H(t=>It(e),[`stop`])},W(V(X)(`@WORKBENCH:取消完成`)),9,Wi)):U(``,!0),L(`button`,{class:`wb-exec-sub-btn wb-exec-sub-btn--del`,title:V(X)(`@WORKBENCH:删除`),disabled:_t(e.id),onClick:H(t=>bt(e),[`stop`])},`×`,8,Gi)])])],10,Ni))),128)),d.value.subtasks.length===0?(J(),q(`li`,Ki,[L(`div`,qi,[G(c,null,{default:O(()=>[G(V(w))]),_:1})]),L(`div`,Ji,W(V(X)(`@WORKBENCH:拆分任务,逐项执行`)),1),L(`div`,Yi,[G(l,{type:`primary`,size:`small`,icon:V(x),onClick:yt},{default:O(()=>[n(W(V(X)(`@WORKBENCH:添加子任务`)),1)]),_:1},8,[`icon`])])])):U(``,!0)])])),L(`div`,Xi,[m.value?(J(),q(F,{key:1},[L(`details`,{class:z([`wb-simple__override`,{"has-content":!!(d.value.simpleOverride&&d.value.simpleOverride.trim())}])},[L(`summary`,na,[G(c,{class:`wb-simple__override-caret`},{default:O(()=>[G(V(D))]),_:1}),L(`span`,null,W(V(X)(`@WORKBENCH:覆盖预置提示词(可选)`)),1),d.value.simpleOverride&&d.value.simpleOverride.trim()?(J(),q(`span`,{key:0,class:`wb-simple__override-tag`,title:V(X)(`@WORKBENCH:已填写覆盖内容`)},W(V(X)(`@WORKBENCH:已填写`)),9,ra)):U(``,!0),ze(Re(d.value))===`running`&&Re(d.value)?(J(),q(`button`,{key:1,class:`wb-simple__stop`,disabled:_t(Re(d.value).id),onClick:o[24]||=H(e=>Rt(Re(d.value)),[`stop`])},W(V(X)(`@WORKBENCH:停止`)),9,ia)):U(``,!0)]),S(L(`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,aa),[[Ce,d.value.simpleOverride]])],2),(J(!0),q(F,null,T(Le(d.value),e=>(J(),k(Fn,{key:e.id,job:e},null,8,[`job`]))),128)),Re(d.value)&&[`done`,`error`,`cancelled`].includes(ze(Re(d.value)))?(J(),q(`div`,oa,[S(L(`textarea`,{class:`wb-textarea wb-simple__continue-input`,"onUpdate:modelValue":o[26]||=e=>kt[d.value.id]=e,placeholder:V(X)(`@WORKBENCH:输入后续问题继续对话…(Ctrl+Enter 发送)`),rows:`3`,onKeydown:o[27]||=fe(H(e=>jt(d.value),[`ctrl`,`prevent`]),[`enter`])},null,40,sa),[[Ce,kt[d.value.id]]]),L(`div`,ca,[G(l,{onClick:o[28]||=e=>At(d.value)},{default:O(()=>[n(W(V(X)(`@WORKBENCH:退出`)),1)]),_:1}),G(l,{type:`primary`,disabled:!(kt[d.value.id]||``).trim(),onClick:o[29]||=e=>jt(d.value)},{default:O(()=>[n(W(V(X)(`@WORKBENCH:发送`)),1)]),_:1},8,[`disabled`])])])):U(``,!0)],64)):(J(),q(F,{key:0},[_.value?(J(),q(F,{key:1},[L(`div`,Qi,[S(L(`input`,{class:`wb-input`,"onUpdate:modelValue":o[14]||=e=>_.value.title=e,placeholder:V(X)(`@WORKBENCH:子任务标题`),onClick:o[15]||=H(()=>{},[`stop`]),onPaste:o[16]||=e=>Jt(e,{kind:`sub`,task:d.value,sub:_.value})},null,40,$i),[[Ce,_.value.title]]),ae.value.has(_.value.id)?(J(),q(`span`,{key:0,class:`wb-sub-item__dirty`,title:V(X)(`@WORKBENCH:有未保存的更改`)},W(V(X)(`@WORKBENCH:未保存`)),9,ea)):U(``,!0)]),S(L(`textarea`,{class:`wb-textarea wb-textarea--sm`,"onUpdate:modelValue":o[17]||=e=>_.value.desc=e,placeholder:V(X)(`@WORKBENCH:子任务描述 / 独立提示词覆盖`),rows:`3`,onPaste:o[18]||=e=>Jt(e,{kind:`sub`,task:d.value,sub:_.value})},null,40,ta),[[Ce,_.value.desc]]),je(_.value.id)?(J(),k(Fn,{key:0,job:je(_.value.id)},null,8,[`job`])):U(``,!0),G(Yt,{attachments:_.value.attachments||[],"is-image":tn,"human-size":nn,"is-uploading":Vt(`sub-`+_.value.id),"is-paste-hover":$.value===_.value.id,"max-count":9,"on-pick":()=>$t({kind:`sub`,task:d.value,sub:_.value}),"on-remove":e=>Qt({kind:`sub`,task:d.value,sub:_.value},e),onPaste:o[19]||=e=>Jt(e,{kind:`sub`,task:d.value,sub:_.value}),onDrop:o[20]||=H(e=>Xt(e,{kind:`sub`,task:d.value,sub:_.value}),[`prevent`]),onDragover:o[21]||=H(e=>$.value=_.value.id,[`prevent`]),onDragenter:o[22]||=H(e=>$.value=_.value.id,[`prevent`]),onDragleave:o[23]||=e=>$.value=$.value===_.value.id?null:$.value},null,8,[`attachments`,`is-uploading`,`is-paste-hover`,`on-pick`,`on-remove`])],64)):(J(),q(`div`,Zi,[L(`p`,null,W(d.value.subtasks.length===0?V(X)(`@WORKBENCH:手动添加子任务,或让 AI 帮你自动拆分`):V(X)(`@WORKBENCH:左侧选择子任务查看详情`)),1)]))],64))])],2)],64)):(J(),q(`div`,ii,[L(`p`,null,W(V(X)(`@WORKBENCH:左侧选择任务,或新建一个任务开始`)),1)]))])]),G(C,{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:O(()=>[G(pr)]),_:1},8,[`modelValue`,`title`]),G(C,{modelValue:K.visible,"onUpdate:modelValue":o[34]||=e=>K.visible=e,title:K.editing?V(X)(`@WORKBENCH:编辑提示词`):V(X)(`@WORKBENCH:新建提示词`),width:`640px`},{footer:O(()=>[G(l,{onClick:o[33]||=e=>K.visible=!1},{default:O(()=>[n(W(V(X)(`@WORKBENCH:取消`)),1)]),_:1}),G(l,{type:`primary`,onClick:ct},{default:O(()=>[n(W(V(X)(`@WORKBENCH:保存`)),1)]),_:1})]),default:O(()=>[G(M,{"label-position":`top`},{default:O(()=>[G(j,{label:V(X)(`@WORKBENCH:名称`)},{default:O(()=>[G(E,{modelValue:K.name,"onUpdate:modelValue":o[31]||=e=>K.name=e,placeholder:V(X)(`@WORKBENCH:如:代码审查 / 写测试`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`]),G(j,null,{default:O(()=>[L(`div`,la,[G(l,{type:`primary`,plain:``,loading:K.aiLoading,onClick:at},{default:O(()=>[n(W(V(X)(`@WORKBENCH:AI 生成项目架构说明`)),1)]),_:1},8,[`loading`]),G(l,{onClick:ot},{default:O(()=>[n(W(V(X)(`@WORKBENCH:编辑指令`)),1)]),_:1})])]),_:1}),G(j,{label:V(X)(`@WORKBENCH:内容`)},{default:O(()=>[G(E,{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(C,{modelValue:Y.visible,"onUpdate:modelValue":o[37]||=e=>Y.visible=e,title:V(X)(`@WORKBENCH:编辑生成指令`),width:`720px`,"append-to-body":``},{footer:O(()=>[G(l,{onClick:o[36]||=e=>Y.visible=!1},{default:O(()=>[n(W(V(X)(`@WORKBENCH:取消`)),1)]),_:1}),G(l,{type:`primary`,loading:Y.saving,onClick:st},{default:O(()=>[n(W(V(X)(`@WORKBENCH:保存`)),1)]),_:1},8,[`loading`])]),default:O(()=>[G(M,{"label-position":`top`},{default:O(()=>[G(j,{label:V(X)(`@WORKBENCH:指令内容`)},{default:O(()=>[G(E,{modelValue:Y.text,"onUpdate:modelValue":o[35]||=e=>Y.text=e,type:`textarea`,rows:18,placeholder:V(X)(`@WORKBENCH:指令内容`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])]),_:1})]),_:1},8,[`modelValue`,`title`]),G(C,{modelValue:Z.visible,"onUpdate:modelValue":o[45]||=e=>Z.visible=e,title:Z.editing?V(X)(`@WORKBENCH:编辑任务`):V(X)(`@WORKBENCH:新建任务`),width:`600px`},{footer:O(()=>[G(l,{onClick:o[44]||=e=>Z.visible=!1},{default:O(()=>[n(W(V(X)(`@WORKBENCH:取消`)),1)]),_:1}),G(l,{type:`primary`,onClick:dt},{default:O(()=>[n(W(V(X)(`@WORKBENCH:保存`)),1)]),_:1})]),default:O(()=>[G(M,{"label-position":`top`},{default:O(()=>[G(j,{label:V(X)(`@WORKBENCH:标题(可选)`)},{default:O(()=>[G(E,{modelValue:Z.title,"onUpdate:modelValue":o[38]||=e=>Z.title=e,placeholder:V(X)(`@WORKBENCH:不填则自动命名为「无标题」,稍后可在任务列表里改名`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`]),G(j,{label:V(X)(`@WORKBENCH:类型`)},{default:O(()=>[G(P,{modelValue:Z.type,"onUpdate:modelValue":o[39]||=e=>Z.type=e},{default:O(()=>[G(N,{value:`complex`},{default:O(()=>[n(W(V(X)(`@WORKBENCH:复杂任务(需要拆分子任务)`)),1)]),_:1}),G(N,{value:`simple`},{default:O(()=>[n(W(V(X)(`@WORKBENCH:简单任务(直接执行)`)),1)]),_:1})]),_:1},8,[`modelValue`])]),_:1},8,[`label`]),Z.type===`simple`?(J(),k(j,{key:0,label:V(X)(`@WORKBENCH:描述`)},{default:O(()=>[G(E,{modelValue:Z.desc,"onUpdate:modelValue":o[40]||=e=>Z.desc=e,type:`textarea`,rows:4,placeholder:V(X)(`@WORKBENCH:把要做的事直接写在这里,执行时会把这段描述作为 prompt 喂给 Claude`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])):(J(),k(j,{key:1,label:V(X)(`@WORKBENCH:描述`)},{default:O(()=>[G(E,{modelValue:Z.desc,"onUpdate:modelValue":o[41]||=e=>Z.desc=e,type:`textarea`,rows:3},null,8,[`modelValue`])]),_:1},8,[`label`])),Z.type===`simple`?(J(),k(j,{key:2,label:V(X)(`@WORKBENCH:覆盖预置提示词(可选)`)},{default:O(()=>[G(E,{modelValue:Z.simpleOverride,"onUpdate:modelValue":o[42]||=e=>Z.simpleOverride=e,type:`textarea`,rows:5,placeholder:V(X)(`@WORKBENCH:留空则使用「预置提示词」下拉里选定的模板;可用变量同子任务覆盖。`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])):U(``,!0),G(j,{label:V(X)(`@WORKBENCH:预置提示词`)},{default:O(()=>[G(R,{modelValue:Z.promptId,"onUpdate:modelValue":o[43]||=e=>Z.promptId=e,clearable:``,placeholder:V(X)(`@WORKBENCH:不绑定`),style:{width:`100%`}},{default:O(()=>[(J(!0),q(F,null,T(i.value,e=>(J(),k(ce,{key:e.id,label:e.name,value:e.id},null,8,[`label`,`value`]))),128))]),_:1},8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])]),_:1})]),_:1},8,[`modelValue`,`title`]),d.value?(J(),k(Lt,{key:0,modelValue:Ct.value,"onUpdate:modelValue":o[46]||=e=>Ct.value=e,title:d.value.title,desc:d.value.desc,"task-id":d.value.id,"prompt-id":d.value.promptId,onConfirm:Tt},null,8,[`modelValue`,`title`,`desc`,`task-id`,`prompt-id`])):U(``,!0)])}}}),[[`__scopeId`,`data-v-710087b7`]]);export{ma as default};
|