@litmers/cursorflow-orchestrator 0.1.31 → 0.1.36

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 (150) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +182 -59
  3. package/commands/cursorflow-add.md +159 -0
  4. package/commands/cursorflow-doctor.md +45 -23
  5. package/commands/cursorflow-monitor.md +23 -2
  6. package/commands/cursorflow-new.md +87 -0
  7. package/commands/cursorflow-run.md +60 -111
  8. package/dist/cli/add.d.ts +7 -0
  9. package/dist/cli/add.js +377 -0
  10. package/dist/cli/add.js.map +1 -0
  11. package/dist/cli/clean.js +1 -0
  12. package/dist/cli/clean.js.map +1 -1
  13. package/dist/cli/config.d.ts +7 -0
  14. package/dist/cli/config.js +181 -0
  15. package/dist/cli/config.js.map +1 -0
  16. package/dist/cli/doctor.js +47 -4
  17. package/dist/cli/doctor.js.map +1 -1
  18. package/dist/cli/index.js +34 -30
  19. package/dist/cli/index.js.map +1 -1
  20. package/dist/cli/logs.js +17 -34
  21. package/dist/cli/logs.js.map +1 -1
  22. package/dist/cli/monitor.js +62 -65
  23. package/dist/cli/monitor.js.map +1 -1
  24. package/dist/cli/new.d.ts +7 -0
  25. package/dist/cli/new.js +232 -0
  26. package/dist/cli/new.js.map +1 -0
  27. package/dist/cli/prepare.js +95 -193
  28. package/dist/cli/prepare.js.map +1 -1
  29. package/dist/cli/resume.js +57 -68
  30. package/dist/cli/resume.js.map +1 -1
  31. package/dist/cli/run.js +60 -30
  32. package/dist/cli/run.js.map +1 -1
  33. package/dist/cli/stop.js +6 -0
  34. package/dist/cli/stop.js.map +1 -1
  35. package/dist/cli/tasks.d.ts +5 -3
  36. package/dist/cli/tasks.js +181 -29
  37. package/dist/cli/tasks.js.map +1 -1
  38. package/dist/core/failure-policy.d.ts +9 -0
  39. package/dist/core/failure-policy.js +9 -0
  40. package/dist/core/failure-policy.js.map +1 -1
  41. package/dist/core/orchestrator.d.ts +20 -6
  42. package/dist/core/orchestrator.js +215 -334
  43. package/dist/core/orchestrator.js.map +1 -1
  44. package/dist/core/runner/agent.d.ts +27 -0
  45. package/dist/core/runner/agent.js +294 -0
  46. package/dist/core/runner/agent.js.map +1 -0
  47. package/dist/core/runner/index.d.ts +5 -0
  48. package/dist/core/runner/index.js +22 -0
  49. package/dist/core/runner/index.js.map +1 -0
  50. package/dist/core/runner/pipeline.d.ts +9 -0
  51. package/dist/core/runner/pipeline.js +539 -0
  52. package/dist/core/runner/pipeline.js.map +1 -0
  53. package/dist/core/runner/prompt.d.ts +25 -0
  54. package/dist/core/runner/prompt.js +175 -0
  55. package/dist/core/runner/prompt.js.map +1 -0
  56. package/dist/core/runner/task.d.ts +26 -0
  57. package/dist/core/runner/task.js +283 -0
  58. package/dist/core/runner/task.js.map +1 -0
  59. package/dist/core/runner/utils.d.ts +37 -0
  60. package/dist/core/runner/utils.js +161 -0
  61. package/dist/core/runner/utils.js.map +1 -0
  62. package/dist/core/runner.d.ts +2 -96
  63. package/dist/core/runner.js +11 -1136
  64. package/dist/core/runner.js.map +1 -1
  65. package/dist/core/stall-detection.d.ts +326 -0
  66. package/dist/core/stall-detection.js +781 -0
  67. package/dist/core/stall-detection.js.map +1 -0
  68. package/dist/services/logging/console.js +2 -1
  69. package/dist/services/logging/console.js.map +1 -1
  70. package/dist/types/config.d.ts +6 -6
  71. package/dist/types/flow.d.ts +84 -0
  72. package/dist/types/flow.js +10 -0
  73. package/dist/types/flow.js.map +1 -0
  74. package/dist/types/index.d.ts +1 -0
  75. package/dist/types/index.js +3 -3
  76. package/dist/types/index.js.map +1 -1
  77. package/dist/types/lane.d.ts +0 -2
  78. package/dist/types/logging.d.ts +5 -1
  79. package/dist/types/task.d.ts +7 -11
  80. package/dist/utils/config.d.ts +5 -1
  81. package/dist/utils/config.js +15 -16
  82. package/dist/utils/config.js.map +1 -1
  83. package/dist/utils/dependency.d.ts +36 -1
  84. package/dist/utils/dependency.js +256 -1
  85. package/dist/utils/dependency.js.map +1 -1
  86. package/dist/utils/doctor.js +40 -8
  87. package/dist/utils/doctor.js.map +1 -1
  88. package/dist/utils/enhanced-logger.d.ts +45 -82
  89. package/dist/utils/enhanced-logger.js +239 -844
  90. package/dist/utils/enhanced-logger.js.map +1 -1
  91. package/dist/utils/flow.d.ts +9 -0
  92. package/dist/utils/flow.js +73 -0
  93. package/dist/utils/flow.js.map +1 -0
  94. package/dist/utils/git.d.ts +29 -0
  95. package/dist/utils/git.js +115 -5
  96. package/dist/utils/git.js.map +1 -1
  97. package/dist/utils/state.js +0 -2
  98. package/dist/utils/state.js.map +1 -1
  99. package/dist/utils/task-service.d.ts +2 -2
  100. package/dist/utils/task-service.js +40 -31
  101. package/dist/utils/task-service.js.map +1 -1
  102. package/package.json +4 -3
  103. package/src/cli/add.ts +397 -0
  104. package/src/cli/clean.ts +1 -0
  105. package/src/cli/config.ts +177 -0
  106. package/src/cli/doctor.ts +48 -4
  107. package/src/cli/index.ts +36 -32
  108. package/src/cli/logs.ts +20 -33
  109. package/src/cli/monitor.ts +70 -75
  110. package/src/cli/new.ts +235 -0
  111. package/src/cli/prepare.ts +98 -205
  112. package/src/cli/resume.ts +61 -76
  113. package/src/cli/run.ts +333 -306
  114. package/src/cli/stop.ts +8 -0
  115. package/src/cli/tasks.ts +200 -21
  116. package/src/core/failure-policy.ts +9 -0
  117. package/src/core/orchestrator.ts +279 -379
  118. package/src/core/runner/agent.ts +314 -0
  119. package/src/core/runner/index.ts +6 -0
  120. package/src/core/runner/pipeline.ts +567 -0
  121. package/src/core/runner/prompt.ts +174 -0
  122. package/src/core/runner/task.ts +320 -0
  123. package/src/core/runner/utils.ts +142 -0
  124. package/src/core/runner.ts +8 -1347
  125. package/src/core/stall-detection.ts +936 -0
  126. package/src/services/logging/console.ts +2 -1
  127. package/src/types/config.ts +6 -6
  128. package/src/types/flow.ts +91 -0
  129. package/src/types/index.ts +15 -3
  130. package/src/types/lane.ts +0 -2
  131. package/src/types/logging.ts +5 -1
  132. package/src/types/task.ts +7 -11
  133. package/src/utils/config.ts +16 -17
  134. package/src/utils/dependency.ts +311 -2
  135. package/src/utils/doctor.ts +36 -8
  136. package/src/utils/enhanced-logger.ts +264 -927
  137. package/src/utils/flow.ts +42 -0
  138. package/src/utils/git.ts +145 -5
  139. package/src/utils/state.ts +0 -2
  140. package/src/utils/task-service.ts +48 -40
  141. package/commands/cursorflow-review.md +0 -56
  142. package/commands/cursorflow-runs.md +0 -59
  143. package/dist/cli/runs.d.ts +0 -5
  144. package/dist/cli/runs.js +0 -214
  145. package/dist/cli/runs.js.map +0 -1
  146. package/dist/core/reviewer.d.ts +0 -66
  147. package/dist/core/reviewer.js +0 -265
  148. package/dist/core/reviewer.js.map +0 -1
  149. package/src/cli/runs.ts +0 -212
  150. package/src/core/reviewer.ts +0 -285
