claude-code-workflow 6.3.28 → 6.3.29

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.
@@ -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',
@@ -3347,6 +3397,8 @@ const i18n = {
3347
3397
  'hook.wizard.memoryUpdateDesc': '基于队列的 CLAUDE.md 更新,支持阈值和超时配置',
3348
3398
  'hook.wizard.queueBasedUpdate': '队列批量更新',
3349
3399
  'hook.wizard.queueBasedUpdateDesc': '达到路径数量阈值或超时时批量更新',
3400
+ 'hook.wizard.cliTool': 'CLI 工具',
3401
+ 'hook.wizard.cliToolDesc': '用于生成 CLAUDE.md 的 CLI 工具',
3350
3402
  'hook.wizard.thresholdPaths': '阈值(路径数)',
3351
3403
  'hook.wizard.thresholdPathsDesc': '触发批量更新的路径数量',
3352
3404
  'hook.wizard.timeoutSeconds': '超时(秒)',
@@ -3523,6 +3575,54 @@ const i18n = {
3523
3575
  'multiCli.toolbar.noTasks': '暂无任务',
3524
3576
  'multiCli.toolbar.scrollToTask': '点击定位到任务',
3525
3577
 
3578
+ // Context Tab
3579
+ 'multiCli.context.taskDescription': '任务描述',
3580
+ 'multiCli.context.constraints': '约束条件',
3581
+ 'multiCli.context.focusPaths': '焦点路径',
3582
+ 'multiCli.context.relevantFiles': '相关文件',
3583
+ 'multiCli.context.dependencies': '依赖项',
3584
+ 'multiCli.context.conflictRisks': '冲突风险',
3585
+ 'multiCli.context.sessionId': '会话ID',
3586
+ 'multiCli.context.rawJson': '原始JSON',
3587
+
3588
+ // Summary Tab
3589
+ 'multiCli.summary.title': '摘要',
3590
+ 'multiCli.summary.convergence': '收敛状态',
3591
+ 'multiCli.summary.solutions': '解决方案',
3592
+ 'multiCli.summary.solution': '方案',
3593
+
3594
+ // Task Overview
3595
+ 'multiCli.task.description': '描述',
3596
+ 'multiCli.task.keyPoint': '关键点',
3597
+ 'multiCli.task.scope': '范围',
3598
+ 'multiCli.task.dependencies': '依赖项',
3599
+ 'multiCli.task.targetFiles': '目标文件',
3600
+ 'multiCli.task.acceptanceCriteria': '验收标准',
3601
+ 'multiCli.task.reference': '参考资料',
3602
+ 'multiCli.task.pattern': '模式',
3603
+ 'multiCli.task.files': '文件',
3604
+ 'multiCli.task.examples': '示例',
3605
+ 'multiCli.task.noOverviewData': '无概览数据',
3606
+
3607
+ // Task Implementation
3608
+ 'multiCli.task.implementationSteps': '实现步骤',
3609
+ 'multiCli.task.modificationPoints': '修改点',
3610
+ 'multiCli.task.verification': '验证',
3611
+ 'multiCli.task.noImplementationData': '无实现详情',
3612
+ 'multiCli.task.noFilesSpecified': '未指定文件',
3613
+
3614
+ // Discussion Tab
3615
+ 'multiCli.discussion.title': '讨论',
3616
+ 'multiCli.discussion.discussionTopic': '讨论主题',
3617
+ 'multiCli.solutions': '解决方案',
3618
+ 'multiCli.decision': '决策',
3619
+
3620
+ // Plan
3621
+ 'multiCli.plan.objective': '目标',
3622
+ 'multiCli.plan.solution': '解决方案',
3623
+ 'multiCli.plan.approach': '实现方式',
3624
+ 'multiCli.plan.risk': '风险',
3625
+
3526
3626
  // Modals
3527
3627
  'modal.contentPreview': '内容预览',
3528
3628
  'modal.raw': '原始',