claude-code-workflow 6.0.4 → 6.1.0

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 (120) hide show
  1. package/.claude/agents/action-planning-agent.md +1 -1
  2. package/.claude/agents/cli-execution-agent.md +269 -269
  3. package/.claude/agents/cli-explore-agent.md +182 -182
  4. package/.claude/agents/context-search-agent.md +582 -582
  5. package/.claude/agents/memory-bridge.md +93 -93
  6. package/.claude/commands/cli/cli-init.md +1 -1
  7. package/.claude/commands/memory/docs-full-cli.md +471 -471
  8. package/.claude/commands/memory/docs-related-cli.md +386 -386
  9. package/.claude/commands/memory/docs.md +615 -615
  10. package/.claude/commands/memory/load.md +1 -1
  11. package/.claude/commands/memory/update-full.md +332 -332
  12. package/.claude/commands/memory/update-related.md +5 -5
  13. package/.claude/commands/workflow/init.md +1 -1
  14. package/.claude/commands/workflow/lite-fix.md +621 -621
  15. package/.claude/commands/workflow/lite-plan.md +592 -592
  16. package/.claude/commands/workflow/tools/context-gather.md +434 -434
  17. package/.claude/commands/workflow/ui-design/generate.md +504 -504
  18. package/.claude/commands/workflow/ui-design/import-from-code.md +537 -537
  19. package/.claude/scripts/classify-folders.sh +4 -0
  20. package/.claude/scripts/convert_tokens_to_css.sh +4 -0
  21. package/.claude/scripts/detect_changed_modules.sh +5 -1
  22. package/.claude/scripts/discover-design-files.sh +87 -83
  23. package/.claude/scripts/generate_module_docs.sh +717 -713
  24. package/.claude/scripts/get_modules_by_depth.sh +5 -1
  25. package/.claude/scripts/ui-generate-preview.sh +4 -0
  26. package/.claude/scripts/ui-instantiate-prototypes.sh +4 -0
  27. package/.claude/scripts/update_module_claude.sh +4 -0
  28. package/.claude/skills/command-guide/index/all-commands.json +1 -12
  29. package/.claude/skills/command-guide/index/by-category.json +1 -12
  30. package/.claude/skills/command-guide/index/by-use-case.json +1 -12
  31. package/.claude/skills/command-guide/index/essential-commands.json +1 -12
  32. package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +127 -71
  33. package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +269 -269
  34. package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +182 -182
  35. package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +18 -38
  36. package/.claude/skills/command-guide/reference/agents/context-search-agent.md +582 -577
  37. package/.claude/skills/command-guide/reference/agents/memory-bridge.md +93 -93
  38. package/.claude/skills/command-guide/reference/commands/cli/cli-init.md +1 -1
  39. package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +471 -471
  40. package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +386 -386
  41. package/.claude/skills/command-guide/reference/commands/memory/docs.md +615 -610
  42. package/.claude/skills/command-guide/reference/commands/memory/load.md +1 -1
  43. package/.claude/skills/command-guide/reference/commands/memory/update-full.md +332 -332
  44. package/.claude/skills/command-guide/reference/commands/memory/update-related.md +5 -5
  45. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/artifacts.md +299 -451
  46. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +14 -37
  47. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/synthesis.md +252 -350
  48. package/.claude/skills/command-guide/reference/commands/workflow/init.md +2 -2
  49. package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +52 -0
  50. package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +621 -602
  51. package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +46 -36
  52. package/.claude/skills/command-guide/reference/commands/workflow/review-fix.md +18 -58
  53. package/.claude/skills/command-guide/reference/commands/workflow/review-module-cycle.md +22 -52
  54. package/.claude/skills/command-guide/reference/commands/workflow/review-session-cycle.md +19 -48
  55. package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +25 -5
  56. package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +1 -1
  57. package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +7 -7
  58. package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +434 -434
  59. package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +151 -11
  60. package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +4 -4
  61. package/.claude/skills/command-guide/reference/commands/workflow/tools/test-task-generate.md +1 -1
  62. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/generate.md +504 -504
  63. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +537 -537
  64. package/.claude/workflows/context-search-strategy.md +77 -77
  65. package/.claude/workflows/tool-strategy.md +90 -71
  66. package/.claude/workflows/workflow-architecture.md +1 -1
  67. package/ccw/package.json +6 -6
  68. package/ccw/src/cli.js +16 -0
  69. package/ccw/src/commands/stop.js +101 -0
  70. package/ccw/src/commands/tool.js +181 -0
  71. package/ccw/src/core/dashboard-generator.js +18 -3
  72. package/ccw/src/core/lite-scanner.js +35 -11
  73. package/ccw/src/core/server.js +583 -17
  74. package/ccw/src/templates/dashboard-css/01-base.css +161 -0
  75. package/ccw/src/templates/dashboard-css/02-session.css +726 -0
  76. package/ccw/src/templates/dashboard-css/03-tasks.css +512 -0
  77. package/ccw/src/templates/dashboard-css/04-lite-tasks.css +843 -0
  78. package/ccw/src/templates/dashboard-css/05-context.css +2206 -0
  79. package/ccw/src/templates/dashboard-css/06-cards.css +1570 -0
  80. package/ccw/src/templates/dashboard-css/07-managers.css +936 -0
  81. package/ccw/src/templates/dashboard-css/08-review.css +1266 -0
  82. package/ccw/src/templates/dashboard-css/09-explorer.css +1397 -0
  83. package/ccw/src/templates/dashboard-js/components/global-notifications.js +219 -0
  84. package/ccw/src/templates/dashboard-js/components/hook-manager.js +10 -0
  85. package/ccw/src/templates/dashboard-js/components/mcp-manager.js +24 -2
  86. package/ccw/src/templates/dashboard-js/components/navigation.js +11 -5
  87. package/ccw/src/templates/dashboard-js/components/tabs-context.js +20 -20
  88. package/ccw/src/templates/dashboard-js/components/tabs-other.js +11 -11
  89. package/ccw/src/templates/dashboard-js/components/theme.js +29 -1
  90. package/ccw/src/templates/dashboard-js/main.js +4 -0
  91. package/ccw/src/templates/dashboard-js/state.js +5 -0
  92. package/ccw/src/templates/dashboard-js/views/explorer.js +852 -0
  93. package/ccw/src/templates/dashboard-js/views/home.js +13 -9
  94. package/ccw/src/templates/dashboard-js/views/hook-manager.js +8 -5
  95. package/ccw/src/templates/dashboard-js/views/lite-tasks.js +21 -16
  96. package/ccw/src/templates/dashboard-js/views/mcp-manager.js +148 -8
  97. package/ccw/src/templates/dashboard-js/views/project-overview.js +15 -11
  98. package/ccw/src/templates/dashboard-js/views/review-session.js +3 -3
  99. package/ccw/src/templates/dashboard-js/views/session-detail.js +38 -28
  100. package/ccw/src/templates/dashboard.html +129 -28
  101. package/ccw/src/tools/classify-folders.js +204 -0
  102. package/ccw/src/tools/convert-tokens-to-css.js +250 -0
  103. package/ccw/src/tools/detect-changed-modules.js +288 -0
  104. package/ccw/src/tools/discover-design-files.js +134 -0
  105. package/ccw/src/tools/edit-file.js +266 -0
  106. package/ccw/src/tools/generate-module-docs.js +416 -0
  107. package/ccw/src/tools/get-modules-by-depth.js +308 -0
  108. package/ccw/src/tools/index.js +176 -0
  109. package/ccw/src/tools/ui-generate-preview.js +327 -0
  110. package/ccw/src/tools/ui-instantiate-prototypes.js +301 -0
  111. package/ccw/src/tools/update-module-claude.js +380 -0
  112. package/ccw/src/utils/browser-launcher.js +15 -4
  113. package/package.json +1 -1
  114. package/.claude/skills/command-guide/reference/commands/workflow/status.md +0 -352
  115. package/ccw/src/core/server.js.bak +0 -385
  116. package/ccw/src/core/server_original.bak +0 -385
  117. package/ccw/src/templates/dashboard.css +0 -8114
  118. package/ccw/src/templates/dashboard_tailwind.html +0 -42
  119. package/ccw/src/templates/dashboard_test.html +0 -37
  120. package/ccw/src/templates/tailwind-base.css +0 -212
