claude-code-workflow 6.3.28 → 6.3.30
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/.claude/commands/issue/execute.md +133 -18
- package/.claude/commands/workflow/debug.md +6 -0
- package/.claude/commands/workflow/execute.md +4 -0
- package/.claude/commands/workflow/lite-execute.md +4 -0
- package/.claude/commands/workflow/lite-lite-lite.md +179 -544
- package/.claude/commands/workflow/review-fix.md +4 -0
- package/.claude/commands/workflow/test-cycle-execute.md +4 -0
- package/.codex/prompts/issue-execute.md +72 -12
- package/README.md +3 -0
- package/ccw/dist/core/data-aggregator.js +20 -7
- package/ccw/dist/core/data-aggregator.js.map +1 -1
- package/ccw/dist/core/lite-scanner.d.ts.map +1 -1
- package/ccw/dist/core/lite-scanner.js +56 -3
- package/ccw/dist/core/lite-scanner.js.map +1 -1
- package/ccw/dist/core/routes/issue-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/issue-routes.js +249 -4
- package/ccw/dist/core/routes/issue-routes.js.map +1 -1
- package/ccw/dist/tools/memory-update-queue.d.ts.map +1 -1
- package/ccw/dist/tools/memory-update-queue.js +5 -11
- package/ccw/dist/tools/memory-update-queue.js.map +1 -1
- package/ccw/src/core/data-aggregator.ts +19 -7
- package/ccw/src/core/lite-scanner.ts +58 -3
- package/ccw/src/core/routes/issue-routes.ts +275 -4
- package/ccw/src/templates/dashboard-css/03-tasks.css +5 -0
- package/ccw/src/templates/dashboard-css/04-lite-tasks.css +630 -1
- package/ccw/src/templates/dashboard-css/32-issue-manager.css +435 -37
- package/ccw/src/templates/dashboard-js/components/hook-manager.js +30 -21
- package/ccw/src/templates/dashboard-js/i18n.js +118 -0
- package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +5 -5
- package/ccw/src/templates/dashboard-js/views/issue-manager.js +744 -29
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +1138 -334
- package/ccw/src/templates/dashboard-js/views/skills-manager.js +2 -4
- package/ccw/src/tools/memory-update-queue.js +5 -11
- package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/commands.py +78 -0
- package/package.json +1 -1
|
@@ -52,12 +52,13 @@ const HOOK_TEMPLATES = {
|
|
|
52
52
|
'memory-update-queue': {
|
|
53
53
|
event: 'Stop',
|
|
54
54
|
matcher: '',
|
|
55
|
-
command: '
|
|
56
|
-
args: ['-
|
|
55
|
+
command: 'node',
|
|
56
|
+
args: ['-e', "require('child_process').spawnSync(process.platform==='win32'?'cmd':'ccw',process.platform==='win32'?['/c','ccw','tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'gemini'})]:['tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'gemini'})],{stdio:'inherit'})"],
|
|
57
57
|
description: 'Queue CLAUDE.md update when session ends (batched by threshold/timeout)',
|
|
58
58
|
category: 'memory',
|
|
59
59
|
configurable: true,
|
|
60
60
|
config: {
|
|
61
|
+
tool: { type: 'select', default: 'gemini', options: ['gemini', 'qwen', 'codex', 'opencode'], label: 'CLI Tool' },
|
|
61
62
|
threshold: { type: 'number', default: 5, min: 1, max: 20, label: 'Threshold (paths)', step: 1 },
|
|
62
63
|
timeout: { type: 'number', default: 300, min: 60, max: 1800, label: 'Timeout (seconds)', step: 60 }
|
|
63
64
|
}
|
|
@@ -66,8 +67,8 @@ const HOOK_TEMPLATES = {
|
|
|
66
67
|
'skill-context-keyword': {
|
|
67
68
|
event: 'UserPromptSubmit',
|
|
68
69
|
matcher: '',
|
|
69
|
-
command: '
|
|
70
|
-
args: ['-
|
|
70
|
+
command: 'node',
|
|
71
|
+
args: ['-e', "const p=JSON.parse(process.env.HOOK_INPUT||'{}');require('child_process').spawnSync('ccw',['tool','exec','skill_context_loader',JSON.stringify({prompt:p.user_prompt||''})],{stdio:'inherit'})"],
|
|
71
72
|
description: 'Load SKILL context based on keyword matching in user prompt',
|
|
72
73
|
category: 'skill',
|
|
73
74
|
configurable: true,
|
|
@@ -79,8 +80,8 @@ const HOOK_TEMPLATES = {
|
|
|
79
80
|
'skill-context-auto': {
|
|
80
81
|
event: 'UserPromptSubmit',
|
|
81
82
|
matcher: '',
|
|
82
|
-
command: '
|
|
83
|
-
args: ['-
|
|
83
|
+
command: 'node',
|
|
84
|
+
args: ['-e', "const p=JSON.parse(process.env.HOOK_INPUT||'{}');require('child_process').spawnSync('ccw',['tool','exec','skill_context_loader',JSON.stringify({mode:'auto',prompt:p.user_prompt||''})],{stdio:'inherit'})"],
|
|
84
85
|
description: 'Auto-detect and load SKILL based on skill name in prompt',
|
|
85
86
|
category: 'skill',
|
|
86
87
|
configurable: false
|
|
@@ -195,6 +196,7 @@ const WIZARD_TEMPLATES = {
|
|
|
195
196
|
}
|
|
196
197
|
],
|
|
197
198
|
configFields: [
|
|
199
|
+
{ key: 'tool', type: 'select', label: 'CLI Tool', default: 'gemini', options: ['gemini', 'qwen', 'codex', 'opencode'], description: 'CLI tool for CLAUDE.md generation' },
|
|
198
200
|
{ key: 'threshold', type: 'number', label: 'Threshold (paths)', default: 5, min: 1, max: 20, step: 1, description: 'Number of paths to trigger batch update' },
|
|
199
201
|
{ key: 'timeout', type: 'number', label: 'Timeout (seconds)', default: 300, min: 60, max: 1800, step: 60, description: 'Auto-flush queue after this time' }
|
|
200
202
|
]
|
|
@@ -748,6 +750,7 @@ function renderWizardModalContent() {
|
|
|
748
750
|
// Helper to get translated field labels
|
|
749
751
|
const getFieldLabel = (fieldKey) => {
|
|
750
752
|
const labels = {
|
|
753
|
+
'tool': t('hook.wizard.cliTool') || 'CLI Tool',
|
|
751
754
|
'threshold': t('hook.wizard.thresholdPaths') || 'Threshold (paths)',
|
|
752
755
|
'timeout': t('hook.wizard.timeoutSeconds') || 'Timeout (seconds)'
|
|
753
756
|
};
|
|
@@ -756,6 +759,7 @@ function renderWizardModalContent() {
|
|
|
756
759
|
|
|
757
760
|
const getFieldDesc = (fieldKey) => {
|
|
758
761
|
const descs = {
|
|
762
|
+
'tool': t('hook.wizard.cliToolDesc') || 'CLI tool for CLAUDE.md generation',
|
|
759
763
|
'threshold': t('hook.wizard.thresholdPathsDesc') || 'Number of paths to trigger batch update',
|
|
760
764
|
'timeout': t('hook.wizard.timeoutSecondsDesc') || 'Auto-flush queue after this time'
|
|
761
765
|
};
|
|
@@ -1121,20 +1125,19 @@ function generateWizardCommand() {
|
|
|
1121
1125
|
keywords: c.keywords.split(',').map(k => k.trim()).filter(k => k)
|
|
1122
1126
|
}));
|
|
1123
1127
|
|
|
1124
|
-
|
|
1125
|
-
|
|
1128
|
+
// Use node + spawnSync for cross-platform JSON handling
|
|
1129
|
+
const paramsObj = { configs: configJson, prompt: '${p.user_prompt}' };
|
|
1130
|
+
return `node -e "const p=JSON.parse(process.env.HOOK_INPUT||'{}');require('child_process').spawnSync('ccw',['tool','exec','skill_context_loader',JSON.stringify(${JSON.stringify(paramsObj).replace('${p.user_prompt}', "'+p.user_prompt+'")})],{stdio:'inherit'})"`;
|
|
1126
1131
|
} else {
|
|
1127
|
-
// auto mode
|
|
1128
|
-
const
|
|
1129
|
-
return `ccw tool exec skill_context_loader '${params}'`;
|
|
1132
|
+
// auto mode - use node + spawnSync
|
|
1133
|
+
return `node -e "const p=JSON.parse(process.env.HOOK_INPUT||'{}');require('child_process').spawnSync('ccw',['tool','exec','skill_context_loader',JSON.stringify({mode:'auto',prompt:p.user_prompt||''})],{stdio:'inherit'})"`;
|
|
1130
1134
|
}
|
|
1131
1135
|
}
|
|
1132
1136
|
|
|
1133
1137
|
// Handle memory-update wizard (default)
|
|
1134
|
-
//
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
return `ccw tool exec memory_queue ${params}`;
|
|
1138
|
+
// Use node + spawnSync for cross-platform JSON handling
|
|
1139
|
+
const selectedTool = wizardConfig.tool || 'gemini';
|
|
1140
|
+
return `node -e "require('child_process').spawnSync(process.platform==='win32'?'cmd':'ccw',process.platform==='win32'?['/c','ccw','tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'${selectedTool}'})]:['tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'${selectedTool}'})],{stdio:'inherit'})"`;
|
|
1138
1141
|
}
|
|
1139
1142
|
|
|
1140
1143
|
async function submitHookWizard() {
|
|
@@ -1217,13 +1220,18 @@ async function submitHookWizard() {
|
|
|
1217
1220
|
const baseTemplate = HOOK_TEMPLATES[selectedOption.templateId];
|
|
1218
1221
|
if (!baseTemplate) return;
|
|
1219
1222
|
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
args: ['-c', command]
|
|
1223
|
+
// Build hook data with configured values
|
|
1224
|
+
let hookData = {
|
|
1225
|
+
command: baseTemplate.command,
|
|
1226
|
+
args: [...baseTemplate.args]
|
|
1225
1227
|
};
|
|
1226
1228
|
|
|
1229
|
+
// For memory-update wizard, use configured tool in args (cross-platform)
|
|
1230
|
+
if (wizard.id === 'memory-update') {
|
|
1231
|
+
const selectedTool = wizardConfig.tool || 'gemini';
|
|
1232
|
+
hookData.args = ['-e', `require('child_process').spawnSync(process.platform==='win32'?'cmd':'ccw',process.platform==='win32'?['/c','ccw','tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'${selectedTool}'})]:['tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'${selectedTool}'})],{stdio:'inherit'})`];
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1227
1235
|
if (baseTemplate.matcher) {
|
|
1228
1236
|
hookData.matcher = baseTemplate.matcher;
|
|
1229
1237
|
}
|
|
@@ -1232,6 +1240,7 @@ async function submitHookWizard() {
|
|
|
1232
1240
|
|
|
1233
1241
|
// For memory-update wizard, also configure queue settings
|
|
1234
1242
|
if (wizard.id === 'memory-update') {
|
|
1243
|
+
const selectedTool = wizardConfig.tool || 'gemini';
|
|
1235
1244
|
const threshold = wizardConfig.threshold || 5;
|
|
1236
1245
|
const timeout = wizardConfig.timeout || 300;
|
|
1237
1246
|
try {
|
|
@@ -1242,7 +1251,7 @@ async function submitHookWizard() {
|
|
|
1242
1251
|
body: JSON.stringify({ tool: 'memory_queue', params: configParams })
|
|
1243
1252
|
});
|
|
1244
1253
|
if (response.ok) {
|
|
1245
|
-
showRefreshToast(`Queue configured: threshold=${threshold}, timeout=${timeout}s`, 'success');
|
|
1254
|
+
showRefreshToast(`Queue configured: tool=${selectedTool}, threshold=${threshold}, timeout=${timeout}s`, 'success');
|
|
1246
1255
|
}
|
|
1247
1256
|
} catch (e) {
|
|
1248
1257
|
console.warn('Failed to configure memory queue:', e);
|
|
@@ -1107,6 +1107,8 @@ const i18n = {
|
|
|
1107
1107
|
'hook.wizard.memoryUpdateDesc': 'Queue-based CLAUDE.md updates with configurable threshold and timeout',
|
|
1108
1108
|
'hook.wizard.queueBasedUpdate': 'Queue-Based Update',
|
|
1109
1109
|
'hook.wizard.queueBasedUpdateDesc': 'Batch updates when threshold reached or timeout expires',
|
|
1110
|
+
'hook.wizard.cliTool': 'CLI Tool',
|
|
1111
|
+
'hook.wizard.cliToolDesc': 'CLI tool for CLAUDE.md generation',
|
|
1110
1112
|
'hook.wizard.thresholdPaths': 'Threshold (paths)',
|
|
1111
1113
|
'hook.wizard.thresholdPathsDesc': 'Number of paths to trigger batch update',
|
|
1112
1114
|
'hook.wizard.timeoutSeconds': 'Timeout (seconds)',
|
|
@@ -1283,6 +1285,54 @@ const i18n = {
|
|
|
1283
1285
|
'multiCli.toolbar.noTasks': 'No tasks available',
|
|
1284
1286
|
'multiCli.toolbar.scrollToTask': 'Click to scroll to task',
|
|
1285
1287
|
|
|
1288
|
+
// Context Tab
|
|
1289
|
+
'multiCli.context.taskDescription': 'Task Description',
|
|
1290
|
+
'multiCli.context.constraints': 'Constraints',
|
|
1291
|
+
'multiCli.context.focusPaths': 'Focus Paths',
|
|
1292
|
+
'multiCli.context.relevantFiles': 'Relevant Files',
|
|
1293
|
+
'multiCli.context.dependencies': 'Dependencies',
|
|
1294
|
+
'multiCli.context.conflictRisks': 'Conflict Risks',
|
|
1295
|
+
'multiCli.context.sessionId': 'Session ID',
|
|
1296
|
+
'multiCli.context.rawJson': 'Raw JSON',
|
|
1297
|
+
|
|
1298
|
+
// Summary Tab
|
|
1299
|
+
'multiCli.summary.title': 'Summary',
|
|
1300
|
+
'multiCli.summary.convergence': 'Convergence',
|
|
1301
|
+
'multiCli.summary.solutions': 'Solutions',
|
|
1302
|
+
'multiCli.summary.solution': 'Solution',
|
|
1303
|
+
|
|
1304
|
+
// Task Overview
|
|
1305
|
+
'multiCli.task.description': 'Description',
|
|
1306
|
+
'multiCli.task.keyPoint': 'Key Point',
|
|
1307
|
+
'multiCli.task.scope': 'Scope',
|
|
1308
|
+
'multiCli.task.dependencies': 'Dependencies',
|
|
1309
|
+
'multiCli.task.targetFiles': 'Target Files',
|
|
1310
|
+
'multiCli.task.acceptanceCriteria': 'Acceptance Criteria',
|
|
1311
|
+
'multiCli.task.reference': 'Reference',
|
|
1312
|
+
'multiCli.task.pattern': 'PATTERN',
|
|
1313
|
+
'multiCli.task.files': 'FILES',
|
|
1314
|
+
'multiCli.task.examples': 'EXAMPLES',
|
|
1315
|
+
'multiCli.task.noOverviewData': 'No overview data available',
|
|
1316
|
+
|
|
1317
|
+
// Task Implementation
|
|
1318
|
+
'multiCli.task.implementationSteps': 'Implementation Steps',
|
|
1319
|
+
'multiCli.task.modificationPoints': 'Modification Points',
|
|
1320
|
+
'multiCli.task.verification': 'Verification',
|
|
1321
|
+
'multiCli.task.noImplementationData': 'No implementation details available',
|
|
1322
|
+
'multiCli.task.noFilesSpecified': 'No files specified',
|
|
1323
|
+
|
|
1324
|
+
// Discussion Tab
|
|
1325
|
+
'multiCli.discussion.title': 'Discussion',
|
|
1326
|
+
'multiCli.discussion.discussionTopic': 'Discussion Topic',
|
|
1327
|
+
'multiCli.solutions': 'Solutions',
|
|
1328
|
+
'multiCli.decision': 'Decision',
|
|
1329
|
+
|
|
1330
|
+
// Plan
|
|
1331
|
+
'multiCli.plan.objective': 'Objective',
|
|
1332
|
+
'multiCli.plan.solution': 'Solution',
|
|
1333
|
+
'multiCli.plan.approach': 'Approach',
|
|
1334
|
+
'multiCli.plan.risk': 'risk',
|
|
1335
|
+
|
|
1286
1336
|
// Modals
|
|
1287
1337
|
'modal.contentPreview': 'Content Preview',
|
|
1288
1338
|
'modal.raw': 'Raw',
|
|
@@ -2219,6 +2269,15 @@ const i18n = {
|
|
|
2219
2269
|
'issues.queueCommandInfo': 'After running the command, click "Refresh" to see the updated queue.',
|
|
2220
2270
|
'issues.alternative': 'Alternative',
|
|
2221
2271
|
'issues.refreshAfter': 'Refresh Queue',
|
|
2272
|
+
'issues.activate': 'Activate',
|
|
2273
|
+
'issues.deactivate': 'Deactivate',
|
|
2274
|
+
'issues.queueActivated': 'Queue activated',
|
|
2275
|
+
'issues.queueDeactivated': 'Queue deactivated',
|
|
2276
|
+
'issues.executionQueues': 'Execution Queues',
|
|
2277
|
+
'issues.queues': 'queues',
|
|
2278
|
+
'issues.noQueues': 'No queues found',
|
|
2279
|
+
'issues.queueEmptyHint': 'Generate execution queue from bound solutions',
|
|
2280
|
+
'issues.refresh': 'Refresh',
|
|
2222
2281
|
// issue.* keys (legacy)
|
|
2223
2282
|
'issue.viewIssues': 'Issues',
|
|
2224
2283
|
'issue.viewQueue': 'Queue',
|
|
@@ -3347,6 +3406,8 @@ const i18n = {
|
|
|
3347
3406
|
'hook.wizard.memoryUpdateDesc': '基于队列的 CLAUDE.md 更新,支持阈值和超时配置',
|
|
3348
3407
|
'hook.wizard.queueBasedUpdate': '队列批量更新',
|
|
3349
3408
|
'hook.wizard.queueBasedUpdateDesc': '达到路径数量阈值或超时时批量更新',
|
|
3409
|
+
'hook.wizard.cliTool': 'CLI 工具',
|
|
3410
|
+
'hook.wizard.cliToolDesc': '用于生成 CLAUDE.md 的 CLI 工具',
|
|
3350
3411
|
'hook.wizard.thresholdPaths': '阈值(路径数)',
|
|
3351
3412
|
'hook.wizard.thresholdPathsDesc': '触发批量更新的路径数量',
|
|
3352
3413
|
'hook.wizard.timeoutSeconds': '超时(秒)',
|
|
@@ -3523,6 +3584,54 @@ const i18n = {
|
|
|
3523
3584
|
'multiCli.toolbar.noTasks': '暂无任务',
|
|
3524
3585
|
'multiCli.toolbar.scrollToTask': '点击定位到任务',
|
|
3525
3586
|
|
|
3587
|
+
// Context Tab
|
|
3588
|
+
'multiCli.context.taskDescription': '任务描述',
|
|
3589
|
+
'multiCli.context.constraints': '约束条件',
|
|
3590
|
+
'multiCli.context.focusPaths': '焦点路径',
|
|
3591
|
+
'multiCli.context.relevantFiles': '相关文件',
|
|
3592
|
+
'multiCli.context.dependencies': '依赖项',
|
|
3593
|
+
'multiCli.context.conflictRisks': '冲突风险',
|
|
3594
|
+
'multiCli.context.sessionId': '会话ID',
|
|
3595
|
+
'multiCli.context.rawJson': '原始JSON',
|
|
3596
|
+
|
|
3597
|
+
// Summary Tab
|
|
3598
|
+
'multiCli.summary.title': '摘要',
|
|
3599
|
+
'multiCli.summary.convergence': '收敛状态',
|
|
3600
|
+
'multiCli.summary.solutions': '解决方案',
|
|
3601
|
+
'multiCli.summary.solution': '方案',
|
|
3602
|
+
|
|
3603
|
+
// Task Overview
|
|
3604
|
+
'multiCli.task.description': '描述',
|
|
3605
|
+
'multiCli.task.keyPoint': '关键点',
|
|
3606
|
+
'multiCli.task.scope': '范围',
|
|
3607
|
+
'multiCli.task.dependencies': '依赖项',
|
|
3608
|
+
'multiCli.task.targetFiles': '目标文件',
|
|
3609
|
+
'multiCli.task.acceptanceCriteria': '验收标准',
|
|
3610
|
+
'multiCli.task.reference': '参考资料',
|
|
3611
|
+
'multiCli.task.pattern': '模式',
|
|
3612
|
+
'multiCli.task.files': '文件',
|
|
3613
|
+
'multiCli.task.examples': '示例',
|
|
3614
|
+
'multiCli.task.noOverviewData': '无概览数据',
|
|
3615
|
+
|
|
3616
|
+
// Task Implementation
|
|
3617
|
+
'multiCli.task.implementationSteps': '实现步骤',
|
|
3618
|
+
'multiCli.task.modificationPoints': '修改点',
|
|
3619
|
+
'multiCli.task.verification': '验证',
|
|
3620
|
+
'multiCli.task.noImplementationData': '无实现详情',
|
|
3621
|
+
'multiCli.task.noFilesSpecified': '未指定文件',
|
|
3622
|
+
|
|
3623
|
+
// Discussion Tab
|
|
3624
|
+
'multiCli.discussion.title': '讨论',
|
|
3625
|
+
'multiCli.discussion.discussionTopic': '讨论主题',
|
|
3626
|
+
'multiCli.solutions': '解决方案',
|
|
3627
|
+
'multiCli.decision': '决策',
|
|
3628
|
+
|
|
3629
|
+
// Plan
|
|
3630
|
+
'multiCli.plan.objective': '目标',
|
|
3631
|
+
'multiCli.plan.solution': '解决方案',
|
|
3632
|
+
'multiCli.plan.approach': '实现方式',
|
|
3633
|
+
'multiCli.plan.risk': '风险',
|
|
3634
|
+
|
|
3526
3635
|
// Modals
|
|
3527
3636
|
'modal.contentPreview': '内容预览',
|
|
3528
3637
|
'modal.raw': '原始',
|
|
@@ -4492,6 +4601,15 @@ const i18n = {
|
|
|
4492
4601
|
'issues.queueCommandInfo': '运行命令后,点击"刷新"查看更新后的队列。',
|
|
4493
4602
|
'issues.alternative': '或者',
|
|
4494
4603
|
'issues.refreshAfter': '刷新队列',
|
|
4604
|
+
'issues.activate': '激活',
|
|
4605
|
+
'issues.deactivate': '取消激活',
|
|
4606
|
+
'issues.queueActivated': '队列已激活',
|
|
4607
|
+
'issues.queueDeactivated': '队列已取消激活',
|
|
4608
|
+
'issues.executionQueues': '执行队列',
|
|
4609
|
+
'issues.queues': '个队列',
|
|
4610
|
+
'issues.noQueues': '暂无队列',
|
|
4611
|
+
'issues.queueEmptyHint': '从绑定的解决方案生成执行队列',
|
|
4612
|
+
'issues.refresh': '刷新',
|
|
4495
4613
|
// issue.* keys (legacy)
|
|
4496
4614
|
'issue.viewIssues': '议题',
|
|
4497
4615
|
'issue.viewQueue': '队列',
|
|
@@ -6381,12 +6381,12 @@ async function showWatcherControlModal() {
|
|
|
6381
6381
|
|
|
6382
6382
|
// Get first indexed project path as default
|
|
6383
6383
|
let defaultPath = '';
|
|
6384
|
-
if (indexes.success && indexes.
|
|
6385
|
-
// Sort by
|
|
6386
|
-
const sorted = indexes.
|
|
6387
|
-
new Date(b.
|
|
6384
|
+
if (indexes.success && indexes.indexes && indexes.indexes.length > 0) {
|
|
6385
|
+
// Sort by lastModified desc and pick the most recent
|
|
6386
|
+
const sorted = indexes.indexes.sort((a, b) =>
|
|
6387
|
+
new Date(b.lastModified || 0) - new Date(a.lastModified || 0)
|
|
6388
6388
|
);
|
|
6389
|
-
defaultPath = sorted[0].
|
|
6389
|
+
defaultPath = sorted[0].path || '';
|
|
6390
6390
|
}
|
|
6391
6391
|
|
|
6392
6392
|
const modalHtml = buildWatcherControlContent(status, defaultPath);
|