claude-code-workflow 6.3.36 → 6.3.37

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 (134) hide show
  1. package/.claude/commands/workflow/lite-fix.md +108 -9
  2. package/.claude/skills/ccw-loop/README.md +303 -0
  3. package/.claude/skills/ccw-loop/SKILL.md +259 -0
  4. package/.claude/skills/ccw-loop/phases/actions/action-complete.md +320 -0
  5. package/.claude/skills/ccw-loop/phases/actions/action-debug-with-file.md +485 -0
  6. package/.claude/skills/ccw-loop/phases/actions/action-develop-with-file.md +365 -0
  7. package/.claude/skills/ccw-loop/phases/actions/action-init.md +200 -0
  8. package/.claude/skills/ccw-loop/phases/actions/action-menu.md +192 -0
  9. package/.claude/skills/ccw-loop/phases/actions/action-validate-with-file.md +307 -0
  10. package/.claude/skills/ccw-loop/phases/orchestrator.md +486 -0
  11. package/.claude/skills/ccw-loop/phases/state-schema.md +474 -0
  12. package/.claude/skills/ccw-loop/specs/action-catalog.md +300 -0
  13. package/.claude/skills/ccw-loop/specs/loop-requirements.md +192 -0
  14. package/.claude/skills/ccw-loop/templates/progress-template.md +175 -0
  15. package/.claude/skills/ccw-loop/templates/understanding-template.md +303 -0
  16. package/.claude/skills/ccw-loop/templates/validation-template.md +258 -0
  17. package/ccw/dist/cli.d.ts.map +1 -1
  18. package/ccw/dist/cli.js +8 -1
  19. package/ccw/dist/cli.js.map +1 -1
  20. package/ccw/dist/commands/cli.d.ts.map +1 -1
  21. package/ccw/dist/commands/cli.js +14 -1
  22. package/ccw/dist/commands/cli.js.map +1 -1
  23. package/ccw/dist/commands/loop.d.ts +10 -0
  24. package/ccw/dist/commands/loop.d.ts.map +1 -0
  25. package/ccw/dist/commands/loop.js +289 -0
  26. package/ccw/dist/commands/loop.js.map +1 -0
  27. package/ccw/dist/core/dashboard-generator.d.ts.map +1 -1
  28. package/ccw/dist/core/dashboard-generator.js +4 -1
  29. package/ccw/dist/core/dashboard-generator.js.map +1 -1
  30. package/ccw/dist/core/routes/claude-routes.d.ts.map +1 -1
  31. package/ccw/dist/core/routes/claude-routes.js +5 -3
  32. package/ccw/dist/core/routes/claude-routes.js.map +1 -1
  33. package/ccw/dist/core/routes/cli-routes.d.ts +6 -0
  34. package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
  35. package/ccw/dist/core/routes/cli-routes.js +42 -13
  36. package/ccw/dist/core/routes/cli-routes.js.map +1 -1
  37. package/ccw/dist/core/routes/cli-settings-routes.d.ts.map +1 -1
  38. package/ccw/dist/core/routes/cli-settings-routes.js +44 -0
  39. package/ccw/dist/core/routes/cli-settings-routes.js.map +1 -1
  40. package/ccw/dist/core/routes/codexlens/semantic-handlers.d.ts.map +1 -1
  41. package/ccw/dist/core/routes/codexlens/semantic-handlers.js +3 -2
  42. package/ccw/dist/core/routes/codexlens/semantic-handlers.js.map +1 -1
  43. package/ccw/dist/core/routes/core-memory-routes.d.ts.map +1 -1
  44. package/ccw/dist/core/routes/core-memory-routes.js +4 -2
  45. package/ccw/dist/core/routes/core-memory-routes.js.map +1 -1
  46. package/ccw/dist/core/routes/files-routes.d.ts.map +1 -1
  47. package/ccw/dist/core/routes/files-routes.js +4 -2
  48. package/ccw/dist/core/routes/files-routes.js.map +1 -1
  49. package/ccw/dist/core/routes/loop-routes.d.ts +24 -0
  50. package/ccw/dist/core/routes/loop-routes.d.ts.map +1 -0
  51. package/ccw/dist/core/routes/loop-routes.js +334 -0
  52. package/ccw/dist/core/routes/loop-routes.js.map +1 -0
  53. package/ccw/dist/core/routes/loop-v2-routes.d.ts +35 -0
  54. package/ccw/dist/core/routes/loop-v2-routes.d.ts.map +1 -0
  55. package/ccw/dist/core/routes/loop-v2-routes.js +1208 -0
  56. package/ccw/dist/core/routes/loop-v2-routes.js.map +1 -0
  57. package/ccw/dist/core/routes/memory-routes.d.ts.map +1 -1
  58. package/ccw/dist/core/routes/memory-routes.js +2 -1
  59. package/ccw/dist/core/routes/memory-routes.js.map +1 -1
  60. package/ccw/dist/core/routes/task-routes.d.ts +12 -0
  61. package/ccw/dist/core/routes/task-routes.d.ts.map +1 -0
  62. package/ccw/dist/core/routes/task-routes.js +321 -0
  63. package/ccw/dist/core/routes/task-routes.js.map +1 -0
  64. package/ccw/dist/core/routes/test-loop-routes.d.ts +11 -0
  65. package/ccw/dist/core/routes/test-loop-routes.d.ts.map +1 -0
  66. package/ccw/dist/core/routes/test-loop-routes.js +298 -0
  67. package/ccw/dist/core/routes/test-loop-routes.js.map +1 -0
  68. package/ccw/dist/core/server.d.ts.map +1 -1
  69. package/ccw/dist/core/server.js +43 -3
  70. package/ccw/dist/core/server.js.map +1 -1
  71. package/ccw/dist/core/websocket.d.ts +59 -0
  72. package/ccw/dist/core/websocket.d.ts.map +1 -1
  73. package/ccw/dist/core/websocket.js +34 -0
  74. package/ccw/dist/core/websocket.js.map +1 -1
  75. package/ccw/dist/tools/claude-cli-tools.d.ts +40 -0
  76. package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -1
  77. package/ccw/dist/tools/claude-cli-tools.js +119 -0
  78. package/ccw/dist/tools/claude-cli-tools.js.map +1 -1
  79. package/ccw/dist/tools/loop-manager.d.ts +84 -0
  80. package/ccw/dist/tools/loop-manager.d.ts.map +1 -0
  81. package/ccw/dist/tools/loop-manager.js +425 -0
  82. package/ccw/dist/tools/loop-manager.js.map +1 -0
  83. package/ccw/dist/tools/loop-state-manager.d.ts +47 -0
  84. package/ccw/dist/tools/loop-state-manager.d.ts.map +1 -0
  85. package/ccw/dist/tools/loop-state-manager.js +149 -0
  86. package/ccw/dist/tools/loop-state-manager.js.map +1 -0
  87. package/ccw/dist/tools/loop-task-manager.d.ts +138 -0
  88. package/ccw/dist/tools/loop-task-manager.d.ts.map +1 -0
  89. package/ccw/dist/tools/loop-task-manager.js +270 -0
  90. package/ccw/dist/tools/loop-task-manager.js.map +1 -0
  91. package/ccw/dist/types/index.d.ts +1 -0
  92. package/ccw/dist/types/index.d.ts.map +1 -1
  93. package/ccw/dist/types/index.js +1 -0
  94. package/ccw/dist/types/index.js.map +1 -1
  95. package/ccw/dist/types/loop.d.ts +257 -0
  96. package/ccw/dist/types/loop.d.ts.map +1 -0
  97. package/ccw/dist/types/loop.js +17 -0
  98. package/ccw/dist/types/loop.js.map +1 -0
  99. package/ccw/src/cli.ts +9 -1
  100. package/ccw/src/commands/cli.ts +14 -1
  101. package/ccw/src/commands/loop.ts +344 -0
  102. package/ccw/src/core/dashboard-generator.ts +4 -1
  103. package/ccw/src/core/routes/claude-routes.ts +5 -3
  104. package/ccw/src/core/routes/cli-routes.ts +47 -15
  105. package/ccw/src/core/routes/cli-settings-routes.ts +47 -0
  106. package/ccw/src/core/routes/codexlens/semantic-handlers.ts +3 -2
  107. package/ccw/src/core/routes/core-memory-routes.ts +4 -2
  108. package/ccw/src/core/routes/files-routes.ts +4 -2
  109. package/ccw/src/core/routes/loop-routes.ts +386 -0
  110. package/ccw/src/core/routes/loop-v2-routes.ts +1412 -0
  111. package/ccw/src/core/routes/memory-routes.ts +2 -1
  112. package/ccw/src/core/routes/task-routes.ts +361 -0
  113. package/ccw/src/core/routes/test-loop-routes.ts +312 -0
  114. package/ccw/src/core/server.ts +44 -3
  115. package/ccw/src/core/websocket.ts +104 -0
  116. package/ccw/src/templates/dashboard-css/12-cli-legacy.css +56 -0
  117. package/ccw/src/templates/dashboard-css/33-cli-stream-viewer.css +55 -0
  118. package/ccw/src/templates/dashboard-css/36-loop-monitor.css +1896 -0
  119. package/ccw/src/templates/dashboard-css/36-loop-monitor.css.backup +1877 -0
  120. package/ccw/src/templates/dashboard-js/components/cli-status.js +64 -3
  121. package/ccw/src/templates/dashboard-js/components/cli-stream-viewer.js +251 -110
  122. package/ccw/src/templates/dashboard-js/components/navigation.js +10 -0
  123. package/ccw/src/templates/dashboard-js/components/notifications.js +16 -0
  124. package/ccw/src/templates/dashboard-js/i18n.js +475 -1
  125. package/ccw/src/templates/dashboard-js/views/cli-manager.js +3 -2
  126. package/ccw/src/templates/dashboard-js/views/loop-monitor.js +3244 -0
  127. package/ccw/src/templates/dashboard.html +20 -2
  128. package/ccw/src/tools/claude-cli-tools.ts +143 -0
  129. package/ccw/src/tools/loop-manager.ts +519 -0
  130. package/ccw/src/tools/loop-state-manager.ts +173 -0
  131. package/ccw/src/tools/loop-task-manager.ts +380 -0
  132. package/ccw/src/types/index.ts +1 -0
  133. package/ccw/src/types/loop.ts +316 -0
  134. package/package.json +1 -1
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Loop System Type Definitions
3
+ * CCW Loop System - JSON-based state management for multi-CLI orchestration
4
+ * Reference: .workflow/.scratchpad/loop-system-complete-design-20260121.md
5
+ */
6
+ /**
7
+ * Loop status enumeration
8
+ */
9
+ export declare enum LoopStatus {
10
+ CREATED = "created",
11
+ RUNNING = "running",
12
+ PAUSED = "paused",
13
+ COMPLETED = "completed",
14
+ FAILED = "failed"
15
+ }
16
+ /**
17
+ * CLI step configuration
18
+ * Defines a single step in the CLI execution sequence
19
+ */
20
+ export interface CliStepConfig {
21
+ /** Step unique identifier */
22
+ step_id: string;
23
+ /** CLI tool name */
24
+ tool: 'bash' | 'gemini' | 'codex' | 'qwen' | string;
25
+ /** Execution mode (for gemini/codex/claude) */
26
+ mode?: 'analysis' | 'write' | 'review';
27
+ /** Bash command (when tool='bash') */
28
+ command?: string;
29
+ /** Prompt template with variable replacement support */
30
+ prompt_template?: string;
31
+ /** Step failure behavior */
32
+ on_error?: 'continue' | 'pause' | 'fail_fast';
33
+ /** Custom parameters */
34
+ custom_args?: Record<string, unknown>;
35
+ }
36
+ /**
37
+ * Error policy configuration
38
+ */
39
+ export interface ErrorPolicy {
40
+ /** Failure behavior */
41
+ on_failure: 'pause' | 'retry' | 'fail_fast';
42
+ /** Retry count */
43
+ retry_count: number;
44
+ /** Maximum retries (optional) */
45
+ max_retries?: number;
46
+ }
47
+ /**
48
+ * Loop state - complete definition
49
+ * Single source of truth stored in loop-state.json
50
+ */
51
+ export interface LoopState {
52
+ /** Loop unique identifier */
53
+ loop_id: string;
54
+ /** Associated task ID */
55
+ task_id: string;
56
+ /** Current status */
57
+ status: LoopStatus;
58
+ /** Current iteration (1-indexed) */
59
+ current_iteration: number;
60
+ /** Maximum iterations */
61
+ max_iterations: number;
62
+ /** Current CLI step index (0-indexed) */
63
+ current_cli_step: number;
64
+ /** CLI execution sequence */
65
+ cli_sequence: CliStepConfig[];
66
+ /**
67
+ * Session mapping table
68
+ * Key format: {tool}_{step_index}
69
+ * Value: conversation_id or execution_id
70
+ */
71
+ session_mapping: Record<string, string>;
72
+ /**
73
+ * State variables
74
+ * Key format: {step_id}_{stdout|stderr}
75
+ * Value: corresponding output content
76
+ */
77
+ state_variables: Record<string, string>;
78
+ /** Success condition expression (JavaScript) */
79
+ success_condition?: string;
80
+ /** Error policy */
81
+ error_policy: ErrorPolicy;
82
+ /** Creation timestamp */
83
+ created_at: string;
84
+ /** Last update timestamp */
85
+ updated_at: string;
86
+ /** Completion timestamp (if applicable) */
87
+ completed_at?: string;
88
+ /** Failure reason (if applicable) */
89
+ failure_reason?: string;
90
+ /** Execution history (optional) */
91
+ execution_history?: ExecutionRecord[];
92
+ }
93
+ /**
94
+ * Execution record for history tracking
95
+ */
96
+ export interface ExecutionRecord {
97
+ iteration: number;
98
+ step_index: number;
99
+ step_id: string;
100
+ tool: string;
101
+ conversation_id: string;
102
+ exit_code: number;
103
+ duration_ms: number;
104
+ timestamp: string;
105
+ }
106
+ /**
107
+ * Skill State - Extension fields managed by ccw-loop skill
108
+ * Stored in .workflow/.loop/{loopId}.json alongside API fields
109
+ */
110
+ export interface SkillState {
111
+ /** Current action being executed */
112
+ current_action: 'init' | 'develop' | 'debug' | 'validate' | 'complete' | null;
113
+ /** Last completed action */
114
+ last_action: string | null;
115
+ /** List of completed action names */
116
+ completed_actions: string[];
117
+ /** Execution mode */
118
+ mode: 'interactive' | 'auto';
119
+ /** Development phase state */
120
+ develop: {
121
+ total: number;
122
+ completed: number;
123
+ current_task?: string;
124
+ tasks: DevelopTask[];
125
+ last_progress_at: string | null;
126
+ };
127
+ /** Debug phase state */
128
+ debug: {
129
+ active_bug?: string;
130
+ hypotheses_count: number;
131
+ hypotheses: Hypothesis[];
132
+ confirmed_hypothesis: string | null;
133
+ iteration: number;
134
+ last_analysis_at: string | null;
135
+ };
136
+ /** Validation phase state */
137
+ validate: {
138
+ pass_rate: number;
139
+ coverage: number;
140
+ test_results: TestResult[];
141
+ passed: boolean;
142
+ failed_tests: string[];
143
+ last_run_at: string | null;
144
+ };
145
+ /** Error tracking */
146
+ errors: Array<{
147
+ action: string;
148
+ message: string;
149
+ timestamp: string;
150
+ }>;
151
+ }
152
+ /**
153
+ * Development task
154
+ */
155
+ export interface DevelopTask {
156
+ id: string;
157
+ description: string;
158
+ tool: 'gemini' | 'qwen' | 'codex' | 'bash';
159
+ mode: 'analysis' | 'write';
160
+ status: 'pending' | 'in_progress' | 'completed' | 'failed';
161
+ files_changed?: string[];
162
+ created_at: string;
163
+ completed_at?: string;
164
+ }
165
+ /**
166
+ * Debug hypothesis
167
+ */
168
+ export interface Hypothesis {
169
+ id: string;
170
+ description: string;
171
+ testable_condition: string;
172
+ logging_point: string;
173
+ evidence_criteria: {
174
+ confirm: string;
175
+ reject: string;
176
+ };
177
+ likelihood: number;
178
+ status: 'pending' | 'confirmed' | 'rejected' | 'inconclusive';
179
+ evidence?: Record<string, unknown>;
180
+ verdict_reason?: string;
181
+ }
182
+ /**
183
+ * Test result
184
+ */
185
+ export interface TestResult {
186
+ test_name: string;
187
+ suite: string;
188
+ status: 'passed' | 'failed' | 'skipped';
189
+ duration_ms: number;
190
+ error_message?: string;
191
+ stack_trace?: string;
192
+ }
193
+ /**
194
+ * V2 Loop Storage Format (simplified, for Dashboard API)
195
+ * This is the unified state structure used by both API and ccw-loop skill
196
+ */
197
+ export interface V2LoopState {
198
+ loop_id: string;
199
+ title: string;
200
+ description: string;
201
+ max_iterations: number;
202
+ status: LoopStatus;
203
+ current_iteration: number;
204
+ created_at: string;
205
+ updated_at: string;
206
+ completed_at?: string;
207
+ failure_reason?: string;
208
+ skill_state?: SkillState;
209
+ }
210
+ /**
211
+ * Task Loop control configuration
212
+ * Extension to Task JSON schema
213
+ */
214
+ export interface TaskLoopControl {
215
+ /** Enable loop */
216
+ enabled: boolean;
217
+ /** Loop description */
218
+ description: string;
219
+ /** Maximum iterations */
220
+ max_iterations: number;
221
+ /** Success condition (JavaScript expression) */
222
+ success_condition: string;
223
+ /** Error policy */
224
+ error_policy: {
225
+ on_failure: 'pause' | 'retry' | 'fail_fast';
226
+ max_retries?: number;
227
+ };
228
+ /** CLI execution sequence */
229
+ cli_sequence: CliStepConfig[];
230
+ }
231
+ /**
232
+ * Minimal Task interface for loop operations
233
+ * Compatible with task JSON schema
234
+ */
235
+ export interface Task {
236
+ /** Task ID */
237
+ id: string;
238
+ /** Task title */
239
+ title?: string;
240
+ /** Task description */
241
+ description?: string;
242
+ /** Task status */
243
+ status?: string;
244
+ /** Task metadata */
245
+ meta?: {
246
+ type?: string;
247
+ created_by?: string;
248
+ };
249
+ /** Task context */
250
+ context?: {
251
+ requirements?: string[];
252
+ acceptance?: string[];
253
+ };
254
+ /** Loop control configuration */
255
+ loop_control?: TaskLoopControl;
256
+ }
257
+ //# sourceMappingURL=loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/types/loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Loop System Type Definitions
3
+ * CCW Loop System - JSON-based state management for multi-CLI orchestration
4
+ * Reference: .workflow/.scratchpad/loop-system-complete-design-20260121.md
5
+ */
6
+ /**
7
+ * Loop status enumeration
8
+ */
9
+ export var LoopStatus;
10
+ (function (LoopStatus) {
11
+ LoopStatus["CREATED"] = "created";
12
+ LoopStatus["RUNNING"] = "running";
13
+ LoopStatus["PAUSED"] = "paused";
14
+ LoopStatus["COMPLETED"] = "completed";
15
+ LoopStatus["FAILED"] = "failed";
16
+ })(LoopStatus || (LoopStatus = {}));
17
+ //# sourceMappingURL=loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/types/loop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,CAAN,IAAY,UAMX;AAND,WAAY,UAAU;IACpB,iCAAmB,CAAA;IACnB,iCAAmB,CAAA;IACnB,+BAAiB,CAAA;IACjB,qCAAuB,CAAA;IACvB,+BAAiB,CAAA;AACnB,CAAC,EANW,UAAU,KAAV,UAAU,QAMrB"}
package/ccw/src/cli.ts CHANGED
@@ -14,6 +14,7 @@ import { coreMemoryCommand } from './commands/core-memory.js';
14
14
  import { hookCommand } from './commands/hook.js';