@@ -1,385 +0,0 @@
1
- import http from 'http';
2
- import { URL } from 'url';
3
- import { readFileSync, existsSync, readdirSync } from 'fs';
4
- import { join } from 'path';
5
- import { scanSessions } from './session-scanner.js';
6
- import { aggregateData } from './data-aggregator.js';
7
- import { resolvePath, getRecentPaths, trackRecentPath, normalizePathForDisplay, getWorkflowDir } from '../utils/path-resolver.js';
8
-
9
- const TEMPLATE_PATH = join(import.meta.dirname, '../templates/dashboard.html');
10
- const CSS_FILE = join(import.meta.dirname, '../templates/dashboard.css');
11
- const JS_FILE = join(import.meta.dirname, '../templates/dashboard.js');
12
-
13
- /**
14
- * Create and start the dashboard server
15
- * @param {Object} options - Server options
16
- * @param {number} options.port - Port to listen on (default: 3456)
17
- * @param {string} options.initialPath - Initial project path
18
- * @returns {Promise<http.Server>}
19
- */
20
- export async function startServer(options = {}) {
21
- const port = options.port || 3456;
22
- const initialPath = options.initialPath || process.cwd();
23
-
24
- const server = http.createServer(async (req, res) => {
25
- const url = new URL(req.url, `http://localhost:${port}`);
26
- const pathname = url.pathname;
27
-
28
- // CORS headers for API requests
29
- res.setHeader('Access-Control-Allow-Origin', '*');
30
- res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
31
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
32
-
33
- if (req.method === 'OPTIONS') {
34
- res.writeHead(200);
35
- res.end();
36
- return;
37
- }
38
-
39
- try {
40
- // API: Get workflow data for a path
41
- if (pathname === '/api/data') {
42
- const projectPath = url.searchParams.get('path') || initialPath;
43
- const data = await getWorkflowData(projectPath);
44
-
45
- res.writeHead(200, { 'Content-Type': 'application/json' });
46
- res.end(JSON.stringify(data));
47
- return;
48
- }
49
-
50
- // API: Get recent paths
51
- if (pathname === '/api/recent-paths') {
52
- const paths = getRecentPaths();
53
- res.writeHead(200, { 'Content-Type': 'application/json' });
54
- res.end(JSON.stringify({ paths }));
55
- return;
56
- }
57
-
58
- // API: Get session detail data (context, summaries, impl-plan, review)
59
- if (pathname === '/api/session-detail') {
60
- const sessionPath = url.searchParams.get('path');
61
- const dataType = url.searchParams.get('type') || 'all';
62
-
63
- if (!sessionPath) {
64
- res.writeHead(400, { 'Content-Type': 'application/json' });
65
- res.end(JSON.stringify({ error: 'Session path is required' }));
66
- return;
67
- }
68
-
69
- const detail = await getSessionDetailData(sessionPath, dataType);
70
- res.writeHead(200, { 'Content-Type': 'application/json' });
71
- res.end(JSON.stringify(detail));
72
- return;
73
- }
74
-
75
- // Serve dashboard HTML
76
- if (pathname === '/' || pathname === '/index.html') {
77
- const html = generateServerDashboard(initialPath);
78
- res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
79
- res.end(html);
80
- return;
81
- }
82
-
83
- // 404
84
- res.writeHead(404, { 'Content-Type': 'text/plain' });
85
- res.end('Not Found');
86
-
87
- } catch (error) {
88
- console.error('Server error:', error);
89
- res.writeHead(500, { 'Content-Type': 'application/json' });
90
- res.end(JSON.stringify({ error: error.message }));
91
- }
92
- });
93
-
94
- return new Promise((resolve, reject) => {
95
- server.listen(port, () => {
96
- console.log(`Dashboard server running at http://localhost:${port}`);
97
- resolve(server);
98
- });
99
- server.on('error', reject);
100
- });
101
- }
102
-
103
- /**
104
- * Get workflow data for a project path
105
- * @param {string} projectPath
106
- * @returns {Promise<Object>}
107
- */
108
- async function getWorkflowData(projectPath) {
109
- const resolvedPath = resolvePath(projectPath);
110
- const workflowDir = join(resolvedPath, '.workflow');
111
-
112
- // Track this path
113
- trackRecentPath(resolvedPath);
114
-
115
- // Check if .workflow exists
116
- if (!existsSync(workflowDir)) {
117
- return {
118
- generatedAt: new Date().toISOString(),
119
- activeSessions: [],
120
- archivedSessions: [],
121
- liteTasks: { litePlan: [], liteFix: [] },
122
- reviewData: { dimensions: {} },
123
- projectOverview: null,
124
- statistics: {
125
- totalSessions: 0,
126
- activeSessions: 0,
127
- totalTasks: 0,
128
- completedTasks: 0,
129
- reviewFindings: 0,
130
- litePlanCount: 0,
131
- liteFixCount: 0
132
- },
133
- projectPath: normalizePathForDisplay(resolvedPath),
134
- recentPaths: getRecentPaths()
135
- };
136
- }
137
-
138
- // Scan and aggregate data
139
- const sessions = await scanSessions(workflowDir);
140
- const data = await aggregateData(sessions, workflowDir);
141
-
142
- data.projectPath = normalizePathForDisplay(resolvedPath);
143
- data.recentPaths = getRecentPaths();
144
-
145
- return data;
146
- }
147
-
148
- /**
149
- * Get session detail data (context, summaries, impl-plan, review)
150
- * @param {string} sessionPath - Path to session directory
151
- * @param {string} dataType - Type of data to load: context, summary, impl-plan, review, or all
152
- * @returns {Promise<Object>}
153
- */
154
- async function getSessionDetailData(sessionPath, dataType) {
155
- const result = {};
156
-
157
- // Normalize path
158
- const normalizedPath = sessionPath.replace(/\\/g, '/');
159
-
160
- try {
161
- // Load context-package.json (in .process/ subfolder)
162
- if (dataType === 'context' || dataType === 'all') {
163
- // Try .process/context-package.json first (common location)
164
- let contextFile = join(normalizedPath, '.process', 'context-package.json');
165
- if (!existsSync(contextFile)) {
166
- // Fallback to session root
167
- contextFile = join(normalizedPath, 'context-package.json');
168
- }
169
- if (existsSync(contextFile)) {
170
- try {
171
- result.context = JSON.parse(readFileSync(contextFile, 'utf8'));
172
- } catch (e) {
173
- result.context = null;
174
- }
175
- }
176
- }
177
-
178
- // Load task JSONs from .task/ folder
179
- if (dataType === 'tasks' || dataType === 'all') {
180
- const taskDir = join(normalizedPath, '.task');
181
- result.tasks = [];
182
- if (existsSync(taskDir)) {
183
- const files = readdirSync(taskDir).filter(f => f.endsWith('.json') && f.startsWith('IMPL-'));
184
- for (const file of files) {
185
- try {
186
- const content = JSON.parse(readFileSync(join(taskDir, file), 'utf8'));
187
- result.tasks.push({
188
- filename: file,
189
- task_id: file.replace('.json', ''),
190
- ...content
191
- });
192
- } catch (e) {
193
- // Skip unreadable files
194
- }
195
- }
196
- // Sort by task ID
197
- result.tasks.sort((a, b) => a.task_id.localeCompare(b.task_id));
198
- }
199
- }
200
-
201
- // Load summaries from .summaries/
202
- if (dataType === 'summary' || dataType === 'all') {
203
- const summariesDir = join(normalizedPath, '.summaries');
204
- result.summaries = [];
205
- if (existsSync(summariesDir)) {
206
- const files = readdirSync(summariesDir).filter(f => f.endsWith('.md'));
207
- for (const file of files) {
208
- try {
209
- const content = readFileSync(join(summariesDir, file), 'utf8');
210
- result.summaries.push({ name: file.replace('.md', ''), content });
211
- } catch (e) {
212
- // Skip unreadable files
213
- }
214
- }
215
- }
216
- }
217
-
218
- // Load plan.json (for lite tasks)
219
- if (dataType === 'plan' || dataType === 'all') {
220
- const planFile = join(normalizedPath, 'plan.json');
221
- if (existsSync(planFile)) {
222
- try {
223
- result.plan = JSON.parse(readFileSync(planFile, 'utf8'));
224
- } catch (e) {
225
- result.plan = null;
226
- }
227
- }
228
- }
229
-
230
- // Load IMPL_PLAN.md
231
- if (dataType === 'impl-plan' || dataType === 'all') {
232
- const implPlanFile = join(normalizedPath, 'IMPL_PLAN.md');
233
- if (existsSync(implPlanFile)) {
234
- try {
235
- result.implPlan = readFileSync(implPlanFile, 'utf8');
236
- } catch (e) {
237
- result.implPlan = null;
238
- }
239
- }
240
- }
241
-
242
- // Load review data from .review/
243
- if (dataType === 'review' || dataType === 'all') {
244
- const reviewDir = join(normalizedPath, '.review');
245
- result.review = {
246
- state: null,
247
- dimensions: [],
248
- severityDistribution: null,
249
- totalFindings: 0
250
- };
251
-
252
- if (existsSync(reviewDir)) {
253
- // Load review-state.json
254
- const stateFile = join(reviewDir, 'review-state.json');
255
- if (existsSync(stateFile)) {
256
- try {
257
- const state = JSON.parse(readFileSync(stateFile, 'utf8'));
258
- result.review.state = state;
259
- result.review.severityDistribution = state.severity_distribution || {};
260
- result.review.totalFindings = state.total_findings || 0;
261
- result.review.phase = state.phase || 'unknown';
262
- result.review.dimensionSummaries = state.dimension_summaries || {};
263
- result.review.crossCuttingConcerns = state.cross_cutting_concerns || [];
264
- result.review.criticalFiles = state.critical_files || [];
265
- } catch (e) {
266
- // Skip unreadable state
267
- }
268
- }
269
-
270
- // Load dimension findings
271
- const dimensionsDir = join(reviewDir, 'dimensions');
272
- if (existsSync(dimensionsDir)) {
273
- const files = readdirSync(dimensionsDir).filter(f => f.endsWith('.json'));
274
- for (const file of files) {
275
- try {
276
- const dimName = file.replace('.json', '');
277
- const data = JSON.parse(readFileSync(join(dimensionsDir, file), 'utf8'));
278
-
279
- // Handle array structure: [ { findings: [...] } ]
280
- let findings = [];
281
- let summary = null;
282
-
283
- if (Array.isArray(data) && data.length > 0) {
284
- const dimData = data[0];
285
- findings = dimData.findings || [];
286
- summary = dimData.summary || null;
287
- } else if (data.findings) {
288
- findings = data.findings;
289
- summary = data.summary || null;
290
- }
291
-
292
- result.review.dimensions.push({
293
- name: dimName,
294
- findings: findings,
295
- summary: summary,
296
- count: findings.length
297
- });
298
- } catch (e) {
299
- // Skip unreadable files
300
- }
301
- }
302
- }
303
- }
304
- }
305
-
306
- } catch (error) {
307
- console.error('Error loading session detail:', error);
308
- result.error = error.message;
309
- }
310
-
311
- return result;
312
- }
313
-
314
- /**
315
- * Generate dashboard HTML for server mode
316
- * @param {string} initialPath
317
- * @returns {string}
318
- */
319
- function generateServerDashboard(initialPath) {
320
- let html = readFileSync(TEMPLATE_PATH, 'utf8');
321
-
322
- // Read CSS and JS files
323
- const cssContent = existsSync(CSS_FILE) ? readFileSync(CSS_FILE, 'utf8') : '';
324
- let jsContent = existsSync(JS_FILE) ? readFileSync(JS_FILE, 'utf8') : '';
325
-
326
- // Inject CSS content
327
- html = html.replace('{{CSS_CONTENT}}', cssContent);
328
-
329
- // Prepare JS content with empty initial data (will be loaded dynamically)
330
- const emptyData = {
331
- generatedAt: new Date().toISOString(),
332
- activeSessions: [],
333
- archivedSessions: [],
334
- liteTasks: { litePlan: [], liteFix: [] },
335
- reviewData: { dimensions: {} },
336
- projectOverview: null,
337
- statistics: { totalSessions: 0, activeSessions: 0, totalTasks: 0, completedTasks: 0, reviewFindings: 0, litePlanCount: 0, liteFixCount: 0 }
338
- };
339
-
340
- // Replace JS placeholders
341
- jsContent = jsContent.replace('{{WORKFLOW_DATA}}', JSON.stringify(emptyData, null, 2));
342
- jsContent = jsContent.replace(/\{\{PROJECT_PATH\}\}/g, normalizePathForDisplay(initialPath).replace(/\\/g, '/'));
343
- jsContent = jsContent.replace('{{RECENT_PATHS}}', JSON.stringify(getRecentPaths()));
344
-
345
- // Add server mode flag and dynamic loading functions at the start of JS
346
- const serverModeScript = `
347
- // Server mode - load data dynamically
348
- window.SERVER_MODE = true;
349
- window.INITIAL_PATH = '${normalizePathForDisplay(initialPath).replace(/\\/g, '/')}';
350
-
351
- async function loadDashboardData(path) {
352
- try {
353
- const res = await fetch('/api/data?path=' + encodeURIComponent(path));
354
- if (!res.ok) throw new Error('Failed to load data');
355
- return await res.json();
356
- } catch (err) {
357
- console.error('Error loading data:', err);
358
- return null;
359
- }
360
- }
361
-
362
- async function loadRecentPaths() {
363
- try {
364
- const res = await fetch('/api/recent-paths');
365
- if (!res.ok) return [];
366
- const data = await res.json();
367
- return data.paths || [];
368
- } catch (err) {
369
- return [];
370
- }
371
- }
372
-
373
- `;
374
-
375
- // Prepend server mode script to JS content
376
- jsContent = serverModeScript + jsContent;
377
-
378
- // Inject JS content
379
- html = html.replace('{{JS_CONTENT}}', jsContent);
380
-
381
- // Replace any remaining placeholders in HTML
382
- html = html.replace(/\{\{PROJECT_PATH\}\}/g, normalizePathForDisplay(initialPath).replace(/\\/g, '/'));
383
-
384
- return html;
385
- }