claude-code-workflow 6.3.24 → 6.3.26

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 (75) hide show
  1. package/.claude/commands/issue/discover-by-prompt.md +764 -0
  2. package/.claude/skills/text-formatter/SKILL.md +196 -0
  3. package/.claude/skills/text-formatter/phases/01-input-collection.md +111 -0
  4. package/.claude/skills/text-formatter/phases/02-content-analysis.md +248 -0
  5. package/.claude/skills/text-formatter/phases/03-format-transform.md +245 -0
  6. package/.claude/skills/text-formatter/phases/04-output-preview.md +183 -0
  7. package/.claude/skills/text-formatter/specs/callout-types.md +293 -0
  8. package/.claude/skills/text-formatter/specs/element-mapping.md +226 -0
  9. package/.claude/skills/text-formatter/specs/format-rules.md +273 -0
  10. package/.claude/skills/text-formatter/templates/bbcode-template.md +350 -0
  11. package/ccw/dist/core/routes/help-routes.d.ts.map +1 -1
  12. package/ccw/dist/core/routes/help-routes.js +43 -7
  13. package/ccw/dist/core/routes/help-routes.js.map +1 -1
  14. package/ccw/dist/core/routes/litellm-api-routes.d.ts.map +1 -1
  15. package/ccw/dist/core/routes/litellm-api-routes.js +31 -5
  16. package/ccw/dist/core/routes/litellm-api-routes.js.map +1 -1
  17. package/ccw/dist/core/routes/memory-routes.d.ts.map +1 -1
  18. package/ccw/dist/core/routes/memory-routes.js +73 -0
  19. package/ccw/dist/core/routes/memory-routes.js.map +1 -1
  20. package/ccw/dist/core/routes/status-routes.d.ts.map +1 -1
  21. package/ccw/dist/core/routes/status-routes.js +36 -4
  22. package/ccw/dist/core/routes/status-routes.js.map +1 -1
  23. package/ccw/dist/core/server.d.ts.map +1 -1
  24. package/ccw/dist/core/server.js +58 -0
  25. package/ccw/dist/core/server.js.map +1 -1
  26. package/ccw/dist/core/services/api-key-tester.d.ts.map +1 -1
  27. package/ccw/dist/core/services/api-key-tester.js +8 -3
  28. package/ccw/dist/core/services/api-key-tester.js.map +1 -1
  29. package/ccw/dist/tools/claude-cli-tools.d.ts +7 -0
  30. package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -1
  31. package/ccw/dist/tools/claude-cli-tools.js +11 -1
  32. package/ccw/dist/tools/claude-cli-tools.js.map +1 -1
  33. package/ccw/dist/tools/cli-executor-core.d.ts +11 -0
  34. package/ccw/dist/tools/cli-executor-core.d.ts.map +1 -1
  35. package/ccw/dist/tools/cli-executor-core.js +89 -2
  36. package/ccw/dist/tools/cli-executor-core.js.map +1 -1
  37. package/ccw/dist/tools/codex-lens.d.ts +2 -1
  38. package/ccw/dist/tools/codex-lens.d.ts.map +1 -1
  39. package/ccw/dist/tools/codex-lens.js +51 -8
  40. package/ccw/dist/tools/codex-lens.js.map +1 -1
  41. package/ccw/dist/tools/index.d.ts.map +1 -1
  42. package/ccw/dist/tools/index.js +2 -0
  43. package/ccw/dist/tools/index.js.map +1 -1
  44. package/ccw/dist/tools/litellm-client.d.ts +6 -0
  45. package/ccw/dist/tools/litellm-client.d.ts.map +1 -1
  46. package/ccw/dist/tools/litellm-client.js +22 -1
  47. package/ccw/dist/tools/litellm-client.js.map +1 -1
  48. package/ccw/dist/tools/litellm-executor.js +2 -2
  49. package/ccw/dist/tools/litellm-executor.js.map +1 -1
  50. package/ccw/dist/tools/memory-update-queue.d.ts +172 -0
  51. package/ccw/dist/tools/memory-update-queue.d.ts.map +1 -0
  52. package/ccw/dist/tools/memory-update-queue.js +431 -0
  53. package/ccw/dist/tools/memory-update-queue.js.map +1 -0
  54. package/ccw/src/core/routes/help-routes.ts +46 -7
  55. package/ccw/src/core/routes/litellm-api-routes.ts +35 -4
  56. package/ccw/src/core/routes/memory-routes.ts +84 -0
  57. package/ccw/src/core/routes/status-routes.ts +39 -4
  58. package/ccw/src/core/server.ts +62 -0
  59. package/ccw/src/core/services/api-key-tester.ts +9 -3
  60. package/ccw/src/templates/dashboard-css/21-cli-toolmgmt.css +45 -0
  61. package/ccw/src/templates/dashboard-js/components/cli-status.js +36 -5
  62. package/ccw/src/templates/dashboard-js/components/hook-manager.js +42 -81
  63. package/ccw/src/templates/dashboard-js/components/mcp-manager.js +170 -28
  64. package/ccw/src/templates/dashboard-js/components/notifications.js +14 -4
  65. package/ccw/src/templates/dashboard-js/i18n.js +26 -0
  66. package/ccw/src/templates/dashboard-js/views/cli-manager.js +72 -2
  67. package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +11 -1
  68. package/ccw/src/tools/claude-cli-tools.ts +17 -1
  69. package/ccw/src/tools/cli-executor-core.ts +103 -2
  70. package/ccw/src/tools/codex-lens.ts +63 -8
  71. package/ccw/src/tools/index.ts +2 -0
  72. package/ccw/src/tools/litellm-client.ts +25 -3
  73. package/ccw/src/tools/litellm-executor.ts +2 -2
  74. package/ccw/src/tools/memory-update-queue.js +499 -0
  75. package/package.json +91 -91