15
15
  import { issueCommand } from './commands/issue.js';
16
16
  import { workflowCommand } from './commands/workflow.js';
17
+ import { loopCommand } from './commands/loop.js';
17
18
  import { readFileSync, existsSync } from 'fs';
18
19
  import { fileURLToPath } from 'url';
19
20
  import { dirname, join } from 'path';
@@ -172,7 +173,7 @@ export function run(argv: string[]): void {
172
173
  .description('Unified CLI tool executor (gemini/qwen/codex/claude)')
173
174
  .option('-p, --prompt <prompt>', 'Prompt text (alternative to positional argument)')
174
175
  .option('-f, --file <file>', 'Read prompt from file (best for multi-line prompts)')
175
- .option('--tool <tool>', 'CLI tool to use', 'gemini')
176
+ .option('--tool <tool>', 'CLI tool to use (reads from cli-settings.json defaultTool if not specified)')
176
177
  .option('--mode <mode>', 'Execution mode: analysis, write, auto', 'analysis')
177
178
  .option('-d, --debug', 'Enable debug logging for troubleshooting')
178
179
  .option('--model <model>', 'Model override')
@@ -301,6 +302,13 @@ export function run(argv: string[]): void {
301
302
  .option('--queue <queue-id>', 'Target queue ID for multi-queue operations')
302
303
  .action((subcommand, args, options) => issueCommand(subcommand, args, options));
303
304
 
305
+ // Loop command - Loop management for multi-CLI orchestration
306
+ program
307
+ .command('loop [subcommand] [args...]')
308
+ .description('Loop management for automated multi-CLI execution')
309
+ .option('--session <name>', 'Specify workflow session')
310
+ .action((subcommand, args, options) => loopCommand(subcommand, args, options));
311
+
304
312
  // Workflow command - Workflow installation and management
305
313
  program
306
314
  .command('workflow [subcommand] [args...]')
@@ -30,6 +30,7 @@ import {
30
30
  } from '../tools/storage-manager.js';
31
31
  import { getHistoryStore } from '../tools/cli-history-store.js';
32
32
  import { createSpinner } from '../utils/ui.js';
33
+ import { loadClaudeCliSettings } from '../tools/claude-cli-tools.js';
33
34
 
34
35
  // Dashboard notification settings
35
36
  const DASHBOARD_PORT = process.env.CCW_PORT || 3456;
@@ -548,7 +549,19 @@ async function statusAction(debug?: boolean): Promise<void> {
548
549
  * @param {Object} options - CLI options
549
550
  */
550
551
  async function execAction(positionalPrompt: string | undefined, options: CliExecOptions): Promise<void> {
551
- const { prompt: optionPrompt, file, tool = 'gemini', mode = 'analysis', model, cd, includeDirs, stream, resume, id, noNative, cache, injectMode, debug, uncommitted, base, commit, title, rule } = options;
552
+ const { prompt: optionPrompt, file, tool: userTool, mode = 'analysis', model, cd, includeDirs, stream, resume, id, noNative, cache, injectMode, debug, uncommitted, base, commit, title, rule } = options;
553
+
554
+ // Determine the tool to use: explicit --tool option, or defaultTool from config
555
+ let tool = userTool;
556
+ if (!tool) {
557
+ try {
558
+ const settings = loadClaudeCliSettings(cd || process.cwd());
559
+ tool = settings.defaultTool || 'gemini';
560
+ } catch {
561
+ // Fallback to gemini if config cannot be loaded
562
+ tool = 'gemini';
563
+ }
564
+ }
552
565
 
553
566
  // Enable debug mode if --debug flag is set
554
567
  if (debug) {
@@ -0,0 +1,344 @@
1
+ /**
2
+ * Loop Command
3
+ * CCW Loop System - CLI interface for loop management
4
+ * Reference: .workflow/.scratchpad/loop-system-complete-design-20260121.md section 4.3
5
+ */
6
+
7
+ import chalk from 'chalk';
8
+ import { readFile } from 'fs/promises';
9
+ import { join, resolve } from 'path';
10
+ import { existsSync } from 'fs';
11
+ import { LoopManager } from '../tools/loop-manager.js';
12
+ import type { TaskLoopControl } from '../types/loop.js';
13
+
14
+ // Minimal Task interface for task config files
15
+ interface Task {
16
+ id: string;
17
+ title?: string;
18
+ loop_control?: TaskLoopControl;
19
+ }
20
+
21
+ /**
22
+ * Read task configuration
23
+ */
24
+ async function readTaskConfig(taskId: string, workflowDir: string): Promise<Task> {
25
+ const taskFile = join(workflowDir, '.task', `${taskId}.json`);
26
+
27
+ if (!existsSync(taskFile)) {
28
+ throw new Error(`Task file not found: ${taskFile}`);
29
+ }
30
+
31
+ const content = await readFile(taskFile, 'utf-8');
32
+ return JSON.parse(content) as Task;
33
+ }
34
+
35
+ /**
36
+ * Find active workflow session
37
+ */
38
+ function findActiveSession(cwd: string): string | null {
39
+ const workflowDir = join(cwd, '.workflow', 'active');
40
+
41
+ if (!existsSync(workflowDir)) {
42
+ return null;
43
+ }
44
+
45
+ const { readdirSync } = require('fs');
46
+ const sessions = readdirSync(workflowDir).filter((d: string) => d.startsWith('WFS-'));
47
+
48
+ if (sessions.length === 0) {
49
+ return null;
50
+ }
51
+
52
+ if (sessions.length === 1) {
53
+ return join(cwd, '.workflow', 'active', sessions[0]);
54
+ }
55
+
56
+ // Multiple sessions, require user to specify
57
+ console.error(chalk.red('\n Error: Multiple active sessions found:'));
58
+ sessions.forEach((s: string) => console.error(chalk.gray(` - ${s}`)));
59
+ console.error(chalk.yellow('\n Please specify session with --session <name>\n'));
60
+ return null;
61
+ }
62
+
63
+ /**
64
+ * Get status badge with color
65
+ */
66
+ function getStatusBadge(status: string): string {
67
+ switch (status) {
68
+ case 'created':
69
+ return chalk.gray('○ created');
70
+ case 'running':
71
+ return chalk.cyan('● running');
72
+ case 'paused':
73
+ return chalk.yellow('⏸ paused');
74
+ case 'completed':
75
+ return chalk.green('✓ completed');
76
+ case 'failed':
77
+ return chalk.red('✗ failed');
78
+ default:
79
+ return status;
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Format time ago
85
+ */
86
+ function timeAgo(timestamp: string): string {
87
+ const now = Date.now();
88
+ const then = new Date(timestamp).getTime();
89
+ const diff = Math.floor((now - then) / 1000);
90
+
91
+ if (diff < 60) return `${diff}s ago`;
92
+ if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
93
+ if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;
94
+ return `${Math.floor(diff / 86400)}d ago`;
95
+ }
96
+
97
+ /**
98
+ * Start action
99
+ */
100
+ async function startAction(taskId: string, options: { session?: string }): Promise<void> {
101
+ const currentCwd = process.cwd();
102
+
103
+ // Find workflow session
104
+ let sessionDir: string | null;
105
+
106
+ if (options.session) {
107
+ sessionDir = join(currentCwd, '.workflow', 'active', options.session);
108
+ if (!existsSync(sessionDir)) {
109
+ console.error(chalk.red(`\n Error: Session not found: ${options.session}\n`));
110
+ process.exit(1);
111
+ }
112
+ } else {
113
+ sessionDir = findActiveSession(currentCwd);
114
+ if (!sessionDir) {
115
+ console.error(chalk.red('\n Error: No active workflow session found.'));
116
+ console.error(chalk.gray(' Run "ccw workflow:plan" first to create a session.\n'));
117
+ process.exit(1);
118
+ }
119
+ }
120
+
121
+ console.log(chalk.cyan(` Using session: ${sessionDir.split(/[\\/]/).pop()}`));
122
+
123
+ // Read task config
124
+ const task = await readTaskConfig(taskId, sessionDir);
125
+
126
+ if (!task.loop_control?.enabled) {
127
+ console.error(chalk.red(`\n Error: Task ${taskId} does not have loop enabled.\n`));
128
+ process.exit(1);
129
+ }
130
+
131
+ // Start loop
132
+ const loopManager = new LoopManager(sessionDir);
133
+ const loopId = await loopManager.startLoop(task as any); // Task interface compatible
134
+
135
+ console.log(chalk.green(`\n ✓ Loop started: ${loopId}`));
136
+ console.log(chalk.dim(` Status: ccw loop status ${loopId}`));
137
+ console.log(chalk.dim(` Pause: ccw loop pause ${loopId}`));
138
+ console.log(chalk.dim(` Stop: ccw loop stop ${loopId}\n`));
139
+ }
140
+
141
+ /**
142
+ * Status action
143
+ */
144
+ async function statusAction(loopId: string | undefined, options: { session?: string }): Promise<void> {
145
+ const currentCwd = process.cwd();
146
+ const sessionDir = options?.session
147
+ ? join(currentCwd, '.workflow', 'active', options.session)
148
+ : findActiveSession(currentCwd);
149
+
150
+ if (!sessionDir) {
151
+ console.error(chalk.red('\n Error: No active session found.\n'));
152
+ process.exit(1);
153
+ }
154
+
155
+ const loopManager = new LoopManager(sessionDir);
156
+
157
+ if (loopId) {
158
+ // Show single loop detail
159
+ const state = await loopManager.getStatus(loopId);
160
+
161
+ console.log(chalk.bold.cyan('\n Loop Status\n'));
162
+ console.log(` ${chalk.gray('ID:')} ${state.loop_id}`);
163
+ console.log(` ${chalk.gray('Task:')} ${state.task_id}`);
164
+ console.log(` ${chalk.gray('Status:')} ${getStatusBadge(state.status)}`);
165
+ console.log(` ${chalk.gray('Iteration:')} ${state.current_iteration}/${state.max_iterations}`);
166
+ console.log(` ${chalk.gray('Step:')} ${state.current_cli_step + 1}/${state.cli_sequence.length}`);
167
+ console.log(` ${chalk.gray('Created:')} ${state.created_at}`);
168
+ console.log(` ${chalk.gray('Updated:')} ${state.updated_at}`);
169
+
170
+ if (state.failure_reason) {
171
+ console.log(` ${chalk.gray('Reason:')} ${chalk.red(state.failure_reason)}`);
172
+ }
173
+
174
+ console.log(chalk.bold.cyan('\n CLI Sequence\n'));
175
+ state.cli_sequence.forEach((step, i) => {
176
+ const current = i === state.current_cli_step ? chalk.cyan('→') : ' ';
177
+ console.log(` ${current} ${i + 1}. ${chalk.bold(step.step_id)} (${step.tool})`);
178
+ });
179
+
180
+ if (state.execution_history && state.execution_history.length > 0) {
181
+ console.log(chalk.bold.cyan('\n Recent Executions\n'));
182
+ const recent = state.execution_history.slice(-5);
183
+ recent.forEach(exec => {
184
+ const status = exec.exit_code === 0 ? chalk.green('✓') : chalk.red('✗');
185
+ console.log(` ${status} ${exec.step_id} (${exec.tool}) - ${(exec.duration_ms / 1000).toFixed(1)}s`);
186
+ });
187
+ }
188
+
189
+ console.log();
190
+ } else {
191
+ // List all loops
192
+ const loops = await loopManager.listLoops();
193
+
194
+ if (loops.length === 0) {
195
+ console.log(chalk.yellow('\n No loops found.\n'));
196
+ return;
197
+ }
198
+
199
+ console.log(chalk.bold.cyan('\n Active Loops\n'));
200
+ console.log(chalk.gray(' Status ID Iteration Task'));
201
+ console.log(chalk.gray(' ' + '─'.repeat(70)));
202
+
203
+ loops.forEach(loop => {
204
+ const status = getStatusBadge(loop.status);
205
+ const iteration = `${loop.current_iteration}/${loop.max_iterations}`;
206
+ console.log(` ${status} ${chalk.dim(loop.loop_id.padEnd(35))} ${iteration.padEnd(9)} ${loop.task_id}`);
207
+ });
208
+
209
+ console.log();
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Pause action
215
+ */
216
+ async function pauseAction(loopId: string, options: { session?: string }): Promise<void> {
217
+ const currentCwd = process.cwd();
218
+ const sessionDir = options.session
219
+ ? join(currentCwd, '.workflow', 'active', options.session)
220
+ : findActiveSession(currentCwd);
221
+
222
+ if (!sessionDir) {
223
+ console.error(chalk.red('\n Error: No active session found.\n'));
224
+ process.exit(1);
225
+ }
226
+
227
+ const loopManager = new LoopManager(sessionDir);
228
+ await loopManager.pauseLoop(loopId);
229
+ }
230
+
231
+ /**
232
+ * Resume action
233
+ */
234
+ async function resumeAction(loopId: string, options: { session?: string }): Promise<void> {
235
+ const currentCwd = process.cwd();
236
+ const sessionDir = options.session
237
+ ? join(currentCwd, '.workflow', 'active', options.session)
238
+ : findActiveSession(currentCwd);
239
+
240
+ if (!sessionDir) {
241
+ console.error(chalk.red('\n Error: No active session found.\n'));
242
+ process.exit(1);
243
+ }
244
+
245
+ const loopManager = new LoopManager(sessionDir);
246
+ await loopManager.resumeLoop(loopId);
247
+ }
248
+
249
+ /**
250
+ * Stop action
251
+ */
252
+ async function stopAction(loopId: string, options: { session?: string }): Promise<void> {
253
+ const currentCwd = process.cwd();
254
+ const sessionDir = options.session
255
+ ? join(currentCwd, '.workflow', 'active', options.session)
256
+ : findActiveSession(currentCwd);
257
+
258
+ if (!sessionDir) {
259
+ console.error(chalk.red('\n Error: No active session found.\n'));
260
+ process.exit(1);
261
+ }
262
+
263
+ const loopManager = new LoopManager(sessionDir);
264
+ await loopManager.stopLoop(loopId);
265
+ }
266
+
267
+ /**
268
+ * Loop command entry point
269
+ */
270
+ export async function loopCommand(
271
+ subcommand: string,
272
+ args: string | string[],
273
+ options: any
274
+ ): Promise<void> {
275
+ const argsArray = Array.isArray(args) ? args : (args ? [args] : []);
276
+
277
+ try {
278
+ switch (subcommand) {
279
+ case 'start':
280
+ if (!argsArray[0]) {
281
+ console.error(chalk.red('\n Error: Task ID is required\n'));
282
+ console.error(chalk.gray(' Usage: ccw loop start <task-id> [--session <name>]\n'));
283
+ process.exit(1);
284
+ }
285
+ await startAction(argsArray[0], options);
286
+ break;
287
+
288
+ case 'status':
289
+ await statusAction(argsArray[0], options);
290
+ break;
291
+
292
+ case 'pause':
293
+ if (!argsArray[0]) {
294
+ console.error(chalk.red('\n Error: Loop ID is required\n'));
295
+ console.error(chalk.gray(' Usage: ccw loop pause <loop-id>\n'));
296
+ process.exit(1);
297
+ }
298
+ await pauseAction(argsArray[0], options);
299
+ break;
300
+
301
+ case 'resume':
302
+ if (!argsArray[0]) {
303
+ console.error(chalk.red('\n Error: Loop ID is required\n'));
304
+ console.error(chalk.gray(' Usage: ccw loop resume <loop-id>\n'));
305
+ process.exit(1);
306
+ }
307
+ await resumeAction(argsArray[0], options);
308
+ break;
309
+
310
+ case 'stop':
311
+ if (!argsArray[0]) {
312
+ console.error(chalk.red('\n Error: Loop ID is required\n'));
313
+ console.error(chalk.gray(' Usage: ccw loop stop <loop-id>\n'));
314
+ process.exit(1);
315
+ }
316
+ await stopAction(argsArray[0], options);
317
+ break;
318
+
319
+ default:
320
+ // Show help
321
+ console.log(chalk.bold.cyan('\n CCW Loop System\n'));
322
+ console.log(' Manage automated CLI execution loops\n');
323
+ console.log(' Subcommands:');
324
+ console.log(chalk.gray(' start <task-id> Start a new loop from task configuration'));
325
+ console.log(chalk.gray(' status [loop-id] Show loop status (all or specific)'));
326
+ console.log(chalk.gray(' pause <loop-id> Pause a running loop'));
327
+ console.log(chalk.gray(' resume <loop-id> Resume a paused loop'));
328
+ console.log(chalk.gray(' stop <loop-id> Stop a loop'));
329
+ console.log();
330
+ console.log(' Options:');
331
+ console.log(chalk.gray(' --session <name> Specify workflow session'));
332
+ console.log();
333
+ console.log(' Examples:');
334
+ console.log(chalk.gray(' ccw loop start IMPL-3'));
335
+ console.log(chalk.gray(' ccw loop status'));
336
+ console.log(chalk.gray(' ccw loop status loop-IMPL-3-20260121120000'));
337
+ console.log(chalk.gray(' ccw loop pause loop-IMPL-3-20260121120000'));
338
+ console.log();
339
+ }
340
+ } catch (error) {
341
+ console.error(chalk.red(`\n ✗ Error: ${error instanceof Error ? error.message : error}\n`));
342
+ process.exit(1);
343
+ }
344
+ }