codexmate 0.1.9 → 0.1.10

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.
@@ -1,379 +1,3 @@
1
- function normalizeTaskDraftLines(text) {
2
- return String(text || '')
3
- .split(/\r?\n/g)
4
- .map((item) => item.trim())
5
- .filter(Boolean);
6
- }
7
-
8
- function readTaskOrchestrationDraftMetrics(taskOrchestration) {
9
- const state = taskOrchestration && typeof taskOrchestration === 'object' ? taskOrchestration : {};
10
- const target = String(state.target || '').trim();
11
- const notes = String(state.notes || '').trim();
12
- const title = String(state.title || '').trim();
13
- const workflowIds = normalizeTaskDraftLines(state.workflowIdsText);
14
- const followUps = normalizeTaskDraftLines(state.followUpsText);
15
- const requestCount = target ? followUps.length + 1 : 0;
16
- const engine = String(state.selectedEngine || 'openai-chat').trim().toLowerCase() === 'workflow' ? 'workflow' : 'openai-chat';
17
- const runMode = String(state.runMode || 'write').trim().toLowerCase();
18
- const allowWrite = runMode === 'write';
19
- const dryRun = runMode === 'dry-run';
20
- const plan = state.plan && typeof state.plan === 'object' ? state.plan : null;
21
- const planNodes = Array.isArray(plan && plan.nodes) ? plan.nodes : [];
22
- const planIssues = Array.isArray(state.planIssues) ? state.planIssues : [];
23
- const planWarnings = Array.isArray(state.planWarnings) ? state.planWarnings : [];
24
- return {
25
- engine,
26
- runMode,
27
- title,
28
- target,
29
- notes,
30
- workflowIds,
31
- followUps,
32
- hasTarget: target.length > 0,
33
- hasNotes: notes.length > 0,
34
- hasTitle: title.length > 0,
35
- hasPlan: !!plan,
36
- planNodes,
37
- planIssues,
38
- planWarnings,
39
- workflowCount: workflowIds.length,
40
- followUpCount: followUps.length,
41
- requestCount,
42
- hasSequentialFollowUps: followUps.length > 0,
43
- planNodeCount: planNodes.length,
44
- allowWrite,
45
- dryRun
46
- };
47
- }
48
-
49
-
50
- function formatTaskConversationMeta(items) {
51
- return items.filter(Boolean).join(' · ');
52
- }
53
-
54
- function collectTaskRunWorkspaceFileLines(detail) {
55
- const run = detail && detail.run && typeof detail.run === 'object' ? detail.run : null;
56
- const nodes = Array.isArray(detail && detail.nodes)
57
- ? detail.nodes
58
- : (Array.isArray(run && run.nodes) ? run.nodes : []);
59
- const files = [];
60
- for (const node of nodes) {
61
- const output = node && node.output && typeof node.output === 'object' ? node.output : null;
62
- const workspaceFiles = Array.isArray(output && output.workspaceFiles) ? output.workspaceFiles : [];
63
- const materializedFiles = Array.isArray(output && output.materializedFiles) ? output.materializedFiles : [];
64
- for (const file of workspaceFiles) {
65
- if (!file || typeof file !== 'object') continue;
66
- const op = String(file.operation || '').trim().toUpperCase() || 'FILE';
67
- const filePath = String(file.relativePath || file.path || '').trim();
68
- if (filePath) files.push(`${op} ${filePath}`);
69
- }
70
- for (const file of materializedFiles) {
71
- if (!file || typeof file !== 'object') continue;
72
- const filePath = String(file.relativePath || file.path || '').trim();
73
- if (filePath) files.push(`WRITE ${filePath}`);
74
- }
75
- }
76
- return Array.from(new Set(files)).slice(0, 6);
77
- }
78
-
79
- function normalizeTaskWorkspacePath(value) {
80
- return String(value || '').trim().replace(/\\+/g, '/').replace(/\/$/, '');
81
- }
82
-
83
- function readTaskWorkspacePathFromItem(item) {
84
- if (!item || typeof item !== 'object') return '';
85
- return normalizeTaskWorkspacePath(item.cwd || item.workspacePath || item.projectPath || item.path);
86
- }
87
-
88
- function formatTaskWorkspaceLabel(workspacePath, fallback = 'Auto workspace') {
89
- const normalized = normalizeTaskWorkspacePath(workspacePath);
90
- if (!normalized) return fallback;
91
- const parts = normalized.split('/').filter(Boolean);
92
- return parts.length ? parts[parts.length - 1] : normalized;
93
- }
94
-
95
- function readTaskItemTimestamp(item) {
96
- if (!item || typeof item !== 'object') return '';
97
- return String(item.updatedAt || item.completedAt || item.startedAt || item.createdAt || item.enqueuedAt || '').trim();
98
- }
99
-
100
- function addTaskWorkspaceCandidate(workspaces, workspacePath, source, timestamp = '') {
101
- const normalized = normalizeTaskWorkspacePath(workspacePath);
102
- if (!normalized) return;
103
- const key = normalized.toLowerCase();
104
- const current = workspaces.get(key) || {
105
- key,
106
- path: normalized,
107
- label: formatTaskWorkspaceLabel(normalized),
108
- meta: normalized,
109
- queueCount: 0,
110
- runCount: 0,
111
- lastActivity: ''
112
- };
113
- if (source === 'queue') current.queueCount += 1;
114
- if (source === 'run') current.runCount += 1;
115
- if (timestamp && (!current.lastActivity || timestamp > current.lastActivity)) {
116
- current.lastActivity = timestamp;
117
- }
118
- workspaces.set(key, current);
119
- }
120
-
121
- function taskItemMatchesWorkspace(item, workspacePath) {
122
- const selectedWorkspacePath = normalizeTaskWorkspacePath(workspacePath);
123
- if (!selectedWorkspacePath) return true;
124
- return readTaskWorkspacePathFromItem(item) === selectedWorkspacePath;
125
- }
126
-
127
- function createTaskWorkspaceItems(taskOrchestration) {
128
- const state = taskOrchestration && typeof taskOrchestration === 'object' ? taskOrchestration : {};
129
- const workspaces = new Map();
130
- addTaskWorkspaceCandidate(workspaces, state.workspacePath, 'draft');
131
- const detail = state.selectedRunDetail && typeof state.selectedRunDetail === 'object' ? state.selectedRunDetail : null;
132
- if (detail) addTaskWorkspaceCandidate(workspaces, detail.cwd, 'detail');
133
- const queue = Array.isArray(state.queue) ? state.queue : [];
134
- const runs = Array.isArray(state.runs) ? state.runs : [];
135
- queue.forEach((item) => addTaskWorkspaceCandidate(workspaces, readTaskWorkspacePathFromItem(item), 'queue', readTaskItemTimestamp(item)));
136
- runs.forEach((item) => addTaskWorkspaceCandidate(workspaces, readTaskWorkspacePathFromItem(item), 'run', readTaskItemTimestamp(item)));
137
- const items = Array.from(workspaces.values()).sort((a, b) => {
138
- const byActivity = String(b.lastActivity || '').localeCompare(String(a.lastActivity || ''));
139
- if (byActivity !== 0) return byActivity;
140
- return a.label.localeCompare(b.label);
141
- });
142
- if (items.length === 0) {
143
- items.push({
144
- key: '__auto__',
145
- path: '',
146
- label: 'Auto workspace',
147
- meta: 'Server default cwd',
148
- queueCount: queue.length,
149
- runCount: runs.length,
150
- lastActivity: ''
151
- });
152
- }
153
- return items;
154
- }
155
-
156
- function createTaskWorkspaceSessions(taskOrchestration, workspacePath) {
157
- const state = taskOrchestration && typeof taskOrchestration === 'object' ? taskOrchestration : {};
158
- const queue = Array.isArray(state.queue) ? state.queue : [];
159
- const runs = Array.isArray(state.runs) ? state.runs : [];
160
- const queueSessions = queue
161
- .filter((item) => taskItemMatchesWorkspace(item, workspacePath))
162
- .map((item) => ({
163
- id: item.taskId || item.lastRunId || `queue-${readTaskItemTimestamp(item)}`,
164
- type: 'queue',
165
- status: item.status || item.runStatus || 'queued',
166
- title: item.title || item.target || item.taskId || 'Queued task',
167
- meta: item.threadId || item.cwd || item.taskId || '',
168
- taskId: item.taskId || '',
169
- runId: item.lastRunId || '',
170
- threadId: item.threadId || '',
171
- cwd: readTaskWorkspacePathFromItem(item),
172
- timestamp: readTaskItemTimestamp(item),
173
- active: true
174
- }));
175
- const runSessions = runs
176
- .filter((item) => taskItemMatchesWorkspace(item, workspacePath))
177
- .map((item) => ({
178
- id: item.runId || item.taskId || `run-${readTaskItemTimestamp(item)}`,
179
- type: 'run',
180
- status: item.status || 'completed',
181
- title: item.title || item.summary || item.taskId || item.runId || 'Run',
182
- meta: item.threadId || item.cwd || `${item.durationMs || 0}ms`,
183
- taskId: item.taskId || '',
184
- runId: item.runId || '',
185
- threadId: item.threadId || '',
186
- cwd: readTaskWorkspacePathFromItem(item),
187
- timestamp: readTaskItemTimestamp(item),
188
- active: false
189
- }));
190
- return queueSessions.concat(runSessions).sort((a, b) => {
191
- if (a.active !== b.active) return a.active ? -1 : 1;
192
- return String(b.timestamp || '').localeCompare(String(a.timestamp || ''));
193
- });
194
- }
195
-
196
- function createTaskConversationMessages(taskOrchestration, t = null) {
197
- const state = taskOrchestration && typeof taskOrchestration === 'object' ? taskOrchestration : {};
198
- const messages = [];
199
- const target = String(state.target || '').trim();
200
- const followUps = normalizeTaskDraftLines(state.followUpsText);
201
- const detail = state.selectedRunDetail && typeof state.selectedRunDetail === 'object' ? state.selectedRunDetail : null;
202
- const detailRun = detail && detail.run && typeof detail.run === 'object' ? detail.run : null;
203
- if (detail) {
204
- const fileLines = collectTaskRunWorkspaceFileLines(detail);
205
- const resultLines = [];
206
- if (detailRun && detailRun.summary) {
207
- resultLines.push(detailRun.summary);
208
- } else {
209
- resultLines.push(translateTaskText(t, 'orchestration.chat.assistant.contextFallback', '已选中一个历史任务,继续时会继承它的线程和工作区。'));
210
- }
211
- if (fileLines.length > 0) {
212
- resultLines.push(translateTaskText(t, 'orchestration.chat.assistant.filesSummary', `文件操作:${fileLines.join(';')}`, { files: fileLines.join(';') }));
213
- }
214
- messages.push({
215
- id: 'context-run',
216
- role: 'assistant',
217
- label: detailRun && detailRun.status === 'success'
218
- ? translateTaskText(t, 'orchestration.chat.assistant.resultLabel', '实现结果')
219
- : translateTaskText(t, 'orchestration.chat.assistant.contextLabel', '上一轮上下文'),
220
- text: resultLines.join('\n'),
221
- meta: formatTaskConversationMeta([
222
- detail.threadId ? translateTaskText(t, 'orchestration.chat.meta.thread', `线程 ${detail.threadId}`, { value: detail.threadId }) : '',
223
- detail.cwd ? translateTaskText(t, 'orchestration.chat.meta.workspace', `工作区 ${detail.cwd}`, { value: detail.cwd }) : '',
224
- detailRun && detailRun.status ? detailRun.status : ''
225
- ])
226
- });
227
- } else if (!target && followUps.length === 0) {
228
- messages.push({
229
- id: 'assistant-empty',
230
- role: 'assistant',
231
- label: translateTaskText(t, 'orchestration.chat.assistant.readyLabel', 'Codexmate'),
232
- text: translateTaskText(t, 'orchestration.chat.assistant.empty', '先发第一个需求;如果还有第二个需求,继续发送,Codexmate 会按顺序处理并保留上下文。'),
233
- meta: translateTaskText(t, 'orchestration.chat.meta.order', '顺序执行 · 保留上下文')
234
- });
235
- }
236
- if (target) {
237
- messages.push({
238
- id: 'user-target',
239
- role: 'user',
240
- label: translateTaskText(t, 'orchestration.chat.user.step', '需求 {count}', { count: 1 }),
241
- text: target,
242
- meta: translateTaskText(t, 'orchestration.chat.meta.first', '先完成这一条')
243
- });
244
- }
245
- followUps.forEach((item, index) => {
246
- const step = index + 2;
247
- messages.push({
248
- id: `user-follow-up-${index}`,
249
- role: 'user',
250
- label: translateTaskText(t, 'orchestration.chat.user.step', '需求 {count}', { count: step }),
251
- text: item,
252
- meta: translateTaskText(t, 'orchestration.chat.meta.afterPrevious', '等待前一条完成后继续')
253
- });
254
- });
255
- if (!state.plan && target) {
256
- messages.push({
257
- id: 'assistant-next',
258
- role: 'assistant',
259
- label: translateTaskText(t, 'orchestration.chat.assistant.readyLabel', 'Codexmate'),
260
- text: followUps.length > 0
261
- ? translateTaskText(t, 'orchestration.chat.assistant.sequenceReady', '已收到多条需求;执行时会先完成需求 1,再带着上下文继续后续需求。')
262
- : translateTaskText(t, 'orchestration.chat.assistant.singleReady', '已收到第一条需求。可以继续补需求 2,或直接预览并执行。'),
263
- meta: translateTaskText(t, 'orchestration.chat.meta.previewNext', '下一步:预览计划')
264
- });
265
- }
266
- return messages;
267
- }
268
-
269
- function translateTaskText(t, key, fallback, params = null) {
270
- if (typeof t !== 'function') return fallback;
271
- const translated = t(key, params);
272
- return translated === key ? fallback : translated;
273
- }
274
-
275
- function createTaskDraftChecklist(metrics, t = null) {
276
- const workflowReady = metrics.engine !== 'workflow' || metrics.workflowCount > 0;
277
- const scopeReady = metrics.hasNotes || !metrics.allowWrite;
278
- const previewReady = metrics.hasPlan && metrics.planIssues.length === 0;
279
- return [
280
- {
281
- key: 'target',
282
- label: translateTaskText(t, 'orchestration.readiness.target.label', '目标'),
283
- done: metrics.hasTarget,
284
- detail: metrics.hasTarget ? translateTaskText(t, 'orchestration.readiness.target.done', '已写目标') : translateTaskText(t, 'orchestration.readiness.target.missing', '还没写目标')
285
- },
286
- {
287
- key: 'sequence',
288
- label: translateTaskText(t, 'orchestration.readiness.sequence.label', '顺序'),
289
- done: metrics.hasTarget,
290
- detail: !metrics.hasTarget
291
- ? translateTaskText(t, 'orchestration.readiness.sequence.missing', '先发送需求 1')
292
- : (metrics.hasSequentialFollowUps
293
- ? translateTaskText(t, 'orchestration.readiness.sequence.multiple', '{count} 条需求会按顺序执行:先完成需求 1,再继续需求 2。', { count: metrics.requestCount })
294
- : translateTaskText(t, 'orchestration.readiness.sequence.single', '当前只有需求 1;继续发送会变成需求 2。'))
295
- },
296
- {
297
- key: 'engine',
298
- label: metrics.engine === 'workflow' ? 'Workflow' : translateTaskText(t, 'orchestration.readiness.engine.label', '执行策略'),
299
- done: workflowReady,
300
- detail: metrics.engine === 'workflow'
301
- ? (metrics.workflowCount > 0 ? translateTaskText(t, 'orchestration.readiness.workflow.done', `已选 ${metrics.workflowCount} 个 Workflow`, { count: metrics.workflowCount }) : translateTaskText(t, 'orchestration.readiness.workflow.missing', '还没选 Workflow ID'))
302
- : translateTaskText(t, 'orchestration.readiness.engine.openaiChat', '使用 OpenAI Chat-compatible 节点')
303
- },
304
- {
305
- key: 'scope',
306
- label: translateTaskText(t, 'orchestration.readiness.scope.label', '边界'),
307
- done: scopeReady,
308
- detail: metrics.hasNotes
309
- ? translateTaskText(t, 'orchestration.readiness.scope.done', '已补充说明')
310
- : (metrics.allowWrite ? translateTaskText(t, 'orchestration.readiness.scope.writeHint', '建议补说明后再写入') : translateTaskText(t, 'orchestration.readiness.scope.readonlyHint', '当前是只读,可直接试'))
311
- },
312
- {
313
- key: 'preview',
314
- label: translateTaskText(t, 'orchestration.readiness.preview.label', '预览'),
315
- done: previewReady,
316
- detail: !metrics.hasPlan
317
- ? translateTaskText(t, 'orchestration.readiness.preview.missing', '还没发送 /plan')
318
- : (metrics.planIssues.length > 0 ? translateTaskText(t, 'orchestration.readiness.preview.blocked', `有 ${metrics.planIssues.length} 个阻塞项`, { count: metrics.planIssues.length }) : translateTaskText(t, 'orchestration.readiness.preview.ready', `计划可用,${metrics.planNodeCount} 个节点`, { count: metrics.planNodeCount }))
319
- }
320
- ];
321
- }
322
-
323
- function createTaskDraftReadiness(metrics, t = null) {
324
- if (!metrics.hasTarget) {
325
- return {
326
- tone: 'neutral',
327
- title: translateTaskText(t, 'orchestration.readiness.empty.title', '先写目标'),
328
- summary: translateTaskText(t, 'orchestration.readiness.empty.summary', '先把想完成的结果写清楚,再让编排器拆节点。')
329
- };
330
- }
331
- if (metrics.engine === 'workflow' && metrics.workflowCount === 0) {
332
- return {
333
- tone: 'warn',
334
- title: translateTaskText(t, 'orchestration.readiness.workflow.title', '缺少 Workflow'),
335
- summary: translateTaskText(t, 'orchestration.readiness.workflow.summary', '你已经选了 Workflow 模式,但还没指定可复用流程。')
336
- };
337
- }
338
- if (!metrics.hasPlan) {
339
- return {
340
- tone: 'warn',
341
- title: translateTaskText(t, 'orchestration.readiness.preview.title', '建议先预览'),
342
- summary: metrics.hasSequentialFollowUps
343
- ? translateTaskText(t, 'orchestration.readiness.preview.sequenceSummary', '草稿已成形,已锁定 {count} 条顺序需求:先完成需求 1,再继续需求 2。', { count: metrics.requestCount })
344
- : translateTaskText(t, 'orchestration.readiness.preview.summary', '草稿已成形,发送 /plan 预览方案,确认节点和依赖再执行。')
345
- };
346
- }
347
- if (metrics.planIssues.length > 0) {
348
- return {
349
- tone: 'error',
350
- title: translateTaskText(t, 'orchestration.readiness.blocked.title', '预览有阻塞'),
351
- summary: translateTaskText(t, 'orchestration.readiness.blocked.summary', `当前计划里还有 ${metrics.planIssues.length} 个阻塞项,先处理它们。`, { count: metrics.planIssues.length })
352
- };
353
- }
354
- if (metrics.planWarnings.length > 0) {
355
- return {
356
- tone: 'warn',
357
- title: translateTaskText(t, 'orchestration.readiness.warn.title', '可以执行,但有提醒'),
358
- summary: translateTaskText(t, 'orchestration.readiness.warn.summary', `/plan 方案已生成,但还有 ${metrics.planWarnings.length} 条提醒值得先看一眼。`, { count: metrics.planWarnings.length })
359
- };
360
- }
361
- if (metrics.dryRun) {
362
- return {
363
- tone: 'success',
364
- title: translateTaskText(t, 'orchestration.readiness.dryRun.title', '适合先预演'),
365
- summary: translateTaskText(t, 'orchestration.readiness.dryRun.summary', '现在可以安全地跑一次仅预演,先看结果再决定是否真实执行。')
366
- };
367
- }
368
- return {
369
- tone: 'success',
370
- title: translateTaskText(t, 'orchestration.readiness.ready.title', '可以执行'),
371
- summary: metrics.followUpCount > 0
372
- ? translateTaskText(t, 'orchestration.readiness.ready.withFollowUps', `已锁定 ${metrics.requestCount} 条顺序需求:先完成需求 1,再带上下文继续需求 2。`, { count: metrics.requestCount })
373
- : translateTaskText(t, 'orchestration.readiness.ready.summary', '主目标已经够清楚了,可以直接执行或入队。')
374
- };
375
- }
376
-
377
1
  export function createMainTabsComputed() {
378
2
  return {
379
3
  mainTabKicker() {
@@ -381,7 +5,6 @@ export function createMainTabsComputed() {
381
5
  if (this.mainTab === 'config') return this.t('kicker.config');
382
6
  if (this.mainTab === 'sessions') return this.t('kicker.sessions');
383
7
  if (this.mainTab === 'usage') return this.t('kicker.usage');
384
- if (this.mainTab === 'orchestration') return this.t('kicker.orchestration');
385
8
  if (this.mainTab === 'market') return this.t('kicker.market');
386
9
  if (this.mainTab === 'plugins') return this.t('kicker.plugins');
387
10
  if (this.mainTab === 'docs') return this.t('kicker.docs');
@@ -394,7 +17,6 @@ export function createMainTabsComputed() {
394
17
  if (this.mainTab === 'config') return this.t('title.config');
395
18
  if (this.mainTab === 'sessions') return this.t('title.sessions');
396
19
  if (this.mainTab === 'usage') return this.t('title.usage');
397
- if (this.mainTab === 'orchestration') return this.t('title.orchestration');
398
20
  if (this.mainTab === 'market') return this.t('title.market');
399
21
  if (this.mainTab === 'plugins') return this.t('title.plugins');
400
22
  if (this.mainTab === 'docs') return this.t('title.docs');
@@ -407,108 +29,12 @@ export function createMainTabsComputed() {
407
29
  if (this.mainTab === 'config') return this.t('subtitle.config');
408
30
  if (this.mainTab === 'sessions') return this.t('subtitle.sessions');
409
31
  if (this.mainTab === 'usage') return this.t('subtitle.usage');
410
- if (this.mainTab === 'orchestration') return this.t('subtitle.orchestration');
411
32
  if (this.mainTab === 'market') return this.t('subtitle.market');
412
33
  if (this.mainTab === 'plugins') return this.t('subtitle.plugins');
413
34
  if (this.mainTab === 'docs') return this.t('subtitle.docs');
414
35
  if (this.mainTab === 'trash') return this.t('settings.trash.meta');
415
36
  if (this.mainTab === 'prompts') return this.t('subtitle.prompts');
416
37
  return this.t('subtitle.settings');
417
- },
418
- taskOrchestrationSelectedRun() {
419
- return this.taskOrchestration && this.taskOrchestration.selectedRunDetail
420
- ? this.taskOrchestration.selectedRunDetail
421
- : null;
422
- },
423
- taskOrchestrationSelectedRunNodes() {
424
- const detail = this.taskOrchestrationSelectedRun;
425
- const run = detail && detail.run && typeof detail.run === 'object' ? detail.run : {};
426
- if (detail && Array.isArray(detail.nodes)) return detail.nodes;
427
- return Array.isArray(run.nodes) ? run.nodes : [];
428
- },
429
- taskOrchestrationActiveQueue() {
430
- const queue = this.taskOrchestration && Array.isArray(this.taskOrchestration.queue)
431
- ? this.taskOrchestration.queue
432
- : [];
433
- return queue.filter((item) => {
434
- const status = String((item && (item.status || item.runStatus)) || '').trim().toLowerCase();
435
- return status === 'queued' || status === 'running';
436
- });
437
- },
438
- taskOrchestrationEngineLabel() {
439
- const state = this.taskOrchestration && typeof this.taskOrchestration === 'object'
440
- ? this.taskOrchestration
441
- : {};
442
- return state.selectedEngine === 'workflow' ? 'Workflow' : 'Codex';
443
- },
444
- taskOrchestrationWorkbenchVisible() {
445
- const state = this.taskOrchestration && typeof this.taskOrchestration === 'object'
446
- ? this.taskOrchestration
447
- : {};
448
- const activeQueue = Array.isArray(this.taskOrchestrationActiveQueue)
449
- ? this.taskOrchestrationActiveQueue
450
- : [];
451
- return activeQueue.length > 0
452
- || !!String(state.selectedRunId || '').trim()
453
- || !!String(state.selectedRunError || '').trim()
454
- || (state.workspaceTab === 'runs' && Array.isArray(state.runs) && state.runs.length > 0);
455
- },
456
- taskOrchestrationWorkspacePath() {
457
- const state = this.taskOrchestration && typeof this.taskOrchestration === 'object'
458
- ? this.taskOrchestration
459
- : {};
460
- const detail = state.selectedRunDetail && typeof state.selectedRunDetail === 'object'
461
- ? state.selectedRunDetail
462
- : null;
463
- return normalizeTaskWorkspacePath(state.workspacePath || (detail && detail.cwd) || '');
464
- },
465
- taskOrchestrationWorkspaceItems() {
466
- const items = createTaskWorkspaceItems(this.taskOrchestration);
467
- const selectedPath = this.taskOrchestrationWorkspacePath;
468
- return items.map((item) => ({
469
- ...item,
470
- active: normalizeTaskWorkspacePath(item.path) === selectedPath || (!selectedPath && !item.path)
471
- }));
472
- },
473
- taskOrchestrationWorkspaceQueue() {
474
- const queue = this.taskOrchestration && Array.isArray(this.taskOrchestration.queue)
475
- ? this.taskOrchestration.queue
476
- : [];
477
- return queue.filter((item) => taskItemMatchesWorkspace(item, this.taskOrchestrationWorkspacePath));
478
- },
479
- taskOrchestrationWorkspaceRuns() {
480
- const runs = this.taskOrchestration && Array.isArray(this.taskOrchestration.runs)
481
- ? this.taskOrchestration.runs
482
- : [];
483
- return runs.filter((item) => taskItemMatchesWorkspace(item, this.taskOrchestrationWorkspacePath));
484
- },
485
- taskOrchestrationWorkspaceSessions() {
486
- return createTaskWorkspaceSessions(this.taskOrchestration, this.taskOrchestrationWorkspacePath);
487
- },
488
- taskOrchestrationQueueStats() {
489
- const queue = this.taskOrchestration && Array.isArray(this.taskOrchestration.queue)
490
- ? this.taskOrchestration.queue
491
- : [];
492
- const stats = { queued: 0, running: 0, failed: 0 };
493
- for (const item of queue) {
494
- const status = String((item && (item.status || item.runStatus)) || '').trim().toLowerCase();
495
- if (status === 'queued') stats.queued += 1;
496
- else if (status === 'running') stats.running += 1;
497
- else if (status === 'failed') stats.failed += 1;
498
- }
499
- return stats;
500
- },
501
- taskOrchestrationDraftMetrics() {
502
- return readTaskOrchestrationDraftMetrics(this.taskOrchestration);
503
- },
504
- taskOrchestrationDraftChecklist() {
505
- return createTaskDraftChecklist(this.taskOrchestrationDraftMetrics, this.t && this.t.bind(this));
506
- },
507
- taskOrchestrationDraftReadiness() {
508
- return createTaskDraftReadiness(this.taskOrchestrationDraftMetrics, this.t && this.t.bind(this));
509
- },
510
- taskOrchestrationConversationMessages() {
511
- return createTaskConversationMessages(this.taskOrchestration, this.t && this.t.bind(this));
512
38
  }
513
39
  };
514
40
  }
@@ -26,7 +26,6 @@ import { createProvidersMethods } from './app.methods.providers.mjs';
26
26
  import { createProviderCacheMethods } from './app.methods.provider-cache.mjs';
27
27
  import { createRuntimeMethods } from './app.methods.runtime.mjs';
28
28
  import { createToolConfigPermissionMethods } from './app.methods.tool-config-permissions.mjs';
29
- import { createTaskOrchestrationMethods } from './app.methods.task-orchestration.mjs';
30
29
  import { createSessionActionMethods } from './app.methods.session-actions.mjs';
31
30
  import { createSessionBrowserMethods } from './app.methods.session-browser.mjs';
32
31
  import { createSessionTimelineMethods } from './app.methods.session-timeline.mjs';
@@ -104,7 +103,6 @@ export function createAppMethods() {
104
103
  }),
105
104
  ...createKilocodeConfigMethods({ api }),
106
105
  ...createInstallMethods({ api }),
107
- ...createRuntimeMethods({ api }),
108
- ...createTaskOrchestrationMethods({ api })
106
+ ...createRuntimeMethods({ api })
109
107
  };
110
108
  }