package/src/cli/resume.ts CHANGED
@@ -11,6 +11,7 @@ import { loadState, saveState } from '../utils/state';
11
11
  import { LaneState } from '../types';
12
12
  import { runDoctor } from '../utils/doctor';
13
13
  import { safeJoin } from '../utils/path';
14
+ import { findFlowDir } from '../utils/flow';
14
15
  import {
15
16
  EnhancedLogManager,
16
17
  createLogManager,
@@ -115,7 +116,6 @@ interface LaneInfo {
115
116
  dir: string;
116
117
  state: LaneState | null;
117
118
  needsResume: boolean;
118
- dependsOn: string[];
119
119
  isCompleted: boolean;
120
120
  }
121
121
 
@@ -295,39 +295,22 @@ function getAllLaneStatuses(runDir: string): LaneInfo[] {
295
295
  ) : true;
296
296
 
297
297
  const isCompleted = state?.status === 'completed';
298
- const dependsOn = state?.dependsOn || [];
299
298
 
300
- return { name, dir, state, needsResume, dependsOn, isCompleted };
299
+ return { name, dir, state, needsResume, isCompleted };
301
300
  });
302
301
 
303
302
  return lanes;
304
303
  }
305
304
 
306
305
  /**
307
- * Check if all dependencies of a lane are completed
306
+ * Check if lane can be resumed (lane-level deps removed, always true)
308
307
  */
