@litmers/cursorflow-orchestrator 0.1.31 → 0.1.34
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/README.md +144 -52
- package/commands/cursorflow-add.md +159 -0
- package/commands/cursorflow-monitor.md +23 -2
- package/commands/cursorflow-new.md +87 -0
- package/dist/cli/add.d.ts +7 -0
- package/dist/cli/add.js +377 -0
- package/dist/cli/add.js.map +1 -0
- package/dist/cli/clean.js +1 -0
- package/dist/cli/clean.js.map +1 -1
- package/dist/cli/config.d.ts +7 -0
- package/dist/cli/config.js +181 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.js +34 -30
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/logs.js +7 -33
- package/dist/cli/logs.js.map +1 -1
- package/dist/cli/monitor.js +51 -62
- package/dist/cli/monitor.js.map +1 -1
- package/dist/cli/new.d.ts +7 -0
- package/dist/cli/new.js +232 -0
- package/dist/cli/new.js.map +1 -0
- package/dist/cli/prepare.js +95 -193
- package/dist/cli/prepare.js.map +1 -1
- package/dist/cli/resume.js +11 -47
- package/dist/cli/resume.js.map +1 -1
- package/dist/cli/run.js +27 -22
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/tasks.js +1 -2
- package/dist/cli/tasks.js.map +1 -1
- package/dist/core/failure-policy.d.ts +9 -0
- package/dist/core/failure-policy.js +9 -0
- package/dist/core/failure-policy.js.map +1 -1
- package/dist/core/orchestrator.d.ts +20 -6
- package/dist/core/orchestrator.js +213 -333
- package/dist/core/orchestrator.js.map +1 -1
- package/dist/core/runner/agent.d.ts +27 -0
- package/dist/core/runner/agent.js +294 -0
- package/dist/core/runner/agent.js.map +1 -0
- package/dist/core/runner/index.d.ts +5 -0
- package/dist/core/runner/index.js +22 -0
- package/dist/core/runner/index.js.map +1 -0
- package/dist/core/runner/pipeline.d.ts +9 -0
- package/dist/core/runner/pipeline.js +539 -0
- package/dist/core/runner/pipeline.js.map +1 -0
- package/dist/core/runner/prompt.d.ts +25 -0
- package/dist/core/runner/prompt.js +175 -0
- package/dist/core/runner/prompt.js.map +1 -0
- package/dist/core/runner/task.d.ts +26 -0
- package/dist/core/runner/task.js +283 -0
- package/dist/core/runner/task.js.map +1 -0
- package/dist/core/runner/utils.d.ts +37 -0
- package/dist/core/runner/utils.js +161 -0
- package/dist/core/runner/utils.js.map +1 -0
- package/dist/core/runner.d.ts +2 -96
- package/dist/core/runner.js +11 -1136
- package/dist/core/runner.js.map +1 -1
- package/dist/core/stall-detection.d.ts +326 -0
- package/dist/core/stall-detection.js +781 -0
- package/dist/core/stall-detection.js.map +1 -0
- package/dist/types/config.d.ts +6 -6
- package/dist/types/flow.d.ts +84 -0
- package/dist/types/flow.js +10 -0
- package/dist/types/flow.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +3 -3
- package/dist/types/index.js.map +1 -1
- package/dist/types/lane.d.ts +0 -2
- package/dist/types/logging.d.ts +5 -1
- package/dist/types/task.d.ts +7 -11
- package/dist/utils/config.js +7 -15
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/dependency.d.ts +36 -1
- package/dist/utils/dependency.js +256 -1
- package/dist/utils/dependency.js.map +1 -1
- package/dist/utils/enhanced-logger.d.ts +45 -82
- package/dist/utils/enhanced-logger.js +238 -844
- package/dist/utils/enhanced-logger.js.map +1 -1
- package/dist/utils/git.d.ts +29 -0
- package/dist/utils/git.js +115 -5
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/state.js +0 -2
- package/dist/utils/state.js.map +1 -1
- package/dist/utils/task-service.d.ts +2 -2
- package/dist/utils/task-service.js +40 -31
- package/dist/utils/task-service.js.map +1 -1
- package/package.json +4 -3
- package/src/cli/add.ts +397 -0
- package/src/cli/clean.ts +1 -0
- package/src/cli/config.ts +177 -0
- package/src/cli/index.ts +36 -32
- package/src/cli/logs.ts +7 -31
- package/src/cli/monitor.ts +55 -71
- package/src/cli/new.ts +235 -0
- package/src/cli/prepare.ts +98 -205
- package/src/cli/resume.ts +13 -56
- package/src/cli/run.ts +311 -306
- package/src/cli/tasks.ts +1 -2
- package/src/core/failure-policy.ts +9 -0
- package/src/core/orchestrator.ts +277 -378
- package/src/core/runner/agent.ts +314 -0
- package/src/core/runner/index.ts +6 -0
- package/src/core/runner/pipeline.ts +567 -0
- package/src/core/runner/prompt.ts +174 -0
- package/src/core/runner/task.ts +320 -0
- package/src/core/runner/utils.ts +142 -0
- package/src/core/runner.ts +8 -1347
- package/src/core/stall-detection.ts +936 -0
- package/src/types/config.ts +6 -6
- package/src/types/flow.ts +91 -0
- package/src/types/index.ts +15 -3
- package/src/types/lane.ts +0 -2
- package/src/types/logging.ts +5 -1
- package/src/types/task.ts +7 -11
- package/src/utils/config.ts +8 -16
- package/src/utils/dependency.ts +311 -2
- package/src/utils/enhanced-logger.ts +263 -927
- package/src/utils/git.ts +145 -5
- package/src/utils/state.ts +0 -2
- package/src/utils/task-service.ts +48 -40
- package/commands/cursorflow-review.md +0 -56
- package/commands/cursorflow-runs.md +0 -59
- package/dist/cli/runs.d.ts +0 -5
- package/dist/cli/runs.js +0 -214
- package/dist/cli/runs.js.map +0 -1
- package/dist/core/reviewer.d.ts +0 -66
- package/dist/core/reviewer.js +0 -265
- package/dist/core/reviewer.js.map +0 -1
- package/src/cli/runs.ts +0 -212
- package/src/core/reviewer.ts +0 -285
package/src/core/reviewer.ts
DELETED
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reviewer - Code review agent
|
|
3
|
-
*
|
|
4
|
-
* Adapted from reviewer-agent.js
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import * as logger from '../utils/logger';
|
|
8
|
-
import { appendLog, createConversationEntry } from '../utils/state';
|
|
9
|
-
import * as path from 'path';
|
|
10
|
-
import { ReviewResult, ReviewIssue, TaskResult, RunnerConfig, AgentSendResult } from '../utils/types';
|
|
11
|
-
import { events } from '../utils/events';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Build review prompt
|
|
15
|
-
*/
|
|
16
|
-
export function buildReviewPrompt({ taskName, taskBranch, acceptanceCriteria = [] }: { taskName: string; taskBranch: string; acceptanceCriteria?: string[] }): string {
|
|
17
|
-
const criteriaList = acceptanceCriteria.length > 0
|
|
18
|
-
? acceptanceCriteria.map((c, i) => `${i + 1}. ${c}`).join('\n')
|
|
19
|
-
: 'Work should be completed properly.';
|
|
20
|
-
|
|
21
|
-
return `# Code Review: ${taskName}
|
|
22
|
-
|
|
23
|
-
## Role
|
|
24
|
-
You are a senior code reviewer. Please review the results of this task.
|
|
25
|
-
|
|
26
|
-
## Task Details
|
|
27
|
-
- Name: ${taskName}
|
|
28
|
-
- Branch: ${taskBranch}
|
|
29
|
-
|
|
30
|
-
## Acceptance Criteria
|
|
31
|
-
${criteriaList}
|
|
32
|
-
|
|
33
|
-
## Review Checklist
|
|
34
|
-
1. **Build Success**: Does \`pnpm build\` complete without errors?
|
|
35
|
-
2. **Code Quality**: Are there no linting or TypeScript type errors?
|
|
36
|
-
3. **Completeness**: Are all acceptance criteria met?
|
|
37
|
-
4. **Bugs**: Are there any obvious bugs or logic errors?
|
|
38
|
-
5. **Commit Status**: Are changes properly committed and pushed?
|
|
39
|
-
|
|
40
|
-
## Output Format (MUST follow exactly)
|
|
41
|
-
\`\`\`json
|
|
42
|
-
{
|
|
43
|
-
"status": "approved" | "needs_changes",
|
|
44
|
-
"buildSuccess": true | false,
|
|
45
|
-
"issues": [
|
|
46
|
-
{
|
|
47
|
-
"severity": "critical" | "major" | "minor",
|
|
48
|
-
"description": "...",
|
|
49
|
-
"file": "...",
|
|
50
|
-
"suggestion": "..."
|
|
51
|
-
}
|
|
52
|
-
],
|
|
53
|
-
"suggestions": ["..."],
|
|
54
|
-
"summary": "One-line summary"
|
|
55
|
-
}
|
|
56
|
-
\`\`\`
|
|
57
|
-
|
|
58
|
-
IMPORTANT: You MUST respond in the exact JSON format above. "status" must be either "approved" or "needs_changes".
|
|
59
|
-
`;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Parse review result
|
|
64
|
-
*/
|
|
65
|
-
export function parseReviewResult(text: string): ReviewResult {
|
|
66
|
-
const t = String(text || '');
|
|
67
|
-
|
|
68
|
-
// Try JSON block
|
|
69
|
-
const jsonMatch = t.match(/```json\n([\s\S]*?)\n```/);
|
|
70
|
-
if (jsonMatch) {
|
|
71
|
-
try {
|
|
72
|
-
const parsed = JSON.parse(jsonMatch[1]!);
|
|
73
|
-
return {
|
|
74
|
-
status: parsed.status || 'needs_changes',
|
|
75
|
-
buildSuccess: parsed.buildSuccess !== false,
|
|
76
|
-
issues: Array.isArray(parsed.issues) ? (parsed.issues as ReviewIssue[]) : [],
|
|
77
|
-
suggestions: Array.isArray(parsed.suggestions) ? (parsed.suggestions as string[]) : [],
|
|
78
|
-
summary: parsed.summary || '',
|
|
79
|
-
raw: t,
|
|
80
|
-
};
|
|
81
|
-
} catch (err: any) {
|
|
82
|
-
logger.warn(`JSON parse failed: ${err.message}`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Fallback parsing
|
|
87
|
-
const hasApproved = t.toLowerCase().includes('approved');
|
|
88
|
-
const hasIssues = t.toLowerCase().includes('needs_changes') ||
|
|
89
|
-
t.toLowerCase().includes('error') ||
|
|
90
|
-
t.toLowerCase().includes('failed');
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
status: hasApproved && !hasIssues ? 'approved' : 'needs_changes',
|
|
94
|
-
buildSuccess: !t.toLowerCase().includes('build') || !t.toLowerCase().includes('fail'),
|
|
95
|
-
issues: hasIssues ? [{ severity: 'major', description: 'Parse failed, see logs' }] : [],
|
|
96
|
-
suggestions: [],
|
|
97
|
-
summary: 'Auto-parsed - check original response',
|
|
98
|
-
raw: t,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Build feedback prompt
|
|
104
|
-
*/
|
|
105
|
-
export function buildFeedbackPrompt(review: ReviewResult): string {
|
|
106
|
-
const lines: string[] = [];
|
|
107
|
-
lines.push('# Code Review Feedback');
|
|
108
|
-
lines.push('');
|
|
109
|
-
lines.push('The reviewer found the following issues. Please fix them:');
|
|
110
|
-
lines.push('');
|
|
111
|
-
|
|
112
|
-
if (!review.buildSuccess) {
|
|
113
|
-
lines.push('## CRITICAL: Build Failed');
|
|
114
|
-
lines.push('- \`pnpm build\` failed. Fix build errors first.');
|
|
115
|
-
lines.push('');
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
for (const issue of review.issues || []) {
|
|
119
|
-
const severity = (issue.severity || 'major').toUpperCase();
|
|
120
|
-
lines.push(`## ${severity}: ${issue.description}`);
|
|
121
|
-
if (issue.file) lines.push(`- File: ${issue.file}`);
|
|
122
|
-
if (issue.suggestion) lines.push(`- Suggestion: ${issue.suggestion}`);
|
|
123
|
-
lines.push('');
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (review.suggestions && review.suggestions.length > 0) {
|
|
127
|
-
lines.push('## Additional Suggestions');
|
|
128
|
-
for (const s of review.suggestions) {
|
|
129
|
-
lines.push(`- ${s}`);
|
|
130
|
-
}
|
|
131
|
-
lines.push('');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
lines.push('## Requirements');
|
|
135
|
-
lines.push('1. Fix all issues listed above');
|
|
136
|
-
lines.push('2. Ensure \`pnpm build\` succeeds');
|
|
137
|
-
lines.push('3. Commit and push your changes');
|
|
138
|
-
lines.push('');
|
|
139
|
-
lines.push('**Let me know when fixes are complete.**');
|
|
140
|
-
|
|
141
|
-
return lines.join('\n');
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Review task
|
|
146
|
-
*/
|
|
147
|
-
export async function reviewTask({ taskResult, worktreeDir, runDir, config, model, cursorAgentSend, cursorAgentCreateChat }: {
|
|
148
|
-
taskResult: TaskResult;
|
|
149
|
-
worktreeDir: string;
|
|
150
|
-
runDir: string;
|
|
151
|
-
config: RunnerConfig;
|
|
152
|
-
model?: string;
|
|
153
|
-
cursorAgentSend: (options: {
|
|
154
|
-
workspaceDir: string;
|
|
155
|
-
chatId: string;
|
|
156
|
-
prompt: string;
|
|
157
|
-
model?: string;
|
|
158
|
-
outputFormat?: 'stream-json' | 'json' | 'plain';
|
|
159
|
-
taskName?: string;
|
|
160
|
-
}) => Promise<AgentSendResult>;
|
|
161
|
-
cursorAgentCreateChat: () => string;
|
|
162
|
-
}): Promise<ReviewResult> {
|
|
163
|
-
const reviewPrompt = buildReviewPrompt({
|
|
164
|
-
taskName: taskResult.taskName,
|
|
165
|
-
taskBranch: taskResult.taskBranch,
|
|
166
|
-
acceptanceCriteria: taskResult.acceptanceCriteria || config.acceptanceCriteria || [],
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
logger.info(`Reviewing: ${taskResult.taskName}`);
|
|
170
|
-
|
|
171
|
-
events.emit('review.started', {
|
|
172
|
-
taskName: taskResult.taskName,
|
|
173
|
-
taskBranch: taskResult.taskBranch,
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
const reviewChatId = cursorAgentCreateChat();
|
|
177
|
-
const reviewModel = model || config.reviewModel || config.model || 'sonnet-4.5';
|
|
178
|
-
|
|
179
|
-
const reviewResult = await cursorAgentSend({
|
|
180
|
-
workspaceDir: worktreeDir,
|
|
181
|
-
chatId: reviewChatId,
|
|
182
|
-
prompt: reviewPrompt,
|
|
183
|
-
model: reviewModel,
|
|
184
|
-
outputFormat: config.agentOutputFormat,
|
|
185
|
-
taskName: `review:${taskResult.taskName}`,
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
const review = parseReviewResult(reviewResult.resultText || '');
|
|
189
|
-
|
|
190
|
-
// Log review
|
|
191
|
-
const convoPath = path.join(runDir, 'conversation.jsonl');
|
|
192
|
-
appendLog(convoPath, createConversationEntry('reviewer', reviewResult.resultText || 'No result', {
|
|
193
|
-
task: taskResult.taskName,
|
|
194
|
-
model: reviewModel,
|
|
195
|
-
}));
|
|
196
|
-
|
|
197
|
-
logger.info(`Review result: ${review.status} (${review.issues?.length || 0} issues)`);
|
|
198
|
-
|
|
199
|
-
events.emit('review.completed', {
|
|
200
|
-
taskName: taskResult.taskName,
|
|
201
|
-
status: review.status,
|
|
202
|
-
issueCount: review.issues?.length || 0,
|
|
203
|
-
summary: review.summary,
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
return review;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Review loop with feedback
|
|
211
|
-
*/
|
|
212
|
-
export async function runReviewLoop({ taskResult, worktreeDir, runDir, config, workChatId, model, cursorAgentSend, cursorAgentCreateChat }: {
|
|
213
|
-
taskResult: TaskResult;
|
|
214
|
-
worktreeDir: string;
|
|
215
|
-
runDir: string;
|
|
216
|
-
config: RunnerConfig;
|
|
217
|
-
workChatId: string;
|
|
218
|
-
model?: string;
|
|
219
|
-
cursorAgentSend: (options: {
|
|
220
|
-
workspaceDir: string;
|
|
221
|
-
chatId: string;
|
|
222
|
-
prompt: string;
|
|
223
|
-
model?: string;
|
|
224
|
-
outputFormat?: 'stream-json' | 'json' | 'plain';
|
|
225
|
-
taskName?: string;
|
|
226
|
-
}) => Promise<AgentSendResult>;
|
|
227
|
-
cursorAgentCreateChat: () => string;
|
|
228
|
-
}): Promise<{ approved: boolean; review: ReviewResult; iterations: number; error?: string }> {
|
|
229
|
-
const maxIterations = config.maxReviewIterations || 3;
|
|
230
|
-
let iteration = 0;
|
|
231
|
-
let currentReview: ReviewResult | null = null;
|
|
232
|
-
|
|
233
|
-
while (iteration < maxIterations) {
|
|
234
|
-
currentReview = await reviewTask({
|
|
235
|
-
taskResult,
|
|
236
|
-
worktreeDir,
|
|
237
|
-
runDir,
|
|
238
|
-
config,
|
|
239
|
-
model,
|
|
240
|
-
cursorAgentSend,
|
|
241
|
-
cursorAgentCreateChat,
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
if (currentReview.status === 'approved') {
|
|
245
|
-
logger.success(`Review passed: ${taskResult.taskName} (iteration ${iteration + 1})`);
|
|
246
|
-
events.emit('review.approved', {
|
|
247
|
-
taskName: taskResult.taskName,
|
|
248
|
-
iterations: iteration + 1,
|
|
249
|
-
});
|
|
250
|
-
return { approved: true, review: currentReview, iterations: iteration + 1 };
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
iteration++;
|
|
254
|
-
|
|
255
|
-
if (iteration >= maxIterations) {
|
|
256
|
-
logger.warn(`Max review iterations (${maxIterations}) reached: ${taskResult.taskName}`);
|
|
257
|
-
events.emit('review.rejected', {
|
|
258
|
-
taskName: taskResult.taskName,
|
|
259
|
-
reason: 'Max iterations reached',
|
|
260
|
-
iterations: iteration,
|
|
261
|
-
});
|
|
262
|
-
break;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Send feedback
|
|
266
|
-
logger.info(`Sending feedback (iteration ${iteration}/${maxIterations})`);
|
|
267
|
-
const feedbackPrompt = buildFeedbackPrompt(currentReview);
|
|
268
|
-
|
|
269
|
-
const fixResult = await cursorAgentSend({
|
|
270
|
-
workspaceDir: worktreeDir,
|
|
271
|
-
chatId: workChatId,
|
|
272
|
-
prompt: feedbackPrompt,
|
|
273
|
-
model: config.model,
|
|
274
|
-
outputFormat: config.agentOutputFormat,
|
|
275
|
-
taskName: taskResult.taskName,
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
if (!fixResult.ok) {
|
|
279
|
-
logger.error(`Feedback application failed: ${fixResult.error}`);
|
|
280
|
-
return { approved: false, review: currentReview, iterations: iteration, error: fixResult.error };
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
return { approved: false, review: currentReview!, iterations: iteration };
|
|
285
|
-
}
|