@@ -0,0 +1,499 @@
1
+ /**
2
+ * Memory Update Queue Tool
3
+ * Queue mechanism for batching CLAUDE.md updates
4
+ *
5
+ * Configuration:
6
+ * - Threshold: 5 paths trigger update
7
+ * - Timeout: 5 minutes auto-trigger
8
+ * - Storage: ~/.claude/.memory-queue.json
9
+ * - Deduplication: Same path only kept once
10
+ */
11
+
12
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
13
+ import { join, dirname, resolve } from 'path';
14
+ import { homedir } from 'os';
15
+
16
+ // Default configuration
17
+ const DEFAULT_THRESHOLD = 5;
18
+ const DEFAULT_TIMEOUT_SECONDS = 300; // 5 minutes
19
+ const QUEUE_FILE_PATH = join(homedir(), '.claude', '.memory-queue.json');
20
+
21
+ /**
22
+ * Get queue configuration (from file or defaults)
23
+ * @returns {{ threshold: number, timeoutMs: number }}
24
+ */
25
+ function getQueueConfig() {
26
+ try {
27
+ if (existsSync(QUEUE_FILE_PATH)) {
28
+ const content = readFileSync(QUEUE_FILE_PATH, 'utf8');
29
+ const data = JSON.parse(content);
30
+ return {
31
+ threshold: data.config?.threshold || DEFAULT_THRESHOLD,
32
+ timeoutMs: (data.config?.timeout || DEFAULT_TIMEOUT_SECONDS) * 1000
33
+ };
34
+ }
35
+ } catch (e) {
36
+ // Use defaults
37
+ }
38
+ return {
39
+ threshold: DEFAULT_THRESHOLD,
40
+ timeoutMs: DEFAULT_TIMEOUT_SECONDS * 1000
41
+ };
42
+ }
43
+
44
+ // In-memory timeout reference (for cross-call persistence, we track via file timestamp)
45
+ let scheduledTimeoutId = null;
46
+
47
+ /**
48
+ * Ensure parent directory exists
49
+ */
50
+ function ensureDir(filePath) {
51
+ const dir = dirname(filePath);
52
+ if (!existsSync(dir)) {
53
+ mkdirSync(dir, { recursive: true });
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Load queue from file
59
+ * @returns {{ items: Array<{path: string, tool: string, strategy: string, addedAt: string}>, createdAt: string | null, config?: { threshold: number, timeout: number } }}
60
+ */
61
+ function loadQueue() {
62
+ try {
63
+ if (existsSync(QUEUE_FILE_PATH)) {
64
+ const content = readFileSync(QUEUE_FILE_PATH, 'utf8');
65
+ const data = JSON.parse(content);
66
+ return {
67
+ items: Array.isArray(data.items) ? data.items : [],
68
+ createdAt: data.createdAt || null,
69
+ config: data.config || null
70
+ };
71
+ }
72
+ } catch (e) {
73
+ console.error('[MemoryQueue] Failed to load queue:', e.message);
74
+ }
75
+ return { items: [], createdAt: null, config: null };
76
+ }
77
+
78
+ /**
79
+ * Save queue to file
80
+ * @param {{ items: Array<{path: string, tool: string, strategy: string, addedAt: string}>, createdAt: string | null }} data
81
+ */
82
+ function saveQueue(data) {
83
+ try {
84
+ ensureDir(QUEUE_FILE_PATH);
85
+ writeFileSync(QUEUE_FILE_PATH, JSON.stringify(data, null, 2), 'utf8');
86
+ } catch (e) {
87
+ console.error('[MemoryQueue] Failed to save queue:', e.message);
88
+ throw e;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Normalize path for comparison (handle Windows/Unix differences)
94
+ * @param {string} p
95
+ * @returns {string}
96
+ */
97
+ function normalizePath(p) {
98
+ return resolve(p).replace(/\\/g, '/').toLowerCase();
99
+ }
100
+
101
+ /**
102
+ * Add path to queue with deduplication
103
+ * @param {string} path - Module path to update
104
+ * @param {{ tool?: string, strategy?: string }} options
105
+ * @returns {{ queued: boolean, queueSize: number, willFlush: boolean, message: string }}
106
+ */
107
+ function addToQueue(path, options = {}) {
108
+ const { tool = 'gemini', strategy = 'single-layer' } = options;
109
+ const queue = loadQueue();
110
+ const config = getQueueConfig();
111
+ const normalizedPath = normalizePath(path);
112
+ const now = new Date().toISOString();
113
+
114
+ // Check for duplicates
115
+ const existingIndex = queue.items.findIndex(
116
+ item => normalizePath(item.path) === normalizedPath
117
+ );
118
+
119
+ if (existingIndex !== -1) {
120
+ // Update existing entry timestamp but keep it deduplicated
121
+ queue.items[existingIndex].addedAt = now;
122
+ queue.items[existingIndex].tool = tool;
123
+ queue.items[existingIndex].strategy = strategy;
124
+ saveQueue(queue);
125
+
126
+ return {
127
+ queued: false,
128
+ queueSize: queue.items.length,
129
+ willFlush: queue.items.length >= config.threshold,
130
+ message: `Path already in queue (updated): ${path}`
131
+ };
132
+ }
133
+
134
+ // Add new item
135
+ queue.items.push({
136
+ path,
137
+ tool,
138
+ strategy,
139
+ addedAt: now
140
+ });
141
+
142
+ // Set createdAt if this is the first item
143
+ if (!queue.createdAt) {
144
+ queue.createdAt = now;
145
+ }
146
+
147
+ saveQueue(queue);
148
+
149
+ const willFlush = queue.items.length >= config.threshold;
150
+
151
+ // Schedule timeout if not already scheduled
152
+ scheduleTimeout();
153
+
154
+ return {
155
+ queued: true,
156
+ queueSize: queue.items.length,
157
+ willFlush,
158
+ message: willFlush
159
+ ? `Queue threshold reached (${queue.items.length}/${config.threshold}), will flush`
160
+ : `Added to queue (${queue.items.length}/${config.threshold})`
161
+ };
162
+ }
163
+
164
+ /**
165
+ * Get current queue status
166
+ * @returns {{ queueSize: number, threshold: number, items: Array, timeoutMs: number | null, createdAt: string | null }}
167
+ */
168
+ function getQueueStatus() {
169
+ const queue = loadQueue();
170
+ const config = getQueueConfig();
171
+ let timeUntilTimeout = null;
172
+
173
+ if (queue.createdAt && queue.items.length > 0) {
174
+ const createdTime = new Date(queue.createdAt).getTime();
175
+ const elapsed = Date.now() - createdTime;
176
+ timeUntilTimeout = Math.max(0, config.timeoutMs - elapsed);
177
+ }
178
+
179
+ return {
180
+ queueSize: queue.items.length,
181
+ threshold: config.threshold,
182
+ items: queue.items,
183
+ timeoutMs: config.timeoutMs,
184
+ timeoutSeconds: config.timeoutMs / 1000,
185
+ timeUntilTimeout,
186
+ createdAt: queue.createdAt
187
+ };
188
+ }
189
+
190
+ /**
191
+ * Configure queue settings
192
+ * @param {{ threshold?: number, timeout?: number }} settings
193
+ * @returns {{ success: boolean, config: { threshold: number, timeout: number } }}
194
+ */
195
+ function configureQueue(settings) {
196
+ const queue = loadQueue();
197
+ const currentConfig = getQueueConfig();
198
+
199
+ const newConfig = {
200
+ threshold: settings.threshold || currentConfig.threshold,
201
+ timeout: settings.timeout || (currentConfig.timeoutMs / 1000)
202
+ };
203
+
204
+ // Validate
205
+ if (newConfig.threshold < 1 || newConfig.threshold > 20) {
206
+ throw new Error('Threshold must be between 1 and 20');
207
+ }
208
+ if (newConfig.timeout < 60 || newConfig.timeout > 1800) {
209
+ throw new Error('Timeout must be between 60 and 1800 seconds');
210
+ }
211
+
212
+ queue.config = newConfig;
213
+ saveQueue(queue);
214
+
215
+ return {
216
+ success: true,
217
+ config: newConfig,
218
+ message: `Queue configured: threshold=${newConfig.threshold}, timeout=${newConfig.timeout}s`
219
+ };
220
+ }
221
+
222
+ /**
223
+ * Flush queue - execute batch update
224
+ * @returns {Promise<{ success: boolean, processed: number, results: Array, errors: Array }>}
225
+ */
226
+ async function flushQueue() {
227
+ const queue = loadQueue();
228
+
229
+ if (queue.items.length === 0) {
230
+ return {
231
+ success: true,
232
+ processed: 0,
233
+ results: [],
234
+ errors: [],
235
+ message: 'Queue is empty'
236
+ };
237
+ }
238
+
239
+ // Clear timeout
240
+ clearScheduledTimeout();
241
+
242
+ // Import update_module_claude dynamically to avoid circular deps
243
+ const { updateModuleClaudeTool } = await import('./update-module-claude.js');
244
+
245
+ const results = [];
246
+ const errors = [];
247
+
248
+ // Group by tool and strategy for efficiency
249
+ const groups = new Map();
250
+ for (const item of queue.items) {
251
+ const key = `${item.tool}:${item.strategy}`;
252
+ if (!groups.has(key)) {
253
+ groups.set(key, []);
254
+ }
255
+ groups.get(key).push(item);
256
+ }
257
+
258
+ // Process each group
259
+ for (const [key, items] of groups) {
260
+ const [tool, strategy] = key.split(':');
261
+ console.log(`[MemoryQueue] Processing ${items.length} items with ${tool}/${strategy}`);
262
+
263
+ for (const item of items) {
264
+ try {
265
+ const result = await updateModuleClaudeTool.execute({
266
+ path: item.path,
267
+ tool: item.tool,
268
+ strategy: item.strategy
269
+ });
270
+
271
+ results.push({
272
+ path: item.path,
273
+ success: result.success !== false,
274
+ result
275
+ });
276
+ } catch (e) {
277
+ console.error(`[MemoryQueue] Failed to update ${item.path}:`, e.message);
278
+ errors.push({
279
+ path: item.path,
280
+ error: e.message
281
+ });
282
+ }
283
+ }
284
+ }
285
+
286
+ // Clear queue after processing
287
+ saveQueue({ items: [], createdAt: null });
288
+
289
+ return {
290
+ success: errors.length === 0,
291
+ processed: queue.items.length,
292
+ results,
293
+ errors,
294
+ message: `Processed ${results.length} items, ${errors.length} errors`
295
+ };
296
+ }
297
+
298
+ /**
299
+ * Schedule timeout for auto-flush
300
+ */
301
+ function scheduleTimeout() {
302
+ // We use file-based timeout tracking for persistence across process restarts
303
+ // The actual timeout check happens on next add/status call
304
+ const queue = loadQueue();
305
+ const config = getQueueConfig();
306
+
307
+ if (!queue.createdAt || queue.items.length === 0) {
308
+ return;
309
+ }
310
+
311
+ const createdTime = new Date(queue.createdAt).getTime();
312
+ const elapsed = Date.now() - createdTime;
313
+
314
+ if (elapsed >= config.timeoutMs) {
315
+ // Timeout already exceeded, should flush
316
+ console.log('[MemoryQueue] Timeout exceeded, auto-flushing');
317
+ // Don't await here to avoid blocking
318
+ flushQueue().catch(e => {
319
+ console.error('[MemoryQueue] Auto-flush failed:', e.message);
320
+ });
321
+ } else if (!scheduledTimeoutId) {
322
+ // Schedule in-memory timeout for current process
323
+ const remaining = config.timeoutMs - elapsed;
324
+ scheduledTimeoutId = setTimeout(() => {
325
+ scheduledTimeoutId = null;
326
+ const currentQueue = loadQueue();
327
+ if (currentQueue.items.length > 0) {
328
+ console.log('[MemoryQueue] Timeout reached, auto-flushing');
329
+ flushQueue().catch(e => {
330
+ console.error('[MemoryQueue] Auto-flush failed:', e.message);
331
+ });
332
+ }
333
+ }, remaining);
334
+
335
+ // Prevent timeout from keeping process alive
336
+ if (scheduledTimeoutId.unref) {
337
+ scheduledTimeoutId.unref();
338
+ }
339
+ }
340
+ }
341
+
342
+ /**
343
+ * Clear scheduled timeout
344
+ */
345
+ function clearScheduledTimeout() {
346
+ if (scheduledTimeoutId) {
347
+ clearTimeout(scheduledTimeoutId);
348
+ scheduledTimeoutId = null;
349
+ }
350
+ }
351
+
352
+ /**
353
+ * Check if timeout has expired and auto-flush if needed
354
+ * @returns {Promise<{ expired: boolean, flushed: boolean, result?: object }>}
355
+ */
356
+ async function checkTimeout() {
357
+ const queue = loadQueue();
358
+ const config = getQueueConfig();
359
+
360
+ if (!queue.createdAt || queue.items.length === 0) {
361
+ return { expired: false, flushed: false };
362
+ }
363
+
364
+ const createdTime = new Date(queue.createdAt).getTime();
365
+ const elapsed = Date.now() - createdTime;
366
+
367
+ if (elapsed >= config.timeoutMs) {
368
+ console.log('[MemoryQueue] Timeout expired, triggering flush');
369
+ const result = await flushQueue();
370
+ return { expired: true, flushed: true, result };
371
+ }
372
+
373
+ return { expired: false, flushed: false };
374
+ }
375
+
376
+ /**
377
+ * Main execute function for tool interface
378
+ * @param {Record<string, unknown>} params
379
+ * @returns {Promise<unknown>}
380
+ */
381
+ async function execute(params) {
382
+ const { action, path, tool = 'gemini', strategy = 'single-layer', threshold, timeout } = params;
383
+
384
+ switch (action) {
385
+ case 'add':
386
+ if (!path) {
387
+ throw new Error('Parameter "path" is required for add action');
388
+ }
389
+ // Check timeout first
390
+ const timeoutCheck = await checkTimeout();
391
+ if (timeoutCheck.flushed) {
392
+ // Queue was flushed due to timeout, add to fresh queue
393
+ const result = addToQueue(path, { tool, strategy });
394
+ return {
395
+ ...result,
396
+ timeoutFlushed: true,
397
+ flushResult: timeoutCheck.result
398
+ };
399
+ }
400
+
401
+ const addResult = addToQueue(path, { tool, strategy });
402
+
403
+ // Auto-flush if threshold reached
404
+ if (addResult.willFlush) {
405
+ const flushResult = await flushQueue();
406
+ return {
407
+ ...addResult,
408
+ flushed: true,
409
+ flushResult
410
+ };
411
+ }
412
+
413
+ return addResult;
414
+
415
+ case 'status':
416
+ // Check timeout first
417
+ await checkTimeout();
418
+ return getQueueStatus();
419
+
420
+ case 'flush':
421
+ return await flushQueue();
422
+
423
+ case 'configure':
424
+ return configureQueue({ threshold, timeout });
425
+
426
+ default:
427
+ throw new Error(`Unknown action: ${action}. Valid actions: add, status, flush, configure`);
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Tool Definition
433
+ */
434
+ export const memoryQueueTool = {
435
+ name: 'memory_queue',
436
+ description: `Memory update queue management. Batches CLAUDE.md updates for efficiency.
437
+
438
+ Actions:
439
+ - add: Add path to queue (auto-flushes at configured threshold/timeout)
440
+ - status: Get queue status and configuration
441
+ - flush: Immediately execute all queued updates
442
+ - configure: Set threshold and timeout settings`,
443
+ parameters: {
444
+ type: 'object',
445
+ properties: {
446
+ action: {
447
+ type: 'string',
448
+ enum: ['add', 'status', 'flush', 'configure'],
449
+ description: 'Queue action to perform'
450
+ },
451
+ path: {
452
+ type: 'string',
453
+ description: 'Module directory path (required for add action)'
454
+ },
455
+ threshold: {
456
+ type: 'number',
457
+ description: 'Number of paths to trigger flush (1-20, for configure action)',
458
+ minimum: 1,
459
+ maximum: 20
460
+ },
461
+ timeout: {
462
+ type: 'number',
463
+ description: 'Timeout in seconds to trigger flush (60-1800, for configure action)',
464
+ minimum: 60,
465
+ maximum: 1800
466
+ },
467
+ tool: {
468
+ type: 'string',
469
+ enum: ['gemini', 'qwen', 'codex'],
470
+ description: 'CLI tool to use (default: gemini)',
471
+ default: 'gemini'
472
+ },
473
+ strategy: {
474
+ type: 'string',
475
+ enum: ['single-layer', 'multi-layer'],
476
+ description: 'Update strategy (default: single-layer)',
477
+ default: 'single-layer'
478
+ }
479
+ },
480
+ required: ['action']
481
+ },
482
+ execute
483
+ };
484
+
485
+ // Export individual functions for direct use
486
+ export {
487
+ loadQueue,
488
+ saveQueue,
489
+ addToQueue,
490
+ getQueueStatus,
491
+ flushQueue,
492
+ configureQueue,
493
+ scheduleTimeout,
494
+ clearScheduledTimeout,
495
+ checkTimeout,
496
+ DEFAULT_THRESHOLD,
497
+ DEFAULT_TIMEOUT_SECONDS,
498
+ QUEUE_FILE_PATH
499
+ };
package/package.json CHANGED
@@ -1,91 +1,91 @@
1
- {
2
- "name": "claude-code-workflow",
3
- "version": "6.3.24",
4
- "description": "JSON-driven multi-agent development framework with intelligent CLI orchestration (Gemini/Qwen/Codex), context-first architecture, and automated workflow execution",
5
- "type": "module",
6
- "main": "ccw/src/index.js",
7
- "bin": {
8
- "ccw": "./ccw/bin/ccw.js",
9
- "ccw-mcp": "./ccw/bin/ccw-mcp.js"
10
- },
11
- "scripts": {
12
- "build": "tsc -p ccw/tsconfig.json",
13
- "start": "node ccw/bin/ccw.js",
14
- "test": "node --experimental-strip-types --test ccw/tests/*.test.js",
15
- "test:visual": "node --experimental-strip-types --test ccw/tests/visual/**/*.visual.test.ts",
16
- "test:e2e": "node --experimental-strip-types --test ccw/tests/e2e/*.e2e.test.ts",
17
- "prepublishOnly": "npm run build && echo 'Ready to publish @dyw/claude-code-workflow'"
18
- },
19
- "keywords": [
20
- "claude",
21
- "workflow",
22
- "ai",
23
- "cli",
24
- "dashboard",
25
- "code-review",
26
- "automation",
27
- "development"
28
- ],
29
- "author": "dyw",
30
- "license": "MIT",
31
- "engines": {
32
- "node": ">=16.0.0"
33
- },
34
- "dependencies": {
35
- "@modelcontextprotocol/sdk": "^1.0.4",
36
- "better-sqlite3": "^11.7.0",
37
- "boxen": "^7.1.0",
38
- "chalk": "^5.3.0",
39
- "commander": "^11.0.0",
40
- "figlet": "^1.7.0",
41
- "glob": "^10.3.0",
42
- "gradient-string": "^2.0.2",
43
- "inquirer": "^9.2.0",
44
- "jsonwebtoken": "^9.0.3",
45
- "open": "^9.1.0",
46
- "ora": "^7.0.0",
47
- "zod": "^4.1.13"
48
- },
49
- "files": [
50
- "ccw/bin/",
51
- "ccw/dist/",
52
- "ccw/src/",
53
- ".claude/agents/",
54
- ".claude/commands/",
55
- ".claude/output-styles/",
56
- ".claude/workflows/",
57
- ".claude/scripts/",
58
- ".claude/prompt-templates/",
59
- ".claude/python_script/",
60
- ".claude/skills/",
61
- ".codex/",
62
- ".gemini/",
63
- ".qwen/",
64
- "codex-lens/src/codexlens/",
65
- "codex-lens/pyproject.toml",
66
- "ccw-litellm/src/ccw_litellm/",
67
- "ccw-litellm/pyproject.toml",
68
- "CLAUDE.md",
69
- "README.md"
70
- ],
71
- "repository": {
72
- "type": "git",
73
- "url": "git+https://github.com/catlog22/Claude-Code-Workflow.git"
74
- },
75
- "bugs": {
76
- "url": "https://github.com/catlog22/Claude-Code-Workflow/issues"
77
- },
78
- "homepage": "https://github.com/catlog22/Claude-Code-Workflow#readme",
79
- "devDependencies": {
80
- "@playwright/test": "^1.57.0",
81
- "@types/better-sqlite3": "^7.6.12",
82
- "@types/gradient-string": "^1.1.6",
83
- "@types/inquirer": "^9.0.9",
84
- "@types/jsonwebtoken": "^9.0.10",
85
- "@types/node": "^25.0.1",
86
- "pixelmatch": "^7.1.0",
87
- "playwright": "^1.57.0",
88
- "pngjs": "^7.0.0",
89
- "typescript": "^5.9.3"
90
- }
91
- }
1
+ {
2
+ "name": "claude-code-workflow",
3
+ "version": "6.3.26",
4
+ "description": "JSON-driven multi-agent development framework with intelligent CLI orchestration (Gemini/Qwen/Codex), context-first architecture, and automated workflow execution",
5
+ "type": "module",
6
+ "main": "ccw/src/index.js",
7
+ "bin": {
8
+ "ccw": "./ccw/bin/ccw.js",
9
+ "ccw-mcp": "./ccw/bin/ccw-mcp.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc -p ccw/tsconfig.json",
13
+ "start": "node ccw/bin/ccw.js",
14
+ "test": "node --experimental-strip-types --test ccw/tests/*.test.js",
15
+ "test:visual": "node --experimental-strip-types --test ccw/tests/visual/**/*.visual.test.ts",
16
+ "test:e2e": "node --experimental-strip-types --test ccw/tests/e2e/*.e2e.test.ts",
17
+ "prepublishOnly": "npm run build && echo 'Ready to publish @dyw/claude-code-workflow'"
18
+ },
19
+ "keywords": [
20
+ "claude",
21
+ "workflow",
22
+ "ai",
23
+ "cli",
24
+ "dashboard",
25
+ "code-review",
26
+ "automation",
27
+ "development"
28
+ ],
29
+ "author": "dyw",
30
+ "license": "MIT",
31
+ "engines": {
32
+ "node": ">=16.0.0"
33
+ },
34
+ "dependencies": {
35
+ "@modelcontextprotocol/sdk": "^1.0.4",
36
+ "better-sqlite3": "^11.7.0",
37
+ "boxen": "^7.1.0",
38
+ "chalk": "^5.3.0",
39
+ "commander": "^11.0.0",
40
+ "figlet": "^1.7.0",
41
+ "glob": "^10.3.0",
42
+ "gradient-string": "^2.0.2",
43
+ "inquirer": "^9.2.0",
44
+ "jsonwebtoken": "^9.0.3",
45
+ "open": "^9.1.0",
46
+ "ora": "^7.0.0",
47
+ "zod": "^4.1.13"
48
+ },
49
+ "files": [
50
+ "ccw/bin/",
51
+ "ccw/dist/",
52
+ "ccw/src/",
53
+ ".claude/agents/",
54
+ ".claude/commands/",
55
+ ".claude/output-styles/",
56
+ ".claude/workflows/",
57
+ ".claude/scripts/",
58
+ ".claude/prompt-templates/",
59
+ ".claude/python_script/",
60
+ ".claude/skills/",
61
+ ".codex/",
62
+ ".gemini/",
63
+ ".qwen/",
64
+ "codex-lens/src/codexlens/",
65
+ "codex-lens/pyproject.toml",
66
+ "ccw-litellm/src/ccw_litellm/",
67
+ "ccw-litellm/pyproject.toml",
68
+ "CLAUDE.md",
69
+ "README.md"
70
+ ],
71
+ "repository": {
72
+ "type": "git",
73
+ "url": "git+https://github.com/catlog22/Claude-Code-Workflow.git"
74
+ },
75
+ "bugs": {
76
+ "url": "https://github.com/catlog22/Claude-Code-Workflow/issues"
77
+ },
78
+ "homepage": "https://github.com/catlog22/Claude-Code-Workflow#readme",
79
+ "devDependencies": {
80
+ "@playwright/test": "^1.57.0",
81
+ "@types/better-sqlite3": "^7.6.12",
82
+ "@types/gradient-string": "^1.1.6",
83
+ "@types/inquirer": "^9.0.9",
84
+ "@types/jsonwebtoken": "^9.0.10",
85
+ "@types/node": "^25.0.1",
86
+ "pixelmatch": "^7.1.0",
87
+ "playwright": "^1.57.0",
88
+ "pngjs": "^7.0.0",
89
+ "typescript": "^5.9.3"
90
+ }
91
+ }