@@ -9,7 +9,6 @@
9
9
  'config',
10
10
  'sessions',
11
11
  'usage',
12
- 'orchestration',
13
12
  'market',
14
13
  'plugins',
15
14
  'docs',
@@ -18,7 +17,7 @@
18
17
  'prompts'
19
18
  ];
20
19
  const MAIN_TAB_SET = new Set(MAIN_TAB_ORDER);
21
- const DISABLED_MAIN_TAB_SET = new Set(['orchestration']);
20
+ const DISABLED_MAIN_TAB_SET = new Set();
22
21
  const normalizeMainTab = (tab) => typeof tab === 'string'
23
22
  ? tab.trim().toLowerCase()
24
23
  : '';
@@ -646,18 +646,6 @@ export function createSessionActionMethods(options = {}) {
646
646
  return false;
647
647
  }
648
648
  const useTrash = this.sessionTrashEnabled !== false;
649
- if (!batch && !useTrash && typeof this.requestConfirmDialog === 'function') {
650
- const confirmed = await this.requestConfirmDialog({
651
- title: '直接删除会话',
652
- message: '关闭回收站后,删除会话将直接永久删除,且无法恢复。',
653
- confirmText: '直接删除',
654
- cancelText: '取消',
655
- danger: true
656
- });
657
- if (!confirmed) {
658
- return false;
659
- }
660
- }
661
649
  const key = this.getSessionExportKey(session);
