claude-code-workflow 6.1.3 → 6.1.4

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.
@@ -67,7 +67,9 @@ Phase 4: Execution Strategy & Task Execution
67
67
  ├─ Get next in_progress task from TodoWrite
68
68
  ├─ Lazy load task JSON
69
69
  ├─ Launch agent with task context
70
- ├─ Mark task completed
70
+ ├─ Mark task completed (update IMPL-*.json status)
71
+ │ # Quick fix: Update task status for ccw dashboard
72
+ │ # TS=$(date -Iseconds) && jq --arg ts "$TS" '.status="completed" | .status_history=(.status_history // [])+[{"from":"in_progress","to":"completed","changed_at":$ts}]' IMPL-X.json > tmp.json && mv tmp.json IMPL-X.json
71
73
  └─ Advance to next task
72
74
 
73
75
  Phase 5: Completion
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  <div align="center">
7
7
 
8
- [![Version](https://img.shields.io/badge/version-v6.1.2-blue.svg)](https://github.com/catlog22/Claude-Code-Workflow/releases)
8
+ [![Version](https://img.shields.io/badge/version-v6.1.3-blue.svg)](https://github.com/catlog22/Claude-Code-Workflow/releases)
9
9
  [![npm](https://img.shields.io/npm/v/claude-code-workflow.svg)](https://www.npmjs.com/package/claude-code-workflow)
10
10
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
11
11
  [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)]()
@@ -18,11 +18,11 @@
18
18
 
19
19
  **Claude Code Workflow (CCW)** is a JSON-driven multi-agent development framework with intelligent CLI orchestration (Gemini/Qwen/Codex), context-first architecture, and automated workflow execution. It transforms AI development from simple prompt chaining into a powerful orchestration system.
20
20
 
21
- > **🎉 Version 6.1.2: Dashboard Update Notification & Bug Fixes**
21
+ > **🎉 Version 6.1.3: CLI Tool Simplification**
22
22
  >
23
23
  > **Core Improvements**:
24
- > - 🔔 **Version Update Notification**: Dashboard now checks npm for updates and displays upgrade banner
25
- > - 🔧 **Hook Manager Fix**: Fixed button click event handling for edit/delete operations
24
+ > - 🔧 **Simplified edit_file**: Parameter-based input only (`--path`, `--old`, `--new`)
25
+ > - 📝 **Updated tool-strategy.md**: Added sed as line operation alternative
26
26
  >
27
27
  > See [CHANGELOG.md](CHANGELOG.md) for complete details.
28
28
 
@@ -39,6 +39,11 @@ function scanLiteDir(dir, type) {
39
39
  tasks: loadTaskJsons(sessionPath)
40
40
  };
41
41
 
42
+ // For lite-fix sessions, also load diagnoses separately
43
+ if (type === 'lite-fix') {
44
+ session.diagnoses = loadDiagnoses(sessionPath);
45
+ }
46
+
42
47
  // Calculate progress
43
48
  session.progress = calculateProgress(session.tasks);
44
49
 
@@ -268,7 +273,7 @@ export function getLiteTaskDetail(workflowDir, type, sessionId) {
268
273
 
269
274
  if (!existsSync(dir)) return null;
270
275
 
271
- return {
276
+ const detail = {
272
277
  id: sessionId,
273
278
  type,
274
279
  path: dir,
@@ -277,6 +282,13 @@ export function getLiteTaskDetail(workflowDir, type, sessionId) {
277
282
  explorations: loadExplorations(dir),
278
283
  clarifications: loadClarifications(dir)
279
284
  };
285
+
286
+ // For lite-fix sessions, also load diagnoses
287
+ if (type === 'lite-fix') {
288
+ detail.diagnoses = loadDiagnoses(dir);
289
+ }
290
+
291
+ return detail;
280
292
  }
281
293
 
282
294
  /**
@@ -312,3 +324,50 @@ function loadClarifications(sessionPath) {
312
324
  return null;
313
325
  }
314
326
  }
327
+
328
+ /**
329
+ * Load diagnosis files for lite-fix sessions
330
+ * Loads diagnosis-*.json files from session root directory
331
+ * @param {string} sessionPath - Session directory path
332
+ * @returns {Object} - Diagnoses data with manifest and items
333
+ */
334
+ function loadDiagnoses(sessionPath) {
335
+ const result = {
336
+ manifest: null,
337
+ items: []
338
+ };
339
+
340
+ // Try to load diagnoses-manifest.json first
341
+ const manifestPath = join(sessionPath, 'diagnoses-manifest.json');
342
+ if (existsSync(manifestPath)) {
343
+ try {
344
+ result.manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
345
+ } catch {
346
+ // Continue without manifest
347
+ }
348
+ }
349
+
350
+ // Load all diagnosis-*.json files from session root
351
+ try {
352
+ const diagnosisFiles = readdirSync(sessionPath)
353
+ .filter(f => f.startsWith('diagnosis-') && f.endsWith('.json'));
354
+
355
+ for (const file of diagnosisFiles) {
356
+ const filePath = join(sessionPath, file);
357
+ try {
358
+ const content = JSON.parse(readFileSync(filePath, 'utf8'));
359
+ result.items.push({
360
+ id: file.replace('diagnosis-', '').replace('.json', ''),
361
+ filename: file,
362
+ ...content
363
+ });
364
+ } catch {
365
+ // Skip invalid files
366
+ }
367
+ }
368
+ } catch {
369
+ // Return empty items if directory read fails
370
+ }
371
+
372
+ return result;
373
+ }
@@ -841,3 +841,331 @@
841
841
  overflow: hidden;
842
842
  }
843
843
 
844
+ /* ===================================
845
+ Fix Plan Enhanced Styles
846
+ =================================== */
847
+
848
+ .plan-root-cause-text,
849
+ .plan-strategy-text,
850
+ .plan-requirements-text {
851
+ font-size: 0.875rem;
852
+ line-height: 1.6;
853
+ color: hsl(var(--foreground));
854
+ background: hsl(var(--muted) / 0.3);
855
+ padding: 0.75rem;
856
+ border-radius: 0.375rem;
857
+ border-left: 3px solid hsl(var(--primary));
858
+ }
859
+
860
+ .severity-badge,
861
+ .risk-badge {
862
+ display: inline-block;
863
+ padding: 0.125rem 0.5rem;
864
+ border-radius: 0.25rem;
865
+ font-size: 0.75rem;
866
+ font-weight: 500;
867
+ text-transform: uppercase;
868
+ }
869
+
870
+ .severity-badge.critical,
871
+ .risk-badge.high {
872
+ background: hsl(0 70% 50% / 0.15);
873
+ color: hsl(0 70% 45%);
874
+ }
875
+
876
+ .severity-badge.high,
877
+ .risk-badge.medium {
878
+ background: hsl(30 90% 50% / 0.15);
879
+ color: hsl(30 90% 40%);
880
+ }
881
+
882
+ .severity-badge.medium {
883
+ background: hsl(45 90% 50% / 0.15);
884
+ color: hsl(45 80% 35%);
885
+ }
886
+
887
+ .severity-badge.low,
888
+ .risk-badge.low {
889
+ background: hsl(142 70% 50% / 0.15);
890
+ color: hsl(142 70% 35%);
891
+ }
892
+
893
+ .fix-tasks-summary {
894
+ display: flex;
895
+ flex-direction: column;
896
+ gap: 0.5rem;
897
+ }
898
+
899
+ .fix-task-summary-item {
900
+ background: hsl(var(--card));
901
+ border: 1px solid hsl(var(--border));
902
+ border-radius: 0.5rem;
903
+ overflow: hidden;
904
+ }
905
+
906
+ .fix-task-summary-item .collapsible-header {
907
+ padding: 0.75rem 1rem;
908
+ }
909
+
910
+ .task-num {
911
+ font-weight: 600;
912
+ color: hsl(var(--primary));
913
+ font-size: 0.85rem;
914
+ }
915
+
916
+ .task-title-brief {
917
+ font-size: 0.875rem;
918
+ color: hsl(var(--foreground));
919
+ flex: 1;
920
+ }
921
+
922
+ .task-scope-badge {
923
+ padding: 0.125rem 0.5rem;
924
+ background: hsl(var(--muted));
925
+ border-radius: 0.25rem;
926
+ font-size: 0.7rem;
927
+ color: hsl(var(--muted-foreground));
928
+ }
929
+
930
+ .task-detail-section {
931
+ margin-bottom: 1rem;
932
+ }
933
+
934
+ .task-detail-section:last-child {
935
+ margin-bottom: 0;
936
+ }
937
+
938
+ .task-detail-section strong {
939
+ display: block;
940
+ font-size: 0.75rem;
941
+ text-transform: uppercase;
942
+ letter-spacing: 0.025em;
943
+ color: hsl(var(--muted-foreground));
944
+ margin-bottom: 0.5rem;
945
+ }
946
+
947
+ .mod-points-list,
948
+ .verify-list {
949
+ margin: 0;
950
+ padding-left: 1rem;
951
+ font-size: 0.8rem;
952
+ }
953
+
954
+ .mod-points-list li,
955
+ .verify-list li {
956
+ margin-bottom: 0.375rem;
957
+ line-height: 1.5;
958
+ }
959
+
960
+ .mod-points-list code {
961
+ font-size: 0.75rem;
962
+ padding: 0.125rem 0.375rem;
963
+ background: hsl(var(--muted));
964
+ border-radius: 0.25rem;
965
+ color: hsl(var(--primary));
966
+ }
967
+
968
+ .func-name {
969
+ color: hsl(var(--muted-foreground));
970
+ font-size: 0.75rem;
971
+ }
972
+
973
+ .change-type {
974
+ color: hsl(var(--muted-foreground));
975
+ font-size: 0.7rem;
976
+ font-style: italic;
977
+ }
978
+
979
+ /* ===================================
980
+ Diagnoses Tab Styles
981
+ =================================== */
982
+
983
+ .diagnoses-tab-content {
984
+ display: flex;
985
+ flex-direction: column;
986
+ gap: 1.5rem;
987
+ }
988
+
989
+ .diagnoses-section-title {
990
+ font-size: 1rem;
991
+ font-weight: 600;
992
+ color: hsl(var(--foreground));
993
+ margin-bottom: 0.75rem;
994
+ display: flex;
995
+ align-items: center;
996
+ gap: 0.5rem;
997
+ }
998
+
999
+ .diagnoses-manifest-section {
1000
+ background: hsl(var(--muted) / 0.3);
1001
+ border: 1px solid hsl(var(--border));
1002
+ border-radius: 0.5rem;
1003
+ padding: 1rem;
1004
+ }
1005
+
1006
+ .manifest-meta-grid {
1007
+ display: flex;
1008
+ flex-wrap: wrap;
1009
+ gap: 1rem;
1010
+ }
1011
+
1012
+ .diagnoses-grid {
1013
+ display: flex;
1014
+ flex-direction: column;
1015
+ gap: 0.75rem;
1016
+ }
1017
+
1018
+ .diagnosis-card {
1019
+ background: hsl(var(--card));
1020
+ border: 1px solid hsl(var(--border));
1021
+ border-radius: 0.5rem;
1022
+ overflow: hidden;
1023
+ }
1024
+
1025
+ .diagnosis-header {
1026
+ background: hsl(var(--muted) / 0.3);
1027
+ }
1028
+
1029
+ .diagnosis-id {
1030
+ font-weight: 600;
1031
+ color: hsl(var(--foreground));
1032
+ flex: 1;
1033
+ display: flex;
1034
+ align-items: center;
1035
+ gap: 0.5rem;
1036
+ }
1037
+
1038
+ .diag-section {
1039
+ margin-bottom: 1rem;
1040
+ padding-bottom: 1rem;
1041
+ border-bottom: 1px solid hsl(var(--border) / 0.5);
1042
+ }
1043
+
1044
+ .diag-section:last-child {
1045
+ margin-bottom: 0;
1046
+ padding-bottom: 0;
1047
+ border-bottom: none;
1048
+ }
1049
+
1050
+ .diag-section strong {
1051
+ display: block;
1052
+ font-size: 0.75rem;
1053
+ text-transform: uppercase;
1054
+ letter-spacing: 0.025em;
1055
+ color: hsl(var(--muted-foreground));
1056
+ margin-bottom: 0.5rem;
1057
+ }
1058
+
1059
+ .diag-section p {
1060
+ margin: 0;
1061
+ font-size: 0.875rem;
1062
+ line-height: 1.6;
1063
+ color: hsl(var(--foreground));
1064
+ }
1065
+
1066
+ .issues-list {
1067
+ margin: 0;
1068
+ padding-left: 1rem;
1069
+ font-size: 0.85rem;
1070
+ }
1071
+
1072
+ .issue-item {
1073
+ margin-bottom: 0.5rem;
1074
+ padding: 0.5rem;
1075
+ background: hsl(var(--muted) / 0.3);
1076
+ border-radius: 0.25rem;
1077
+ }
1078
+
1079
+ .issue-title {
1080
+ font-weight: 500;
1081
+ color: hsl(var(--foreground));
1082
+ }
1083
+
1084
+ .issue-location {
1085
+ font-size: 0.75rem;
1086
+ margin-top: 0.25rem;
1087
+ }
1088
+
1089
+ .issue-location code {
1090
+ padding: 0.125rem 0.375rem;
1091
+ background: hsl(var(--muted));
1092
+ border-radius: 0.25rem;
1093
+ color: hsl(var(--primary));
1094
+ }
1095
+
1096
+ .contracts-list {
1097
+ display: flex;
1098
+ flex-direction: column;
1099
+ gap: 0.5rem;
1100
+ }
1101
+
1102
+ .contract-item {
1103
+ padding: 0.75rem;
1104
+ background: hsl(var(--muted) / 0.3);
1105
+ border: 1px solid hsl(var(--border));
1106
+ border-radius: 0.375rem;
1107
+ }
1108
+
1109
+ .contract-header {
1110
+ display: flex;
1111
+ align-items: center;
1112
+ gap: 0.5rem;
1113
+ margin-bottom: 0.25rem;
1114
+ }
1115
+
1116
+ .contract-endpoint {
1117
+ font-weight: 500;
1118
+ color: hsl(var(--foreground));
1119
+ }
1120
+
1121
+ .contract-method {
1122
+ padding: 0.125rem 0.375rem;
1123
+ background: hsl(var(--primary) / 0.15);
1124
+ color: hsl(var(--primary));
1125
+ border-radius: 0.25rem;
1126
+ font-size: 0.7rem;
1127
+ font-weight: 600;
1128
+ }
1129
+
1130
+ .contract-desc {
1131
+ font-size: 0.8rem;
1132
+ color: hsl(var(--muted-foreground));
1133
+ }
1134
+
1135
+ .contract-issues {
1136
+ font-size: 0.75rem;
1137
+ color: hsl(0 70% 50%);
1138
+ margin-top: 0.25rem;
1139
+ }
1140
+
1141
+ .dataflow-details {
1142
+ display: flex;
1143
+ flex-direction: column;
1144
+ gap: 0.5rem;
1145
+ }
1146
+
1147
+ .df-item {
1148
+ font-size: 0.85rem;
1149
+ }
1150
+
1151
+ .df-label {
1152
+ font-weight: 500;
1153
+ color: hsl(var(--muted-foreground));
1154
+ }
1155
+
1156
+ .df-transforms {
1157
+ margin: 0.25rem 0 0 1rem;
1158
+ padding-left: 0;
1159
+ }
1160
+
1161
+ .recommendations-list {
1162
+ margin: 0;
1163
+ padding-left: 1.25rem;
1164
+ font-size: 0.85rem;
1165
+ }
1166
+
1167
+ .recommendations-list li {
1168
+ margin-bottom: 0.375rem;
1169
+ line-height: 1.5;
1170
+ }
1171
+
@@ -136,6 +136,13 @@ function showLiteTaskDetailPage(sessionKey) {
136
136
  <span class="tab-icon"><i data-lucide="ruler" class="w-4 h-4"></i></span>
137
137
  <span class="tab-text">Plan</span>
138
138
  </button>
139
+ ${session.type === 'lite-fix' ? `
140
+ <button class="detail-tab" data-tab="diagnoses" onclick="switchLiteDetailTab('diagnoses')">
141
+ <span class="tab-icon"><i data-lucide="stethoscope" class="w-4 h-4"></i></span>
142
+ <span class="tab-text">Diagnoses</span>
143
+ ${session.diagnoses?.items?.length ? `<span class="tab-count">${session.diagnoses.items.length}</span>` : ''}
144
+ </button>
145
+ ` : ''}
139
146
  <button class="detail-tab" data-tab="context" onclick="switchLiteDetailTab('context')">
140
147
  <span class="tab-icon"><i data-lucide="package" class="w-4 h-4"></i></span>
141
148
  <span class="tab-text">Context</span>
@@ -196,6 +203,17 @@ function switchLiteDetailTab(tabName) {
196
203
  break;
197
204
  case 'plan':
198
205
  contentArea.innerHTML = renderLitePlanTab(session);
206
+ // Re-initialize collapsible sections for plan tab
207
+ setTimeout(() => {
208
+ initCollapsibleSections(contentArea);
209
+ }, 50);
210
+ break;
211
+ case 'diagnoses':
212
+ contentArea.innerHTML = renderDiagnosesTab(session);
213
+ // Re-initialize collapsible sections for diagnoses tab
214
+ setTimeout(() => {
215
+ initCollapsibleSections(contentArea);
216
+ }, 50);
199
217
  break;
200
218
  case 'context':
201
219
  loadAndRenderLiteContextTab(session, contentArea);
@@ -287,13 +305,14 @@ function openTaskDrawerForLite(sessionId, taskId) {
287
305
 
288
306
  function renderLitePlanTab(session) {
289
307
  const plan = session.plan;
308
+ const isFixPlan = session.type === 'lite-fix';
290
309
 
291
310
  if (!plan) {
292
311
  return `
293
312
  <div class="tab-empty-state">
294
313
  <div class="empty-icon"><i data-lucide="ruler" class="w-12 h-12"></i></div>
295
314
  <div class="empty-title">No Plan Data</div>
296
- <div class="empty-text">No plan.json found for this session.</div>
315
+ <div class="empty-text">No ${isFixPlan ? 'fix-plan.json' : 'plan.json'} found for this session.</div>
297
316
  </div>
298
317
  `;
299
318
  }
@@ -308,6 +327,22 @@ function renderLitePlanTab(session) {
308
327
  </div>
309
328
  ` : ''}
310
329
 
330
+ <!-- Root Cause (fix-plan specific) -->
331
+ ${plan.root_cause ? `
332
+ <div class="plan-section">
333
+ <h4 class="plan-section-title"><i data-lucide="search" class="w-4 h-4 inline mr-1"></i> Root Cause</h4>
334
+ <p class="plan-root-cause-text">${escapeHtml(plan.root_cause)}</p>
335
+ </div>
336
+ ` : ''}
337
+
338
+ <!-- Strategy (fix-plan specific) -->
339
+ ${plan.strategy ? `
340
+ <div class="plan-section">
341
+ <h4 class="plan-section-title"><i data-lucide="route" class="w-4 h-4 inline mr-1"></i> Fix Strategy</h4>
342
+ <p class="plan-strategy-text">${escapeHtml(plan.strategy)}</p>
343
+ </div>
344
+ ` : ''}
345
+
311
346
  <!-- Approach -->
312
347
  ${plan.approach ? `
313
348
  <div class="plan-section">
@@ -316,6 +351,14 @@ function renderLitePlanTab(session) {
316
351
  </div>
317
352
  ` : ''}
318
353
 
354
+ <!-- User Requirements (fix-plan specific) -->
355
+ ${plan.user_requirements ? `
356
+ <div class="plan-section">
357
+ <h4 class="plan-section-title"><i data-lucide="user" class="w-4 h-4 inline mr-1"></i> User Requirements</h4>
358
+ <p class="plan-requirements-text">${escapeHtml(plan.user_requirements)}</p>
359
+ </div>
360
+ ` : ''}
361
+
319
362
  <!-- Focus Paths -->
320
363
  ${plan.focus_paths?.length ? `
321
364
  <div class="plan-section">
@@ -330,16 +373,74 @@ function renderLitePlanTab(session) {
330
373
  <div class="plan-section">
331
374
  <h4 class="plan-section-title"><i data-lucide="info" class="w-4 h-4 inline mr-1"></i> Metadata</h4>
332
375
  <div class="plan-meta-grid">
376
+ ${plan.severity ? `<div class="meta-item"><span class="meta-label">Severity:</span> <span class="severity-badge ${escapeHtml(plan.severity)}">${escapeHtml(plan.severity)}</span></div>` : ''}
377
+ ${plan.risk_level ? `<div class="meta-item"><span class="meta-label">Risk Level:</span> <span class="risk-badge ${escapeHtml(plan.risk_level)}">${escapeHtml(plan.risk_level)}</span></div>` : ''}
333
378
  ${plan.estimated_time ? `<div class="meta-item"><span class="meta-label">Estimated Time:</span> ${escapeHtml(plan.estimated_time)}</div>` : ''}
334
379
  ${plan.complexity ? `<div class="meta-item"><span class="meta-label">Complexity:</span> ${escapeHtml(plan.complexity)}</div>` : ''}
335
380
  ${plan.recommended_execution ? `<div class="meta-item"><span class="meta-label">Execution:</span> ${escapeHtml(plan.recommended_execution)}</div>` : ''}
336
381
  </div>
337
382
  </div>
338
383
 
384
+ <!-- Fix Tasks Summary (fix-plan specific) -->
385
+ ${plan.tasks?.length ? `
386
+ <div class="plan-section">
387
+ <h4 class="plan-section-title"><i data-lucide="list-checks" class="w-4 h-4 inline mr-1"></i> Fix Tasks (${plan.tasks.length})</h4>
388
+ <div class="fix-tasks-summary">
389
+ ${plan.tasks.map((task, idx) => `
390
+ <div class="fix-task-summary-item collapsible-section">
391
+ <div class="collapsible-header">
392
+ <span class="collapse-icon">▶</span>
393
+ <span class="task-num">#${idx + 1}</span>
394
+ <span class="task-title-brief">${escapeHtml(task.title || task.summary || 'Untitled')}</span>
395
+ ${task.scope ? `<span class="task-scope-badge">${escapeHtml(task.scope)}</span>` : ''}
396
+ </div>
397
+ <div class="collapsible-content collapsed">
398
+ ${task.modification_points?.length ? `
399
+ <div class="task-detail-section">
400
+ <strong>Modification Points:</strong>
401
+ <ul class="mod-points-list">
402
+ ${task.modification_points.map(mp => `
403
+ <li>
404
+ <code>${escapeHtml(mp.file || '')}</code>
405
+ ${mp.function_name ? `<span class="func-name">→ ${escapeHtml(mp.function_name)}</span>` : ''}
406
+ ${mp.change_type ? `<span class="change-type">(${escapeHtml(mp.change_type)})</span>` : ''}
407
+ </li>
408
+ `).join('')}
409
+ </ul>
410
+ </div>
411
+ ` : ''}
412
+ ${task.implementation?.length ? `
413
+ <div class="task-detail-section">
414
+ <strong>Implementation Steps:</strong>
415
+ <ol class="impl-steps-list">
416
+ ${task.implementation.map(step => `<li>${escapeHtml(step)}</li>`).join('')}
417
+ </ol>
418
+ </div>
419
+ ` : ''}
420
+ ${task.verification?.length ? `
421
+ <div class="task-detail-section">
422
+ <strong>Verification:</strong>
423
+ <ul class="verify-list">
424
+ ${task.verification.map(v => `<li>${escapeHtml(v)}</li>`).join('')}
425
+ </ul>
426
+ </div>
427
+ ` : ''}
428
+ </div>
429
+ </div>
430
+ `).join('')}
431
+ </div>
432
+ </div>
433
+ ` : ''}
434
+
339
435
  <!-- Raw JSON -->
340
- <div class="plan-section">
341
- <h4 class="plan-section-title">{ } Raw JSON</h4>
342
- <pre class="json-content">${escapeHtml(JSON.stringify(plan, null, 2))}</pre>
436
+ <div class="plan-section collapsible-section">
437
+ <div class="collapsible-header">
438
+ <span class="collapse-icon">▶</span>
439
+ <span class="section-label">{ } Raw JSON</span>
440
+ </div>
441
+ <div class="collapsible-content collapsed">
442
+ <pre class="json-content">${escapeHtml(JSON.stringify(plan, null, 2))}</pre>
443
+ </div>
343
444
  </div>
344
445
  </div>
345
446
  `;
@@ -393,3 +494,192 @@ async function loadAndRenderLiteSummaryTab(session, contentArea) {
393
494
  contentArea.innerHTML = `<div class="tab-error">Failed to load summaries: ${err.message}</div>`;
394
495
  }
395
496
  }
497
+
498
+ // ============================================
499
+ // DIAGNOSES TAB RENDERING (lite-fix specific)
500
+ // ============================================
501
+
502
+ function renderDiagnosesTab(session) {
503
+ const diagnoses = session.diagnoses;
504
+
505
+ if (!diagnoses || (!diagnoses.manifest && diagnoses.items?.length === 0)) {
506
+ return `
507
+ <div class="tab-empty-state">
508
+ <div class="empty-icon"><i data-lucide="stethoscope" class="w-12 h-12"></i></div>
509
+ <div class="empty-title">No Diagnoses</div>
510
+ <div class="empty-text">No diagnosis-*.json files found for this session.</div>
511
+ </div>
512
+ `;
513
+ }
514
+
515
+ let sections = [];
516
+
517
+ // Manifest summary (if available)
518
+ if (diagnoses.manifest) {
519
+ sections.push(`
520
+ <div class="diagnoses-manifest-section">
521
+ <h4 class="diagnoses-section-title"><i data-lucide="clipboard-check" class="w-4 h-4 inline mr-1"></i> Diagnosis Summary</h4>
522
+ <div class="manifest-meta-grid">
523
+ ${diagnoses.manifest.total_diagnoses ? `<div class="meta-item"><span class="meta-label">Total Diagnoses:</span> ${diagnoses.manifest.total_diagnoses}</div>` : ''}
524
+ ${diagnoses.manifest.diagnosis_angles ? `<div class="meta-item"><span class="meta-label">Angles:</span> ${diagnoses.manifest.diagnosis_angles.join(', ')}</div>` : ''}
525
+ ${diagnoses.manifest.created_at ? `<div class="meta-item"><span class="meta-label">Created:</span> ${formatDate(diagnoses.manifest.created_at)}</div>` : ''}
526
+ </div>
527
+ </div>
528
+ `);
529
+ }
530
+
531
+ // Individual diagnosis items
532
+ if (diagnoses.items && diagnoses.items.length > 0) {
533
+ const diagnosisCards = diagnoses.items.map(diag => renderDiagnosisCard(diag)).join('');
534
+ sections.push(`
535
+ <div class="diagnoses-items-section">
536
+ <h4 class="diagnoses-section-title"><i data-lucide="search" class="w-4 h-4 inline mr-1"></i> Diagnosis Details (${diagnoses.items.length})</h4>
537
+ <div class="diagnoses-grid">
538
+ ${diagnosisCards}
539
+ </div>
540
+ </div>
541
+ `);
542
+ }
543
+
544
+ return `<div class="diagnoses-tab-content">${sections.join('')}</div>`;
545
+ }
546
+
547
+ function renderDiagnosisCard(diag) {
548
+ const diagJsonId = `diag-json-${diag.id}`.replace(/[^a-zA-Z0-9-]/g, '-');
549
+ taskJsonStore[diagJsonId] = diag;
550
+
551
+ return `
552
+ <div class="diagnosis-card collapsible-section">
553
+ <div class="collapsible-header diagnosis-header">
554
+ <span class="collapse-icon">▶</span>
555
+ <span class="diagnosis-id"><i data-lucide="file-search" class="w-4 h-4 inline mr-1"></i>${escapeHtml(diag.id)}</span>
556
+ <button class="btn-view-json" onclick="event.stopPropagation(); showJsonModal('${diagJsonId}', '${escapeHtml(diag.id)}')">{ } JSON</button>
557
+ </div>
558
+ <div class="collapsible-content collapsed">
559
+ ${renderDiagnosisContent(diag)}
560
+ </div>
561
+ </div>
562
+ `;
563
+ }
564
+
565
+ function renderDiagnosisContent(diag) {
566
+ let content = [];
567
+
568
+ // Summary/Overview
569
+ if (diag.summary || diag.overview) {
570
+ content.push(`
571
+ <div class="diag-section">
572
+ <strong>Summary:</strong>
573
+ <p>${escapeHtml(diag.summary || diag.overview)}</p>
574
+ </div>
575
+ `);
576
+ }
577
+
578
+ // Root Cause Analysis
579
+ if (diag.root_cause || diag.root_cause_analysis) {
580
+ content.push(`
581
+ <div class="diag-section">
582
+ <strong>Root Cause:</strong>
583
+ <p>${escapeHtml(diag.root_cause || diag.root_cause_analysis)}</p>
584
+ </div>
585
+ `);
586
+ }
587
+
588
+ // Issues/Findings
589
+ if (diag.issues && Array.isArray(diag.issues)) {
590
+ content.push(`
591
+ <div class="diag-section">
592
+ <strong>Issues Found (${diag.issues.length}):</strong>
593
+ <ul class="issues-list">
594
+ ${diag.issues.map(issue => `
595
+ <li class="issue-item">
596
+ ${typeof issue === 'string' ? escapeHtml(issue) : `
597
+ <div class="issue-title">${escapeHtml(issue.title || issue.description || 'Unknown')}</div>
598
+ ${issue.location ? `<div class="issue-location"><code>${escapeHtml(issue.location)}</code></div>` : ''}
599
+ ${issue.severity ? `<span class="severity-badge ${issue.severity}">${escapeHtml(issue.severity)}</span>` : ''}
600
+ `}
601
+ </li>
602
+ `).join('')}
603
+ </ul>
604
+ </div>
605
+ `);
606
+ }
607
+
608
+ // Affected Files
609
+ if (diag.affected_files && Array.isArray(diag.affected_files)) {
610
+ content.push(`
611
+ <div class="diag-section">
612
+ <strong>Affected Files:</strong>
613
+ <div class="path-tags">
614
+ ${diag.affected_files.map(f => `<span class="path-tag">${escapeHtml(typeof f === 'string' ? f : f.path || f.file)}</span>`).join('')}
615
+ </div>
616
+ </div>
617
+ `);
618
+ }
619
+
620
+ // API Contracts (for api-contracts diagnosis)
621
+ if (diag.contracts && Array.isArray(diag.contracts)) {
622
+ content.push(`
623
+ <div class="diag-section">
624
+ <strong>API Contracts (${diag.contracts.length}):</strong>
625
+ <div class="contracts-list">
626
+ ${diag.contracts.map(contract => `
627
+ <div class="contract-item">
628
+ <div class="contract-header">
629
+ <span class="contract-endpoint">${escapeHtml(contract.endpoint || contract.name || 'Unknown')}</span>
630
+ ${contract.method ? `<span class="contract-method">${escapeHtml(contract.method)}</span>` : ''}
631
+ </div>
632
+ ${contract.description ? `<div class="contract-desc">${escapeHtml(contract.description)}</div>` : ''}
633
+ ${contract.issues?.length ? `<div class="contract-issues">${contract.issues.length} issue(s)</div>` : ''}
634
+ </div>
635
+ `).join('')}
636
+ </div>
637
+ </div>
638
+ `);
639
+ }
640
+
641
+ // Dataflow Analysis (for dataflow diagnosis)
642
+ if (diag.dataflow || diag.data_flow) {
643
+ const df = diag.dataflow || diag.data_flow;
644
+ content.push(`
645
+ <div class="diag-section">
646
+ <strong>Data Flow Analysis:</strong>
647
+ ${typeof df === 'string' ? `<p>${escapeHtml(df)}</p>` : `
648
+ <div class="dataflow-details">
649
+ ${df.source ? `<div class="df-item"><span class="df-label">Source:</span> ${escapeHtml(df.source)}</div>` : ''}
650
+ ${df.sink ? `<div class="df-item"><span class="df-label">Sink:</span> ${escapeHtml(df.sink)}</div>` : ''}
651
+ ${df.transformations?.length ? `
652
+ <div class="df-item">
653
+ <span class="df-label">Transformations:</span>
654
+ <ol class="df-transforms">${df.transformations.map(t => `<li>${escapeHtml(t)}</li>`).join('')}</ol>
655
+ </div>
656
+ ` : ''}
657
+ </div>
658
+ `}
659
+ </div>
660
+ `);
661
+ }
662
+
663
+ // Recommendations
664
+ if (diag.recommendations && Array.isArray(diag.recommendations)) {
665
+ content.push(`
666
+ <div class="diag-section">
667
+ <strong>Recommendations:</strong>
668
+ <ol class="recommendations-list">
669
+ ${diag.recommendations.map(rec => `<li>${escapeHtml(typeof rec === 'string' ? rec : rec.description || rec.action)}</li>`).join('')}
670
+ </ol>
671
+ </div>
672
+ `);
673
+ }
674
+
675
+ // If no specific content was rendered, show raw JSON preview
676
+ if (content.length === 0) {
677
+ content.push(`
678
+ <div class="diag-section">
679
+ <pre class="json-content">${escapeHtml(JSON.stringify(diag, null, 2))}</pre>
680
+ </div>
681
+ `);
682
+ }
683
+
684
+ return content.join('');
685
+ }
package/package.json CHANGED
@@ -1,67 +1,67 @@
1
- {
2
- "name": "claude-code-workflow",
3
- "version": "6.1.3",
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
- },
10
- "scripts": {
11
- "start": "node ccw/bin/ccw.js",
12
- "test": "node --test",
13
- "prepublishOnly": "echo 'Ready to publish @dyw/claude-code-workflow'"
14
- },
15
- "keywords": [
16
- "claude",
17
- "workflow",
18
- "ai",
19
- "cli",
20
- "dashboard",
21
- "code-review",
22
- "automation",
23
- "development"
24
- ],
25
- "author": "dyw",
26
- "license": "MIT",
27
- "engines": {
28
- "node": ">=16.0.0"
29
- },
30
- "dependencies": {
31
- "boxen": "^7.1.0",
32
- "chalk": "^5.3.0",
33
- "commander": "^11.0.0",
34
- "figlet": "^1.7.0",
35
- "glob": "^10.3.0",
36
- "gradient-string": "^2.0.2",
37
- "inquirer": "^9.2.0",
38
- "open": "^9.1.0",
39
- "ora": "^7.0.0"
40
- },
41
- "files": [
42
- "ccw/bin/",
43
- "ccw/src/",
44
- "ccw/package.json",
45
- ".claude/agents/",
46
- ".claude/commands/",
47
- ".claude/output-styles/",
48
- ".claude/workflows/",
49
- ".claude/scripts/",
50
- ".claude/prompt-templates/",
51
- ".claude/python_script/",
52
- ".claude/skills/",
53
- ".codex/",
54
- ".gemini/",
55
- ".qwen/",
56
- "CLAUDE.md",
57
- "README.md"
58
- ],
59
- "repository": {
60
- "type": "git",
61
- "url": "git+https://github.com/catlog22/Claude-Code-Workflow.git"
62
- },
63
- "bugs": {
64
- "url": "https://github.com/catlog22/Claude-Code-Workflow/issues"
65
- },
66
- "homepage": "https://github.com/catlog22/Claude-Code-Workflow#readme"
67
- }
1
+ {
2
+ "name": "claude-code-workflow",
3
+ "version": "6.1.4",
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
+ },
10
+ "scripts": {
11
+ "start": "node ccw/bin/ccw.js",
12
+ "test": "node --test",
13
+ "prepublishOnly": "echo 'Ready to publish @dyw/claude-code-workflow'"
14
+ },
15
+ "keywords": [
16
+ "claude",
17
+ "workflow",
18
+ "ai",
19
+ "cli",
20
+ "dashboard",
21
+ "code-review",
22
+ "automation",
23
+ "development"
24
+ ],
25
+ "author": "dyw",
26
+ "license": "MIT",
27
+ "engines": {
28
+ "node": ">=16.0.0"
29
+ },
30
+ "dependencies": {
31
+ "boxen": "^7.1.0",
32
+ "chalk": "^5.3.0",
33
+ "commander": "^11.0.0",
34
+ "figlet": "^1.7.0",
35
+ "glob": "^10.3.0",
36
+ "gradient-string": "^2.0.2",
37
+ "inquirer": "^9.2.0",
38
+ "open": "^9.1.0",
39
+ "ora": "^7.0.0"
40
+ },
41
+ "files": [
42
+ "ccw/bin/",
43
+ "ccw/src/",
44
+ "ccw/package.json",
45
+ ".claude/agents/",
46
+ ".claude/commands/",
47
+ ".claude/output-styles/",
48
+ ".claude/workflows/",
49
+ ".claude/scripts/",
50
+ ".claude/prompt-templates/",
51
+ ".claude/python_script/",
52
+ ".claude/skills/",
53
+ ".codex/",
54
+ ".gemini/",
55
+ ".qwen/",
56
+ "CLAUDE.md",
57
+ "README.md"
58
+ ],
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "git+https://github.com/catlog22/Claude-Code-Workflow.git"
62
+ },
63
+ "bugs": {
64
+ "url": "https://github.com/catlog22/Claude-Code-Workflow/issues"
65
+ },
66
+ "homepage": "https://github.com/catlog22/Claude-Code-Workflow#readme"
67
+ }