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.
Files changed (37) hide show
  1. package/.claude/commands/issue/execute.md +133 -18
  2. package/.claude/commands/workflow/debug.md +6 -0
  3. package/.claude/commands/workflow/execute.md +4 -0
  4. package/.claude/commands/workflow/lite-execute.md +4 -0
  5. package/.claude/commands/workflow/lite-lite-lite.md +179 -544
  6. package/.claude/commands/workflow/review-fix.md +4 -0
  7. package/.claude/commands/workflow/test-cycle-execute.md +4 -0
  8. package/.codex/prompts/issue-execute.md +72 -12
  9. package/README.md +3 -0
  10. package/ccw/dist/core/data-aggregator.js +20 -7
  11. package/ccw/dist/core/data-aggregator.js.map +1 -1
  12. package/ccw/dist/core/lite-scanner.d.ts.map +1 -1
  13. package/ccw/dist/core/lite-scanner.js +56 -3
  14. package/ccw/dist/core/lite-scanner.js.map +1 -1
  15. package/ccw/dist/core/routes/issue-routes.d.ts.map +1 -1
  16. package/ccw/dist/core/routes/issue-routes.js +249 -4
  17. package/ccw/dist/core/routes/issue-routes.js.map +1 -1
  18. package/ccw/dist/tools/memory-update-queue.d.ts.map +1 -1
  19. package/ccw/dist/tools/memory-update-queue.js +5 -11
  20. package/ccw/dist/tools/memory-update-queue.js.map +1 -1
  21. package/ccw/src/core/data-aggregator.ts +19 -7
  22. package/ccw/src/core/lite-scanner.ts +58 -3
  23. package/ccw/src/core/routes/issue-routes.ts +275 -4
  24. package/ccw/src/templates/dashboard-css/03-tasks.css +5 -0
  25. package/ccw/src/templates/dashboard-css/04-lite-tasks.css +630 -1
  26. package/ccw/src/templates/dashboard-css/32-issue-manager.css +435 -37
  27. package/ccw/src/templates/dashboard-js/components/hook-manager.js +30 -21
  28. package/ccw/src/templates/dashboard-js/i18n.js +118 -0
  29. package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +5 -5
  30. package/ccw/src/templates/dashboard-js/views/issue-manager.js +744 -29
  31. package/ccw/src/templates/dashboard-js/views/lite-tasks.js +1138 -334
  32. package/ccw/src/templates/dashboard-js/views/skills-manager.js +2 -4
  33. package/ccw/src/tools/memory-update-queue.js +5 -11
  34. package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-312.pyc +0 -0
  35. package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
  36. package/codex-lens/src/codexlens/cli/commands.py +78 -0
  37. 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: 'bash',
56
- args: ['-c', 'ccw tool exec memory_queue "{\\"action\\":\\"add\\",\\"path\\":\\"$CLAUDE_PROJECT_DIR\\"}"'],
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: 'bash',
70
- args: ['-c', 'ccw tool exec skill_context_loader --stdin'],
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: 'bash',
83
- args: ['-c', 'ccw tool exec skill_context_loader --stdin --mode auto'],
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
- const params = JSON.stringify({ configs: configJson, prompt: '$CLAUDE_PROMPT' });
1125
- return `ccw tool exec skill_context_loader '${params}'`;
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 params = JSON.stringify({ mode: 'auto', prompt: '$CLAUDE_PROMPT' });
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
- // Now uses memory_queue for batched updates with configurable threshold/timeout
1135
- // The command adds to queue, configuration is applied separately via submitHookWizard
1136
- const params = `"{\\"action\\":\\"add\\",\\"path\\":\\"$CLAUDE_PROJECT_DIR\\"}"`;
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
- const command = generateWizardCommand();
1221
-
1222
- const hookData = {
1223
- command: 'bash',
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.projects && indexes.projects.length > 0) {
6385
- // Sort by last_indexed desc and pick the most recent
6386
- const sorted = indexes.projects.sort((a, b) =>
6387
- new Date(b.last_indexed || 0) - new Date(a.last_indexed || 0)
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].source_root || '';
6389
+ defaultPath = sorted[0].path || '';
6390
6390
  }
6391
6391
 
6392
6392
  const modalHtml = buildWatcherControlContent(status, defaultPath);