@litmers/cursorflow-orchestrator 0.1.20 → 0.1.28
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.
- package/CHANGELOG.md +20 -0
- package/commands/cursorflow-clean.md +19 -0
- package/commands/cursorflow-runs.md +59 -0
- package/commands/cursorflow-stop.md +55 -0
- package/dist/cli/clean.js +171 -0
- package/dist/cli/clean.js.map +1 -1
- package/dist/cli/index.js +7 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.js +1 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/logs.js +83 -42
- package/dist/cli/logs.js.map +1 -1
- package/dist/cli/monitor.d.ts +7 -0
- package/dist/cli/monitor.js +1007 -189
- package/dist/cli/monitor.js.map +1 -1
- package/dist/cli/prepare.js +87 -3
- package/dist/cli/prepare.js.map +1 -1
- package/dist/cli/resume.js +188 -236
- package/dist/cli/resume.js.map +1 -1
- package/dist/cli/run.js +125 -3
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/runs.d.ts +5 -0
- package/dist/cli/runs.js +214 -0
- package/dist/cli/runs.js.map +1 -0
- package/dist/cli/setup-commands.js +0 -0
- package/dist/cli/signal.js +1 -1
- package/dist/cli/signal.js.map +1 -1
- package/dist/cli/stop.d.ts +5 -0
- package/dist/cli/stop.js +215 -0
- package/dist/cli/stop.js.map +1 -0
- package/dist/cli/tasks.d.ts +10 -0
- package/dist/cli/tasks.js +165 -0
- package/dist/cli/tasks.js.map +1 -0
- package/dist/core/auto-recovery.d.ts +212 -0
- package/dist/core/auto-recovery.js +737 -0
- package/dist/core/auto-recovery.js.map +1 -0
- package/dist/core/failure-policy.d.ts +156 -0
- package/dist/core/failure-policy.js +488 -0
- package/dist/core/failure-policy.js.map +1 -0
- package/dist/core/orchestrator.d.ts +15 -2
- package/dist/core/orchestrator.js +397 -15
- package/dist/core/orchestrator.js.map +1 -1
- package/dist/core/reviewer.d.ts +2 -0
- package/dist/core/reviewer.js +2 -0
- package/dist/core/reviewer.js.map +1 -1
- package/dist/core/runner.d.ts +33 -10
- package/dist/core/runner.js +321 -146
- package/dist/core/runner.js.map +1 -1
- package/dist/services/logging/buffer.d.ts +67 -0
- package/dist/services/logging/buffer.js +309 -0
- package/dist/services/logging/buffer.js.map +1 -0
- package/dist/services/logging/console.d.ts +89 -0
- package/dist/services/logging/console.js +169 -0
- package/dist/services/logging/console.js.map +1 -0
- package/dist/services/logging/file-writer.d.ts +71 -0
- package/dist/services/logging/file-writer.js +516 -0
- package/dist/services/logging/file-writer.js.map +1 -0
- package/dist/services/logging/formatter.d.ts +39 -0
- package/dist/services/logging/formatter.js +227 -0
- package/dist/services/logging/formatter.js.map +1 -0
- package/dist/services/logging/index.d.ts +11 -0
- package/dist/services/logging/index.js +30 -0
- package/dist/services/logging/index.js.map +1 -0
- package/dist/services/logging/parser.d.ts +31 -0
- package/dist/services/logging/parser.js +222 -0
- package/dist/services/logging/parser.js.map +1 -0
- package/dist/services/process/index.d.ts +59 -0
- package/dist/services/process/index.js +257 -0
- package/dist/services/process/index.js.map +1 -0
- package/dist/types/agent.d.ts +20 -0
- package/dist/types/agent.js +6 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/config.d.ts +65 -0
- package/dist/types/config.js +6 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/events.d.ts +125 -0
- package/dist/types/events.js +6 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.js +37 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/lane.d.ts +43 -0
- package/dist/types/lane.js +6 -0
- package/dist/types/lane.js.map +1 -0
- package/dist/types/logging.d.ts +71 -0
- package/dist/types/logging.js +16 -0
- package/dist/types/logging.js.map +1 -0
- package/dist/types/review.d.ts +17 -0
- package/dist/types/review.js +6 -0
- package/dist/types/review.js.map +1 -0
- package/dist/types/run.d.ts +32 -0
- package/dist/types/run.js +6 -0
- package/dist/types/run.js.map +1 -0
- package/dist/types/task.d.ts +71 -0
- package/dist/types/task.js +6 -0
- package/dist/types/task.js.map +1 -0
- package/dist/ui/components.d.ts +134 -0
- package/dist/ui/components.js +389 -0
- package/dist/ui/components.js.map +1 -0
- package/dist/ui/log-viewer.d.ts +49 -0
- package/dist/ui/log-viewer.js +449 -0
- package/dist/ui/log-viewer.js.map +1 -0
- package/dist/utils/checkpoint.d.ts +87 -0
- package/dist/utils/checkpoint.js +317 -0
- package/dist/utils/checkpoint.js.map +1 -0
- package/dist/utils/config.d.ts +4 -0
- package/dist/utils/config.js +11 -2
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/cursor-agent.js.map +1 -1
- package/dist/utils/dependency.d.ts +74 -0
- package/dist/utils/dependency.js +420 -0
- package/dist/utils/dependency.js.map +1 -0
- package/dist/utils/doctor.js +10 -5
- package/dist/utils/doctor.js.map +1 -1
- package/dist/utils/enhanced-logger.d.ts +10 -33
- package/dist/utils/enhanced-logger.js +94 -9
- package/dist/utils/enhanced-logger.js.map +1 -1
- package/dist/utils/git.d.ts +121 -0
- package/dist/utils/git.js +322 -2
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/health.d.ts +91 -0
- package/dist/utils/health.js +556 -0
- package/dist/utils/health.js.map +1 -0
- package/dist/utils/lock.d.ts +95 -0
- package/dist/utils/lock.js +332 -0
- package/dist/utils/lock.js.map +1 -0
- package/dist/utils/log-buffer.d.ts +17 -0
- package/dist/utils/log-buffer.js +14 -0
- package/dist/utils/log-buffer.js.map +1 -0
- package/dist/utils/log-constants.d.ts +23 -0
- package/dist/utils/log-constants.js +28 -0
- package/dist/utils/log-constants.js.map +1 -0
- package/dist/utils/log-formatter.d.ts +9 -0
- package/dist/utils/log-formatter.js +113 -70
- package/dist/utils/log-formatter.js.map +1 -1
- package/dist/utils/log-service.d.ts +19 -0
- package/dist/utils/log-service.js +47 -0
- package/dist/utils/log-service.js.map +1 -0
- package/dist/utils/logger.d.ts +46 -27
- package/dist/utils/logger.js +82 -60
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/process-manager.d.ts +21 -0
- package/dist/utils/process-manager.js +138 -0
- package/dist/utils/process-manager.js.map +1 -0
- package/dist/utils/retry.d.ts +121 -0
- package/dist/utils/retry.js +374 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/run-service.d.ts +88 -0
- package/dist/utils/run-service.js +412 -0
- package/dist/utils/run-service.js.map +1 -0
- package/dist/utils/state.d.ts +58 -2
- package/dist/utils/state.js +306 -3
- package/dist/utils/state.js.map +1 -1
- package/dist/utils/task-service.d.ts +82 -0
- package/dist/utils/task-service.js +348 -0
- package/dist/utils/task-service.js.map +1 -0
- package/dist/utils/types.d.ts +2 -272
- package/dist/utils/types.js +16 -0
- package/dist/utils/types.js.map +1 -1
- package/package.json +38 -23
- package/scripts/ai-security-check.js +0 -1
- package/scripts/local-security-gate.sh +0 -0
- package/scripts/monitor-lanes.sh +94 -0
- package/scripts/patches/test-cursor-agent.js +0 -1
- package/scripts/release.sh +0 -0
- package/scripts/setup-security.sh +0 -0
- package/scripts/stream-logs.sh +72 -0
- package/scripts/verify-and-fix.sh +0 -0
- package/src/cli/clean.ts +180 -0
- package/src/cli/index.ts +7 -0
- package/src/cli/init.ts +1 -1
- package/src/cli/logs.ts +79 -42
- package/src/cli/monitor.ts +1815 -899
- package/src/cli/prepare.ts +97 -3
- package/src/cli/resume.ts +220 -277
- package/src/cli/run.ts +154 -3
- package/src/cli/runs.ts +212 -0
- package/src/cli/setup-commands.ts +0 -0
- package/src/cli/signal.ts +1 -1
- package/src/cli/stop.ts +209 -0
- package/src/cli/tasks.ts +154 -0
- package/src/core/auto-recovery.ts +909 -0
- package/src/core/failure-policy.ts +592 -0
- package/src/core/orchestrator.ts +1136 -675
- package/src/core/reviewer.ts +4 -0
- package/src/core/runner.ts +1443 -1217
- package/src/services/logging/buffer.ts +326 -0
- package/src/services/logging/console.ts +193 -0
- package/src/services/logging/file-writer.ts +526 -0
- package/src/services/logging/formatter.ts +268 -0
- package/src/services/logging/index.ts +16 -0
- package/src/services/logging/parser.ts +232 -0
- package/src/services/process/index.ts +261 -0
- package/src/types/agent.ts +24 -0
- package/src/types/config.ts +79 -0
- package/src/types/events.ts +156 -0
- package/src/types/index.ts +29 -0
- package/src/types/lane.ts +56 -0
- package/src/types/logging.ts +96 -0
- package/src/types/review.ts +20 -0
- package/src/types/run.ts +37 -0
- package/src/types/task.ts +79 -0
- package/src/ui/components.ts +430 -0
- package/src/ui/log-viewer.ts +485 -0
- package/src/utils/checkpoint.ts +374 -0
- package/src/utils/config.ts +11 -2
- package/src/utils/cursor-agent.ts +1 -1
- package/src/utils/dependency.ts +482 -0
- package/src/utils/doctor.ts +11 -5
- package/src/utils/enhanced-logger.ts +108 -49
- package/src/utils/git.ts +871 -499
- package/src/utils/health.ts +596 -0
- package/src/utils/lock.ts +346 -0
- package/src/utils/log-buffer.ts +28 -0
- package/src/utils/log-constants.ts +26 -0
- package/src/utils/log-formatter.ts +120 -37
- package/src/utils/log-service.ts +49 -0
- package/src/utils/logger.ts +100 -51
- package/src/utils/process-manager.ts +100 -0
- package/src/utils/retry.ts +413 -0
- package/src/utils/run-service.ts +433 -0
- package/src/utils/state.ts +369 -3
- package/src/utils/task-service.ts +370 -0
- package/src/utils/types.ts +2 -315
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process Management Service
|
|
3
|
+
*
|
|
4
|
+
* Utilities for detecting and managing lane processes.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { execSync, spawnSync } from 'child_process';
|
|
10
|
+
|
|
11
|
+
export interface ProcessInfo {
|
|
12
|
+
pid: number;
|
|
13
|
+
exists: boolean;
|
|
14
|
+
isRunning: boolean;
|
|
15
|
+
command?: string;
|
|
16
|
+
uptime?: number;
|
|
17
|
+
cpuPercent?: number;
|
|
18
|
+
memoryMb?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface LaneProcessStatus {
|
|
22
|
+
laneName: string;
|
|
23
|
+
pid: number | null;
|
|
24
|
+
processExists: boolean;
|
|
25
|
+
processRunning: boolean;
|
|
26
|
+
stateStatus: string;
|
|
27
|
+
actualStatus: 'running' | 'dead' | 'unknown' | 'completed' | 'failed' | 'pending';
|
|
28
|
+
startTime: number | null;
|
|
29
|
+
endTime: number | null;
|
|
30
|
+
duration: number;
|
|
31
|
+
isStale: boolean;
|
|
32
|
+
processInfo?: ProcessInfo;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Check if a process exists and is running
|
|
37
|
+
*/
|
|
38
|
+
export function checkProcess(pid: number): ProcessInfo {
|
|
39
|
+
const result: ProcessInfo = {
|
|
40
|
+
pid,
|
|
41
|
+
exists: false,
|
|
42
|
+
isRunning: false,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
// Send signal 0 to check if process exists
|
|
47
|
+
process.kill(pid, 0);
|
|
48
|
+
result.exists = true;
|
|
49
|
+
result.isRunning = true;
|
|
50
|
+
|
|
51
|
+
// Try to get more info on Linux/macOS
|
|
52
|
+
if (process.platform !== 'win32') {
|
|
53
|
+
try {
|
|
54
|
+
const psResult = spawnSync('ps', ['-p', pid.toString(), '-o', 'pid,stat,comm,etime,%cpu,%mem'], {
|
|
55
|
+
encoding: 'utf8',
|
|
56
|
+
timeout: 1000,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (psResult.status === 0) {
|
|
60
|
+
const psOutput = psResult.stdout.trim();
|
|
61
|
+
const lines = psOutput.split('\n');
|
|
62
|
+
if (lines.length > 1) {
|
|
63
|
+
const fields = lines[1]!.trim().split(/\s+/);
|
|
64
|
+
if (fields.length >= 4) {
|
|
65
|
+
result.command = fields[2];
|
|
66
|
+
|
|
67
|
+
// Parse elapsed time (formats: MM:SS, HH:MM:SS, D-HH:MM:SS)
|
|
68
|
+
const etime = fields[3]!;
|
|
69
|
+
result.uptime = parseElapsedTime(etime);
|
|
70
|
+
|
|
71
|
+
if (fields.length >= 5) {
|
|
72
|
+
result.cpuPercent = parseFloat(fields[4]!);
|
|
73
|
+
}
|
|
74
|
+
if (fields.length >= 6) {
|
|
75
|
+
result.memoryMb = parseFloat(fields[5]!);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
// ps failed, but process exists
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} catch (err: any) {
|
|
85
|
+
// ESRCH = no such process
|
|
86
|
+
// EPERM = permission denied but process exists
|
|
87
|
+
if (err.code === 'EPERM') {
|
|
88
|
+
result.exists = true;
|
|
89
|
+
result.isRunning = true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Parse ps elapsed time format to milliseconds
|
|
98
|
+
*/
|
|
99
|
+
function parseElapsedTime(etime: string): number {
|
|
100
|
+
// Formats: SS, MM:SS, HH:MM:SS, D-HH:MM:SS
|
|
101
|
+
const parts = etime.split('-');
|
|
102
|
+
let days = 0;
|
|
103
|
+
let timeStr = etime;
|
|
104
|
+
|
|
105
|
+
if (parts.length === 2) {
|
|
106
|
+
days = parseInt(parts[0]!, 10);
|
|
107
|
+
timeStr = parts[1]!;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const timeParts = timeStr.split(':').reverse();
|
|
111
|
+
let seconds = 0;
|
|
112
|
+
|
|
113
|
+
if (timeParts.length >= 1) seconds += parseInt(timeParts[0]!, 10);
|
|
114
|
+
if (timeParts.length >= 2) seconds += parseInt(timeParts[1]!, 10) * 60;
|
|
115
|
+
if (timeParts.length >= 3) seconds += parseInt(timeParts[2]!, 10) * 3600;
|
|
116
|
+
seconds += days * 86400;
|
|
117
|
+
|
|
118
|
+
return seconds * 1000;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get accurate lane process status
|
|
123
|
+
*/
|
|
124
|
+
export function getLaneProcessStatus(lanePath: string, laneName: string): LaneProcessStatus {
|
|
125
|
+
const statePath = path.join(lanePath, 'state.json');
|
|
126
|
+
|
|
127
|
+
const result: LaneProcessStatus = {
|
|
128
|
+
laneName,
|
|
129
|
+
pid: null,
|
|
130
|
+
processExists: false,
|
|
131
|
+
processRunning: false,
|
|
132
|
+
stateStatus: 'unknown',
|
|
133
|
+
actualStatus: 'unknown',
|
|
134
|
+
startTime: null,
|
|
135
|
+
endTime: null,
|
|
136
|
+
duration: 0,
|
|
137
|
+
isStale: false,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
if (!fs.existsSync(statePath)) {
|
|
141
|
+
result.stateStatus = 'pending';
|
|
142
|
+
result.actualStatus = 'pending';
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
148
|
+
result.stateStatus = state.status || 'unknown';
|
|
149
|
+
result.pid = state.pid || null;
|
|
150
|
+
result.startTime = state.startTime || null;
|
|
151
|
+
result.endTime = state.endTime || null;
|
|
152
|
+
|
|
153
|
+
// Calculate duration
|
|
154
|
+
if (result.startTime) {
|
|
155
|
+
if (result.endTime) {
|
|
156
|
+
result.duration = result.endTime - result.startTime;
|
|
157
|
+
} else if (result.stateStatus === 'running' || result.stateStatus === 'reviewing') {
|
|
158
|
+
result.duration = Date.now() - result.startTime;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Determine actual status based on process check
|
|
163
|
+
if (result.stateStatus === 'completed') {
|
|
164
|
+
result.actualStatus = 'completed';
|
|
165
|
+
} else if (result.stateStatus === 'failed') {
|
|
166
|
+
result.actualStatus = 'failed';
|
|
167
|
+
} else if (result.stateStatus === 'pending' || result.stateStatus === 'waiting') {
|
|
168
|
+
result.actualStatus = 'pending';
|
|
169
|
+
} else if (result.pid) {
|
|
170
|
+
// Check if process is actually running
|
|
171
|
+
const processInfo = checkProcess(result.pid);
|
|
172
|
+
result.processInfo = processInfo;
|
|
173
|
+
result.processExists = processInfo.exists;
|
|
174
|
+
result.processRunning = processInfo.isRunning;
|
|
175
|
+
|
|
176
|
+
if (processInfo.isRunning) {
|
|
177
|
+
result.actualStatus = 'running';
|
|
178
|
+
} else {
|
|
179
|
+
// Process is gone but state says running - stale state
|
|
180
|
+
result.actualStatus = 'dead';
|
|
181
|
+
result.isStale = true;
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
// No PID but state says running
|
|
185
|
+
if (result.stateStatus === 'running') {
|
|
186
|
+
result.actualStatus = 'dead';
|
|
187
|
+
result.isStale = true;
|
|
188
|
+
} else {
|
|
189
|
+
result.actualStatus = 'pending';
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
} catch {
|
|
193
|
+
result.actualStatus = 'unknown';
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Get all lane process statuses for a run directory
|
|
201
|
+
*/
|
|
202
|
+
export function getAllLaneProcessStatuses(runDir: string): LaneProcessStatus[] {
|
|
203
|
+
const lanesDir = path.join(runDir, 'lanes');
|
|
204
|
+
if (!fs.existsSync(lanesDir)) return [];
|
|
205
|
+
|
|
206
|
+
const lanes = fs.readdirSync(lanesDir).filter(name => {
|
|
207
|
+
const dirPath = path.join(lanesDir, name);
|
|
208
|
+
return fs.statSync(dirPath).isDirectory();
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
return lanes.map(laneName => {
|
|
212
|
+
const lanePath = path.join(lanesDir, laneName);
|
|
213
|
+
return getLaneProcessStatus(lanePath, laneName);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Check if any flow process is alive
|
|
219
|
+
*/
|
|
220
|
+
export function isFlowAlive(runDir: string): boolean {
|
|
221
|
+
const statuses = getAllLaneProcessStatuses(runDir);
|
|
222
|
+
return statuses.some(s => s.actualStatus === 'running');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Get flow status summary
|
|
227
|
+
*/
|
|
228
|
+
export function getFlowSummary(runDir: string): {
|
|
229
|
+
total: number;
|
|
230
|
+
running: number;
|
|
231
|
+
completed: number;
|
|
232
|
+
failed: number;
|
|
233
|
+
pending: number;
|
|
234
|
+
dead: number;
|
|
235
|
+
isAlive: boolean;
|
|
236
|
+
} {
|
|
237
|
+
const statuses = getAllLaneProcessStatuses(runDir);
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
total: statuses.length,
|
|
241
|
+
running: statuses.filter(s => s.actualStatus === 'running').length,
|
|
242
|
+
completed: statuses.filter(s => s.actualStatus === 'completed').length,
|
|
243
|
+
failed: statuses.filter(s => s.actualStatus === 'failed').length,
|
|
244
|
+
pending: statuses.filter(s => s.actualStatus === 'pending').length,
|
|
245
|
+
dead: statuses.filter(s => s.actualStatus === 'dead').length,
|
|
246
|
+
isAlive: statuses.some(s => s.actualStatus === 'running'),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Kill a lane process
|
|
252
|
+
*/
|
|
253
|
+
export function killLaneProcess(pid: number, signal: NodeJS.Signals = 'SIGTERM'): boolean {
|
|
254
|
+
try {
|
|
255
|
+
process.kill(pid, signal);
|
|
256
|
+
return true;
|
|
257
|
+
} catch {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-related type definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface DependencyPolicy {
|
|
6
|
+
allowDependencyChange: boolean;
|
|
7
|
+
lockfileReadOnly: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface DependencyRequestPlan {
|
|
11
|
+
reason: string;
|
|
12
|
+
changes: string[];
|
|
13
|
+
commands: string[];
|
|
14
|
+
notes?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface AgentSendResult {
|
|
18
|
+
ok: boolean;
|
|
19
|
+
exitCode: number;
|
|
20
|
+
error?: string;
|
|
21
|
+
sessionId?: string;
|
|
22
|
+
resultText?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration-related type definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface LaneConfig {
|
|
6
|
+
devPort: number;
|
|
7
|
+
autoCreatePr: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface WebhookConfig {
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
url: string;
|
|
13
|
+
secret?: string;
|
|
14
|
+
events?: string[]; // ['*'] for all, ['task.*'] for wildcards
|
|
15
|
+
headers?: Record<string, string>;
|
|
16
|
+
retries?: number;
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface EnhancedLogConfig {
|
|
21
|
+
/** Enable enhanced logging features (default: true) */
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
|
|
24
|
+
/** Strip ANSI escape codes from clean logs (default: true) */
|
|
25
|
+
stripAnsi: boolean;
|
|
26
|
+
|
|
27
|
+
/** Add timestamps to each line (default: true) */
|
|
28
|
+
addTimestamps: boolean;
|
|
29
|
+
|
|
30
|
+
/** Maximum size in bytes before rotation (default: 50MB) */
|
|
31
|
+
maxFileSize: number;
|
|
32
|
+
|
|
33
|
+
/** Number of rotated files to keep (default: 5) */
|
|
34
|
+
maxFiles: number;
|
|
35
|
+
|
|
36
|
+
/** Write raw output with ANSI codes to separate file (default: true) */
|
|
37
|
+
keepRawLogs: boolean;
|
|
38
|
+
|
|
39
|
+
/** Keep absolute raw logs without any processing */
|
|
40
|
+
keepAbsoluteRawLogs?: boolean;
|
|
41
|
+
|
|
42
|
+
/** Write structured JSON log entries (default: true) */
|
|
43
|
+
writeJsonLog: boolean;
|
|
44
|
+
|
|
45
|
+
/** Timestamp format: 'iso' | 'relative' | 'short' (default: 'iso') */
|
|
46
|
+
timestampFormat: 'iso' | 'relative' | 'short';
|
|
47
|
+
|
|
48
|
+
/** Raw output mode */
|
|
49
|
+
raw?: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface CursorFlowConfig {
|
|
53
|
+
tasksDir: string;
|
|
54
|
+
logsDir: string;
|
|
55
|
+
pofDir: string;
|
|
56
|
+
/** Base branch (optional, auto-detected from current branch if not specified) */
|
|
57
|
+
baseBranch?: string;
|
|
58
|
+
branchPrefix: string;
|
|
59
|
+
executor: 'cursor-agent' | 'cloud';
|
|
60
|
+
pollInterval: number;
|
|
61
|
+
allowDependencyChange: boolean;
|
|
62
|
+
lockfileReadOnly: boolean;
|
|
63
|
+
enableReview: boolean;
|
|
64
|
+
reviewModel: string;
|
|
65
|
+
reviewAllTasks?: boolean;
|
|
66
|
+
maxReviewIterations: number;
|
|
67
|
+
defaultLaneConfig: LaneConfig;
|
|
68
|
+
logLevel: string;
|
|
69
|
+
verboseGit: boolean;
|
|
70
|
+
worktreePrefix: string;
|
|
71
|
+
maxConcurrentLanes: number;
|
|
72
|
+
projectRoot: string;
|
|
73
|
+
/** Output format for cursor-agent (default: 'stream-json') */
|
|
74
|
+
agentOutputFormat: 'stream-json' | 'json' | 'plain';
|
|
75
|
+
webhooks?: WebhookConfig[];
|
|
76
|
+
/** Enhanced logging configuration */
|
|
77
|
+
enhancedLogging?: Partial<EnhancedLogConfig>;
|
|
78
|
+
}
|
|
79
|
+
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event-related type definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { DependencyRequestPlan } from './agent';
|
|
6
|
+
|
|
7
|
+
export interface CursorFlowEvent<T = Record<string, any>> {
|
|
8
|
+
id: string;
|
|
9
|
+
type: string;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
runId: string;
|
|
12
|
+
payload: T;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type EventHandler<T = any> = (event: CursorFlowEvent<T>) => void | Promise<void>;
|
|
16
|
+
|
|
17
|
+
// Orchestration Events
|
|
18
|
+
export interface OrchestrationStartedPayload {
|
|
19
|
+
runId: string;
|
|
20
|
+
tasksDir: string;
|
|
21
|
+
laneCount: number;
|
|
22
|
+
runRoot: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface OrchestrationCompletedPayload {
|
|
26
|
+
runId: string;
|
|
27
|
+
laneCount: number;
|
|
28
|
+
completedCount: number;
|
|
29
|
+
failedCount: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface OrchestrationFailedPayload {
|
|
33
|
+
error: string;
|
|
34
|
+
blockedLanes?: string[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Lane Events
|
|
38
|
+
export interface LaneStartedPayload {
|
|
39
|
+
laneName: string;
|
|
40
|
+
pid?: number;
|
|
41
|
+
logPath: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface LaneCompletedPayload {
|
|
45
|
+
laneName: string;
|
|
46
|
+
exitCode: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface LaneFailedPayload {
|
|
50
|
+
laneName: string;
|
|
51
|
+
exitCode: number;
|
|
52
|
+
error: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface LaneDependencyRequestedPayload {
|
|
56
|
+
laneName: string;
|
|
57
|
+
dependencyRequest: DependencyRequestPlan;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Task Events
|
|
61
|
+
export interface TaskStartedPayload {
|
|
62
|
+
taskName: string;
|
|
63
|
+
taskBranch: string;
|
|
64
|
+
index: number;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface TaskCompletedPayload {
|
|
68
|
+
taskName: string;
|
|
69
|
+
taskBranch: string;
|
|
70
|
+
status: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface TaskFailedPayload {
|
|
74
|
+
taskName: string;
|
|
75
|
+
taskBranch: string;
|
|
76
|
+
error: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Agent Events
|
|
80
|
+
export interface AgentPromptSentPayload {
|
|
81
|
+
taskName: string;
|
|
82
|
+
model: string;
|
|
83
|
+
promptLength: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface AgentResponseReceivedPayload {
|
|
87
|
+
taskName: string;
|
|
88
|
+
ok: boolean;
|
|
89
|
+
duration: number;
|
|
90
|
+
responseLength: number;
|
|
91
|
+
error?: string;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Review Events
|
|
95
|
+
export interface ReviewStartedPayload {
|
|
96
|
+
taskName: string;
|
|
97
|
+
taskBranch: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface ReviewCompletedPayload {
|
|
101
|
+
taskName: string;
|
|
102
|
+
status: 'approved' | 'needs_changes';
|
|
103
|
+
issueCount: number;
|
|
104
|
+
summary: string;
|
|
105
|
+
raw: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface ReviewApprovedPayload {
|
|
109
|
+
taskName: string;
|
|
110
|
+
iterations: number;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface ReviewRejectedPayload {
|
|
114
|
+
taskName: string;
|
|
115
|
+
reason: string;
|
|
116
|
+
iterations: number;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Recovery Events
|
|
120
|
+
export interface RecoveryContinueSignalPayload {
|
|
121
|
+
laneName: string;
|
|
122
|
+
idleSeconds: number;
|
|
123
|
+
signalCount: number;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface RecoveryStrongerPromptPayload {
|
|
127
|
+
laneName: string;
|
|
128
|
+
prompt?: string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface RecoveryRestartPayload {
|
|
132
|
+
laneName: string;
|
|
133
|
+
restartCount: number;
|
|
134
|
+
maxRestarts: number;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface RecoveryDiagnosedPayload {
|
|
138
|
+
laneName: string;
|
|
139
|
+
diagnostic: {
|
|
140
|
+
timestamp?: number;
|
|
141
|
+
agentHealthy: boolean;
|
|
142
|
+
authHealthy: boolean;
|
|
143
|
+
systemHealthy?: boolean;
|
|
144
|
+
suggestedAction?: string;
|
|
145
|
+
details?: string;
|
|
146
|
+
issues?: string[];
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export interface RecoveryConflictResolutionPayload {
|
|
151
|
+
success: boolean;
|
|
152
|
+
strategy: string;
|
|
153
|
+
resolvedCount: number;
|
|
154
|
+
unresolvedCount: number;
|
|
155
|
+
}
|
|
156
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central type definitions for CursorFlow
|
|
3
|
+
* Re-exports all types from separate modules
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Config
|
|
7
|
+
export * from './config';
|
|
8
|
+
|
|
9
|
+
// Lane
|
|
10
|
+
export * from './lane';
|
|
11
|
+
|
|
12
|
+
// Task
|
|
13
|
+
export * from './task';
|
|
14
|
+
|
|
15
|
+
// Agent
|
|
16
|
+
export * from './agent';
|
|
17
|
+
|
|
18
|
+
// Review
|
|
19
|
+
export * from './review';
|
|
20
|
+
|
|
21
|
+
// Events
|
|
22
|
+
export * from './events';
|
|
23
|
+
|
|
24
|
+
// Logging
|
|
25
|
+
export * from './logging';
|
|
26
|
+
|
|
27
|
+
// Run
|
|
28
|
+
export * from './run';
|
|
29
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lane-related type definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { DependencyRequestPlan } from './agent';
|
|
6
|
+
|
|
7
|
+
export type LaneStatus =
|
|
8
|
+
| 'pending'
|
|
9
|
+
| 'running'
|
|
10
|
+
| 'completed'
|
|
11
|
+
| 'failed'
|
|
12
|
+
| 'paused'
|
|
13
|
+
| 'waiting'
|
|
14
|
+
| 'reviewing';
|
|
15
|
+
|
|
16
|
+
export interface LaneInfo {
|
|
17
|
+
name: string;
|
|
18
|
+
status: string;
|
|
19
|
+
currentTask: number;
|
|
20
|
+
totalTasks: number;
|
|
21
|
+
pid?: number;
|
|
22
|
+
pipelineBranch?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface LaneState {
|
|
26
|
+
label: string;
|
|
27
|
+
status: LaneStatus;
|
|
28
|
+
currentTaskIndex: number;
|
|
29
|
+
totalTasks: number;
|
|
30
|
+
worktreeDir: string | null;
|
|
31
|
+
pipelineBranch: string | null;
|
|
32
|
+
startTime: number;
|
|
33
|
+
endTime: number | null;
|
|
34
|
+
error: string | null;
|
|
35
|
+
dependencyRequest: DependencyRequestPlan | null;
|
|
36
|
+
updatedAt?: number;
|
|
37
|
+
tasksFile?: string; // Original tasks file path
|
|
38
|
+
dependsOn?: string[];
|
|
39
|
+
pid?: number;
|
|
40
|
+
/** List of completed task names in this lane */
|
|
41
|
+
completedTasks?: string[];
|
|
42
|
+
/** Task-level dependencies currently being waited for (format: "lane:task") */
|
|
43
|
+
waitingFor?: string[];
|
|
44
|
+
/** Chat session ID */
|
|
45
|
+
chatId?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface LaneFileInfo {
|
|
49
|
+
fileName: string;
|
|
50
|
+
laneName: string;
|
|
51
|
+
preset: string;
|
|
52
|
+
taskCount: number;
|
|
53
|
+
taskFlow: string;
|
|
54
|
+
dependsOn: string[];
|
|
55
|
+
}
|
|
56
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging-related type definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export enum LogImportance {
|
|
6
|
+
CRITICAL = 'critical',
|
|
7
|
+
HIGH = 'high',
|
|
8
|
+
MEDIUM = 'medium',
|
|
9
|
+
LOW = 'low',
|
|
10
|
+
INFO = 'info',
|
|
11
|
+
DEBUG = 'debug'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type MessageType =
|
|
15
|
+
| 'system'
|
|
16
|
+
| 'user'
|
|
17
|
+
| 'assistant'
|
|
18
|
+
| 'tool'
|
|
19
|
+
| 'tool_result'
|
|
20
|
+
| 'result'
|
|
21
|
+
| 'thinking'
|
|
22
|
+
| 'success'
|
|
23
|
+
| 'info'
|
|
24
|
+
| 'warn'
|
|
25
|
+
| 'error'
|
|
26
|
+
| 'stdout'
|
|
27
|
+
| 'stderr';
|
|
28
|
+
|
|
29
|
+
export interface ParsedMessage {
|
|
30
|
+
type: MessageType;
|
|
31
|
+
role: string;
|
|
32
|
+
content: string;
|
|
33
|
+
timestamp: number;
|
|
34
|
+
metadata?: Record<string, any>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface JsonLogEntry {
|
|
38
|
+
timestamp: string;
|
|
39
|
+
type?: string;
|
|
40
|
+
level?: 'stdout' | 'stderr' | 'info' | 'error' | 'debug' | 'session';
|
|
41
|
+
source?: string;
|
|
42
|
+
task?: string;
|
|
43
|
+
lane?: string;
|
|
44
|
+
message?: string;
|
|
45
|
+
content?: string;
|
|
46
|
+
raw?: string;
|
|
47
|
+
metadata?: Record<string, any>;
|
|
48
|
+
[key: string]: any;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface BufferedLogEntry {
|
|
52
|
+
id: number;
|
|
53
|
+
timestamp: Date;
|
|
54
|
+
laneName: string;
|
|
55
|
+
level: string;
|
|
56
|
+
type: MessageType | string;
|
|
57
|
+
message: string;
|
|
58
|
+
raw?: JsonLogEntry;
|
|
59
|
+
importance: LogImportance;
|
|
60
|
+
laneColor: string;
|
|
61
|
+
metadata?: Record<string, any>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Re-export EnhancedLogConfig from config.ts
|
|
65
|
+
export type { EnhancedLogConfig } from './config';
|
|
66
|
+
|
|
67
|
+
export interface LogSession {
|
|
68
|
+
id: string;
|
|
69
|
+
laneName: string;
|
|
70
|
+
taskName?: string;
|
|
71
|
+
model?: string;
|
|
72
|
+
startTime: number;
|
|
73
|
+
metadata?: Record<string, any>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface ConversationEntry {
|
|
77
|
+
timestamp: string;
|
|
78
|
+
role: 'user' | 'assistant' | 'reviewer' | 'system' | 'intervention';
|
|
79
|
+
task: string | null;
|
|
80
|
+
fullText: string;
|
|
81
|
+
textLength: number;
|
|
82
|
+
model: string | null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface GitLogEntry {
|
|
86
|
+
timestamp: string;
|
|
87
|
+
operation: string;
|
|
88
|
+
[key: string]: any;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface EventEntry {
|
|
92
|
+
timestamp: string;
|
|
93
|
+
event: string;
|
|
94
|
+
[key: string]: any;
|
|
95
|
+
}
|
|
96
|
+
|