zen-gitsync 2.13.14 → 2.13.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/package.json +1 -1
- package/scripts/README_COLOR_CONVERTER.md +196 -196
- package/scripts/README_FONTSIZE_CONVERTER.md +278 -278
- package/scripts/README_SPACING_CONVERTER.md +126 -126
- package/scripts/README_STYLE_VARS.md +180 -180
- package/src/ui/public/assets/{EditorView-S6HDGyLD.js → EditorView-nLJuJf8I.js} +0 -0
- package/src/ui/public/assets/{SourceMapView-C10WxgGh.js → SourceMapView-BfQkRIld.js} +1 -1
- package/src/ui/public/assets/WorkbenchView-DBm4y9hO.css +1 -0
- package/src/ui/public/assets/WorkbenchView-DadqVl2m.js +9 -0
- package/src/ui/public/assets/{_plugin-vue_export-helper-8__zdPsB.js → _plugin-vue_export-helper-FEqtfvX2.js} +3 -3
- package/src/ui/public/assets/index-BB8LQ04I.css +1 -0
- package/src/ui/public/assets/{index-D-XpqSmG.js → index-YZlo31ni.js} +11 -11
- package/src/ui/public/assets/{vendor-D72Z0Jmi.js → vendor-1pu0KtT-.js} +90 -90
- package/src/ui/public/assets/{vendor-F3eVqHe1.css → vendor-B99WlFa_.css} +1 -1
- package/src/ui/public/favicon.svg +75 -75
- package/src/ui/public/index.html +22 -22
- package/src/ui/public/logo.svg +74 -74
- package/src/ui/server/routes/workbench.js +226 -21
- package/src/ui/public/assets/WorkbenchView-7COIW5s0.js +0 -9
- package/src/ui/public/assets/WorkbenchView-zVvptY6a.css +0 -1
- package/src/ui/public/assets/index-CHX2_Fog.css +0 -1
|
@@ -83,11 +83,12 @@ const MAX_ATTACHMENTS_PER_SUBTASK = 9;
|
|
|
83
83
|
const DEFAULT_SUBTASK_INSTRUCTION_ZH = `你是一名任务拆分助手。
|
|
84
84
|
|
|
85
85
|
【思考过程】
|
|
86
|
-
在给出 JSON 之前,请先在内部仔细思考(如果模型支持,把思考放在 reasoning
|
|
87
|
-
-
|
|
88
|
-
-
|
|
86
|
+
在给出 JSON 之前,请先在内部仔细思考(如果模型支持,把思考放在 reasoning 中;否则可以先输出一段较长的仔细分析,再输出 JSON)。分析要覆盖足够维度,不要简短一两句话就过:
|
|
87
|
+
- 任务的真实目标是什么?用户提供的描述/图片/上下文里有哪些关键信息和隐藏诉求?
|
|
88
|
+
- 涉及哪些技术栈、模块、文件、约束?是否有易被忽略的边界条件、风险点?
|
|
89
89
|
- 自然的执行顺序是什么?哪些步骤是前置依赖?哪些可以并行?
|
|
90
|
-
-
|
|
90
|
+
- 哪些步骤可能失败、需要单独验证?验证方式是什么?
|
|
91
|
+
- 是否需要先做调研/读现有代码的步骤,再做修改?
|
|
91
92
|
|
|
92
93
|
【拆分原则】
|
|
93
94
|
1. 单一职责:每个子任务只做一件事,避免"做 A 和 B"。
|
|
@@ -111,11 +112,12 @@ JSON 要用 \`\`\`json ... \`\`\` 代码块包裹,前面可以有分析文字
|
|
|
111
112
|
const DEFAULT_SUBTASK_INSTRUCTION_EN = `You are a task breakdown assistant.
|
|
112
113
|
|
|
113
114
|
[Thinking process]
|
|
114
|
-
Before producing JSON, think carefully (put your thoughts in reasoning if the model supports it; otherwise output a
|
|
115
|
-
- What is the real goal? What key
|
|
116
|
-
- Which stack, modules, files, constraints are involved? Any easily missed edge cases?
|
|
115
|
+
Before producing JSON, think carefully (put your thoughts in reasoning if the model supports it; otherwise output a longer careful analysis first, then JSON). Cover enough dimensions — don't settle for a one-or-two-sentence summary:
|
|
116
|
+
- What is the real goal? What key info and hidden needs are in the description / images / context?
|
|
117
|
+
- Which stack, modules, files, constraints are involved? Any easily missed edge cases or risks?
|
|
117
118
|
- What is the natural execution order? What blocks what? What can run in parallel?
|
|
118
|
-
- Which steps may fail and need separate verification?
|
|
119
|
+
- Which steps may fail and need separate verification? How will you verify?
|
|
120
|
+
- Should a research / read-existing-code step come before the changes?
|
|
119
121
|
|
|
120
122
|
[Breakdown principles]
|
|
121
123
|
1. Single responsibility: each subtask does only one thing, avoid bundling "do A and B".
|
|
@@ -998,7 +1000,9 @@ function snapshotJobs() {
|
|
|
998
1000
|
startedAt: j.startedAt || null,
|
|
999
1001
|
endedAt: j.endedAt || null,
|
|
1000
1002
|
exitCode: typeof j.exitCode === 'number' ? j.exitCode : null,
|
|
1001
|
-
error: j.error || null
|
|
1003
|
+
error: j.error || null,
|
|
1004
|
+
// 续接对话用:claude --output-format stream-json 的 system.init 事件捕获到的 session_id
|
|
1005
|
+
claudeSessionId: j.claudeSessionId || null
|
|
1002
1006
|
}));
|
|
1003
1007
|
}
|
|
1004
1008
|
|
|
@@ -1006,16 +1010,21 @@ function snapshotJobs() {
|
|
|
1006
1010
|
// 返回 { pid, child }:调用方可以监听 child.stdout/stderr 实时收集输出。
|
|
1007
1011
|
// 不再走 cmd /k 弹窗——claude -p 是非交互模式,输出通过 stdout pipe 实时回传
|
|
1008
1012
|
// 到前端面板展示。
|
|
1009
|
-
function launchClaudeInNewWindow(cwd, promptText) {
|
|
1013
|
+
function launchClaudeInNewWindow(cwd, promptText, resumeSessionId) {
|
|
1010
1014
|
return new Promise((resolve, reject) => {
|
|
1011
|
-
const args = [
|
|
1015
|
+
const args = [];
|
|
1016
|
+
// 续接历史会话:--resume 必须放在 -p 之前,确保 claude CLI 先识别 resume 上下文
|
|
1017
|
+
if (resumeSessionId) {
|
|
1018
|
+
args.push('--resume', String(resumeSessionId));
|
|
1019
|
+
}
|
|
1020
|
+
args.push(
|
|
1012
1021
|
'-p', promptText,
|
|
1013
1022
|
'--input-format', 'text',
|
|
1014
1023
|
'--output-format', 'stream-json',
|
|
1015
1024
|
'--verbose',
|
|
1016
1025
|
'--permission-mode', 'bypassPermissions',
|
|
1017
1026
|
'--dangerously-skip-permissions'
|
|
1018
|
-
|
|
1027
|
+
);
|
|
1019
1028
|
let child;
|
|
1020
1029
|
let spawnedExe = 'claude';
|
|
1021
1030
|
if (process.platform === 'win32') {
|
|
@@ -1088,8 +1097,15 @@ async function runTaskQueue(task, repoPath, branch) {
|
|
|
1088
1097
|
* 前序 done 子任务的输出摘要(in-place 追加)。用于把同一任务下
|
|
1089
1098
|
* 前面已完成的 sub 产物拼到当前 sub 的 prompt 头部,让 Claude
|
|
1090
1099
|
* 知道上下文。单独跑一个 sub 时,这个数组里只会有"前面 done 的 sub"。
|
|
1100
|
+
* @param {object} [options]
|
|
1101
|
+
* @param {string|null} [options.resumeSessionId]
|
|
1102
|
+
* 续接历史 claude 会话:传入上一轮通过 stream-json 的 system.init
|
|
1103
|
+
* 事件捕获到的 session_id,本轮以 --resume <id> 启动,claude 会带着
|
|
1104
|
+
* 上下文继续对话。前端"简单任务执行完成后继续聊"走的就是这条路径。
|
|
1091
1105
|
*/
|
|
1092
|
-
async function runSingleSubtask(task, sub, repoPath, branch, priorOutputs) {
|
|
1106
|
+
async function runSingleSubtask(task, sub, repoPath, branch, priorOutputs, options) {
|
|
1107
|
+
const opts = options || {}
|
|
1108
|
+
const resumeSessionId = opts.resumeSessionId || null
|
|
1093
1109
|
const MAX_PREV_OUTPUT_CHARS = 2000
|
|
1094
1110
|
const promptTemplate = sub.promptOverride || (task.promptId
|
|
1095
1111
|
? (await readJson(PROMPTS_FILE, { prompts: [] })).prompts.find(p => p.id === task.promptId)?.content
|
|
@@ -1124,10 +1140,18 @@ ${prompt}`
|
|
|
1124
1140
|
// claude -p 字符串模式会扫描 prompt 中出现的本地文件路径并自动
|
|
1125
1141
|
// 识别为附件(图片 / PDF / 文本均可)。
|
|
1126
1142
|
// 主任务附件对所有 sub 都可见;子任务自己的附件只对该 sub 可见。
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
];
|
|
1143
|
+
// 注意:run-simple 路径下 virtualSub.attachments 就是 task.attachments 的同一引用,
|
|
1144
|
+
// 不去重会把同一张图在 prompt 里列两遍。按 absolutePath 去重。
|
|
1145
|
+
const taskAtts = Array.isArray(task.attachments) ? task.attachments : [];
|
|
1146
|
+
const subAtts = Array.isArray(sub.attachments) ? sub.attachments : [];
|
|
1147
|
+
const seen = new Set();
|
|
1148
|
+
const allAttachments = [];
|
|
1149
|
+
for (const a of [...subAtts, ...taskAtts]) {
|
|
1150
|
+
if (!a || !a.absolutePath) continue;
|
|
1151
|
+
if (seen.has(a.absolutePath)) continue;
|
|
1152
|
+
seen.add(a.absolutePath);
|
|
1153
|
+
allAttachments.push(a);
|
|
1154
|
+
}
|
|
1131
1155
|
if (allAttachments.length > 0) {
|
|
1132
1156
|
const lines = allAttachments
|
|
1133
1157
|
.filter(a => a && a.absolutePath)
|
|
@@ -1144,7 +1168,9 @@ ${prompt}`
|
|
|
1144
1168
|
subId: sub.id,
|
|
1145
1169
|
title: `${task.title} / ${sub.title}`,
|
|
1146
1170
|
status: 'pending',
|
|
1147
|
-
prompt
|
|
1171
|
+
prompt,
|
|
1172
|
+
// 续接历史会话时先填上,首条 system.init 事件回来后再用真值覆盖(通常等同)
|
|
1173
|
+
claudeSessionId: resumeSessionId
|
|
1148
1174
|
};
|
|
1149
1175
|
jobs.set(jobId, job);
|
|
1150
1176
|
sub.status = 'running';
|
|
@@ -1152,7 +1178,7 @@ ${prompt}`
|
|
|
1152
1178
|
publish('job:update', job);
|
|
1153
1179
|
|
|
1154
1180
|
try {
|
|
1155
|
-
const { pid, child } = await launchClaudeInNewWindow(repoPath || process.cwd(), prompt);
|
|
1181
|
+
const { pid, child } = await launchClaudeInNewWindow(repoPath || process.cwd(), prompt, resumeSessionId);
|
|
1156
1182
|
job.pid = pid;
|
|
1157
1183
|
// 保存 child 引用,供 cancel 接口调用 kill
|
|
1158
1184
|
job.child = child;
|
|
@@ -1194,6 +1220,15 @@ ${prompt}`
|
|
|
1194
1220
|
}
|
|
1195
1221
|
let evt;
|
|
1196
1222
|
try { evt = JSON.parse(trimmed) } catch { continue }
|
|
1223
|
+
// 捕获 system.init 里的 session_id,供后续"续接对话"用(--resume <id>)。
|
|
1224
|
+
// 一个 claude -p 调用只在首行发一次,所以仅在 job 还没记到时写入。
|
|
1225
|
+
if (evt.type === 'system' && evt.subtype === 'init' && typeof evt.session_id === 'string') {
|
|
1226
|
+
if (!job.claudeSessionId || job.claudeSessionId !== evt.session_id) {
|
|
1227
|
+
job.claudeSessionId = evt.session_id;
|
|
1228
|
+
publish('job:update', job);
|
|
1229
|
+
}
|
|
1230
|
+
continue;
|
|
1231
|
+
}
|
|
1197
1232
|
if (evt.type !== 'assistant') continue;
|
|
1198
1233
|
const blocks = evt.message?.content;
|
|
1199
1234
|
if (!Array.isArray(blocks)) continue;
|
|
@@ -1590,6 +1625,11 @@ ${subSummaries.map((s, i) => `\n### [${i + 1}] ${s.name} (${s.root})\n${s.summar
|
|
|
1590
1625
|
const desc = String(req.body?.desc || '').trim();
|
|
1591
1626
|
const taskId = String(req.body?.taskId || '').trim();
|
|
1592
1627
|
const promptId = String(req.body?.promptId || '').trim();
|
|
1628
|
+
// customUserBlock:用户在前端 prompt 预览页编辑过的 user prompt。非空时
|
|
1629
|
+
// 直接拿它发给 LLM,跳过服务端拼装;为空时按老逻辑现拼。
|
|
1630
|
+
// 注意:即便传了 customUserBlock,attachments/imageDataUrls 仍按 taskId 重新读,
|
|
1631
|
+
// 因为图片要随消息发,不能跟 prompt 文本一起塞。
|
|
1632
|
+
const customUserBlock = typeof req.body?.customUserBlock === 'string' ? req.body.customUserBlock : '';
|
|
1593
1633
|
if (!title) {
|
|
1594
1634
|
return res.status(400).json({ success: false, error: '任务标题不能为空' });
|
|
1595
1635
|
}
|
|
@@ -1687,7 +1727,7 @@ ${subSummaries.map((s, i) => `\n### [${i + 1}] ${s.name} (${s.root})\n${s.summar
|
|
|
1687
1727
|
} catch { /* 没拿到附件不影响拆分 */ }
|
|
1688
1728
|
}
|
|
1689
1729
|
|
|
1690
|
-
const userBlock = `${userInstruction}
|
|
1730
|
+
const userBlock = customUserBlock.trim() ? customUserBlock : `${userInstruction}
|
|
1691
1731
|
|
|
1692
1732
|
---
|
|
1693
1733
|
|
|
@@ -1700,7 +1740,7 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
|
|
|
1700
1740
|
- 项目根目录:${projectPath || '(未指定)'}
|
|
1701
1741
|
- 主要 manifest:${manifestHint || '(未识别到)'}
|
|
1702
1742
|
|
|
1703
|
-
|
|
1743
|
+
请先仔细分析(可以放在 reasoning 中或直接写出来)。仔细分析指:列出 5 个维度——任务真实目标 / 关键技术栈与边界 / 自然执行顺序 / 风险点与可能失败步骤 / 是否需要前置调研——不要简短一两句话就过;分析过后再给出 JSON。JSON 用 \`\`\`json ... \`\`\` 包裹:
|
|
1704
1744
|
{
|
|
1705
1745
|
"subtasks": [
|
|
1706
1746
|
{ "title": "子任务标题", "desc": "具体描述" }
|
|
@@ -1753,6 +1793,103 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
|
|
|
1753
1793
|
}
|
|
1754
1794
|
});
|
|
1755
1795
|
|
|
1796
|
+
// POST /api/workbench/tasks/ai-split-preview
|
|
1797
|
+
// body: { title, desc?, taskId?, promptId? }
|
|
1798
|
+
// → { success, system, user, hasImages, imageCount }
|
|
1799
|
+
// "AI 拆分前预览/编辑 prompt" 用:跟 /ai-split-subtasks 做完全一样的拼装,
|
|
1800
|
+
// 但**不调 LLM**,只把拼好的 system + user 返回。前端在 UI 上 textarea 展示,
|
|
1801
|
+
// 用户改完按"发送给 AI"再正式调 /ai-split-subtasks 并把改过的文本作为
|
|
1802
|
+
// customUserBlock 传回。这样省一次 LLM 调用,且让用户能修正提示词后再拆分。
|
|
1803
|
+
app.post('/api/workbench/tasks/ai-split-preview', async (req, res) => {
|
|
1804
|
+
try {
|
|
1805
|
+
const title = String(req.body?.title || '').trim();
|
|
1806
|
+
const desc = String(req.body?.desc || '').trim();
|
|
1807
|
+
const taskId = String(req.body?.taskId || '').trim();
|
|
1808
|
+
const promptId = String(req.body?.promptId || '').trim();
|
|
1809
|
+
if (!title) {
|
|
1810
|
+
return res.status(400).json({ success: false, error: '任务标题不能为空' });
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
const userInstruction = await readSubtaskInstruction(req);
|
|
1814
|
+
const projectPath = typeof getCurrentProjectPath === 'function' ? getCurrentProjectPath() : '';
|
|
1815
|
+
const projectName = projectPath ? path.basename(projectPath) : '(未指定项目)';
|
|
1816
|
+
const manifestHint = await detectProjectManifest(projectPath);
|
|
1817
|
+
|
|
1818
|
+
let templateBlock = '';
|
|
1819
|
+
if (promptId) {
|
|
1820
|
+
try {
|
|
1821
|
+
const promptData = await readJson(PROMPTS_FILE, { prompts: [] });
|
|
1822
|
+
const p = (promptData.prompts || []).find(x => x.id === promptId);
|
|
1823
|
+
if (p && p.content) {
|
|
1824
|
+
templateBlock = `\n\n## 子任务执行模板(每个拆出的子任务最终会被这套模板包裹后送给 claude 执行;拆分时请确保子任务能让模板里的 {{sub.title}} / {{sub.desc}} 等变量填得有意义)\n模板名:${p.name || '(未命名)'}\n---\n${p.content}\n---`;
|
|
1825
|
+
}
|
|
1826
|
+
} catch { /* 模板读取失败不影响预览 */ }
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
// 附件:只列条目,不读图片二进制(preview 阶段不需要 image_data_url)
|
|
1830
|
+
let attachmentBlock = '';
|
|
1831
|
+
let imageCount = 0;
|
|
1832
|
+
if (taskId) {
|
|
1833
|
+
try {
|
|
1834
|
+
const data = await readJson(TASKS_FILE, { tasks: [] });
|
|
1835
|
+
const task = (data.tasks || []).find(t => t.id === taskId);
|
|
1836
|
+
const atts = Array.isArray(task?.attachments) ? task.attachments : [];
|
|
1837
|
+
if (atts.length > 0) {
|
|
1838
|
+
const lines = [];
|
|
1839
|
+
for (let i = 0; i < atts.length; i++) {
|
|
1840
|
+
const a = atts[i];
|
|
1841
|
+
if (!a || !a.absolutePath) continue;
|
|
1842
|
+
lines.push(` ${i + 1}. [${a.mimeType || 'application/octet-stream'}] ${a.absolutePath}`);
|
|
1843
|
+
if (isImageExt(a.ext)) imageCount++;
|
|
1844
|
+
}
|
|
1845
|
+
if (lines.length > 0) {
|
|
1846
|
+
const imgNote = imageCount > 0
|
|
1847
|
+
? `(其中 ${imageCount} 张图片已随消息一并发送,请直接基于图片内容拆分)`
|
|
1848
|
+
: '';
|
|
1849
|
+
attachmentBlock = `\n\n## 任务附件${imgNote}\n${lines.join('\n')}`;
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
} catch { /* 没拿到附件不影响预览 */ }
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
const userBlock = `${userInstruction}
|
|
1856
|
+
|
|
1857
|
+
---
|
|
1858
|
+
|
|
1859
|
+
## 待拆分的任务
|
|
1860
|
+
标题:${title}
|
|
1861
|
+
${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateBlock}
|
|
1862
|
+
|
|
1863
|
+
## 项目上下文(仅供参考,便于拆分时考虑项目特性)
|
|
1864
|
+
- 项目名称:${projectName}
|
|
1865
|
+
- 项目根目录:${projectPath || '(未指定)'}
|
|
1866
|
+
- 主要 manifest:${manifestHint || '(未识别到)'}
|
|
1867
|
+
|
|
1868
|
+
请先仔细分析(可以放在 reasoning 中或直接写出来)。仔细分析指:列出 5 个维度——任务真实目标 / 关键技术栈与边界 / 自然执行顺序 / 风险点与可能失败步骤 / 是否需要前置调研——不要简短一两句话就过;分析过后再给出 JSON。JSON 用 \`\`\`json ... \`\`\` 包裹:
|
|
1869
|
+
{
|
|
1870
|
+
"subtasks": [
|
|
1871
|
+
{ "title": "子任务标题", "desc": "具体描述" }
|
|
1872
|
+
]
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
**JSON 输出严格要求**(不遵守会导致解析失败、用户无法入库):
|
|
1876
|
+
1. title 和 desc 内如需引用术语 / 页面名 / 状态名,**必须使用中文引号「」或『』**,禁止使用 ASCII 双引号、单引号或反引号,否则会破坏外层 JSON 结构。
|
|
1877
|
+
2. JSON 中不允许尾随逗号(最后一个元素后面不能跟逗号)。
|
|
1878
|
+
3. JSON 中不允许写注释。
|
|
1879
|
+
4. 所有字符串字段必须用 ASCII 双引号包裹,字符串内部如有换行用 \\n 转义。`;
|
|
1880
|
+
|
|
1881
|
+
res.json({
|
|
1882
|
+
success: true,
|
|
1883
|
+
system: userInstruction,
|
|
1884
|
+
user: userBlock,
|
|
1885
|
+
hasImages: imageCount > 0,
|
|
1886
|
+
imageCount
|
|
1887
|
+
});
|
|
1888
|
+
} catch (err) {
|
|
1889
|
+
res.status(500).json({ success: false, error: '生成预览失败: ' + (err?.message || String(err)) });
|
|
1890
|
+
}
|
|
1891
|
+
});
|
|
1892
|
+
|
|
1756
1893
|
// POST /api/workbench/tasks/parse-subtasks
|
|
1757
1894
|
// body: { raw: string }
|
|
1758
1895
|
// → { success, subtasks, parseError, parseStage }
|
|
@@ -2303,6 +2440,74 @@ ${desc ? `描述:${desc}` : '描述:(无)'}${attachmentBlock}${templateB
|
|
|
2303
2440
|
}
|
|
2304
2441
|
});
|
|
2305
2442
|
|
|
2443
|
+
// ── 续接简单任务对话 ────────────────────────────────────────────
|
|
2444
|
+
// POST /api/workbench/jobs/:id/continue
|
|
2445
|
+
// 入参 body: { userMessage: string }
|
|
2446
|
+
// 行为:
|
|
2447
|
+
// - 仅用于 type==='simple' 的任务,基于上一轮 job 捕获到的 claudeSessionId,
|
|
2448
|
+
// 用 claude --resume <id> 续接历史对话,**新一轮 = 新 job**
|
|
2449
|
+
// - 新 job 的 subId 形如 `${task.id}__simple__r${n}`,跟首轮 `${task.id}__simple`
|
|
2450
|
+
// 区分;前端按 subId 前缀聚合渲染对话流
|
|
2451
|
+
// - 上一轮还在 pending/running 时拒绝(避免 session 并发跑乱)
|
|
2452
|
+
// - 上一轮未捕获到 session_id(claude 在 init 前就 crash)时拒绝
|
|
2453
|
+
app.post('/api/workbench/jobs/:id/continue', async (req, res) => {
|
|
2454
|
+
try {
|
|
2455
|
+
const userMessage = String(req.body?.userMessage || '').trim();
|
|
2456
|
+
if (!userMessage) {
|
|
2457
|
+
return res.status(400).json({ success: false, error: 'userMessage 不能为空' });
|
|
2458
|
+
}
|
|
2459
|
+
const prevJob = jobs.get(req.params.id);
|
|
2460
|
+
if (!prevJob) {
|
|
2461
|
+
return res.status(404).json({ success: false, error: 'job 不存在' });
|
|
2462
|
+
}
|
|
2463
|
+
if (prevJob.status === 'running' || prevJob.status === 'pending') {
|
|
2464
|
+
return res.status(400).json({ success: false, error: '上一轮还在执行,请等结束后再续接' });
|
|
2465
|
+
}
|
|
2466
|
+
if (!prevJob.claudeSessionId) {
|
|
2467
|
+
return res.status(400).json({ success: false, error: '无法续接:会话标识未捕获' });
|
|
2468
|
+
}
|
|
2469
|
+
const data = await readJson(TASKS_FILE, { tasks: [] });
|
|
2470
|
+
const task = (data.tasks || []).find(t => t.id === prevJob.taskId);
|
|
2471
|
+
if (!task) {
|
|
2472
|
+
return res.status(404).json({ success: false, error: '所属任务不存在' });
|
|
2473
|
+
}
|
|
2474
|
+
if (task.type !== 'simple') {
|
|
2475
|
+
return res.status(400).json({ success: false, error: '仅支持简单任务的续接' });
|
|
2476
|
+
}
|
|
2477
|
+
// 计算续接轮次号:扫所有同 task 下的 __simple / __simple__rN job,取最大 N + 1
|
|
2478
|
+
const subIdPrefix = `${task.id}__simple`;
|
|
2479
|
+
let maxRound = 0;
|
|
2480
|
+
for (const j of jobs.values()) {
|
|
2481
|
+
if (j.taskId !== task.id) continue;
|
|
2482
|
+
if (j.subId === subIdPrefix) continue;
|
|
2483
|
+
const m = j.subId && j.subId.match(/__simple__r(\d+)$/);
|
|
2484
|
+
if (m) {
|
|
2485
|
+
const n = parseInt(m[1], 10);
|
|
2486
|
+
if (!isNaN(n) && n > maxRound) maxRound = n;
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
const nextRound = maxRound + 1;
|
|
2490
|
+
const virtualSub = {
|
|
2491
|
+
id: `${task.id}__simple__r${nextRound}`,
|
|
2492
|
+
title: `续接 #${nextRound}`,
|
|
2493
|
+
desc: '',
|
|
2494
|
+
status: 'todo',
|
|
2495
|
+
// 用户输入的续接消息直接作为本轮 prompt(走 promptOverride,不再拼模板)
|
|
2496
|
+
promptOverride: userMessage,
|
|
2497
|
+
// 续接轮不带附件,避免重复推附件给 claude(已在首轮 prompt 里)
|
|
2498
|
+
attachments: []
|
|
2499
|
+
};
|
|
2500
|
+
const repoPath = typeof getCurrentProjectPath === 'function' ? getCurrentProjectPath() : '';
|
|
2501
|
+
res.json({ success: true, message: '已加入续接队列' });
|
|
2502
|
+
runSingleSubtask(task, virtualSub, repoPath, '', [], { resumeSessionId: prevJob.claudeSessionId })
|
|
2503
|
+
.catch(err => {
|
|
2504
|
+
publish('task:error', { taskId: task.id, error: err.message });
|
|
2505
|
+
});
|
|
2506
|
+
} catch (err) {
|
|
2507
|
+
res.status(500).json({ success: false, error: err.message });
|
|
2508
|
+
}
|
|
2509
|
+
});
|
|
2510
|
+
|
|
2306
2511
|
// ── 执行日志管理 API(持久化 + 清理) ────────────────────────────
|
|
2307
2512
|
// 路径都在 /api/workbench/jobs/* 下;/list、/config、/batch-delete、/clear
|
|
2308
2513
|
// 是字面路径,必须排在 :id 路由之前注册,避免被 :id 匹配吞掉。
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import"./rolldown-runtime-CMxvf4Kt.js";import{$n as e,$t as t,B as n,Bn as r,Ct as i,Fn as a,Gn as o,Hn as s,In as c,J as l,Kn as u,L as d,Ln as f,M as p,N as m,Nt as h,Ot as g,P as _,Pt as v,Rn as y,Sr as b,St as x,Tt as S,Un as C,V as w,Vt as T,Wn as E,Wt as D,Xn as O,Y as k,Yn as A,Zn as j,_r as M,ar as N,br as P,bt as ee,cr as F,ct as te,dr as ne,dt as I,en as re,et as L,fr as R,ft as ie,gr as ae,hr as z,ir as oe,it as se,jt as ce,l as B,ln as le,lt as ue,mr as de,mt as fe,nn as pe,nr as V,on as me,or as H,pr as U,q as he,qn as W,qt as ge,rr as _e,rt as G,sn as ve,st as ye,tt as be,un as K,vt as xe,wt as Se,xr as Ce,xt as we,yr as q,zn as J,zt as Te}from"./vendor-D72Z0Jmi.js";import{n as Y,t as Ee}from"./_plugin-vue_export-helper-8__zdPsB.js";import{n as De}from"./index-D-XpqSmG.js";var X={class:`ai-split-direct-pane`},Oe={key:0,class:`ai-split-status`},ke={key:1,class:`ai-split-status is-error`},Ae={key:2,class:`ai-split-idle`},Z={class:`ai-split-idle__title`},je={class:`ai-split-idle__desc`},Me={class:`ai-split-prompt-actions`},Ne={key:0,class:`ai-split-prompt-editor`},Pe={class:`ai-split-prompt-editor__actions`},Fe={key:1,class:`ai-split-pre`},Ie={class:`ai-split-subhead`},Le={class:`ai-split-pre`},Re={key:0,class:`ai-split-tab-count`},ze={class:`ai-split-pre ai-split-pre--think`},Be={key:0,class:`ai-split-tab-count`},Ve={class:`ai-split-parse-error__detail`},He={class:`ai-split-parse-error__hint`},Ue={class:`ai-split-parse-error__actions`},Q={key:1,class:`ai-split-raw-toolbar`},We={class:`ai-split-raw-tip`},Ge={key:0,class:`ai-split-tab-count`},Ke={key:0,class:`ai-split-empty`},qe={key:1,class:`ai-split-list`},Je={class:`ai-split-list__no`},Ye={class:`ai-split-list__body`},Xe={class:`ai-split-list__title`},Ze={class:`ai-split-list__desc`},Qe={key:4,class:`ai-split-footer-hint`},$e={class:`ai-split-direct-footer`},et=Ee(e({__name:`AISplitDirectPane`,props:{title:{},desc:{},taskId:{},promptId:{}},emits:[`confirm`],setup(e,{emit:t}){let a=e,s=t,c=M(`idle`),l=M(`prompt`),d=M(``),f=M(``),p=M(``),h=M(``),g=M(``),_=M([]),v=M(``),y=M(``),S=M(``),T=null,D=0,k=C(()=>p.value.length),N=C(()=>h.value.length),P=C(()=>c.value===`result`&&_.value.length>0),ee=C(()=>c.value===`running`);function te(){T&&=(T.abort(),null)}function ne(){te(),c.value=`idle`,l.value=`prompt`,d.value=``,f.value=``,p.value=``,h.value=``,g.value=``,_.value=[],v.value=``,y.value=``,S.value=``}async function I(){if(!a.title.trim()){m.warning(Y(`@WORKBENCH:请先填写任务标题`));return}ne();let e=++D;c.value=`running`,l.value=`thinking`,T=new AbortController;let t=T;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:a.title,desc:a.desc,taskId:a.taskId||``,promptId:a.promptId||``}),signal:t.signal});if(e!==D)return;if(!n.ok||!n.body){let e=await n.text().catch(()=>``);throw Error(e||`HTTP ${n.status}`)}let r=n.body.getReader(),i=new TextDecoder(`utf-8`),o=``,s=null;for(;;){let{value:t,done:n}=await r.read();if(e!==D)return;if(n)break;o+=i.decode(t,{stream:!0});let a=o.split(`
|
|
2
|
-
`);o=a.pop()??``;for(let e of a){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`:d.value=r.prompt?.system||``,f.value=r.prompt?.user||``;break;case`thinking`:p.value+=String(r.delta||``);break;case`content`:h.value+=String(r.delta||``);break;case`done`:s=r;break;case`error`:throw Error(r.error||`AI 拆分失败`)}}}if(e!==D)return;if(!s)throw Error(Y(`@WORKBENCH:AI 未返回结果`));_.value=Array.isArray(s.subtasks)?s.subtasks:[],g.value=s.raw||h.value,y.value=String(s.parseError||``),S.value=String(s.parseStage||``),p.value||=Y(`@WORKBENCH:(当前模型未返回独立的思考内容,可切换到「原始结果」查看完整输出)`),c.value=`result`,l.value=_.value.length>0?`confirm`:`raw`}catch(n){if(e!==D)return;if(n?.name===`AbortError`||t.signal.aborted){c.value=`idle`,l.value=`prompt`;return}c.value=`error`,v.value=n?.message||String(n)}finally{e===D&&(T=null)}}function L(){P.value&&s(`confirm`,_.value.slice())}function ie(){I()}function ae(){T&&(T.abort(),T=null,m.info(Y(`@WORKBENCH:已停止拆分`)))}let z=M(!1);async function oe(){if(!h.value.trim()){m.warning(Y(`@WORKBENCH:原始结果为空,无法解析`));return}z.value=!0;try{let e=await fetch(`/api/workbench/tasks/parse-subtasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({raw:h.value})}).then(e=>e.json());if(!e.success){m.error(e.error||Y(`@WORKBENCH:解析失败`));return}_.value=Array.isArray(e.subtasks)?e.subtasks:[],y.value=String(e.parseError||``),S.value=String(e.parseStage||``),g.value=h.value,_.value.length>0?(m.success(Y(`@WORKBENCH:解析成功,已识别 {n} 个子任务`,{n:_.value.length})),l.value=`confirm`):m.warning(Y(`@WORKBENCH:仍未解析到子任务,请继续修改原始结果`))}catch(e){m.error(Y(`@WORKBENCH:解析失败: `)+(e?.message||e))}finally{z.value=!1}}R(()=>a.taskId,()=>{ne()});let se=M(!1),B=M(``),ue=M(!1);function de(){B.value=d.value,se.value=!0}async function pe(){if(!B.value.trim()){m.warning(Y(`@WORKBENCH:指令内容不能为空`));return}ue.value=!0;try{let e=await fetch(`/api/workbench/tasks/ai-subtask-instruction`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({instruction:B.value})}).then(e=>e.json());e.success?(m.success(Y(`@WORKBENCH:已保存指令`)),se.value=!1,ie()):m.error(e.error||Y(`@WORKBENCH:保存失败`))}catch(e){m.error(Y(`@WORKBENCH:保存失败: `)+(e?.message||e))}finally{ue.value=!1}}function V(){se.value=!1}return(e,t)=>{let a=i,s=fe,m=xe,g=n,S=x,C=w;return H(),W(`div`,X,[ee.value?(H(),W(`div`,Oe,[j(a,{class:`is-loading`},{default:U(()=>[j(q(re))]),_:1}),E(`span`,null,b(q(Y)(`@WORKBENCH:AI 正在拆分…`)),1),j(s,{size:`small`,link:``,type:`danger`,class:`ai-split-status__stop`,onClick:ae},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:停止拆分`)),1)]),_:1})])):c.value===`error`?(H(),W(`div`,ke,[j(a,{color:`#f56c6c`},{default:U(()=>[j(q(ce))]),_:1}),E(`span`,null,b(v.value),1)])):c.value===`idle`?(H(),W(`div`,Ae,[t[4]||=A(`<div class="ai-split-idle__icon" aria-hidden="true" data-v-e5c8a5b7><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-e5c8a5b7><path d="M12 3v3" data-v-e5c8a5b7></path><path d="M12 18v3" data-v-e5c8a5b7></path><path d="M3 12h3" data-v-e5c8a5b7></path><path d="M18 12h3" data-v-e5c8a5b7></path><path d="M5.6 5.6l2.1 2.1" data-v-e5c8a5b7></path><path d="M16.3 16.3l2.1 2.1" data-v-e5c8a5b7></path><path d="M5.6 18.4l2.1-2.1" data-v-e5c8a5b7></path><path d="M16.3 7.7l2.1-2.1" data-v-e5c8a5b7></path><circle cx="12" cy="12" r="4" data-v-e5c8a5b7></circle></svg></div>`,1),E(`div`,Z,b(q(Y)(`@WORKBENCH:准备用 AI 拆分任务`)),1),E(`div`,je,b(q(Y)(`@WORKBENCH:点击下方按钮开始生成。生成期间可切换到「思考 / 原始结果」实时查看模型输出。`)),1),j(s,{type:`primary`,icon:q(le),onClick:I},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:开始拆分`)),1)]),_:1},8,[`icon`])])):u(``,!0),c.value===`idle`?u(``,!0):(H(),o(C,{key:3,modelValue:l.value,"onUpdate:modelValue":t[3]||=e=>l.value=e,class:`ai-split-tabs`},{default:U(()=>[j(g,{label:q(Y)(`@WORKBENCH:提示词`),name:`prompt`},{default:U(()=>[E(`div`,Me,[j(s,{size:`small`,disabled:ee.value,onClick:de},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:编辑指令`)),1)]),_:1},8,[`disabled`])]),se.value?(H(),W(`div`,Ne,[j(m,{modelValue:B.value,"onUpdate:modelValue":t[0]||=e=>B.value=e,type:`textarea`,rows:12,placeholder:q(Y)(`@WORKBENCH:指令内容`)},null,8,[`modelValue`,`placeholder`]),E(`div`,Pe,[j(s,{size:`small`,onClick:V},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:取消`)),1)]),_:1}),j(s,{size:`small`,type:`primary`,loading:ue.value,onClick:pe},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:保存并重跑`)),1)]),_:1},8,[`loading`])])])):(H(),W(`pre`,Fe,b(d.value||`(等待 LLM 启动…)`),1)),E(`h4`,Ie,b(q(Y)(`@WORKBENCH:用户提示词(拼装后)`)),1),E(`pre`,Le,b(f.value||`(等待 LLM 启动…)`),1)]),_:1},8,[`label`]),j(g,{name:`thinking`},{label:U(()=>[E(`span`,null,[O(b(q(Y)(`@WORKBENCH:思考`))+` `,1),k.value>0?(H(),W(`span`,Re,`(`+b(k.value)+`)`,1)):u(``,!0)])]),default:U(()=>[E(`pre`,ze,b(p.value||q(Y)(`@WORKBENCH:(暂无输出)`)),1)]),_:1}),j(g,{name:`raw`},{label:U(()=>[E(`span`,null,[O(b(q(Y)(`@WORKBENCH:原始结果`))+` `,1),N.value>0?(H(),W(`span`,Be,`(`+b(N.value)+`)`,1)):u(``,!0)])]),default:U(()=>[y.value&&c.value===`result`?(H(),o(S,{key:0,type:`warning`,"show-icon":``,closable:!1,class:`ai-split-parse-error`},{title:U(()=>[O(b(q(Y)(`@WORKBENCH:模型返回内容解析失败,无法识别为有效的子任务 JSON`)),1)]),default:U(()=>[E(`div`,Ve,b(y.value),1),E(`div`,He,b(q(Y)(`@WORKBENCH:常见原因:desc 内夹杂了 ASCII 双引号、出现尾随逗号,或输出被截断。可在下方文本框中手动修改后点「重新解析」,或重新生成。`)),1),E(`div`,Ue,[j(s,{size:`small`,type:`primary`,loading:z.value,onClick:oe},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:重新解析`)),1)]),_:1},8,[`loading`]),j(s,{size:`small`,onClick:ie},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:重新生成`)),1)]),_:1}),j(s,{size:`small`,onClick:t[1]||=e=>l.value=`prompt`},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:去编辑指令`)),1)]),_:1})])]),_:1})):u(``,!0),c.value===`result`||h.value?(H(),W(`div`,Q,[E(`span`,We,b(q(Y)(`@WORKBENCH:可直接编辑下方文本,修正后点「重新解析」即可入库`)),1),j(s,{size:`small`,type:`primary`,loading:z.value,disabled:!h.value.trim(),onClick:oe},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:重新解析`)),1)]),_:1},8,[`loading`,`disabled`])])):u(``,!0),j(m,{modelValue:h.value,"onUpdate:modelValue":t[2]||=e=>h.value=e,type:`textarea`,rows:14,placeholder:q(Y)(`@WORKBENCH:(暂无输出)`),readonly:ee.value,class:`ai-split-raw-editor`,resize:`none`},null,8,[`modelValue`,`placeholder`,`readonly`])]),_:1}),j(g,{name:`confirm`,disabled:_.value.length===0},{label:U(()=>[E(`span`,null,[O(b(q(Y)(`@WORKBENCH:确认入库`))+` `,1),_.value.length>0?(H(),W(`span`,Ge,`(`+b(_.value.length)+`)`,1)):u(``,!0)])]),default:U(()=>[_.value.length===0?(H(),W(`div`,Ke,b(q(Y)(`@WORKBENCH:(暂无子任务)`)),1)):(H(),W(`ul`,qe,[(H(!0),W(r,null,F(_.value,(e,t)=>(H(),W(`li`,{key:t,class:`ai-split-list__item`},[E(`div`,Je,b(t+1),1),E(`div`,Ye,[E(`div`,Xe,b(e.title),1),E(`div`,Ze,b(e.desc),1)])]))),128))]))]),_:1},8,[`disabled`])]),_:1},8,[`modelValue`])),y.value&&c.value===`result`&&_.value.length===0?(H(),W(`div`,Qe,[j(a,{color:`#e6a23c`},{default:U(()=>[j(q(ce))]),_:1}),E(`span`,null,b(q(Y)(`@WORKBENCH:解析失败,未能从模型输出中提取出子任务 — 请查看「原始结果」`)),1)])):u(``,!0),E(`div`,$e,[c.value===`error`||c.value===`result`&&y.value&&_.value.length===0?(H(),o(s,{key:0,onClick:ie},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:重新生成`)),1)]),_:1})):u(``,!0),c.value===`result`&&_.value.length>0?(H(),o(s,{key:1,onClick:ie},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:重新拆分`)),1)]),_:1})):u(``,!0),j(s,{type:`primary`,disabled:!P.value,onClick:L},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:确认入库`))+` (`+b(_.value.length)+`) `,1)]),_:1},8,[`disabled`])])])}}}),[[`__scopeId`,`data-v-e5c8a5b7`]]),tt={class:`ai-chat-pane`},nt={key:0,class:`ai-chat-streaming-banner`},rt={key:1,class:`ai-chat-empty`},it={class:`ai-chat-empty__title`},at={class:`ai-chat-empty__desc`},ot={key:0,class:`ai-chat-bubble user`},st={class:`ai-chat-content`},ct={key:1,class:`ai-chat-bubble assistant`},lt={class:`ai-chat-pre ai-chat-pre--think`},ut={key:1,class:`ai-chat-content-text`},dt={key:2,class:`ai-chat-subtasks`},ft={class:`ai-chat-subtasks__head`},pt={class:`ai-chat-subtasks__count`},mt={class:`ai-chat-list`},ht={class:`ai-chat-list__no`},gt={class:`ai-chat-list__body`},_t={class:`ai-chat-list__title`},vt={class:`ai-chat-list__desc`},yt={class:`ai-chat-parse-error__detail`},bt={class:`ai-chat-pre`},xt={key:5,class:`ai-chat-turn__actions`},St={class:`ai-chat-input`},Ct={class:`ai-chat-input__actions`},wt={key:0,class:`ai-chat-history__loading`},Tt={key:1,class:`ai-chat-history__empty`},Et={key:2,class:`ai-chat-history__list`},Dt={class:`ai-chat-history__title`},Ot={class:`ai-chat-history__meta`},kt={class:`ai-chat-history__actions`},$=Ee(e({__name:`AISplitChatPane`,props:{title:{},desc:{},taskId:{},promptId:{},initialSessionId:{}},emits:[`confirm`],setup(e,{emit:t}){let n=e,a=t,s=M(`idle`),c=M(``),l=M([]),d=M(``),f=M(``),_=null,v=0,x=M(null),S=C(()=>s.value===`streaming`),w=C(()=>{if(!S.value)return``;let e=[...l.value].reverse().find(e=>e.role===`assistant`);return e?e.content?Y(`@WORKBENCH:AI 正在输出…`):e.thinking?Y(`@WORKBENCH:AI 正在思考… (已思考 {n} 字)`,{n:e.thinking.length}):Y(`@WORKBENCH:AI 正在思考…`):Y(`@WORKBENCH:AI 正在思考…`)}),T=M(!1),D=M(!1),k=M([]);function A(){x.value&&(x.value.scrollTop=x.value.scrollHeight)}async function N(){let e=d.value.trim();if(!e||S.value)return;if(!c.value&&!n.title.trim()){m.warning(Y(`@WORKBENCH:请先填写任务标题`));return}let t=++v;_=new AbortController;let r=_,i={role:`user`,content:e};l.value.push(i),d.value=``;let a={role:`assistant`,content:``,thinking:``};l.value.push(a),s.value=`streaming`,await V(),A();try{let i=await fetch(`/api/workbench/tasks/ai-chat-split`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`text/event-stream`},body:JSON.stringify({sessionId:c.value,title:n.title,desc:n.desc,taskId:n.taskId||``,promptId:n.promptId||``,userMessage:e}),signal:r.signal});if(t!==v)return;if(!i.ok||!i.body){let e=await i.text().catch(()=>``);throw Error(e||`HTTP ${i.status}`)}let o=i.body.getReader(),u=new TextDecoder(`utf-8`),d=``,f=null,p=!1;for(;;){let{value:e,done:n}=await o.read();if(t!==v)return;if(n)break;d+=u.decode(e,{stream:!0});let r=d.split(`
|
|
3
|
-
`);d=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&&(c.value=r.sessionId);break;case`user_echo`:p=!0;break;case`thinking`:a.thinking=(a.thinking||``)+String(r.delta||``);break;case`content`:a.content+=String(r.delta||``);break;case`done`:f=r;break;case`error`:throw Error(r.error||`对话拆分失败`)}}l.value=[...l.value],await V(),A()}if(t!==v)return;if(!p&&!f)throw Error(Y(`@WORKBENCH:AI 未返回结果`));f&&(a.subtasks=Array.isArray(f.subtasks)?f.subtasks:[],a.raw=String(f.raw||a.content),a.parseError=String(f.parseError||``),a.parseStage=String(f.parseStage||``)),l.value=[...l.value],await V(),A(),s.value=`idle`}catch(e){if(t!==v)return;if(e?.name===`AbortError`||r.signal.aborted){a.content=(a.content||``)+`
|
|
4
|
-
|
|
5
|
-
[已停止]`,l.value=[...l.value],s.value=`idle`;return}s.value=`error`,f.value=e?.message||String(e),m.error(f.value)}finally{t===v&&(_=null)}}function ee(){_&&=(_.abort(),null)}function te(){if(S.value){m.warning(Y(`@WORKBENCH:请先停止当前生成`));return}l.value=[],c.value=``,f.value=``,s.value=`idle`}function ne(e){if(!e.subtasks||e.subtasks.length===0){m.warning(Y(`@WORKBENCH:当前没有可应用的子任务`));return}a(`confirm`,e.subtasks.slice())}async function I(){T.value=!0,D.value=!0;try{let e=await fetch(`/api/workbench/tasks/ai-chat-sessions`).then(e=>e.json());if(!e.success){m.error(e.error||Y(`@WORKBENCH:加载历史会话失败`));return}k.value=Array.isArray(e.sessions)?e.sessions:[]}catch(e){m.error(Y(`@WORKBENCH:加载历史会话失败: `)+(e?.message||e))}finally{D.value=!1}}async function R(e){if(T.value=!1,S.value){m.warning(Y(`@WORKBENCH:请先停止当前生成`));return}try{let t=await fetch(`/api/workbench/tasks/ai-chat-sessions/${encodeURIComponent(e)}`).then(e=>e.json());if(!t.success){m.error(t.error||Y(`@WORKBENCH:加载历史会话失败`));return}let n=t.session;c.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),l.value=r,s.value=`idle`,m.success(Y(`@WORKBENCH:已恢复历史会话`)),await V(),A()}catch(e){m.error(Y(`@WORKBENCH:加载历史会话失败: `)+(e?.message||e))}}async function ie(e){try{await p.confirm(Y(`@WORKBENCH:确认删除该会话`),Y(`@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){m.error(t.error||Y(`@WORKBENCH:删除失败`));return}k.value=k.value.filter(t=>t.sessionId!==e),m.success(Y(`@WORKBENCH:已删除`))}catch(e){m.error(Y(`@WORKBENCH:删除失败: `)+(e?.message||e))}}function ae(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 z(e){return e?e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`:`0 B`}return n.initialSessionId&&R(n.initialSessionId),(e,t)=>{let n=i,a=se,s=G,c=fe,f=xe,p=L;return H(),W(`div`,tt,[E(`div`,{ref_key:`streamEl`,ref:x,class:`ai-chat-stream`},[S.value?(H(),W(`div`,nt,[j(n,{class:`is-loading`},{default:U(()=>[j(q(re))]),_:1}),E(`span`,null,b(w.value),1)])):u(``,!0),l.value.length===0&&!S.value?(H(),W(`div`,rt,[j(n,{size:32,color:`#909399`},{default:U(()=>[j(q(g))]),_:1}),E(`div`,it,b(q(Y)(`@WORKBENCH:开始与 AI 对话拆分`)),1),E(`div`,at,b(q(Y)(`@WORKBENCH:输入你想让 AI 怎么拆分或调整(Enter 发送,Shift+Enter 换行)`)),1)])):u(``,!0),(H(!0),W(r,null,F(l.value,(e,t)=>(H(),W(`div`,{key:t,class:P([`ai-chat-turn`,`ai-chat-turn--${e.role}`])},[e.role===`user`?(H(),W(`div`,ot,[E(`pre`,st,b(e.content),1)])):(H(),W(`div`,ct,[e.thinking?(H(),o(s,{key:0,class:`ai-chat-collapse`},{default:U(()=>[j(a,{title:q(Y)(`@WORKBENCH:思考过程`)+` (${e.thinking.length})`,name:`think`},{default:U(()=>[E(`pre`,lt,b(e.thinking),1)]),_:2},1032,[`title`])]),_:2},1024)):u(``,!0),e.content?(H(),W(`div`,ut,b(e.content),1)):u(``,!0),e.subtasks&&e.subtasks.length>0?(H(),W(`div`,dt,[E(`div`,ft,[E(`span`,pt,b(q(Y)(`@WORKBENCH:识别到 {n} 个子任务`,{n:e.subtasks.length})),1)]),E(`ul`,mt,[(H(!0),W(r,null,F(e.subtasks,(e,t)=>(H(),W(`li`,{key:t,class:`ai-chat-list__item`},[E(`div`,ht,b(t+1),1),E(`div`,gt,[E(`div`,_t,b(e.title),1),E(`div`,vt,b(e.desc),1)])]))),128))])])):u(``,!0),e.parseError&&(!e.subtasks||e.subtasks.length===0)?(H(),o(s,{key:3,class:`ai-chat-collapse`},{default:U(()=>[j(a,{title:q(Y)(`@WORKBENCH:查看解析详情`),name:`diag`},{default:U(()=>[E(`div`,yt,b(e.parseError),1)]),_:2},1032,[`title`])]),_:2},1024)):u(``,!0),e.raw&&e.raw!==e.content?(H(),o(s,{key:4,class:`ai-chat-collapse`},{default:U(()=>[j(a,{title:q(Y)(`@WORKBENCH:查看原始 LLM 输出`),name:`raw`},{default:U(()=>[E(`pre`,bt,b(e.raw),1)]),_:2},1032,[`title`])]),_:2},1024)):u(``,!0),e.subtasks&&e.subtasks.length>0?(H(),W(`div`,xt,[j(c,{type:`primary`,size:`small`,icon:q(le),onClick:t=>ne(e)},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:应用本轮`))+` (`+b(e.subtasks.length)+`) `,1)]),_:2},1032,[`icon`,`onClick`])])):u(``,!0)]))],2))),128))],512),E(`div`,St,[j(f,{modelValue:d.value,"onUpdate:modelValue":t[0]||=e=>d.value=e,type:`textarea`,rows:3,disabled:S.value,placeholder:q(Y)(`@WORKBENCH:输入你想让 AI 怎么拆分或调整(Enter 发送,Shift+Enter 换行)`),onKeydown:y(J(N,[`exact`,`prevent`]),[`enter`])},null,8,[`modelValue`,`disabled`,`placeholder`,`onKeydown`]),E(`div`,Ct,[S.value?(H(),o(c,{key:0,type:`danger`,icon:q(ce),onClick:ee},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:停止`)),1)]),_:1},8,[`icon`])):(H(),o(c,{key:1,type:`primary`,icon:q(le),disabled:!d.value.trim(),onClick:N},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:发送`)),1)]),_:1},8,[`icon`,`disabled`])),j(c,{disabled:S.value,icon:q(K),onClick:te},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:清空对话`)),1)]),_:1},8,[`disabled`,`icon`]),j(c,{disabled:S.value,icon:q(h),onClick:I},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:历史会话`)),1)]),_:1},8,[`disabled`,`icon`])])]),j(p,{modelValue:T.value,"onUpdate:modelValue":t[1]||=e=>T.value=e,title:q(Y)(`@WORKBENCH:历史会话`),direction:`rtl`,size:`420px`},{default:U(()=>[D.value?(H(),W(`div`,wt,[j(n,{class:`is-loading`},{default:U(()=>[j(q(re))]),_:1})])):k.value.length===0?(H(),W(`div`,Tt,b(q(Y)(`@WORKBENCH:暂无历史会话`)),1)):(H(),W(`ul`,Et,[(H(!0),W(r,null,F(k.value,e=>(H(),W(`li`,{key:e.sessionId,class:`ai-chat-history__item`},[E(`div`,Dt,b(e.title||`(无标题)`),1),E(`div`,Ot,[E(`span`,null,b(ae(e.updatedAt)),1),t[2]||=E(`span`,null,`·`,-1),E(`span`,null,b(e.messageCount)+` 条消息`,1),t[3]||=E(`span`,null,`·`,-1),E(`span`,null,b(e.latestSubtaskCount)+` 个子任务`,1),t[4]||=E(`span`,null,`·`,-1),E(`span`,null,b(z(e.size)),1)]),E(`div`,kt,[j(c,{size:`small`,type:`primary`,onClick:t=>R(e.sessionId)},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:恢复`)),1)]),_:1},8,[`onClick`]),j(c,{size:`small`,type:`danger`,onClick:t=>ie(e.sessionId)},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:删除`)),1)]),_:1},8,[`onClick`])])]))),128))]))]),_:1},8,[`modelValue`,`title`])])}}}),[[`__scopeId`,`data-v-e5b87036`]]),At={class:`ai-split-mode-bar`},jt=Ee(e({__name:`AISplitDialog`,props:{modelValue:{type:Boolean},title:{},desc:{},taskId:{},promptId:{}},emits:[`update:modelValue`,`confirm`],setup(e,{emit:t}){let n=e,r=t,i=M(`direct`),a=C(()=>[{label:Y(`@WORKBENCH:直接拆分`),value:`direct`},{label:Y(`@WORKBENCH:对话拆分`),value:`chat`}]);function s(e){r(`confirm`,e),r(`update:modelValue`,!1)}return R(()=>n.modelValue,e=>{e&&(i.value=`direct`)}),(t,n)=>{let c=d,l=be;return H(),o(l,{"model-value":e.modelValue,"onUpdate:modelValue":n[1]||=e=>r(`update:modelValue`,e),title:q(Y)(`@WORKBENCH:AI 拆分任务`),width:`800px`,"close-on-click-modal":!1,"close-on-press-escape":!0,"show-close":!0},{default:U(()=>[E(`div`,At,[j(c,{modelValue:i.value,"onUpdate:modelValue":n[0]||=e=>i.value=e,options:a.value,block:!1},null,8,[`modelValue`,`options`])]),i.value===`direct`?(H(),o(et,{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`])):(H(),o($,{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`]]),Mt={class:`wb-attachments__head`},Nt={class:`wb-attachments__label`},Pt={class:`wb-attachments__count`},Ft=[`disabled`],It={key:0,class:`wb-attachments__paste-hint`},Lt={key:1,class:`wb-attachments__list`},Rt=[`title`,`onClick`,`onContextmenu`],zt=[`src`,`alt`],Bt={key:1},Vt={class:`wb-attachment__meta`},Ht=[`title`],Ut=[`onClick`,`title`],Wt=Ee(e({__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 n=e,i=t,a=C(()=>n.attachments.filter(e=>n.isImage(e))),c=C(()=>a.value.map(e=>`/api/workbench/attachments/${e.id}/raw`)),l=M(0),d=M(!1);function f(e){if(n.isImage(e)){let t=a.value.findIndex(t=>t.id===e.id);l.value=t>=0?t:0,d.value=!0}else window.open(`/api/workbench/attachments/${e.id}/raw`,`_blank`,`noopener`)}function p(){d.value=!1}let h=M({visible:!1,x:0,y:0,att:null}),g=M(!1);function _(e,t){if(!n.isImage(e))return;t.preventDefault();let r=window.innerWidth-180,i=window.innerHeight-120;h.value={visible:!0,x:Math.min(t.clientX,r),y:Math.min(t.clientY,i),att:e}}function v(){h.value.visible&&(h.value.visible=!1)}async function y(){let e=h.value.att;if(!(!e||g.value)){if(v(),!navigator.clipboard||typeof ClipboardItem>`u`){m({type:`warning`,message:Y(`@WORKBENCH:当前浏览器不支持复制图片`)});return}g.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]),m({type:`success`,message:Y(`@WORKBENCH:图片已复制到剪贴板`),duration:1800})}catch(e){m({type:`error`,message:Y(`@WORKBENCH:复制失败 {error}`,{error:e?.message||``})})}finally{g.value=!1}}}return typeof window<`u`&&(window.addEventListener(`click`,v),window.addEventListener(`scroll`,v,!0),window.addEventListener(`blur`,v)),_e(()=>{typeof window>`u`||(window.removeEventListener(`click`,v),window.removeEventListener(`scroll`,v,!0),window.removeEventListener(`blur`,v))}),(t,n)=>(H(),W(r,null,[E(`div`,{class:P([`wb-attachments`,{"is-paste-hover":e.isPasteHover}]),onPaste:n[1]||=e=>i(`paste`,e),onDrop:n[2]||=J(e=>i(`drop`,e),[`prevent`]),onDragover:n[3]||=J(e=>i(`dragover`,e),[`prevent`]),onDragenter:n[4]||=J(e=>i(`dragenter`,e),[`prevent`]),onDragleave:n[5]||=e=>i(`dragleave`,e)},[E(`div`,Mt,[E(`span`,Nt,[O(b(q(Y)(`@WORKBENCH:附件`))+` `,1),E(`span`,Pt,b(e.attachments.length)+` / `+b(e.maxCount),1)]),E(`button`,{class:`wb-attachments__add wb-soft-btn`,disabled:e.isUploading||e.attachments.length>=e.maxCount,onClick:n[0]||=(...t)=>e.onPick&&e.onPick(...t)},b(e.isUploading?q(Y)(`@WORKBENCH:上传中…`):q(Y)(`@WORKBENCH:添加附件`)),9,Ft)]),e.isPasteHover?(H(),W(`div`,It,b(q(Y)(`@WORKBENCH:粘贴图片以快速添加`)),1)):u(``,!0),e.attachments.length>0?(H(),W(`ul`,Lt,[(H(!0),W(r,null,F(e.attachments,t=>(H(),W(`li`,{key:t.id,class:`wb-attachment`},[E(`button`,{type:`button`,class:`wb-attachment__preview`,title:q(Y)(`@WORKBENCH:点击预览`),onClick:e=>f(t),onContextmenu:e=>_(t,e)},[E(`div`,{class:P([`wb-attachment__icon`,{"wb-attachment__icon--img":e.isImage(t)}])},[e.isImage(t)?(H(),W(`img`,{key:0,src:`/api/workbench/attachments/${t.id}/raw`,alt:t.originalName,loading:`lazy`},null,8,zt)):(H(),W(`span`,Bt,b(t.ext.toUpperCase()),1))],2),E(`div`,Vt,[E(`div`,{class:`wb-attachment__name`,title:`${t.originalName} (${e.humanSize(t.size)})`},b(t.originalName),9,Ht)])],40,Rt),E(`button`,{class:`wb-attachment__del`,onClick:J(n=>e.onRemove(t),[`stop`]),title:q(Y)(`@WORKBENCH:删除`)},`×`,8,Ut)]))),128))])):u(``,!0)],34),(H(),o(s,{to:`body`},[d.value&&c.value.length>0?(H(),o(q(k),{key:0,"url-list":c.value,"initial-index":l.value,"hide-on-click-modal":!0,onClose:p},null,8,[`url-list`,`initial-index`])):u(``,!0)])),(H(),o(s,{to:`body`},[h.value.visible&&h.value.att&&e.isImage(h.value.att)?(H(),W(`ul`,{key:0,class:`wb-ctx-menu`,style:Ce({top:h.value.y+`px`,left:h.value.x+`px`}),onContextmenu:n[6]||=J(()=>{},[`prevent`])},[E(`li`,{class:P([`wb-ctx-menu__item`,{"is-disabled":g.value}]),onClick:y},[n[7]||=E(`span`,{class:`wb-ctx-menu__icon`,"aria-hidden":`true`},[E(`svg`,{viewBox:`0 0 24 24`,width:`14`,height:`14`,fill:`none`,stroke:`currentColor`,"stroke-width":`1.8`,"stroke-linecap":`round`,"stroke-linejoin":`round`},[E(`rect`,{x:`9`,y:`9`,width:`11`,height:`11`,rx:`2`}),E(`path`,{d:`M5 15V5a2 2 0 0 1 2-2h10`})])],-1),E(`span`,null,b(q(Y)(`@WORKBENCH:复制图片`)),1)],2)],36)):u(``,!0)]))],64))}}),[[`__scopeId`,`data-v-9e1ed466`]]),Gt=[`aria-expanded`],Kt={class:`wb-log-summary__left`},qt={key:0,class:`wb-log-summary__status wb-log-summary__status--running`},Jt={class:`wb-log-summary__label`},Yt={key:0,class:`wb-log-summary__elapsed`},Xt={key:1,class:`wb-log-summary__status wb-log-summary__status--pending`},Zt={class:`wb-log-summary__label`},Qt={key:2,class:`wb-log-summary__status wb-log-summary__status--done`},$t={key:0,class:`wb-log-summary__icon`},en={key:1,class:`wb-log-summary__icon`},tn={class:`wb-log-summary__label`},nn={key:2,class:`wb-log-summary__elapsed`},rn={key:3},an={class:`wb-log-summary__right`},on={class:`wb-log-summary__meta`},sn=[`title`],cn={class:`wb-log-details__body`},ln=[`open`],un={class:`wb-log-section__summary`},dn={class:`wb-log-section__tag wb-log-section__tag--user`},fn={class:`wb-log-section__count`},pn=[`title`],mn={class:`wb-log-section__pre wb-log-section__pre--user`},hn=[`open`],gn={class:`wb-log-section__summary`},_n={class:`wb-log-section__tag wb-log-section__tag--think`},vn={class:`wb-log-section__count`},yn=[`title`],bn={class:`wb-log-section__pre wb-log-section__pre--think`},xn={class:`wb-log-pre__head`},Sn={class:`wb-log-pre__label`},Cn={class:`wb-log-pre__meta`},wn=[`title`],Tn=[`title`,`disabled`],En={key:1,class:`wb-log-pre__empty`},Dn={key:1,class:`wb-log-fullscreen__empty`},On=64*1024,kn=60,An=Ee(e({__name:`JobLogDetails`,props:{job:{}},setup(e){let t=e,n=M(!1);function r(){n.value=!n.value}function i(){let e=t.job.output||``;return e?e.length<=On?e:`${Y(`@WORKBENCH:…(前文已截断)`)}\n${e.slice(-65536)}`:``}async function a(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){m.warning(Y(`@WORKBENCH:暂无内容可复制`));return}await a(n)?m.success(Y(`@WORKBENCH:已复制到剪贴板`)):m.error(Y(`@WORKBENCH:复制失败`))}async function c(){let e=[];if(t.job.prompt&&e.push(`## ${Y(`@WORKBENCH:用户提示词`)}\n\n${t.job.prompt}`),t.job.thinking&&e.push(`## ${Y(`@WORKBENCH:Claude 思考`)}\n\n${t.job.thinking}`),t.job.output&&e.push(`## ${Y(`@WORKBENCH:模型返回`)}\n\n${t.job.output}`),!e.length){m.warning(Y(`@WORKBENCH:暂无内容可复制`));return}await a(e.join(`
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
`))?m.success(Y(`@WORKBENCH:已复制到剪贴板`)):m.error(Y(`@WORKBENCH:复制失败`))}let l=C(()=>i()),d=C(()=>t.job.status===`running`||t.job.status===`pending`),p=C(()=>{let e=t.job.status;return e===`done`||e===`error`||e===`cancelled`}),h=M(0),g=null;function _(){v(),g=setInterval(()=>{let e=l.value.length;if(e===0){h.value=0,v();return}let t=Math.max(1,Math.ceil(kn/30));h.value<e&&(h.value=Math.min(e,h.value+t)),h.value>=e&&v()},33)}function v(){g&&=(clearInterval(g),null)}R(()=>[t.job.output?.length||0,t.job.status],([e,t])=>{t===`done`||t===`error`||t===`cancelled`?(v(),h.value=e):h.value<e&&!g&&_()},{immediate:!0}),N(()=>v());let y=C(()=>l.value.slice(0,h.value)),x=C(()=>(t.job.output||``).slice(0,h.value)),S=C(()=>h.value>=(t.job.output||``).length),w=M(null);R(()=>t.job.status,(e,t)=>{e===`running`&&t!==`running`&&(w.value=w.value??Date.now())});let T=C(()=>{if(!w.value)return``;let e=w.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`)}秒`}),D=M(null),O=!1,k=M(!1);function A(){if(O)return;let e=t.job.status;e===`running`||e===`pending`?k.value=(t.job.thinking||``).length>0:k.value=!1}function ee(e){let t=e.target;O=!0,k.value=t.open}R(()=>t.job.status,(e,t)=>{!(t===`running`||t===`pending`)&&(e===`running`||e===`pending`)&&(O=!1),A()}),R(()=>(t.job.thinking||``).length,()=>A(),{immediate:!0});let F=!1,te=M(!0);function ne(e){let t=e.target;F=!0,te.value=t.open}R(()=>t.job.status,(e,t)=>{!(t===`running`||t===`pending`)&&(e===`running`||e===`pending`)?(F=!1,te.value=!0):F||(te.value=!0)}),R(()=>(t.job.output||``).length,async()=>{n.value||(await V(),D.value&&(D.value.scrollTop=D.value.scrollHeight))});let I=M(!1),re=C(()=>!!(t.job.output&&t.job.output.length)),L=M(null);R(I,async e=>{e&&(await V(),L.value&&(L.value.scrollTop=L.value.scrollHeight))}),R(()=>(t.job.output||``).length,async()=>{I.value&&(await V(),L.value&&(L.value.scrollTop=L.value.scrollHeight))});function ie(){}return(t,i)=>{let a=be;return H(),W(`div`,{class:P([`wb-log-details`,{"is-running":d.value,"is-pending":e.job.status===`pending`,"is-finished":p.value}])},[E(`div`,{class:`wb-log-summary`,onClick:r,role:`button`,"aria-expanded":!n.value},[E(`span`,Kt,[e.job.status===`running`?(H(),W(`span`,qt,[E(`span`,Jt,b(q(Y)(`@WORKBENCH:正在执行…`)),1),i[5]||=E(`span`,{class:`wb-log-dots`,"aria-hidden":`true`},[E(`span`,{class:`wb-log-dots__dot`}),E(`span`,{class:`wb-log-dots__dot`}),E(`span`,{class:`wb-log-dots__dot`})],-1),T.value?(H(),W(`span`,Yt,b(T.value),1)):u(``,!0)])):e.job.status===`pending`?(H(),W(`span`,Xt,[E(`span`,Zt,b(q(Y)(`@WORKBENCH:排队中…`)),1),i[6]||=E(`span`,{class:`wb-log-dots`,"aria-hidden":`true`},[E(`span`,{class:`wb-log-dots__dot`}),E(`span`,{class:`wb-log-dots__dot`}),E(`span`,{class:`wb-log-dots__dot`})],-1)])):p.value?(H(),W(`span`,Qt,[e.job.status===`error`?(H(),W(`span`,$t,`✗`)):(H(),W(`span`,en,`✓`)),E(`span`,tn,b(e.job.status===`error`?q(Y)(`@WORKBENCH:执行出错`):q(Y)(`@WORKBENCH:执行完成`)),1),T.value?(H(),W(`span`,nn,b(T.value),1)):u(``,!0)])):(H(),W(`span`,rn,b(q(Y)(`@WORKBENCH:查看执行日志`)),1))]),E(`span`,an,[E(`span`,on,b((e.job.output||``).length)+` `+b(q(Y)(`@WORKBENCH:字符`)),1),E(`button`,{type:`button`,class:`wb-log-copy`,title:q(Y)(`@WORKBENCH:复制全部(含提示词与输出)`),onClick:J(c,[`stop`])},` ⧉ `+b(q(Y)(`@WORKBENCH:复制全部`)),9,sn)])],8,Gt),de(E(`div`,cn,[e.job.prompt?(H(),W(`details`,{key:0,class:`wb-log-section`,open:te.value,onToggle:ne},[E(`summary`,un,[E(`span`,dn,b(q(Y)(`@WORKBENCH:用户提示词`)),1),E(`span`,fn,b((e.job.prompt||``).length)+` `+b(q(Y)(`@WORKBENCH:字符`)),1),E(`button`,{type:`button`,class:`wb-log-copy wb-log-copy--sm`,title:q(Y)(`@WORKBENCH:复制用户提示词`),onClick:i[0]||=J(e=>s(`prompt`),[`stop`])},` ⧉ `+b(q(Y)(`@WORKBENCH:复制`)),9,pn)]),E(`pre`,mn,b(e.job.prompt),1)],40,ln)):u(``,!0),e.job.thinking?(H(),W(`details`,{key:1,class:`wb-log-section`,open:k.value,onToggle:ee},[E(`summary`,gn,[E(`span`,_n,b(q(Y)(`@WORKBENCH:Claude 思考`)),1),E(`span`,vn,b((e.job.thinking||``).length)+` `+b(q(Y)(`@WORKBENCH:字符`)),1),E(`button`,{type:`button`,class:`wb-log-copy wb-copy--sm`,title:q(Y)(`@WORKBENCH:复制思考内容`),onClick:i[1]||=J(e=>s(`thinking`),[`stop`])},` ⧉ `+b(q(Y)(`@WORKBENCH:复制`)),9,yn)]),E(`pre`,bn,b(e.job.thinking),1)],40,hn)):u(``,!0),E(`div`,xn,[E(`span`,Sn,b(q(Y)(`@WORKBENCH:模型返回`)),1),E(`span`,Cn,b((e.job.output||``).length)+` `+b(q(Y)(`@WORKBENCH:字符`)),1),E(`button`,{type:`button`,class:`wb-log-copy wb-log-copy--sm`,title:q(Y)(`@WORKBENCH:复制模型返回`),onClick:i[2]||=J(e=>s(`output`),[`stop`])},` ⧉ `+b(q(Y)(`@WORKBENCH:复制`)),9,wn),E(`button`,{type:`button`,class:`wb-log-copy wb-log-copy--sm`,title:q(Y)(`@WORKBENCH:全屏查看模型返回`),disabled:!re.value,onClick:i[3]||=J(e=>I.value=!0,[`stop`])},` ⛶ `+b(q(Y)(`@WORKBENCH:全屏`)),9,Tn)]),E(`div`,{ref_key:`preRef`,ref:D,class:`wb-log-pre`},[re.value?(H(),o(q(B),{key:0,content:y.value,final:S.value,typewriter:!1,class:`wb-log-pre__render`},null,8,[`content`,`final`])):(H(),W(`div`,En,b(q(Y)(`@WORKBENCH:(暂无输出)`)),1))],512),j(a,{modelValue:I.value,"onUpdate:modelValue":i[4]||=e=>I.value=e,title:q(Y)(`@WORKBENCH:模型返回 - 全屏查看`),fullscreen:``,"close-on-click-modal":!1,class:`wb-log-fullscreen-dialog`,onClosed:ie},{default:U(()=>[E(`div`,{ref_key:`fullscreenContainerRef`,ref:L,class:`wb-log-fullscreen`},[re.value?(H(),o(q(B),{key:0,content:x.value,final:S.value,typewriter:!1,class:`wb-log-fullscreen__render`},null,8,[`content`,`final`])):(H(),W(`div`,Dn,b(q(Y)(`@WORKBENCH:(暂无输出)`)),1))],512)]),_:1},8,[`modelValue`,`title`])],512),[[f,!n.value]])],2)}}}),[[`__scopeId`,`data-v-c34148d0`]]);function jn(e){switch(e){case`todo`:return Y(`@WORKBENCH:待执行`);case`running`:return Y(`@WORKBENCH:执行中`);case`done`:return Y(`@WORKBENCH:已完成`);case`error`:return Y(`@WORKBENCH:出错`);case`cancelled`:return Y(`@WORKBENCH:已取消`);case`pending`:return Y(`@WORKBENCH:排队中`);default:return e}}function Mn(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 Nn={class:`exec-logs`},Pn={class:`exec-logs__head`},Fn={class:`exec-logs__title-block`},In={class:`exec-logs__stats`},Ln={class:`exec-logs__head-actions`},Rn={class:`exec-logs__config`},zn={class:`exec-logs__config-label`},Bn={class:`exec-logs__config-field`},Vn={class:`exec-logs__config-name`},Hn={class:`exec-logs__config-field`},Un={class:`exec-logs__config-name`},Wn={class:`exec-logs__filter`},Gn={key:0,class:`exec-logs__batch-meta`},Kn={key:0,class:`exec-logs__batch`},qn={class:`exec-logs__list`},Jn={key:0,class:`exec-logs__empty`},Yn={class:`exec-logs__empty-art`,"aria-hidden":`true`},Xn={class:`exec-logs__empty-title`},Zn={class:`exec-logs__empty-hint`},Qn={class:`exec-card__head`},$n=[`title`],er={class:`exec-card__meta`},tr={key:0,class:`exec-card__task`},nr={key:1,class:`exec-card__time`},rr={key:2,class:`exec-card__exit`},ir=[`title`,`onClick`],ar={key:0,class:`exec-card__error`},or={key:1,class:`exec-logs__pager`},sr=50,cr=Ee(e({__name:`ExecutionLogManager`,setup(e){function t(e){return e instanceof Error?e.message:String(e)}let n=M([]),a=M(0),o=ae({count:0,sizeMB:0,byStatus:{}}),s=M(!1),c=M(new Set),d=ae({q:``,status:``,page:1}),f=M({maxCount:500,maxSizeMB:256}),h=ae({maxCount:500,maxSizeMB:256}),g=M(!1),v=[{value:`pending`,label:Y(`@WORKBENCH:排队中`)},{value:`running`,label:Y(`@WORKBENCH:执行中`)},{value:`done`,label:Y(`@WORKBENCH:已完成`)},{value:`error`,label:Y(`@WORKBENCH:出错`)},{value:`cancelled`,label:Y(`@WORKBENCH:已取消`)}],x=C(()=>n.value.length>0&&n.value.every(e=>c.value.has(e.id))),S=C(()=>n.value.some(e=>c.value.has(e.id))&&!x.value);async function w(){s.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(sr)),e.set(`offset`,String((d.page-1)*sr));let t=await fetch(`/api/workbench/jobs/list?${e.toString()}`).then(e=>e.json());if(!t.success)throw Error(t.error||`list failed`);n.value=t.jobs,a.value=t.total,o.count=t.stats.count,o.sizeMB=t.stats.sizeMB,o.byStatus=t.stats.byStatus;let r=new Set(n.value.map(e=>e.id));for(let e of Array.from(c.value))r.has(e)||c.value.delete(e)}catch(e){m.error(Y(`@WORKBENCH:加载失败`)+`: `+t(e))}finally{s.value=!1}}async function D(){try{let e=await fetch(`/api/workbench/jobs/config`).then(e=>e.json());e.success&&(f.value=e.config,h.maxCount=e.config.maxCount,h.maxSizeMB=e.config.maxSizeMB)}catch{}}async function k(){g.value=!0;try{let e=await fetch(`/api/workbench/jobs/config`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({maxCount:h.maxCount,maxSizeMB:h.maxSizeMB})}).then(e=>e.json());if(!e.success)throw Error(e.error||`save failed`);f.value=e.config,m.success(Y(`@WORKBENCH:已保存策略`)),await w()}catch(e){m.error(Y(`@WORKBENCH:保存失败`)+`: `+t(e))}finally{g.value=!1}}function A(){d.page=1,w()}function N(){d.q=``,d.status=``,d.page=1,w()}function ee(e,t){t?c.value.add(e):c.value.delete(e),c.value=new Set(c.value)}function te(e){if(e)for(let e of n.value)c.value.add(e.id);else for(let e of n.value)c.value.delete(e.id);c.value=new Set(c.value)}async function ne(e){try{await p.confirm(Y(`@WORKBENCH:确定要删除所选的 {count} 条日志吗?`,{count:1}),Y(`@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`);c.value.delete(e),c.value=new Set(c.value),await w()}catch(e){m.error(Y(`@WORKBENCH:保存失败`)+`: `+t(e))}}async function re(){let e=Array.from(c.value);if(e.length!==0){try{await p.confirm(Y(`@WORKBENCH:确定要删除所选的 {count} 条日志吗?`,{count:e.length}),Y(`@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`);m.success(Y(`@WORKBENCH:成功删除 {count} 条`,{count:t.removed||e.length})),c.value=new Set,await w()}catch(e){m.error(Y(`@WORKBENCH:保存失败`)+`: `+t(e))}}}async function L(){let e=o.count;if(e!==0){try{await p.confirm(Y(`@WORKBENCH:确定要清空所有 {count} 条执行日志吗?此操作不可恢复。`,{count:e}),Y(`@WORKBENCH:清空全部`),{type:`warning`,confirmButtonText:Y(`@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`);m.success(Y(`@WORKBENCH:成功删除 {count} 条`,{count:t.removed||e})),c.value=new Set,await w()}catch(e){m.error(Y(`@WORKBENCH:保存失败`)+`: `+t(e))}}}function R(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 oe(()=>{w(),D()}),(e,t)=>{let f=fe,p=l,m=xe,C=I,D=ie,M=ue,ae=i,z=he,oe=_;return H(),W(`div`,Nn,[E(`header`,Pn,[E(`div`,Fn,[E(`span`,In,b(q(Y)(`@WORKBENCH:共 {count} 条,占 {size} MB`,{count:o.count,size:o.sizeMB})),1)]),E(`div`,Ln,[j(f,{icon:q(K),size:`small`,loading:s.value,onClick:w},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:刷新`)),1)]),_:1},8,[`icon`,`loading`]),j(f,{type:`danger`,plain:``,size:`small`,disabled:o.count===0,onClick:L},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:清空全部`)),1)]),_:1},8,[`disabled`])])]),E(`div`,Rn,[E(`span`,zn,b(q(Y)(`@WORKBENCH:保存策略`)),1),E(`span`,Bn,[E(`span`,Vn,b(q(Y)(`@WORKBENCH:最大条数`)),1),j(p,{modelValue:h.maxCount,"onUpdate:modelValue":t[0]||=e=>h.maxCount=e,min:0,max:1e4,step:50,size:`small`,"controls-position":`right`,style:{width:`130px`}},null,8,[`modelValue`])]),E(`span`,Hn,[E(`span`,Un,b(q(Y)(`@WORKBENCH:最大体积 (MB)`)),1),j(p,{modelValue:h.maxSizeMB,"onUpdate:modelValue":t[1]||=e=>h.maxSizeMB=e,min:0,max:10240,step:32,size:`small`,"controls-position":`right`,style:{width:`140px`}},null,8,[`modelValue`])]),j(f,{type:`primary`,size:`small`,loading:g.value,onClick:k},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:保存策略`)),1)]),_:1},8,[`loading`])]),E(`div`,Wn,[j(m,{modelValue:d.q,"onUpdate:modelValue":t[2]||=e=>d.q=e,placeholder:q(Y)(`@WORKBENCH:搜索标题 / 任务`),clearable:``,size:`small`,style:{width:`240px`},onKeyup:y(A,[`enter`]),onClear:A},null,8,[`modelValue`,`placeholder`]),j(D,{modelValue:d.status,"onUpdate:modelValue":t[3]||=e=>d.status=e,placeholder:q(Y)(`@WORKBENCH:全部状态`),clearable:``,size:`small`,style:{width:`130px`},onChange:A},{default:U(()=>[(H(),W(r,null,F(v,e=>j(C,{key:e.value,label:e.label,value:e.value},null,8,[`label`,`value`])),64))]),_:1},8,[`modelValue`,`placeholder`]),j(f,{size:`small`,onClick:N},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:重置`)),1)]),_:1}),t[5]||=E(`span`,{class:`exec-logs__filter-spacer`},null,-1),c.value.size>0?(H(),W(`span`,Gn,b(q(Y)(`@WORKBENCH:已选择 {count} 项`,{count:c.value.size})),1)):u(``,!0)]),c.value.size>0?(H(),W(`div`,Kn,[j(M,{"model-value":x.value,indeterminate:S.value,onChange:te},{default:U(()=>[O(b(x.value?q(Y)(`@WORKBENCH:取消全选`):q(Y)(`@WORKBENCH:全选`)),1)]),_:1},8,[`model-value`,`indeterminate`]),j(f,{type:`danger`,size:`small`,onClick:re},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:批量删除`)),1)]),_:1})])):u(``,!0),de((H(),W(`div`,qn,[!s.value&&n.value.length===0?(H(),W(`div`,Jn,[E(`div`,Yn,[j(ae,null,{default:U(()=>[j(q(T))]),_:1})]),E(`div`,Xn,b(q(Y)(`@WORKBENCH:暂无执行日志`)),1),E(`div`,Zn,b(q(Y)(`@WORKBENCH:点击「执行任务」开始一次执行,日志会出现在这里。`)),1)])):u(``,!0),(H(!0),W(r,null,F(n.value,e=>(H(),W(`article`,{key:e.id,class:P([`exec-card`,{"is-selected":c.value.has(e.id)}])},[E(`header`,Qn,[j(M,{"model-value":c.value.has(e.id),onChange:t=>ee(e.id,t)},null,8,[`model-value`,`onChange`]),E(`span`,{class:`exec-card__status`,style:Ce({color:q(Mn)(e.status),borderColor:q(Mn)(e.status)})},b(q(jn)(e.status)),5),E(`span`,{class:`exec-card__title`,title:e.title||q(Y)(`@WORKBENCH:无标题`)},b(e.title||q(Y)(`@WORKBENCH:无标题`)),9,$n),t[6]||=E(`span`,{class:`exec-card__spacer`},null,-1),E(`span`,er,[e.taskTitle?(H(),W(`span`,tr,`📁 `+b(e.taskTitle),1)):u(``,!0),e.startedAt?(H(),W(`span`,nr,`⏱ `+b(R(e.startedAt,e.endedAt)),1)):u(``,!0),e.exitCode===null?u(``,!0):(H(),W(`span`,rr,`exit `+b(e.exitCode),1))]),E(`button`,{type:`button`,class:`exec-card__del`,title:q(Y)(`@WORKBENCH:删除`),onClick:t=>ne(e.id)},`×`,8,ir)]),e.error?(H(),W(`p`,ar,`⚠ `+b(e.error),1)):u(``,!0),j(An,{job:e},null,8,[`job`])],2))),128))])),[[oe,s.value]]),a.value>sr?(H(),W(`footer`,or,[j(z,{"current-page":d.page,"onUpdate:currentPage":t[4]||=e=>d.page=e,"page-size":sr,total:a.value,layout:`prev, pager, next, total`,background:``,small:``,onCurrentChange:w},null,8,[`current-page`,`total`])])):u(``,!0)])}}}),[[`__scopeId`,`data-v-174a9b87`]]),lr={class:`workbench`},ur={class:`workbench__editor-row`},dr={class:`wb-sidebar`},fr={class:`wb-section`},pr={class:`wb-section__head`},mr={class:`wb-section__tag`},hr={class:`wb-section__title`},gr={class:`wb-pill wb-section__count`},_r={class:`wb-task-list`},vr=[`aria-expanded`,`title`,`onClick`,`onKeydown`],yr=[`title`],br={class:`wb-pill wb-task-group__count`},xr=[`data-icon`,`onClick`],Sr=[`data-icon`],Cr={class:`wb-task-item__body`},wr=[`title`],Tr={class:`wb-task-item__meta`},Er=[`title`],Dr={class:`wb-pill wb-task-item__num`},Or=[`title`],kr={class:`wb-pill wb-task-item__num`},Ar=[`title`],jr=[`title`,`aria-label`],Mr=[`title`],Nr=[`title`],Pr=[`onClick`,`title`,`aria-label`],Fr={key:0,class:`wb-empty wb-empty--rich`},Ir={class:`wb-empty__art`,"aria-hidden":`true`},Lr={class:`wb-empty__title`},Rr={class:`wb-empty__hint`},zr={class:`wb-empty__cta`},Br={class:`wb-section`},Vr={class:`wb-section__head`},Hr={class:`wb-section__tag wb-section__tag--accent`},Ur={class:`wb-section__title`},Wr={class:`wb-pill wb-section__count`},Gr=[`title`,`aria-label`],Kr={class:`wb-prompt-list`},qr={class:`wb-prompt-item__icon`},Jr=[`onClick`,`title`],Yr=[`title`],Xr=[`onClick`,`title`,`aria-label`],Zr={key:0,class:`wb-empty wb-empty--compact`},Qr={class:`wb-split`},$r={key:0,class:`wb-placeholder`},ei={class:`wb-split__header`},ti=[`placeholder`],ni=[`title`],ri={key:0,class:`wb-meta-save__dot`},ii={key:1,class:`wb-meta-save__check`},ai={key:2,class:`wb-meta-save__bang`},oi={key:3,class:`wb-meta-save__dot`},si={value:null},ci=[`value`],li=[`aria-label`],ui=[`aria-selected`],di=[`aria-selected`],fi=[`disabled`,`title`],pi=[`title`,`aria-label`],mi=[`open`],hi={class:`wb-task-desc__summary`},gi={class:`wb-task-desc__label`},_i={key:0,class:`wb-task-desc__tag`},vi={key:0},yi={key:1,class:`wb-task-desc__tag-attachment`},bi=[`placeholder`],xi={key:0,class:`wb-exec-list`},Si={class:`wb-exec-list__header`},Ci={class:`wb-exec-list__title`},wi={class:`wb-split__sub-actions`},Ti={key:0,class:`wb-dirty-badge`},Ei={class:`wb-exec-sub-list`},Di=[`onClick`],Oi={class:`wb-exec-sub-item__row1`},ki=[`title`],Ai=[`title`],ji={key:0,class:`wb-exec-sub-item__dirty-dot`,title:`未保存`},Mi={class:`wb-exec-sub-item__row2`},Ni={key:0,class:`wb-sub-item__pid`},Pi={class:`wb-exec-sub-item__actions`},Fi=[`title`,`onClick`],Ii=[`title`,`onClick`],Li=[`title`,`disabled`,`onClick`],Ri=[`title`,`disabled`,`onClick`],zi={key:0,class:`wb-empty wb-empty--rich`},Bi={class:`wb-empty__art`,"aria-hidden":`true`},Vi={class:`wb-empty__title`},Hi={class:`wb-empty__cta`},Ui={class:`wb-exec-detail`},Wi={key:0,class:`wb-placeholder`},Gi={class:`wb-exec-detail__head`},Ki=[`placeholder`],qi=[`title`],Ji=[`placeholder`],Yi={class:`wb-form-item__label wb-simple__override-summary`},Xi=[`title`],Zi=[`disabled`],Qi=[`placeholder`],$i={style:{display:`flex`,gap:`8px`,"align-items":`center`}},ea=`__simple`,ta=`__no_project__`,na=`.png,.jpg,.jpeg,.gif,.webp,.bmp,.svg,.pdf,.txt,.md,.csv,.json,.log`,ra=5*1024*1024,ia=Ee(e({__name:`WorkbenchView`,setup(e){let n=M([]),s=M([]),l=M([]),d=M(!1),f=M(null),h=C(()=>s.value.find(e=>e.id===f.value)||null),g=C(()=>h.value?.type===`simple`),_=M(null),x=C(()=>!h.value||g.value||!_.value?null:h.value.subtasks.find(e=>e.id===_.value)||null),w=M(new Map),k=M({title:``,desc:``,promptId:null,simpleOverride:``});function A(){let e=new Map;if(h.value)for(let t of h.value.subtasks)e.set(t.id,{id:t.id,title:t.title,desc:t.desc,promptOverride:t.promptOverride});w.value=e,h.value?k.value={title:h.value.title,desc:h.value.desc,promptId:h.value.promptId,simpleOverride:h.value.simpleOverride||``}:k.value={title:``,desc:``,promptId:null,simpleOverride:``}}let N=C(()=>{let e=new Set;if(!h.value)return e;for(let t of h.value.subtasks){let n=w.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}),re=C(()=>N.value.size>0),L=M(`idle`),se=M(0),ce=null,B=C(()=>{if(!h.value)return!1;let e=h.value;return k.value.title!==e.title||k.value.desc!==e.desc||k.value.promptId!==e.promptId||k.value.simpleOverride!==(e.simpleOverride||``)});function le(){ce!==null&&(clearTimeout(ce),ce=null)}async function ue(){if(!h.value)return!1;if(!B.value)return!0;if(L.value=`saving`,await _t(!1))return se.value=Date.now(),L.value=`saved`,setTimeout(()=>{L.value===`saved`&&Date.now()-se.value>=4e3&&(L.value=`idle`)},4e3),!0;L.value=`error`;let e=Date.now();return setTimeout(()=>{L.value===`error`&&Date.now()-e>=4e3&&(L.value=`idle`)},4e3),!1}R(()=>h.value?{id:h.value.id,title:h.value.title,desc:h.value.desc,promptId:h.value.promptId,simpleOverride:h.value.simpleOverride||``}:null,(e,t)=>{!e||!t||e.id!==t.id||(ce!==null&&clearTimeout(ce),ce=window.setTimeout(()=>{ue()},1500))},{deep:!0}),R(f,async(e,t)=>{le(),h.value&&B.value&&await ue()}),R(f,()=>{yt.value=!1});function V(e){try{let t=new Blob([JSON.stringify(e)],{type:`application/json`});navigator.sendBeacon?.(`/api/workbench/tasks`,t)}catch{}}function he(){h.value&&B.value&&V(h.value)}let G=ae({visible:!1,editing:null,name:``,content:``,aiLoading:!1}),K=ae({visible:!1,text:``,loading:!1,saving:!1}),Ee=M(!1),X=ae({visible:!1,editing:null,title:``,desc:``,promptId:null,type:`complex`,simpleOverride:``}),Oe=null,ke=De();function Ae(){ke.setRunning(l.value.filter(e=>e.status===`running`).length)}function Z(e){return l.value.find(t=>t.subId===e)||null}function je(e,t){if(e===`hello`){l.value=t.jobs||[],Ae();return}if(e===`job:update`){let e=t,n=l.value.findIndex(t=>t.id===e.id);n>=0?l.value[n]=e:l.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=l.value.findIndex(e=>e.id===t.id);if(i<0)return;let a=l.value[i][n]||``;l.value[i][n]=a+r;return}if(e===`sub:update`){let e=s.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=s.value.findIndex(e=>e.id===t.id);e>=0&&(s.value[e]=t)}e===`task:error`&&m.error(t.error||Y(`@WORKBENCH:执行出错`))}let Me=[{key:`image`,patterns:[/图\s*片/,/上\s*传/,/upload/i,/image/i,/screenshot/i,/截图/,/附件/,/attachment/i]},{key:`icon`,patterns:[/图\s*标/,/icon/i,/svg/i]},{key:`test`,patterns:[/测\s*试/,/test/i,/spec/i,/\bqa\b/i]},{key:`ui`,patterns:[/ui\s*优\s*化/,/样\s*式/,/style/i,/css/i,/界面/,/视\s*觉/,/design/i]}];function Ne(e){let t=(e||``).trim();if(!t)return`doc`;for(let e of Me)if(e.patterns.some(e=>e.test(t)))return e.key;return`doc`}let Pe={icon:z(T),image:z(me),test:z(D),ui:z(pe),doc:z(T),idea:z(pe)};function Fe(e){return Pe[Ne(e.title)]}function Ie(e){return e?Z(`${e.id}${ea}`):null}function Le(e){return e?e.status===`pending`||e.status===`running`?`running`:e.status===`done`?`done`:e.status===`cancelled`?`cancelled`:`error`:`idle`}function Re(e){return Array.isArray(e.attachments)?e.attachments.length:0}function ze(e){return Array.isArray(e.subtasks)?e.subtasks.length:0}function Be(e){return Array.isArray(e.subtasks)?e.subtasks.filter(e=>e&&e.status===`done`).length:0}function Ve(e){if(Array.isArray(e.subtasks)&&e.subtasks.some(e=>e&&e.status===`running`))return!0;let t=l.value.find(t=>t.subId===`${e.id}__simple`);return!!(t&&(t.status===`running`||t.status===`pending`))}async function He(){n.value=(await fetch(`/api/workbench/prompts`).then(e=>e.json()).catch(()=>({prompts:[]}))).prompts||[]}async function Ue(){s.value=(await fetch(`/api/workbench/tasks`).then(e=>e.json()).catch(()=>({tasks:[]}))).tasks||[],!f.value&&s.value.length>0&&(f.value=s.value[0].id),A()}let Q=M({path:``,name:``});async function We(){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 Ge=M(new Set);function Ke(e){return Ge.value.has(e)}function qe(e){Ge.value.has(e)?Ge.value.delete(e):Ge.value.add(e),Ge.value=new Set(Ge.value)}let Je=C(()=>{let e=s.value,t=new Map;for(let n of e){let e=(n.projectPath||``).trim()||ta;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===ta?1:t===ta?-1:e.localeCompare(t));return{groups:r.map(e=>({path:e,label:e===ta?Y(`@WORKBENCH:未关联项目`):e,tasks:t.get(e)})),hasMultiple:r.length>1}});function Ye(e){if(!e||e===ta)return e;let t=e.split(/[\\/]/).filter(Boolean);return t.length<=1?e:t.slice(-2).join(`/`)}R(()=>Je.value.groups.map(e=>e.path),e=>{let t=Q.value.path,n=new Set(Ge.value),r=!1;for(let i of e)i!==t&&!n.has(i)&&(n.add(i),r=!0);r&&(Ge.value=n)},{immediate:!0});async function Xe(){l.value=(await fetch(`/api/workbench/jobs`).then(e=>e.json()).catch(()=>({jobs:[]}))).jobs||[],Ae()}async function Ze(e){try{let t=await fetch(`/api/workbench/jobs/by-task/${encodeURIComponent(e)}`,{method:`DELETE`}).then(e=>e.json());return t?.success?(l.value=l.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}}function Qe(){Oe&&=(Oe.close(),null),Oe=new EventSource(`/api/workbench/events`),Oe.onmessage=e=>{try{let t=JSON.parse(e.data);je(t.event,t.payload)}catch{}},Oe.onerror=()=>{Oe&&=(Oe.close(),null),setTimeout(Qe,3e3)}}function $e(){G.editing=null,G.name=``,G.content=``,G.aiLoading=!1,G.visible=!0}function et(e){G.editing=e,G.name=e.name,G.content=e.content,G.aiLoading=!1,G.visible=!0}async function tt(){if(!G.aiLoading){G.aiLoading=!0;try{let e=await fetch(`/api/workbench/prompts/ai-generate`,{method:`POST`}).then(e=>e.json());e.success?(G.name=e.name||G.name,G.content=e.result||``,m.success(Y(`@WORKBENCH:已生成,可继续编辑`))):m.error(e.error||Y(`@WORKBENCH:生成失败`))}catch(e){m.error(Y(`@WORKBENCH:网络错误: `)+(e&&e.message||e))}finally{G.aiLoading=!1}}}async function nt(){K.visible=!0,K.loading=!0;try{let e=await fetch(`/api/workbench/prompts/ai-instruction`).then(e=>e.json());e.success?K.text=e.instruction||``:m.error(e.error||Y(`@WORKBENCH:读取指令失败`))}catch(e){m.error(Y(`@WORKBENCH:读取指令失败`)+`: `+(e&&e.message||e))}finally{K.loading=!1}}async function rt(){if(!K.text.trim()){m.warning(Y(`@WORKBENCH:指令内容不能为空`));return}K.saving=!0;try{let e=await fetch(`/api/workbench/prompts/ai-instruction`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({instruction:K.text})}).then(e=>e.json());e.success?(m.success(Y(`@WORKBENCH:已保存指令`)),K.visible=!1):m.error(e.error||Y(`@WORKBENCH:保存失败`))}catch(e){m.error(Y(`@WORKBENCH:网络错误: `)+(e&&e.message||e))}finally{K.saving=!1}}async function it(){if(!G.name.trim()||!G.content.trim()){m.warning(Y(`@WORKBENCH:名称和内容不能为空`));return}let e={id:G.editing?.id,name:G.name.trim(),content:G.content},t=await fetch(`/api/workbench/prompts`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)}).then(e=>e.json());t.success?(m.success(Y(`@WORKBENCH:已保存`)),G.visible=!1,He()):m.error(t.error||Y(`@WORKBENCH:保存失败`))}async function at(e){await p.confirm(Y(`@WORKBENCH:删除提示词「{name}」?`,{name:e.name}),Y(`@WORKBENCH:确认`),{type:`warning`}),await fetch(`/api/workbench/prompts/${e.id}`,{method:`DELETE`}),He();for(let t of s.value)t.promptId===e.id&&(t.promptId=null,await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)}));Ue()}function ot(){X.editing=null,X.title=``,X.desc=``,X.promptId=null,X.type=`simple`,X.simpleOverride=``,X.visible=!0}async function st(){let e={id:X.editing?.id,title:X.title.trim(),desc:X.desc,promptId:X.promptId,type:X.type,simpleOverride:X.type===`simple`?X.simpleOverride:``,subtasks:X.editing?.subtasks||[]};!X.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){m.success(Y(`@WORKBENCH:已保存`));let e=!X.editing?.id;X.visible=!1,await Ue(),e&&t.task?.id?(f.value=t.task.id,A()):f.value||=t.task.id}else m.error(t.error||Y(`@WORKBENCH:保存失败`))}async function ct(e,t){if(e.type===t)return;let n=e.type===`complex`&&t===`simple`&&(e.subtasks?.length??0)>0;if(n)try{await p.confirm(Y(`@WORKBENCH:任务「{title}」当前有 {n} 个子任务,切换为简单任务后会清空这些子任务,确认继续?`,{title:e.title,n:e.subtasks.length}),Y(`@WORKBENCH:切换任务类型`),{type:`warning`,confirmButtonText:Y(`@WORKBENCH:切换并清空`),cancelButtonText:Y(`@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){m.error(i.error||Y(`@WORKBENCH:保存失败`));return}await Ue(),m.success(Y(t===`simple`?`@WORKBENCH:已切换为简单任务`:`@WORKBENCH:已切换为复杂任务`))}async function lt(e){h.value&&await ct(h.value,e)}async function ut(e){await p.confirm(Y(`@WORKBENCH:删除任务「{title}」及其所有子任务?`,{title:e.title}),Y(`@WORKBENCH:确认`),{type:`warning`}),await fetch(`/api/workbench/tasks/${e.id}`,{method:`DELETE`}),f.value===e.id&&(f.value=null),Ue()}async function dt(e){f.value!==e.id&&(le(),h.value&&B.value&&await ue(),f.value=e.id,A())}R(()=>h.value,e=>{if(!e||e.type===`simple`){_.value=null;return}_.value=e.subtasks.find(e=>e.status===`running`)?.id||e.subtasks[0]?.id||null},{immediate:!0}),R(()=>h.value?.subtasks?.length,()=>{!h.value||g.value||(!_.value||!h.value.subtasks.find(e=>e.id===_.value))&&(_.value=h.value.subtasks[0]?.id||null)});let ft=M(new Set);function pt(e){return ft.value.has(e)}function mt(e,t){t?ft.value.add(e):ft.value.delete(e),ft.value=new Set(ft.value)}async function ht(){if(!h.value)return;let e={id:`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,title:Y(`@WORKBENCH:新子任务`),desc:``,status:`todo`,promptOverride:``};h.value.subtasks.push(e),mt(e.id,!0);try{await _t(!1)}finally{mt(e.id,!1)}}async function gt(e){if(h.value){h.value.subtasks=h.value.subtasks.filter(t=>t.id!==e.id),mt(e.id,!0);try{await _t(!1)}finally{mt(e.id,!1)}}}async function _t(e){if(!h.value)return!1;let t=await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(h.value)}).then(e=>e.json());return t.success?(e&&m.success(Y(`@WORKBENCH:已保存拆分`)),await Ue(),!0):(m.error(t.error||Y(`@WORKBENCH:保存失败`)),!1)}async function vt(){await _t(!0)}let yt=M(!1);function bt(){if(h.value){if(!(h.value.title||``).trim()){m.warning(Y(`@WORKBENCH:请先填写任务标题`));return}yt.value=!0}}function xt(e){if(h.value){for(let t of e)h.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:[]});m.success(Y(`@WORKBENCH:已生成 {n} 个子任务,请审阅后保存`,{n:e.length}))}}async function St(e){if(e.type===`simple`)return Ct(e);if(!e.subtasks||e.subtasks.length===0){m.warning(Y(`@WORKBENCH:请先拆分任务`));return}if(h.value&&h.value.id===e.id){let t=s.value.find(t=>t.id===e.id);if((!t||t.title!==h.value.title||t.desc!==h.value.desc||JSON.stringify(t.subtasks)!==JSON.stringify(h.value.subtasks)||t.promptId!==h.value.promptId)&&!await _t(!1))return}await Ze(e.id);let t=await fetch(`/api/workbench/tasks/${e.id}/run`,{method:`POST`}).then(e=>e.json());t.success?m.success(t.message||Y(`@WORKBENCH:已加入执行队列`)):m.error(t.error||Y(`@WORKBENCH:执行失败`))}async function Ct(e){if(h.value&&h.value.id===e.id){let t=s.value.find(t=>t.id===e.id);if((!t||t.title!==h.value.title||t.desc!==h.value.desc||t.promptId!==h.value.promptId||(t.simpleOverride||``)!==(h.value.simpleOverride||``))&&!await _t(!1))return}await Ze(e.id);let t=await fetch(`/api/workbench/tasks/${e.id}/run-simple`,{method:`POST`}).then(e=>e.json());t.success?m.success(t.message||Y(`@WORKBENCH:已加入执行队列`)):m.error(t.error||Y(`@WORKBENCH:执行失败`))}async function wt(e){if(!h.value)return;let t=h.value,n=Z(e.id);if(n&&(n.status===`running`||n.status===`pending`)){m.warning(Y(`@WORKBENCH:该子任务正在执行中`));return}let r=s.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 _t(!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?m.success(i.message||Y(`@WORKBENCH:已开始执行子任务`)):m.error(i.error||Y(`@WORKBENCH:执行失败`))}function Tt(e){if(e.status===`done`)return!1;let t=Z(e.id);return!(t&&(t.status===`running`||t.status===`pending`))}async function Et(e){if(h.value&&!pt(e.id)){mt(e.id,!0);try{let t=w.value.get(e.id);t&&w.value.set(e.id,{...t,status:`todo`}),e.status=`todo`,await _t(!1)}finally{mt(e.id,!1)}}}async function Dt(e){try{await p.confirm(Y(`@WORKBENCH:确认停止执行?已输出的内容会保留。`),Y(`@WORKBENCH:停止执行`),{confirmButtonText:Y(`@WORKBENCH:停止`),cancelButtonText:Y(`@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?m.success(Y(`@WORKBENCH:已发送停止信号`)):m.error(t.error||Y(`@WORKBENCH:停止失败`))}oe(async()=>{await Promise.all([He(),Ue(),We(),Xe()]),Qe(),window.addEventListener(`beforeunload`,he)}),_e(()=>{Oe&&=(Oe.close(),null),window.removeEventListener(`beforeunload`,he),h.value&&B.value&&V(h.value)});let Ot=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`]),kt=M({}),$=M(null);function At(e){return!!kt.value[e]}function Mt(e,t){if(e instanceof File)return e;let n=e.type||`application/octet-stream`;return new File([e],t,{type:n})}function Nt(e){return e.kind===`task`?`task-${e.task?.id??``}`:`sub-${e.sub.id}`}function Pt(e){let t=e.kind===`task`?e.task?.attachments:e.sub.attachments;return Array.isArray(t)?t:[]}function Ft(e,t){e.kind===`task`?e.task&&(e.task.attachments=t):e.sub.attachments=t}function It(e){return e.kind===`task`?`/api/workbench/tasks/${e.task?.id??``}/attachments`:`/api/workbench/subtasks/${e.sub.id}/attachments`}function Lt(e,t){return e.kind===`task`?`/api/workbench/tasks/${e.task?.id??``}/attachments/${t}`:`/api/workbench/subtasks/${e.sub.id}/attachments/${t}`}function Rt(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`);Bt(t,Mt(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&&Bt(t,Mt(n,n.name||`pasted-file`))}}}function zt(e,t){$.value=null,Array.from(e.dataTransfer?.files||[]).forEach(e=>Bt(t,e))}async function Bt(e,t){if(t.size>ra){m.error(`「${t.name}」${Y(`@WORKBENCH:超过 5MB 限制`)}`);return}if(!Ot.has(t.type)&&!t.name.match(/\.(png|jpg|jpeg|gif|webp|bmp|svg|pdf|txt|md|markdown|csv|json|log)$/i)){m.error(`${Y(`@WORKBENCH:不支持的文件类型`)}(${t.name})`);return}let n=Pt(e);if(n.length>=9){m.error(Y(`@WORKBENCH:单个任务最多 9 个附件`));return}if(n.find(e=>e.originalName===t.name&&e.size===t.size)){m.info(`${t.name} ${Y(`@WORKBENCH:已存在,已复用`)}`);return}let r=Nt(e);kt.value[r]=!0;try{let n=await fetch(It(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=Pt(e);r.push(n.attachment),Ft(e,r),m.success(`${Y(`@WORKBENCH:已添加:`)}${t.name}`)}else m.error(n.error||Y(`@WORKBENCH:上传失败`))}catch(e){m.error(Y(`@WORKBENCH:上传失败`)+`:`+(e&&e.message||e))}finally{kt.value[r]=!1}}async function Vt(e,t){try{await p.confirm(Y(`@WORKBENCH:删除附件「{name}」?`,{name:t.originalName}),Y(`@WORKBENCH:确认`),{type:`warning`})}catch{return}let n=await fetch(Lt(e,t.id),{method:`DELETE`}).then(e=>e.json());n.success?(Ft(e,Pt(e).filter(e=>e.id!==t.id)),m.success(Y(`@WORKBENCH:已删除`))):m.error(n.error||Y(`@WORKBENCH:删除失败`))}function Ht(e){let t=document.createElement(`input`);t.type=`file`,t.accept=na,t.multiple=!0,t.onchange=()=>{Array.from(t.files||[]).forEach(t=>Bt(e,t))},t.click()}let Ut=new Set([`png`,`jpg`,`jpeg`,`gif`,`webp`,`bmp`,`svg`]);function Gt(e){return Ut.has(String(e.ext||``).toLowerCase())}function Kt(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`}return(e,l)=>{let p=i,m=fe,C=be,w=xe,D=we,k=ee,A=ye,M=te,R=I,ae=ie;return H(),W(`div`,lr,[E(`div`,ur,[E(`aside`,dr,[E(`section`,fr,[E(`header`,pr,[E(`span`,mr,b(q(Y)(`@WORKBENCH:任务`)),1),E(`h3`,hr,b(q(Y)(`@WORKBENCH:任务列表`)),1),E(`span`,gr,b(s.value.length),1)]),E(`button`,{class:`wb-new-btn`,onClick:ot},[j(p,{class:`wb-new-btn__icon`},{default:U(()=>[j(q(ve))]),_:1}),E(`span`,null,b(q(Y)(`@WORKBENCH:新建任务`)),1),l[43]||=E(`span`,{class:`wb-new-btn__shortcut`},`N`,-1)]),E(`ul`,_r,[(H(!0),W(r,null,F(Je.value.groups,e=>(H(),W(r,{key:e.path},[Je.value.hasMultiple?(H(),W(`li`,{key:0,class:P([`wb-task-group__head`,{"is-current":e.path===Q.value.path,"is-collapsed":Ke(e.path)}]),role:`button`,tabindex:`0`,"aria-expanded":!Ke(e.path),title:Ke(e.path)?q(Y)(`@WORKBENCH:展开`):q(Y)(`@WORKBENCH:收起`),onClick:t=>qe(e.path),onKeydown:[y(J(t=>qe(e.path),[`prevent`]),[`enter`]),y(J(t=>qe(e.path),[`prevent`]),[`space`])]},[j(p,{class:`wb-task-group__caret`},{default:U(()=>[(H(),o(ne(Ke(e.path)?q(S):q(Se))))]),_:2},1024),j(p,{class:`wb-task-group__icon`},{default:U(()=>[j(q(ge))]),_:1}),E(`span`,{class:`wb-task-group__name`,title:e.path===Q.value.path?Q.value.path:e.label},b(e.path===Q.value.path?Q.value.name:Ye(e.label)),9,yr),E(`span`,br,b(e.tasks.length),1)],42,vr)):u(``,!0),Ke(e.path)?u(``,!0):(H(!0),W(r,{key:1},F(e.tasks,e=>(H(),W(`li`,{key:e.id,class:P([`wb-task-item`,{active:e.id===f.value,"has-attachment":Re(e)>0,"is-other-project":e.projectPath&&e.projectPath!==Q.value.path,"is-running":Ve(e)}]),"data-icon":Ne(e.title),onClick:t=>dt(e)},[E(`div`,{class:`wb-task-item__avatar`,"data-icon":Ne(e.title)},[j(p,null,{default:U(()=>[(H(),o(ne(Fe(e))))]),_:2},1024)],8,Sr),E(`div`,Cr,[E(`div`,{class:`wb-task-item__title`,title:e.title},b(e.title||q(Y)(`@WORKBENCH:未命名任务`)),9,wr),E(`div`,Tr,[ze(e)>0?(H(),W(`span`,{key:0,class:P([`wb-task-item__meta-item`,{"wb-task-item__meta-item--running":Ve(e)}]),title:q(Y)(`@WORKBENCH:个子任务`)},[j(p,{class:`wb-task-item__meta-icon`},{default:U(()=>[j(q(t))]),_:1}),E(`span`,Dr,b(Be(e))+`/`+b(ze(e)),1)],10,Er)):u(``,!0),Re(e)>0?(H(),W(`span`,{key:1,class:`wb-task-item__meta-item`,title:q(Y)(`@WORKBENCH:附件`)},[j(p,{class:`wb-task-item__meta-icon`},{default:U(()=>[j(q(me))]),_:1}),E(`span`,kr,b(Re(e)),1)],8,Or)):u(``,!0),e.promptId?(H(),W(`span`,{key:2,class:`wb-task-item__meta-item wb-task-item__meta-item--accent`,title:q(Y)(`@WORKBENCH:已绑定预置提示词`)},[j(p,{class:`wb-task-item__meta-icon`},{default:U(()=>[j(q(pe))]),_:1})],8,Ar)):u(``,!0),E(`button`,{type:`button`,class:P([`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`?q(Y)(`@WORKBENCH:简单任务 - 点击切换为复杂任务`):q(Y)(`@WORKBENCH:复杂任务 - 点击切换为简单任务`),"aria-label":e.type===`simple`?q(Y)(`@WORKBENCH:切换为复杂任务`):q(Y)(`@WORKBENCH:切换为简单任务`)},b(e.type===`simple`?q(Y)(`@WORKBENCH:简单`):q(Y)(`@WORKBENCH:复杂`)),11,jr),e.projectPath&&e.projectPath!==Q.value.path?(H(),W(`span`,{key:3,class:`wb-task-item__meta-item wb-task-item__meta-item--project`,title:e.projectPath},b(Ye(e.projectPath)),9,Mr)):u(``,!0)])]),Ve(e)?(H(),W(`span`,{key:0,class:`wb-task-item__running-dot`,title:q(Y)(`@WORKBENCH:执行中`),"aria-hidden":`true`},null,8,Nr)):u(``,!0),E(`button`,{class:`wb-task-item__del`,onClick:J(t=>ut(e),[`stop`]),title:q(Y)(`@WORKBENCH:删除`),"aria-label":q(Y)(`@WORKBENCH:删除`)},[j(p,null,{default:U(()=>[j(q(v))]),_:1})],8,Pr)],10,xr))),128))],64))),128)),s.value.length===0?(H(),W(`li`,Fr,[E(`div`,Ir,[j(p,null,{default:U(()=>[j(q(Te))]),_:1})]),E(`div`,Lr,b(q(Y)(`@WORKBENCH:暂无任务`)),1),E(`div`,Rr,b(q(Y)(`@WORKBENCH:点击上方按钮新建`)),1),E(`div`,zr,[j(m,{type:`primary`,size:`small`,icon:q(ve),onClick:ot},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:新建任务`)),1)]),_:1},8,[`icon`])])])):u(``,!0)])]),E(`section`,Br,[E(`header`,Vr,[E(`span`,Hr,b(q(Y)(`@WORKBENCH:提示`)),1),E(`h3`,Ur,b(q(Y)(`@WORKBENCH:预置提示词`)),1),E(`span`,Wr,b(n.value.length),1),E(`button`,{class:`wb-section__action`,onClick:$e,title:q(Y)(`@WORKBENCH:新建提示词`),"aria-label":q(Y)(`@WORKBENCH:新建提示词`)},[j(p,null,{default:U(()=>[j(q(ve))]),_:1})],8,Gr)]),E(`ul`,Kr,[(H(!0),W(r,null,F(n.value,e=>(H(),W(`li`,{key:e.id,class:`wb-prompt-item`},[E(`div`,qr,[j(p,null,{default:U(()=>[j(q(pe))]),_:1})]),E(`span`,{class:`wb-prompt-item__name`,onClick:t=>et(e),title:e.content},b(e.name),9,Jr),Q.value.name?(H(),W(`span`,{key:0,class:`wb-prompt-item__project`,title:q(Y)(`@WORKBENCH:适用于当前项目`)+`:`+Q.value.path},b(Q.value.name),9,Yr)):u(``,!0),E(`button`,{class:`wb-prompt-item__del`,onClick:t=>at(e),title:q(Y)(`@WORKBENCH:删除`),"aria-label":q(Y)(`@WORKBENCH:删除`)},[j(p,null,{default:U(()=>[j(q(v))]),_:1})],8,Xr)]))),128)),n.value.length===0?(H(),W(`li`,Zr,b(q(Y)(`@WORKBENCH:暂无提示词`)),1)):u(``,!0)])])]),E(`section`,Qr,[h.value?(H(),W(r,{key:1},[E(`div`,ei,[de(E(`input`,{class:`wb-input wb-input--title`,"onUpdate:modelValue":l[0]||=e=>h.value.title=e,placeholder:q(Y)(`@WORKBENCH:任务标题`)},null,8,ti),[[c,h.value.title]]),L.value!==`idle`||B.value?(H(),W(`span`,{key:0,class:P([`wb-meta-save`,{"is-saving":L.value===`saving`,"is-saved":L.value===`saved`,"is-error":L.value===`error`,"is-dirty":B.value&&L.value===`idle`}]),title:L.value===`saving`?q(Y)(`@WORKBENCH:保存中…`):L.value===`error`?q(Y)(`@WORKBENCH:保存失败`):L.value===`saved`?q(Y)(`@WORKBENCH:已保存`):``},[L.value===`saving`?(H(),W(`span`,ri)):L.value===`saved`?(H(),W(`span`,ii,`✓`)):L.value===`error`?(H(),W(`span`,ai,`!`)):(H(),W(`span`,oi)),O(` `+b(L.value===`saving`?q(Y)(`@WORKBENCH:保存中…`):L.value===`saved`?q(Y)(`@WORKBENCH:已保存`):L.value===`error`?q(Y)(`@WORKBENCH:保存失败`):q(Y)(`@WORKBENCH:有未保存的更改`)),1)],10,ni)):u(``,!0),de(E(`select`,{class:`wb-select`,"onUpdate:modelValue":l[1]||=e=>h.value.promptId=e},[E(`option`,si,b(q(Y)(`@WORKBENCH:不绑定预置提示词`)),1),(H(!0),W(r,null,F(n.value,e=>(H(),W(`option`,{key:e.id,value:e.id},b(e.name),9,ci))),128))],512),[[a,h.value.promptId]]),E(`div`,{class:`wb-mode-switch`,role:`tablist`,"aria-label":q(Y)(`@WORKBENCH:任务类型`)},[E(`button`,{type:`button`,role:`tab`,class:P([`wb-mode-switch__btn`,{"is-active":!g.value}]),"aria-selected":!g.value,onClick:l[2]||=e=>lt(`complex`)},b(q(Y)(`@WORKBENCH:复杂`)),11,ui),E(`button`,{type:`button`,role:`tab`,class:P([`wb-mode-switch__btn`,{"is-active":g.value}]),"aria-selected":g.value,onClick:l[3]||=e=>lt(`simple`)},b(q(Y)(`@WORKBENCH:简单`)),11,di),E(`span`,{class:P([`wb-mode-switch__indicator`,{"is-right":g.value}]),"aria-hidden":`true`},null,2)],8,li),g.value?u(``,!0):(H(),W(`button`,{key:1,type:`button`,class:`wb-ai-split-btn`,disabled:!h.value.title||!h.value.title.trim(),title:q(Y)(`@WORKBENCH:AI 拆分`),onClick:bt},[l[44]||=E(`svg`,{class:`wb-ai-split-btn__icon`,viewBox:`0 0 16 16`,width:`14`,height:`14`,"aria-hidden":`true`},[E(`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),E(`span`,null,b(q(Y)(`@WORKBENCH:AI 拆分`)),1)],8,fi)),j(m,{type:`primary`,loading:!1,onClick:l[4]||=e=>St(h.value)},{default:U(()=>[O(b(g.value?q(Y)(`@WORKBENCH:执行`):q(Y)(`@WORKBENCH:执行任务`)),1)]),_:1}),E(`button`,{type:`button`,class:`wb-logs-inline-btn`,title:q(Y)(`@WORKBENCH:执行日志`),"aria-label":q(Y)(`@WORKBENCH:执行日志`),onClick:l[5]||=e=>d.value=!0},[j(p,{class:`wb-logs-inline-btn__icon`},{default:U(()=>[j(q(T))]),_:1}),E(`span`,null,b(q(Y)(`@WORKBENCH:执行日志`)),1)],8,pi)]),E(`details`,{class:`wb-task-desc`,open:Ee.value,onToggle:l[13]||=e=>Ee.value=e.target.open},[E(`summary`,hi,[j(p,{class:`wb-task-desc__caret`},{default:U(()=>[(H(),o(ne(Ee.value?q(Se):q(S))))]),_:1}),E(`span`,gi,b(q(Y)(`@WORKBENCH:任务描述(可选)`)),1),h.value.desc&&h.value.desc.length>0||h.value.attachments&&h.value.attachments.length>0?(H(),W(`span`,_i,[h.value.desc&&h.value.desc.length>0?(H(),W(`span`,vi,b(q(Y)(`@WORKBENCH:已填写`)),1)):u(``,!0),h.value.attachments&&h.value.attachments.length>0?(H(),W(`span`,yi,b(h.value.attachments.length),1)):u(``,!0)])):u(``,!0)]),de(E(`textarea`,{class:`wb-textarea`,"onUpdate:modelValue":l[6]||=e=>h.value.desc=e,placeholder:q(Y)(`@WORKBENCH:任务描述(可选)`),rows:`2`,onPaste:l[7]||=e=>Rt(e,{kind:`task`,task:h.value})},null,40,bi),[[c,h.value.desc]]),j(Wt,{attachments:h.value.attachments||[],"is-image":Gt,"human-size":Kt,"is-uploading":At(`task-`+h.value.id),"is-paste-hover":$.value===`task-`+h.value.id,"max-count":9,"on-pick":()=>Ht({kind:`task`,task:h.value}),"on-remove":e=>Vt({kind:`task`,task:h.value},e),onPaste:l[8]||=e=>Rt(e,{kind:`task`,task:h.value}),onDrop:l[9]||=J(e=>zt(e,{kind:`task`,task:h.value}),[`prevent`]),onDragover:l[10]||=J(e=>$.value=`task-`+h.value.id,[`prevent`]),onDragenter:l[11]||=J(e=>$.value=`task-`+h.value.id,[`prevent`]),onDragleave:l[12]||=e=>$.value=$.value===`task-`+h.value.id?null:$.value},null,8,[`attachments`,`is-uploading`,`is-paste-hover`,`on-pick`,`on-remove`])],40,mi),E(`div`,{class:P([`wb-execution-body`,{"wb-execution-body--simple":g.value}])},[g.value?u(``,!0):(H(),W(`div`,xi,[E(`div`,Si,[E(`h4`,Ci,b(q(Y)(`@WORKBENCH:子任务拆分`)),1),E(`div`,wi,[j(m,{size:`small`,plain:``,icon:q(ve),disabled:h.value.subtasks.length===0,onClick:ht},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:添加子任务`)),1)]),_:1},8,[`icon`,`disabled`]),j(m,{size:`small`,type:re.value?`primary`:`default`,disabled:h.value.subtasks.length===0,onClick:vt},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:保存拆分`))+` `,1),re.value?(H(),W(`span`,Ti,b(N.value.size),1)):u(``,!0)]),_:1},8,[`type`,`disabled`])])]),E(`ul`,Ei,[(H(!0),W(r,null,F(h.value.subtasks,e=>(H(),W(`li`,{key:e.id,class:P([`wb-exec-sub-item`,{"is-selected":_.value===e.id,"is-running":e.status===`running`,"is-done":e.status===`done`,"is-dirty":N.value.has(e.id),"is-persisting":pt(e.id)}]),onClick:t=>_.value=e.id},[E(`div`,Oi,[E(`span`,{class:`wb-sub-item__status wb-sub-item__status--dot`,style:Ce({background:q(Mn)(e.status)}),title:q(Y)(`@WORKBENCH:任务完成状态`)},[...l[45]||=[E(`span`,{class:`wb-simple__status-dot`,"aria-hidden":`true`},null,-1)]],12,ki),E(`span`,{class:`wb-exec-sub-item__title`,title:e.title},b(e.title||q(Y)(`@WORKBENCH:未命名子任务`)),9,Ai),N.value.has(e.id)?(H(),W(`span`,ji)):u(``,!0)]),E(`div`,Mi,[Z(e.id)?(H(),W(`span`,Ni,`PID: `+b(Z(e.id)?.pid),1)):u(``,!0),E(`span`,Pi,[Tt(e)?(H(),W(`button`,{key:0,class:`wb-exec-sub-btn wb-exec-sub-btn--run`,title:q(Y)(`@WORKBENCH:单独执行此子任务`),onClick:J(t=>wt(e),[`stop`])},b(q(Y)(`@WORKBENCH:执行`)),9,Fi)):u(``,!0),Z(e.id)&&(Z(e.id)?.status===`running`||Z(e.id)?.status===`pending`)?(H(),W(`button`,{key:1,class:`wb-exec-sub-btn wb-exec-sub-btn--stop`,title:q(Y)(`@WORKBENCH:停止执行`),onClick:J(t=>Dt(Z(e.id)),[`stop`])},b(q(Y)(`@WORKBENCH:停止`)),9,Ii)):u(``,!0),e.status===`done`?(H(),W(`button`,{key:2,class:`wb-exec-sub-btn wb-exec-sub-btn--undo`,title:q(Y)(`@WORKBENCH:取消完成`),disabled:pt(e.id),onClick:J(t=>Et(e),[`stop`])},b(q(Y)(`@WORKBENCH:取消完成`)),9,Li)):u(``,!0),E(`button`,{class:`wb-exec-sub-btn wb-exec-sub-btn--del`,title:q(Y)(`@WORKBENCH:删除`),disabled:pt(e.id),onClick:J(t=>gt(e),[`stop`])},`×`,8,Ri)])])],10,Di))),128)),h.value.subtasks.length===0?(H(),W(`li`,zi,[E(`div`,Bi,[j(p,null,{default:U(()=>[j(q(t))]),_:1})]),E(`div`,Vi,b(q(Y)(`@WORKBENCH:拆分任务,逐项执行`)),1),E(`div`,Hi,[j(m,{type:`primary`,size:`small`,icon:q(ve),onClick:ht},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:添加子任务`)),1)]),_:1},8,[`icon`])])])):u(``,!0)])])),E(`div`,Ui,[g.value?(H(),W(r,{key:1},[E(`details`,{class:P([`wb-simple__override`,{"has-content":!!(h.value.simpleOverride&&h.value.simpleOverride.trim())}])},[E(`summary`,Yi,[j(p,{class:`wb-simple__override-caret`},{default:U(()=>[j(q(S))]),_:1}),E(`span`,null,b(q(Y)(`@WORKBENCH:覆盖预置提示词(可选)`)),1),h.value.simpleOverride&&h.value.simpleOverride.trim()?(H(),W(`span`,{key:0,class:`wb-simple__override-tag`,title:q(Y)(`@WORKBENCH:已填写覆盖内容`)},b(q(Y)(`@WORKBENCH:已填写`)),9,Xi)):u(``,!0),Le(Ie(h.value))===`running`&&Ie(h.value)?(H(),W(`button`,{key:1,class:`wb-simple__stop`,disabled:pt(Ie(h.value).id),onClick:l[24]||=J(e=>Dt(Ie(h.value)),[`stop`])},b(q(Y)(`@WORKBENCH:停止`)),9,Zi)):u(``,!0)]),de(E(`textarea`,{class:`wb-textarea`,"onUpdate:modelValue":l[25]||=e=>h.value.simpleOverride=e,placeholder:q(Y)(`@WORKBENCH:留空则使用上方选定的「预置提示词」模板;可用变量同子任务:{{task.title}} {{task.desc}} {{repo.path}} {{branch}}`),rows:`6`},null,8,Qi),[[c,h.value.simpleOverride]])],2),Z(`${h.value.id}__simple`)?(H(),o(An,{key:0,job:Z(`${h.value.id}__simple`)},null,8,[`job`])):u(``,!0)],64)):(H(),W(r,{key:0},[x.value?(H(),W(r,{key:1},[E(`div`,Gi,[de(E(`input`,{class:`wb-input`,"onUpdate:modelValue":l[14]||=e=>x.value.title=e,placeholder:q(Y)(`@WORKBENCH:子任务标题`),onClick:l[15]||=J(()=>{},[`stop`]),onPaste:l[16]||=e=>Rt(e,{kind:`sub`,task:h.value,sub:x.value})},null,40,Ki),[[c,x.value.title]]),N.value.has(x.value.id)?(H(),W(`span`,{key:0,class:`wb-sub-item__dirty`,title:q(Y)(`@WORKBENCH:有未保存的更改`)},b(q(Y)(`@WORKBENCH:未保存`)),9,qi)):u(``,!0)]),de(E(`textarea`,{class:`wb-textarea wb-textarea--sm`,"onUpdate:modelValue":l[17]||=e=>x.value.desc=e,placeholder:q(Y)(`@WORKBENCH:子任务描述 / 独立提示词覆盖`),rows:`3`,onPaste:l[18]||=e=>Rt(e,{kind:`sub`,task:h.value,sub:x.value})},null,40,Ji),[[c,x.value.desc]]),Z(x.value.id)?(H(),o(An,{key:0,job:Z(x.value.id)},null,8,[`job`])):u(``,!0),j(Wt,{attachments:x.value.attachments||[],"is-image":Gt,"human-size":Kt,"is-uploading":At(`sub-`+x.value.id),"is-paste-hover":$.value===x.value.id,"max-count":9,"on-pick":()=>Ht({kind:`sub`,task:h.value,sub:x.value}),"on-remove":e=>Vt({kind:`sub`,task:h.value,sub:x.value},e),onPaste:l[19]||=e=>Rt(e,{kind:`sub`,task:h.value,sub:x.value}),onDrop:l[20]||=J(e=>zt(e,{kind:`sub`,task:h.value,sub:x.value}),[`prevent`]),onDragover:l[21]||=J(e=>$.value=x.value.id,[`prevent`]),onDragenter:l[22]||=J(e=>$.value=x.value.id,[`prevent`]),onDragleave:l[23]||=e=>$.value=$.value===x.value.id?null:$.value},null,8,[`attachments`,`is-uploading`,`is-paste-hover`,`on-pick`,`on-remove`])],64)):(H(),W(`div`,Wi,[E(`p`,null,b(h.value.subtasks.length===0?q(Y)(`@WORKBENCH:手动添加子任务,或让 AI 帮你自动拆分`):q(Y)(`@WORKBENCH:左侧选择子任务查看详情`)),1)]))],64))])],2)],64)):(H(),W(`div`,$r,[E(`p`,null,b(q(Y)(`@WORKBENCH:左侧选择任务,或新建一个任务开始`)),1)]))])]),j(C,{modelValue:d.value,"onUpdate:modelValue":l[26]||=e=>d.value=e,title:q(Y)(`@WORKBENCH:执行日志`),width:`1080px`,"close-on-click-modal":!1,top:`6vh`,class:`wb-logs-dialog`},{default:U(()=>[j(cr)]),_:1},8,[`modelValue`,`title`]),j(C,{modelValue:G.visible,"onUpdate:modelValue":l[30]||=e=>G.visible=e,title:G.editing?q(Y)(`@WORKBENCH:编辑提示词`):q(Y)(`@WORKBENCH:新建提示词`),width:`640px`},{footer:U(()=>[j(m,{onClick:l[29]||=e=>G.visible=!1},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:取消`)),1)]),_:1}),j(m,{type:`primary`,onClick:it},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:保存`)),1)]),_:1})]),default:U(()=>[j(k,{"label-position":`top`},{default:U(()=>[j(D,{label:q(Y)(`@WORKBENCH:名称`)},{default:U(()=>[j(w,{modelValue:G.name,"onUpdate:modelValue":l[27]||=e=>G.name=e,placeholder:q(Y)(`@WORKBENCH:如:代码审查 / 写测试`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`]),j(D,null,{default:U(()=>[E(`div`,$i,[j(m,{type:`primary`,plain:``,loading:G.aiLoading,onClick:tt},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:AI 生成项目架构说明`)),1)]),_:1},8,[`loading`]),j(m,{onClick:nt},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:编辑指令`)),1)]),_:1})])]),_:1}),j(D,{label:q(Y)(`@WORKBENCH:内容`)},{default:U(()=>[j(w,{modelValue:G.content,"onUpdate:modelValue":l[28]||=e=>G.content=e,type:`textarea`,rows:10,placeholder:q(Y)(`@WORKBENCH:可用变量:`)+`{{task.title}} {{task.desc}} {{sub.title}} {{sub.desc}} {{repo.path}} {{branch}}`},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])]),_:1})]),_:1},8,[`modelValue`,`title`]),j(C,{modelValue:K.visible,"onUpdate:modelValue":l[33]||=e=>K.visible=e,title:q(Y)(`@WORKBENCH:编辑生成指令`),width:`720px`,"append-to-body":``},{footer:U(()=>[j(m,{onClick:l[32]||=e=>K.visible=!1},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:取消`)),1)]),_:1}),j(m,{type:`primary`,loading:K.saving,onClick:rt},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:保存`)),1)]),_:1},8,[`loading`])]),default:U(()=>[j(k,{"label-position":`top`},{default:U(()=>[j(D,{label:q(Y)(`@WORKBENCH:指令内容`)},{default:U(()=>[j(w,{modelValue:K.text,"onUpdate:modelValue":l[31]||=e=>K.text=e,type:`textarea`,rows:18,placeholder:q(Y)(`@WORKBENCH:指令内容`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])]),_:1})]),_:1},8,[`modelValue`,`title`]),j(C,{modelValue:X.visible,"onUpdate:modelValue":l[41]||=e=>X.visible=e,title:X.editing?q(Y)(`@WORKBENCH:编辑任务`):q(Y)(`@WORKBENCH:新建任务`),width:`600px`},{footer:U(()=>[j(m,{onClick:l[40]||=e=>X.visible=!1},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:取消`)),1)]),_:1}),j(m,{type:`primary`,onClick:st},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:保存`)),1)]),_:1})]),default:U(()=>[j(k,{"label-position":`top`},{default:U(()=>[j(D,{label:q(Y)(`@WORKBENCH:标题(可选)`)},{default:U(()=>[j(w,{modelValue:X.title,"onUpdate:modelValue":l[34]||=e=>X.title=e,placeholder:q(Y)(`@WORKBENCH:不填则自动命名为「无标题」,稍后可在任务列表里改名`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`]),j(D,{label:q(Y)(`@WORKBENCH:类型`)},{default:U(()=>[j(M,{modelValue:X.type,"onUpdate:modelValue":l[35]||=e=>X.type=e},{default:U(()=>[j(A,{value:`complex`},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:复杂任务(需要拆分子任务)`)),1)]),_:1}),j(A,{value:`simple`},{default:U(()=>[O(b(q(Y)(`@WORKBENCH:简单任务(直接执行)`)),1)]),_:1})]),_:1},8,[`modelValue`])]),_:1},8,[`label`]),X.type===`simple`?(H(),o(D,{key:0,label:q(Y)(`@WORKBENCH:描述`)},{default:U(()=>[j(w,{modelValue:X.desc,"onUpdate:modelValue":l[36]||=e=>X.desc=e,type:`textarea`,rows:4,placeholder:q(Y)(`@WORKBENCH:把要做的事直接写在这里,执行时会把这段描述作为 prompt 喂给 Claude`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])):(H(),o(D,{key:1,label:q(Y)(`@WORKBENCH:描述`)},{default:U(()=>[j(w,{modelValue:X.desc,"onUpdate:modelValue":l[37]||=e=>X.desc=e,type:`textarea`,rows:3},null,8,[`modelValue`])]),_:1},8,[`label`])),X.type===`simple`?(H(),o(D,{key:2,label:q(Y)(`@WORKBENCH:覆盖预置提示词(可选)`)},{default:U(()=>[j(w,{modelValue:X.simpleOverride,"onUpdate:modelValue":l[38]||=e=>X.simpleOverride=e,type:`textarea`,rows:5,placeholder:q(Y)(`@WORKBENCH:留空则使用「预置提示词」下拉里选定的模板;可用变量同子任务覆盖。`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])):u(``,!0),j(D,{label:q(Y)(`@WORKBENCH:预置提示词`)},{default:U(()=>[j(ae,{modelValue:X.promptId,"onUpdate:modelValue":l[39]||=e=>X.promptId=e,clearable:``,placeholder:q(Y)(`@WORKBENCH:不绑定`),style:{width:`100%`}},{default:U(()=>[(H(!0),W(r,null,F(n.value,e=>(H(),o(R,{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`]),h.value?(H(),o(jt,{key:0,modelValue:yt.value,"onUpdate:modelValue":l[42]||=e=>yt.value=e,title:h.value.title,desc:h.value.desc,"task-id":h.value.id,"prompt-id":h.value.promptId,onConfirm:xt},null,8,[`modelValue`,`title`,`desc`,`task-id`,`prompt-id`])):u(``,!0)])}}}),[[`__scopeId`,`data-v-57e8677e`]]);export{ia as default};
|