662
650
  if (this.sessionDeleting[key]) {
663
651
  return false;
@@ -792,19 +780,6 @@ export function createSessionActionMethods(options = {}) {
792
780
  return;
793
781
  }
794
782
  const useTrash = this.sessionTrashEnabled !== false;
795
- if (typeof this.requestConfirmDialog === 'function') {
796
- const confirmKey = useTrash ? 'sessions.batch.deleteConfirm' : 'sessions.batch.deleteConfirmHard';
797
- const confirmed = await this.requestConfirmDialog({
798
- title: this.t('sessions.batch.select'),
799
- message: this.t(confirmKey, { count: selected.length }),
800
- confirmText: this.t('sessions.batch.deleteSelected'),
801
- cancelText: this.t('common.cancel'),
802
- danger: !useTrash
803
- });
804
- if (!confirmed) {
805
- return;
806
- }
807
- }
808
783
  this.sessionDeletingSelected = true;
809
784
  let failed = 0;
810
785
  const succeededKeys = [];
@@ -8,7 +8,6 @@ const LEGACY_WEB_UI_PREFERENCE_KEYS = Object.freeze([
8
8
  'codexmate_prompts_sub_tab',
9
9
  'codexmate_project_claude_md_path',
10
10
  'codexmateNavState.v1',
11
- 'codexmateTaskOrchestrationTabEnabled',
12
11
  'codexmateSessionLoadNativeDialog',
13
12
  'codexmateSessionFilterSource',
14
13
  'codexmateSessionPathFilter',
@@ -63,9 +62,21 @@ function normalizeUsageTimeRange(value) {
63
62
  function normalizePromptsSubTab(value) {
64
63
  const normalized = typeof value === 'string' ? value.trim().toLowerCase() : '';
65
64
  if (normalized === 'claude-project') return normalized;
65
+ if (normalized === 'system') return normalized;
66
66
  return 'codex';
67
67
  }
68
68
 
69
+ function normalizeSysPromptScope(value) {
70
+ const normalized = typeof value === 'string' ? value.trim().toLowerCase() : '';
71
+ if (normalized === 'project') return normalized;
72
+ return 'global';
73
+ }
74
+
75
+ function normalizeSysPromptMode(value) {
76
+ const normalized = typeof value === 'string' ? value.trim().toLowerCase() : '';
77
+ return normalized === 'append' ? 'append' : 'system';
78
+ }
79
+
69
80
  function normalizePromptPresets(value) {
70
81
  if (!Array.isArray(value)) return [];
71
82
  const seen = new Set();
@@ -187,10 +198,6 @@ function collectLegacyLocalStoragePreferences(storage) {
187
198
  preferences.configTemplateDiffConfirmEnabled = normalizeBoolean(read('codexmateConfigTemplateDiffConfirmEnabled'), true);
188
199
  found = true;
189
200
  }
190
- if (has('codexmateTaskOrchestrationTabEnabled')) {
191
- preferences.taskOrchestrationTabEnabled = normalizeBoolean(read('codexmateTaskOrchestrationTabEnabled'), true);
192
- found = true;
193
- }
194
201
  if (has('codexmateSessionLoadNativeDialog')) {
195
202
  preferences.sessionLoadNativeDialog = normalizeBoolean(read('codexmateSessionLoadNativeDialog'), false);
196
203
  found = true;
@@ -333,13 +340,14 @@ export function createWebUiPreferencesMethods(options = {}) {
333
340
  : this.configTemplateDiffConfirmEnabled !== false,
334
341
  sessionsUsageTimeRange: normalizeUsageTimeRange(hasOwn(source, 'sessionsUsageTimeRange') ? source.sessionsUsageTimeRange : this.sessionsUsageTimeRange),
335
342
  promptsSubTab: normalizePromptsSubTab(hasOwn(source, 'promptsSubTab') ? source.promptsSubTab : this.promptsSubTab),
343
+ sysPromptScope: normalizeSysPromptScope(hasOwn(source, 'sysPromptScope') ? source.sysPromptScope : this.sysPromptScope),
344
+ sysPromptMode: normalizeSysPromptMode(hasOwn(source, 'sysPromptMode') ? source.sysPromptMode : this.sysPromptMode),
336
345
  promptPresets: normalizePromptPresets(hasOwn(source, 'promptPresets') ? source.promptPresets : this.promptPresets),
337
346
  projectClaudeMdPath: typeof source.projectClaudeMdPath === 'string'
338
347
  ? source.projectClaudeMdPath
339
348
  : (typeof this.projectClaudeMdPath === 'string' ? this.projectClaudeMdPath : ''),
340
349
  sidebarCollapsed: normalizeBoolean(hasOwn(source, 'sidebarCollapsed') ? source.sidebarCollapsed : this.sidebarCollapsed, false),
341
350
  starPrompted: normalizeBoolean(hasOwn(source, 'starPrompted') ? source.starPrompted : this.starPrompted, false),
342
- taskOrchestrationTabEnabled: normalizeBoolean(hasOwn(source, 'taskOrchestrationTabEnabled') ? source.taskOrchestrationTabEnabled : this.taskOrchestrationTabEnabled, true),
343
351
  sessionLoadNativeDialog: normalizeBoolean(hasOwn(source, 'sessionLoadNativeDialog') ? source.sessionLoadNativeDialog : this.sessionLoadNativeDialog, false),
344
352
  language: typeof source.language === 'string'
345
353
  ? source.language
@@ -386,6 +394,12 @@ export function createWebUiPreferencesMethods(options = {}) {
386
394
  if (typeof source.promptsSubTab === 'string') {
387
395
  this.promptsSubTab = normalizePromptsSubTab(source.promptsSubTab);
388
396
  }
397
+ if (typeof source.sysPromptScope === 'string') {
398
+ this.sysPromptScope = normalizeSysPromptScope(source.sysPromptScope);
399
+ }
400
+ if (typeof source.sysPromptMode === 'string') {
401
+ this.sysPromptMode = normalizeSysPromptMode(source.sysPromptMode);
402
+ }
389
403
  if (Array.isArray(source.promptPresets)) {
390
404
  this.promptPresets = normalizePromptPresets(source.promptPresets);
391
405
  if (this.selectedPromptPresetId && !this.promptPresets.some(preset => preset.id === this.selectedPromptPresetId)) {
@@ -401,9 +415,6 @@ export function createWebUiPreferencesMethods(options = {}) {
401
415
  if (hasOwn(source, 'starPrompted')) {
402
416
  this.starPrompted = normalizeBoolean(source.starPrompted, false);
403
417
  }
404
- if (hasOwn(source, 'taskOrchestrationTabEnabled')) {
405
- this.taskOrchestrationTabEnabled = normalizeBoolean(source.taskOrchestrationTabEnabled, true);
406
- }
407
418
  if (hasOwn(source, 'sessionLoadNativeDialog')) {
408
419
  this.sessionLoadNativeDialog = normalizeBoolean(source.sessionLoadNativeDialog, false);
409
420
  }