309
308
  function areDependenciesCompleted(
310
- lane: LaneInfo,
311
- allLanes: LaneInfo[],
312
- completedLanes: Set<string>
309
+ _lane: LaneInfo,
310
+ _allLanes: LaneInfo[],
311
+ _completedLanes: Set<string>
313
312
  ): boolean {
314
- if (!lane.dependsOn || lane.dependsOn.length === 0) {
315
- return true;
316
- }
317
-
318
- for (const depName of lane.dependsOn) {
319
- // Check if dependency is in completed set (already succeeded in this resume session)
320
- if (completedLanes.has(depName)) {
321
- continue;
322
- }
323
-
324
- // Check if dependency was already completed before this resume
325
- const depLane = allLanes.find(l => l.name === depName);
326
- if (!depLane || !depLane.isCompleted) {
327
- return false;
328
- }
329
- }
330
-
313
+ // Lane-level dependencies removed - use task-level dependsOn instead
331
314
  return true;
332
315
  }
333
316
 
@@ -371,40 +354,25 @@ function printAllLaneStatus(runDir: string): { total: number; completed: number;
371
354
  const status = state?.status || 'unknown';
372
355
  const color = STATUS_COLORS[status] || STATUS_COLORS.unknown;
373
356
  const progress = state ? `${state.currentTaskIndex}/${state.totalTasks}` : '-/-';
374
- const dependsOnStr = lane.dependsOn.length > 0 ? lane.dependsOn.join(',').substring(0, 12) : '-';
375
-
376
- // Check if dependencies are met
377
- const depsCompleted = areDependenciesCompleted(lane, lanes, completedSet);
378
- const canResume = lane.needsResume && depsCompleted;
379
- const blockedByDep = lane.needsResume && !depsCompleted;
380
357
 
381
358
  if (status === 'completed') completedCount++;
382
359
  if (lane.needsResume) needsResumeCount++;
383
360
 
384
361
  let resumeIndicator = '';
385
- if (canResume) {
386
- resumeIndicator = '\x1b[33m✓\x1b[0m';
387
- } else if (blockedByDep) {
388
- resumeIndicator = '\x1b[90m⏳ waiting\x1b[0m';
362
+ if (lane.needsResume) {
363
+ resumeIndicator = '\x1b[33m✓ resumable\x1b[0m';
389
364
  }
390
365
 
391
366
  console.log(' ' +
392
- lane.name.padEnd(25) +
367
+ lane.name.padEnd(30) +
393
368
  `${color}${status.padEnd(12)}${RESET}` +
394
369
  progress.padEnd(12) +
395
- dependsOnStr.padEnd(15) +
396
370
  resumeIndicator
397
371
  );
398
372
 
399
373
  // Show error if failed
400
374
  if (status === 'failed' && state?.error) {
401
- console.log(` ${''.padEnd(25)}\x1b[31m└─ ${state.error.substring(0, 50)}${state.error.length > 50 ? '...' : ''}\x1b[0m`);
402
- }
403
-
404
- // Show blocked dependency info
405
- if (blockedByDep) {
406
- const pendingDeps = lane.dependsOn.filter(d => !completedSet.has(d));
407
- console.log(` ${''.padEnd(25)}\x1b[90m└─ waiting for: ${pendingDeps.join(', ')}\x1b[0m`);
375
+ console.log(` ${''.padEnd(30)}\x1b[31m└─ ${state.error.substring(0, 50)}${state.error.length > 50 ? '...' : ''}\x1b[0m`);
408
376
  }
409
377
  }
410
378
 
@@ -464,9 +432,10 @@ function spawnLaneResume(
464
432
  runnerArgs.push('--executor', options.executor);
465
433
  }
466
434
 
435
+ const shortLaneName = laneName.substring(0, 10);
467
436
  const logManager = createLogManager(laneDir, laneName, options.enhancedLogConfig || {}, (msg) => {
468
437
  const formatted = formatMessageForConsole(msg, {
469
- laneLabel: `[${laneName}]`,
438
+ laneLabel: `[${shortLaneName}]`,
470
439
  includeTimestamp: true
471
440
  });
472
441
  process.stdout.write(formatted + '\n');
@@ -532,17 +501,8 @@ async function resumeLanes(
532
501
  const resolvableLanes: LaneInfo[] = [];
533
502
 
534
503
  for (const lane of lanesToResume) {
535
- // Check if all dependencies can be satisfied (either already completed or in the resume list)
536
- const unmetDeps = lane.dependsOn.filter(dep =>
537
- !completedSet.has(dep) && !toResumeNames.has(dep)
538
- );
539
-
540
- if (unmetDeps.length > 0) {
541
- logger.warn(`⏭ Skipping ${lane.name}: unresolvable dependencies (${unmetDeps.join(', ')})`);
542
- skippedLanes.push(lane.name);
543
- } else {
544
- resolvableLanes.push(lane);
545
- }
504
+ // Lane-level dependencies removed - all lanes can be resumed
505
+ resolvableLanes.push(lane);
546
506
  }
547
507
 
548
508
  if (resolvableLanes.length === 0) {
@@ -612,8 +572,7 @@ async function resumeLanes(
612
572
  }
613
573
 
614
574
  pending.delete(lane.name);
615
- const depsInfo = lane.dependsOn.length > 0 ? ` (after: ${lane.dependsOn.join(', ')})` : '';
616
- logger.info(`Starting: ${lane.name} (task ${lane.state!.currentTaskIndex}/${lane.state!.totalTasks})${depsInfo}`);
575
+ logger.info(`Starting: ${lane.name} (task ${lane.state!.currentTaskIndex}/${lane.state!.totalTasks})`);
617
576
 
618
577
  const { child } = spawnLaneResume(lane.name, lane.dir, lane.state!, {
619
578
  restart: options.restart,
@@ -675,8 +634,19 @@ async function resume(args: string[]): Promise<void> {
675
634
 
676
635
  const config = loadConfig();
677
636
  const logsDir = getLogsDir(config);
637
+ const originalCwd = process.cwd();
638
+
639
+ // Change current directory to project root for consistent path handling
640
+ if (config.projectRoot !== originalCwd) {
641
+ logger.debug(`Changing directory to project root: ${config.projectRoot}`);
642
+ process.chdir(config.projectRoot);
643
+ }
678
644
 
679
645
  let runDir = options.runDir;
646
+ if (runDir && !path.isAbsolute(runDir)) {
647
+ runDir = path.resolve(originalCwd, runDir);
648
+ }
649
+
680
650
  if (!runDir) {
681
651
  runDir = findLatestRunDir(logsDir);
682
652
  }
@@ -688,30 +658,45 @@ async function resume(args: string[]): Promise<void> {
688
658
  const allLanes = getAllLaneStatuses(runDir);
689
659
  let lanesToResume: LaneInfo[] = [];
690
660
 
691
- // Check if the lane argument is actually a tasks directory
692
- if (options.lane && fs.existsSync(options.lane) && fs.statSync(options.lane).isDirectory()) {
693
- const tasksDir = path.resolve(options.lane);
694
- lanesToResume = allLanes.filter(l => l.needsResume && l.state?.tasksFile && path.resolve(l.state.tasksFile).startsWith(tasksDir));
661
+ // Check if the lane argument is actually a tasks directory or a flow name
662
+ if (options.lane) {
663
+ let tasksDir = '';
664
+ const lanePathAbs = path.resolve(originalCwd, options.lane);
695
665
 
696
- if (lanesToResume.length > 0) {
697
- logger.info(`📂 Task directory detected: ${options.lane}`);
698
- logger.info(`Resuming ${lanesToResume.length} lane(s) from this directory.`);
666
+ if (fs.existsSync(lanePathAbs) && fs.statSync(lanePathAbs).isDirectory()) {
667
+ tasksDir = lanePathAbs;
699
668
  } else {
700
- logger.warn(`No incomplete lanes found using tasks from directory: ${options.lane}`);
701
- return;
669
+ // Try finding in flowsDir
670
+ const flowsDir = safeJoin(config.projectRoot, config.flowsDir);
671
+ const foundFlow = findFlowDir(flowsDir, options.lane);
672
+ if (foundFlow) {
673
+ tasksDir = foundFlow;
674
+ }
675
+ }
676
+
677
+ if (tasksDir) {
678
+ lanesToResume = allLanes.filter(l => l.needsResume && l.state?.tasksFile && path.resolve(l.state.tasksFile).startsWith(tasksDir));
679
+
680
+ if (lanesToResume.length > 0) {
681
+ logger.info(`📂 Flow/Task directory detected: ${options.lane}`);
682
+ logger.info(`Resuming ${lanesToResume.length} lane(s) from this directory.`);
683
+ } else {
684
+ logger.warn(`No incomplete lanes found using tasks from directory: ${options.lane}`);
685
+ return;
686
+ }
687
+ } else {
688
+ const lane = allLanes.find(l => l.name === options.lane);
689
+ if (!lane) {
690
+ throw new Error(`Lane '${options.lane}' not found in run directory.`);
691
+ }
692
+ if (!lane.needsResume) {
693
+ logger.success(`Lane '${options.lane}' is already completed.`);
694
+ return;
695
+ }
696
+ lanesToResume = [lane];
702
697
  }
703
698
  } else if (options.all) {
704
699
  lanesToResume = allLanes.filter(l => l.needsResume && l.state?.tasksFile);
705
- } else if (options.lane) {
706
- const lane = allLanes.find(l => l.name === options.lane);
707
- if (!lane) {
708
- throw new Error(`Lane '${options.lane}' not found in run directory.`);
709
- }
710
- if (!lane.needsResume) {
711
- logger.success(`Lane '${options.lane}' is already completed.`);
712
- return;
713
- }
714
- lanesToResume = [lane];
715
700
  }
716
701
 
717
702
  // Check for zombie lanes