@litmers/cursorflow-orchestrator 0.1.34 → 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.
- package/CHANGELOG.md +27 -0
- package/README.md +38 -7
- package/commands/cursorflow-doctor.md +45 -23
- package/commands/cursorflow-run.md +60 -111
- package/dist/cli/doctor.js +47 -4
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/logs.js +10 -1
- package/dist/cli/logs.js.map +1 -1
- package/dist/cli/monitor.js +12 -4
- package/dist/cli/monitor.js.map +1 -1
- package/dist/cli/resume.js +46 -21
- package/dist/cli/resume.js.map +1 -1
- package/dist/cli/run.js +33 -8
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/stop.js +6 -0
- package/dist/cli/stop.js.map +1 -1
- package/dist/cli/tasks.d.ts +5 -3
- package/dist/cli/tasks.js +180 -27
- package/dist/cli/tasks.js.map +1 -1
- package/dist/core/orchestrator.js +6 -5
- package/dist/core/orchestrator.js.map +1 -1
- package/dist/services/logging/console.js +2 -1
- package/dist/services/logging/console.js.map +1 -1
- package/dist/utils/config.d.ts +5 -1
- package/dist/utils/config.js +8 -1
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/doctor.js +40 -8
- package/dist/utils/doctor.js.map +1 -1
- package/dist/utils/enhanced-logger.d.ts +1 -1
- package/dist/utils/enhanced-logger.js +3 -2
- package/dist/utils/enhanced-logger.js.map +1 -1
- package/dist/utils/flow.d.ts +9 -0
- package/dist/utils/flow.js +73 -0
- package/dist/utils/flow.js.map +1 -0
- package/package.json +1 -1
- package/src/cli/doctor.ts +48 -4
- package/src/cli/logs.ts +13 -2
- package/src/cli/monitor.ts +16 -5
- package/src/cli/resume.ts +48 -20
- package/src/cli/run.ts +31 -9
- package/src/cli/stop.ts +8 -0
- package/src/cli/tasks.ts +199 -19
- package/src/core/orchestrator.ts +6 -5
- package/src/services/logging/console.ts +2 -1
- package/src/utils/config.ts +8 -1
- package/src/utils/doctor.ts +36 -8
- package/src/utils/enhanced-logger.ts +3 -2
- package/src/utils/flow.ts +42 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.1.36] - 2025-12-26
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **CLI**: Fixed indentation and validation logic in `tasks` command.
|
|
12
|
+
- **Tests**: Improved `stop.test.ts` stability by mocking `process.chdir`.
|
|
13
|
+
- **E2E**: Removed redundant `lane-a.json` from `test-tasks-e2e`.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- **Release**: Improved release process with annotated tags.
|
|
17
|
+
|
|
18
|
+
## [0.1.35] - 2025-12-26
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- **Log Format**: Updated log format to `L{n}-T{t}-{lanename}` with single-digit numbers and 10-char max lane name for cleaner output.
|
|
22
|
+
- **Flow Support**: All commands now support flow names in addition to directory paths.
|
|
23
|
+
- `run`, `resume`, `doctor` can now use flow names like `cursorflow run MyFlow`
|
|
24
|
+
- `tasks` command now browses flows from `_cursorflow/flows/` directory
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- **Build Errors**: Fixed missing `getLogsDir` import in `logs.ts` and `monitor.ts`.
|
|
28
|
+
- **Flow Recognition**: Fixed `flow.meta.json` being incorrectly treated as a lane file in orchestrator.
|
|
29
|
+
- **Doctor CLI**: Fixed positional argument parsing for flow names.
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
- `getFlowsDir()` function in config.ts for consistent flow directory resolution.
|
|
33
|
+
- `findFlowDir()` utility for resolving flow names to paths.
|
|
34
|
+
|
|
8
35
|
## [0.1.30] - 2025-12-25
|
|
9
36
|
|
|
10
37
|
### Added
|
package/README.md
CHANGED
|
@@ -266,23 +266,54 @@ cursorflow doctor --tasks-dir _cursorflow/tasks/my-feature
|
|
|
266
266
|
|
|
267
267
|
## 📚 Commands Reference
|
|
268
268
|
|
|
269
|
+
### Flow Commands (New)
|
|
270
|
+
| Command | Description |
|
|
271
|
+
|---------|-------------|
|
|
272
|
+
| `cursorflow new` | Create Flow with Lanes |
|
|
273
|
+
| `cursorflow add` | Add Tasks to Lane |
|
|
274
|
+
| `cursorflow config` | View/set configuration |
|
|
275
|
+
| `cursorflow tasks` | Browse flows and legacy tasks |
|
|
276
|
+
|
|
277
|
+
### Execution
|
|
269
278
|
| Command | Description |
|
|
270
279
|
|---------|-------------|
|
|
271
|
-
| `cursorflow init` | Initialize CursorFlow in project |
|
|
272
|
-
| `cursorflow setup` | Install Cursor IDE commands |
|
|
273
|
-
| `cursorflow prepare` | Prepare task directory and JSON files |
|
|
274
280
|
| `cursorflow run` | Run orchestration (DAG-based) |
|
|
275
281
|
| `cursorflow monitor` | Interactive lane dashboard |
|
|
276
|
-
| `cursorflow clean` | Clean branches/worktrees/logs/tasks |
|
|
277
282
|
| `cursorflow resume` | Resume lane(s) - use --all for batch resume |
|
|
283
|
+
| `cursorflow stop` | Stop running workflows |
|
|
284
|
+
|
|
285
|
+
### Inspection
|
|
286
|
+
| Command | Description |
|
|
287
|
+
|---------|-------------|
|
|
278
288
|
| `cursorflow doctor` | Check environment and preflight |
|
|
279
|
-
| `cursorflow signal` | Directly intervene in a running lane |
|
|
280
|
-
| `cursorflow models` | List available AI models |
|
|
281
289
|
| `cursorflow logs` | View, export, and follow logs |
|
|
290
|
+
| `cursorflow models` | List available AI models |
|
|
291
|
+
|
|
292
|
+
### Utility
|
|
293
|
+
| Command | Description |
|
|
294
|
+
|---------|-------------|
|
|
295
|
+
| `cursorflow init` | Initialize CursorFlow in project |
|
|
296
|
+
| `cursorflow setup` | Install Cursor IDE commands |
|
|
297
|
+
| `cursorflow clean` | Clean branches/worktrees/logs/tasks |
|
|
298
|
+
| `cursorflow signal` | Directly intervene in a running lane |
|
|
299
|
+
|
|
300
|
+
### Legacy
|
|
301
|
+
| Command | Description |
|
|
302
|
+
|---------|-------------|
|
|
303
|
+
| `cursorflow prepare` | (deprecated) Use 'new' + 'add' instead |
|
|
282
304
|
|
|
283
305
|
## 📝 Enhanced Logging
|
|
284
306
|
|
|
285
|
-
CursorFlow provides comprehensive logging with automatic cleanup and export options
|
|
307
|
+
CursorFlow provides comprehensive logging with automatic cleanup and export options.
|
|
308
|
+
|
|
309
|
+
### Log Format
|
|
310
|
+
|
|
311
|
+
Logs use the format `[L{n}-T{t}-{lanename}]`:
|
|
312
|
+
- `L{n}`: Lane number (1-indexed, single digit)
|
|
313
|
+
- `T{t}`: Task number (1-indexed, single digit)
|
|
314
|
+
- `{lanename}`: First 10 characters of lane name
|
|
315
|
+
|
|
316
|
+
Example: `[L1-T2-backend]` = Lane 1, Task 2, lane "backend"
|
|
286
317
|
|
|
287
318
|
### Features
|
|
288
319
|
- **ANSI Stripping**: Clean logs without terminal escape codes
|
|
@@ -1,42 +1,43 @@
|
|
|
1
1
|
# CursorFlow Doctor
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
|
-
Verify that your environment and
|
|
4
|
+
Verify that your environment and flow configurations are properly set up for CursorFlow.
|
|
5
5
|
|
|
6
6
|
## Usage
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
|
-
cursorflow doctor [options]
|
|
9
|
+
cursorflow doctor [flow-name] [options]
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
## Checks Performed
|
|
13
13
|
- **Environment**: Git repository status, remote availability, and worktree support.
|
|
14
14
|
- **Cursor IDE**: Verifies `cursor-agent` is installed and authenticated.
|
|
15
|
-
- **Tasks**: (Optional) Validates
|
|
15
|
+
- **Flow/Tasks**: (Optional) Validates flow JSON files for schema errors or missing fields.
|
|
16
16
|
|
|
17
17
|
## Options
|
|
18
18
|
|
|
19
19
|
| Option | Description |
|
|
20
20
|
|------|------|
|
|
21
|
-
|
|
|
21
|
+
| `[flow-name]` | Flow name to validate (e.g., `SearchFeature`) |
|
|
22
|
+
| `--tasks-dir <path>` | Validate flow/tasks in a specific directory (legacy) |
|
|
22
23
|
| `--executor <type>` | Check environment for `cursor-agent` \| `cloud` |
|
|
23
24
|
| `--test-agent` | Run an interactive agent test (to approve permissions) |
|
|
24
25
|
| `--no-cursor` | Skip Cursor Agent installation and auth checks |
|
|
25
26
|
| `--json` | Output the report in machine-readable JSON format |
|
|
26
27
|
|
|
27
|
-
##
|
|
28
|
+
## Flow Validation
|
|
28
29
|
|
|
29
|
-
When `--tasks-dir` is provided, the doctor performs comprehensive validation:
|
|
30
|
+
When a flow name or `--tasks-dir` is provided, the doctor performs comprehensive validation:
|
|
30
31
|
|
|
31
32
|
### Structure Validation
|
|
32
33
|
- **tasks array**: Must exist and be non-empty
|
|
33
34
|
- **task.name**: Required, must be alphanumeric with `-` and `_` only, unique within lane
|
|
34
35
|
- **task.prompt**: Required, should be descriptive (warns if < 10 chars)
|
|
35
36
|
- **task.model**: Optional, must be string if provided
|
|
36
|
-
- **task.
|
|
37
|
+
- **task.dependsOn**: Optional, task-level dependencies
|
|
37
38
|
|
|
38
39
|
### Dependency Validation (DAG)
|
|
39
|
-
- **Unknown dependencies**: Reports if `dependsOn` references non-existent lanes
|
|
40
|
+
- **Unknown dependencies**: Reports if `dependsOn` references non-existent lanes/tasks
|
|
40
41
|
- **Circular dependencies**: Detects cycles (e.g., A→B→A) that would cause deadlock
|
|
41
42
|
- Reports the exact cycle path for easy debugging
|
|
42
43
|
|
|
@@ -44,30 +45,44 @@ When `--tasks-dir` is provided, the doctor performs comprehensive validation:
|
|
|
44
45
|
- **Prefix collision**: Warns if multiple lanes use the same `branchPrefix`
|
|
45
46
|
- **Existing branch conflicts**: Detects if existing branches match a lane's prefix
|
|
46
47
|
- **Duplicate lane names**: Ensures each lane file has a unique name
|
|
47
|
-
- **Naming suggestions**: Recommends using lane numbers in branch prefixes for consistency
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
❌ Branch prefix collision
|
|
52
|
-
Multiple lanes use the same branchPrefix "feature/lane-1-": 01-lane-1, 02-lane-2
|
|
53
|
-
Fix: Update the branchPrefix in each lane JSON file to be unique
|
|
54
|
-
|
|
55
|
-
⚠️ Existing branches may conflict with 01-lane-1
|
|
56
|
-
Found 2 existing branch(es) matching prefix "feature/lane-1-": feature/lane-1-abc, feature/lane-1-xyz
|
|
57
|
-
Fix: Delete conflicting branches or change the branchPrefix
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Example
|
|
49
|
+
## Examples
|
|
61
50
|
|
|
62
51
|
```bash
|
|
63
52
|
# Basic environment check
|
|
64
53
|
cursorflow doctor
|
|
65
54
|
|
|
55
|
+
# Validate a specific flow by name
|
|
56
|
+
cursorflow doctor SearchFeature
|
|
57
|
+
|
|
66
58
|
# Test agent permissions
|
|
67
59
|
cursorflow doctor --test-agent
|
|
68
60
|
|
|
69
|
-
# Validate a specific
|
|
70
|
-
cursorflow doctor --tasks-dir _cursorflow/
|
|
61
|
+
# Validate a specific flow directory
|
|
62
|
+
cursorflow doctor --tasks-dir _cursorflow/flows/001_SearchFeature
|
|
63
|
+
|
|
64
|
+
# Skip cursor checks (faster)
|
|
65
|
+
cursorflow doctor SearchFeature --no-cursor
|
|
66
|
+
|
|
67
|
+
# Output as JSON
|
|
68
|
+
cursorflow doctor SearchFeature --json
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Example Output
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
75
|
+
🩺 CursorFlow Doctor
|
|
76
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
77
|
+
|
|
78
|
+
cwd: /home/user/project
|
|
79
|
+
repo: /home/user/project
|
|
80
|
+
tasks: /home/user/project/_cursorflow/flows/001_SearchFeature
|
|
81
|
+
|
|
82
|
+
✅ All checks passed
|
|
83
|
+
|
|
84
|
+
💡 Tip: If this is your first run, we recommend running:
|
|
85
|
+
cursorflow doctor --test-agent
|
|
71
86
|
```
|
|
72
87
|
|
|
73
88
|
## Common Issues & Fixes
|
|
@@ -78,3 +93,10 @@ cursorflow doctor --tasks-dir _cursorflow/tasks/my-feature/
|
|
|
78
93
|
| `Not authenticated` | Open Cursor IDE and log in to your account. |
|
|
79
94
|
| `Worktree not supported` | Upgrade your Git version (requires Git >= 2.5). |
|
|
80
95
|
| `Circular dependency` | Check the `dependsOn` fields in your task JSON files. |
|
|
96
|
+
| `Flow not found` | Verify flow name or create with `cursorflow new`. |
|
|
97
|
+
|
|
98
|
+
## Related Commands
|
|
99
|
+
|
|
100
|
+
- [cursorflow new](cursorflow-new.md) - Create Flow and Lanes
|
|
101
|
+
- [cursorflow add](cursorflow-add.md) - Add Tasks to Lanes
|
|
102
|
+
- [cursorflow run](cursorflow-run.md) - Run Flow
|
|
@@ -2,62 +2,66 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
Execute AI agent orchestration using
|
|
5
|
+
Execute AI agent orchestration using Flow configurations. CursorFlow uses a DAG (Directed Acyclic Graph) scheduler to handle task dependencies and automatic branch merging.
|
|
6
6
|
|
|
7
7
|
## Workflow
|
|
8
8
|
|
|
9
9
|
```
|
|
10
10
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
11
|
-
│ 1. Create
|
|
12
|
-
│ (
|
|
11
|
+
│ 1. Create Flow │ ──▶ │ 2. Add Tasks │ ──▶ │ 3. Validate │ ──▶ │ 4. Run │
|
|
12
|
+
│ (new) │ │ (add) │ │ (doctor) │ │ (run) │
|
|
13
13
|
└─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
## Usage
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
cursorflow run <
|
|
19
|
+
cursorflow run <flow-name> [options]
|
|
20
|
+
cursorflow run <flow-path> [options]
|
|
20
21
|
```
|
|
21
22
|
|
|
22
23
|
### Quick Start
|
|
23
24
|
|
|
24
25
|
```bash
|
|
25
|
-
# Step 1: Create lanes
|
|
26
|
-
cursorflow
|
|
26
|
+
# Step 1: Create flow and lanes
|
|
27
|
+
cursorflow new AddAPI --lanes "backend,frontend"
|
|
27
28
|
|
|
28
|
-
# Step 2:
|
|
29
|
-
cursorflow
|
|
30
|
-
--
|
|
29
|
+
# Step 2: Add tasks to lanes
|
|
30
|
+
cursorflow add AddAPI backend \
|
|
31
|
+
--task "name=implement|prompt=Create REST API for users"
|
|
32
|
+
|
|
33
|
+
cursorflow add AddAPI frontend \
|
|
34
|
+
--task "name=ui|prompt=Create frontend UI" \
|
|
35
|
+
--after "backend:implement"
|
|
31
36
|
|
|
32
37
|
# Step 3: Validate configuration
|
|
33
|
-
cursorflow doctor
|
|
38
|
+
cursorflow doctor AddAPI
|
|
34
39
|
|
|
35
40
|
# Step 4: Run
|
|
36
|
-
cursorflow run
|
|
37
|
-
|
|
38
|
-
# Or run the latest prepared task
|
|
39
|
-
cursorflow run latest
|
|
41
|
+
cursorflow run AddAPI
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
## How It Works
|
|
43
45
|
|
|
44
|
-
1. **Load**: Read all JSON files from the
|
|
46
|
+
1. **Load**: Read all JSON files from the flow directory (excluding `flow.meta.json`)
|
|
45
47
|
2. **Validate**: Check `tasks` array, required fields (`name`, `prompt`)
|
|
46
48
|
3. **Resolve**: Build execution order from `dependsOn` dependencies
|
|
47
49
|
4. **Execute**:
|
|
48
50
|
- Start lanes with no dependencies in parallel
|
|
49
|
-
- When a
|
|
50
|
-
- **Dependent
|
|
51
|
+
- When a task completes, unlock dependent tasks
|
|
52
|
+
- **Dependent tasks auto-merge predecessor branches before starting**
|
|
51
53
|
5. **Monitor**: Heartbeat logs every 30 seconds
|
|
52
54
|
|
|
53
55
|
## Options
|
|
54
56
|
|
|
55
57
|
| Option | Description |
|
|
56
58
|
|--------|-------------|
|
|
57
|
-
| `<
|
|
59
|
+
| `<flow-name>` | Flow name (e.g., `AddAPI`) |
|
|
60
|
+
| `<flow-path>` | Flow directory path (e.g., `_cursorflow/flows/001_AddAPI`) |
|
|
58
61
|
| `--max-concurrent <num>` | Limit concurrent lane execution |
|
|
59
62
|
| `--executor <type>` | `cursor-agent` (default) or `cloud` |
|
|
60
63
|
| `--skip-doctor` | Skip environment checks (not recommended) |
|
|
64
|
+
| `--no-git` | Skip Git operations (worktree, commits, push) |
|
|
61
65
|
| `--dry-run` | Show execution plan without running |
|
|
62
66
|
|
|
63
67
|
## Execution Flow
|
|
@@ -65,15 +69,16 @@ cursorflow run latest
|
|
|
65
69
|
### Single Lane
|
|
66
70
|
|
|
67
71
|
```bash
|
|
68
|
-
cursorflow
|
|
69
|
-
cursorflow
|
|
72
|
+
cursorflow new SimpleFix --lanes "main"
|
|
73
|
+
cursorflow add SimpleFix main --task "name=fix|prompt=Fix the bug"
|
|
74
|
+
cursorflow run SimpleFix
|
|
70
75
|
```
|
|
71
76
|
|
|
72
77
|
```
|
|
73
78
|
┌─────────────────────────────────────────────────────────┐
|
|
74
|
-
│
|
|
79
|
+
│ main │
|
|
75
80
|
│ ┌─────────┐ │
|
|
76
|
-
│ │
|
|
81
|
+
│ │ fix │ → AI executes → Complete │
|
|
77
82
|
│ └─────────┘ │
|
|
78
83
|
└─────────────────────────────────────────────────────────┘
|
|
79
84
|
```
|
|
@@ -81,108 +86,67 @@ cursorflow run _cursorflow/tasks/2412211530_SimpleFix
|
|
|
81
86
|
### Multiple Tasks in Lane
|
|
82
87
|
|
|
83
88
|
```bash
|
|
84
|
-
cursorflow
|
|
85
|
-
--task "plan|
|
|
86
|
-
--task "implement|
|
|
89
|
+
cursorflow add Feature api \
|
|
90
|
+
--task "name=plan|prompt=Create plan" \
|
|
91
|
+
--task "name=implement|prompt=Build feature"
|
|
87
92
|
```
|
|
88
93
|
|
|
89
94
|
```
|
|
90
95
|
┌─────────────────────────────────────────────────────────┐
|
|
91
|
-
│
|
|
96
|
+
│ api │
|
|
92
97
|
│ ┌────┐ ┌─────────┐ │
|
|
93
|
-
│ │plan│ ──▶ │implement│ →
|
|
98
|
+
│ │plan│ ──▶ │implement│ → Complete │
|
|
94
99
|
│ └────┘ └─────────┘ │
|
|
95
100
|
└─────────────────────────────────────────────────────────┘
|
|
96
101
|
```
|
|
97
102
|
|
|
98
|
-
### Sequential Lanes (with
|
|
103
|
+
### Sequential Lanes (with dependencies)
|
|
99
104
|
|
|
100
105
|
```bash
|
|
101
|
-
cursorflow
|
|
102
|
-
|
|
106
|
+
cursorflow new FullStack --lanes "backend,api,frontend"
|
|
107
|
+
|
|
108
|
+
cursorflow add FullStack backend --task "name=db|prompt=Setup database"
|
|
109
|
+
cursorflow add FullStack api --task "name=impl|prompt=Create API" --after "backend"
|
|
110
|
+
cursorflow add FullStack frontend --task "name=ui|prompt=Create UI" --after "api"
|
|
103
111
|
```
|
|
104
112
|
|
|
105
113
|
```
|
|
106
114
|
┌───────────┐ ┌───────────┐ ┌───────────┐
|
|
107
|
-
│
|
|
108
|
-
│
|
|
115
|
+
│ backend │ ──▶ │ api │ ──▶ │ frontend │
|
|
116
|
+
│ (db) │ │ (impl) │ │ (ui) │
|
|
109
117
|
└───────────┘ └───────────┘ └───────────┘
|
|
110
118
|
│ │
|
|
111
|
-
|
|
119
|
+
merges merges
|
|
120
|
+
backend backend,api
|
|
112
121
|
```
|
|
113
122
|
|
|
114
123
|
### Parallel Lanes
|
|
115
124
|
|
|
116
125
|
```bash
|
|
117
|
-
cursorflow
|
|
118
|
-
|
|
126
|
+
cursorflow new FrontBack --lanes "frontend,backend"
|
|
127
|
+
|
|
128
|
+
cursorflow add FrontBack frontend --task "name=ui|prompt=Create UI"
|
|
129
|
+
cursorflow add FrontBack backend --task "name=api|prompt=Create API"
|
|
119
130
|
```
|
|
120
131
|
|
|
121
132
|
```
|
|
122
133
|
┌───────────┐
|
|
123
|
-
│
|
|
134
|
+
│ frontend │ (UI)
|
|
124
135
|
└───────────┘
|
|
125
136
|
─── both run in parallel
|
|
126
137
|
┌───────────┐
|
|
127
|
-
│
|
|
138
|
+
│ backend │ (API)
|
|
128
139
|
└───────────┘
|
|
129
140
|
```
|
|
130
141
|
|
|
131
|
-
##
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
{
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
"timeout": 600000,
|
|
140
|
-
"enableIntervention": false,
|
|
141
|
-
"dependsOn": ["01-lane-1"],
|
|
142
|
-
"dependencyPolicy": {
|
|
143
|
-
"allowDependencyChange": false,
|
|
144
|
-
"lockfileReadOnly": true
|
|
145
|
-
},
|
|
146
|
-
"enableReview": true,
|
|
147
|
-
"reviewModel": "sonnet-4.5-thinking",
|
|
148
|
-
"maxReviewIterations": 3,
|
|
149
|
-
"tasks": [
|
|
150
|
-
{
|
|
151
|
-
"name": "implement",
|
|
152
|
-
"prompt": "Create a reusable button component...",
|
|
153
|
-
"model": "sonnet-4.5",
|
|
154
|
-
"acceptanceCriteria": ["Build passes", "Tests pass"]
|
|
155
|
-
}
|
|
156
|
-
]
|
|
157
|
-
}
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Configuration Reference
|
|
161
|
-
|
|
162
|
-
| Field | Type | Required | Description |
|
|
163
|
-
|-------|------|----------|-------------|
|
|
164
|
-
| `baseBranch` | string | Yes | Branch to create worktree from |
|
|
165
|
-
| `branchPrefix` | string | Yes | Prefix for feature branch naming |
|
|
166
|
-
| `tasks` | Task[] | Yes | Array of task objects to execute |
|
|
167
|
-
| `dependsOn` | string[] | No | Lane names to wait for and merge |
|
|
168
|
-
| `timeout` | number | No | Task timeout in ms (default: 600000) |
|
|
169
|
-
| `enableIntervention` | boolean | No | Allow stdin injection during execution |
|
|
170
|
-
| `dependencyPolicy.allowDependencyChange` | boolean | No | Allow package.json modifications |
|
|
171
|
-
| `dependencyPolicy.lockfileReadOnly` | boolean | No | Keep lockfile read-only |
|
|
172
|
-
| `enableReview` | boolean | No | Enable AI code review (default: true) |
|
|
173
|
-
| `reviewModel` | string | No | Model for code review |
|
|
174
|
-
| `maxReviewIterations` | number | No | Max review cycles (default: 3) |
|
|
175
|
-
|
|
176
|
-
### Task Object
|
|
177
|
-
|
|
178
|
-
| Field | Type | Required | Description |
|
|
179
|
-
|-------|------|----------|-------------|
|
|
180
|
-
| `name` | string | Yes | Task identifier (alphanumeric, `-`, `_`) |
|
|
181
|
-
| `prompt` | string | Yes | Instructions for the AI agent |
|
|
182
|
-
| `model` | string | No | Model override for this task |
|
|
183
|
-
| `acceptanceCriteria` | string[] | No | Criteria for AI reviewer validation |
|
|
184
|
-
| `dependsOn` | string[] | No | Task-level dependencies (lane:task) |
|
|
185
|
-
| `timeout` | number | No | Task-specific timeout in ms |
|
|
142
|
+
## Log Format
|
|
143
|
+
|
|
144
|
+
Logs use the format `[L{n}-T{t}-{lanename}]`:
|
|
145
|
+
- `L{n}`: Lane number (1-indexed)
|
|
146
|
+
- `T{t}`: Task number (1-indexed)
|
|
147
|
+
- `{lanename}`: First 10 characters of lane name
|
|
148
|
+
|
|
149
|
+
Example: `[L1-T2-backend]` = Lane 1, Task 2, lane name "backend"
|
|
186
150
|
|
|
187
151
|
## Monitoring During Execution
|
|
188
152
|
|
|
@@ -190,8 +154,8 @@ Each JSON file in the tasks directory follows this schema:
|
|
|
190
154
|
# In another terminal
|
|
191
155
|
cursorflow monitor latest
|
|
192
156
|
|
|
193
|
-
# Or specify the
|
|
194
|
-
cursorflow monitor _cursorflow/
|
|
157
|
+
# Or specify the run directory
|
|
158
|
+
cursorflow monitor _cursorflow/logs/runs/run-xxxxx
|
|
195
159
|
```
|
|
196
160
|
|
|
197
161
|
The monitor shows:
|
|
@@ -221,33 +185,18 @@ Circular dependency detected
|
|
|
221
185
|
```
|
|
222
186
|
→ Check your `dependsOn` fields for cycles (A→B, B→A)
|
|
223
187
|
|
|
224
|
-
```
|
|
225
|
-
Unknown dependency: 01-lane-99
|
|
226
|
-
```
|
|
227
|
-
→ Verify the lane name in `dependsOn` matches an actual JSON filename
|
|
228
|
-
|
|
229
|
-
### Merge Conflicts
|
|
230
|
-
|
|
231
|
-
When a dependent lane's auto-merge fails:
|
|
232
|
-
|
|
233
|
-
1. Find the worktree path in `cursorflow monitor`
|
|
234
|
-
2. Navigate to the worktree directory
|
|
235
|
-
3. Resolve conflicts manually and commit
|
|
236
|
-
4. Resume with `cursorflow resume <lane-name>`
|
|
237
|
-
|
|
238
188
|
### Lane Stuck
|
|
239
189
|
|
|
240
190
|
If a lane stops responding:
|
|
241
191
|
|
|
242
192
|
1. Check the agent window in Cursor IDE
|
|
243
193
|
2. Use `cursorflow signal <lane-name> --message "continue"` to nudge
|
|
244
|
-
3. Or
|
|
194
|
+
3. Or use `cursorflow resume --all` to resume
|
|
245
195
|
|
|
246
196
|
## Best Practices
|
|
247
197
|
|
|
248
|
-
1. **Always Validate First**: Run `cursorflow doctor
|
|
198
|
+
1. **Always Validate First**: Run `cursorflow doctor <flow-name>` before `run`
|
|
249
199
|
2. **Start Small**: Test with a single lane before scaling up
|
|
250
200
|
3. **Use `--dry-run`**: Preview execution plan before committing
|
|
251
201
|
4. **Monitor Actively**: Keep `cursorflow monitor` running in a separate terminal
|
|
252
202
|
5. **Plan Dependencies**: Draw out the DAG before running complex workflows
|
|
253
|
-
6. **Include Verification**: Add verify tasks to catch edge cases
|
package/dist/cli/doctor.js
CHANGED
|
@@ -46,17 +46,25 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
46
46
|
};
|
|
47
47
|
})();
|
|
48
48
|
const logger = __importStar(require("../utils/logger"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const fs = __importStar(require("fs"));
|
|
49
51
|
const doctor_1 = require("../utils/doctor");
|
|
50
52
|
const cursor_agent_1 = require("../utils/cursor-agent");
|
|
53
|
+
const config_1 = require("../utils/config");
|
|
54
|
+
const path_1 = require("../utils/path");
|
|
55
|
+
const flow_1 = require("../utils/flow");
|
|
51
56
|
function printHelp() {
|
|
52
57
|
console.log(`
|
|
53
|
-
Usage: cursorflow doctor [options]
|
|
58
|
+
Usage: cursorflow doctor [flow-name] [options]
|
|
54
59
|
|
|
55
60
|
Verify your environment is ready for CursorFlow runs.
|
|
56
61
|
|
|
62
|
+
Arguments:
|
|
63
|
+
[flow-name] Flow or task name to validate (optional)
|
|
64
|
+
|
|
57
65
|
Options:
|
|
58
66
|
--json Output machine-readable JSON
|
|
59
|
-
--tasks-dir <path>
|
|
67
|
+
--tasks-dir <path> Validate specific directory (legacy)
|
|
60
68
|
--executor <type> cursor-agent | cloud
|
|
61
69
|
--no-cursor Skip Cursor Agent install/auth checks
|
|
62
70
|
--test-agent Run interactive agent test (to approve MCP/permissions)
|
|
@@ -64,16 +72,26 @@ Options:
|
|
|
64
72
|
|
|
65
73
|
Examples:
|
|
66
74
|
cursorflow doctor
|
|
75
|
+
cursorflow doctor TestFeature
|
|
67
76
|
cursorflow doctor --test-agent
|
|
68
|
-
cursorflow doctor --tasks-dir _cursorflow/
|
|
77
|
+
cursorflow doctor --tasks-dir _cursorflow/flows/001_TestFeature
|
|
69
78
|
`);
|
|
70
79
|
}
|
|
71
80
|
function parseArgs(args) {
|
|
72
81
|
const tasksDirIdx = args.indexOf('--tasks-dir');
|
|
73
82
|
const executorIdx = args.indexOf('--executor');
|
|
83
|
+
// Find positional argument (flow/task name)
|
|
84
|
+
// Exclude args that are values for options
|
|
85
|
+
const optionValueIndices = new Set();
|
|
86
|
+
if (tasksDirIdx >= 0 && tasksDirIdx + 1 < args.length)
|
|
87
|
+
optionValueIndices.add(tasksDirIdx + 1);
|
|
88
|
+
if (executorIdx >= 0 && executorIdx + 1 < args.length)
|
|
89
|
+
optionValueIndices.add(executorIdx + 1);
|
|
90
|
+
const flowOrTaskName = args.find((arg, idx) => !arg.startsWith('--') && !optionValueIndices.has(idx)) || null;
|
|
74
91
|
const options = {
|
|
75
92
|
json: args.includes('--json'),
|
|
76
93
|
tasksDir: tasksDirIdx >= 0 ? (args[tasksDirIdx + 1] || null) : null,
|
|
94
|
+
flowOrTaskName,
|
|
77
95
|
executor: executorIdx >= 0 ? (args[executorIdx + 1] || null) : null,
|
|
78
96
|
includeCursorAgentChecks: !args.includes('--no-cursor'),
|
|
79
97
|
testAgent: args.includes('--test-agent'),
|
|
@@ -130,9 +148,34 @@ async function doctor(args) {
|
|
|
130
148
|
const success = (0, cursor_agent_1.runInteractiveAgentTest)();
|
|
131
149
|
process.exit(success ? 0 : 1);
|
|
132
150
|
}
|
|
151
|
+
// Resolve tasksDir from flow name if provided
|
|
152
|
+
let tasksDir = options.tasksDir;
|
|
153
|
+
if (!tasksDir && options.flowOrTaskName) {
|
|
154
|
+
try {
|
|
155
|
+
const config = (0, config_1.loadConfig)();
|
|
156
|
+
const flowsDir = (0, path_1.safeJoin)(config.projectRoot, config.flowsDir);
|
|
157
|
+
const foundFlow = (0, flow_1.findFlowDir)(flowsDir, options.flowOrTaskName);
|
|
158
|
+
if (foundFlow) {
|
|
159
|
+
tasksDir = foundFlow;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
// Try as a direct path
|
|
163
|
+
const directPath = path.resolve(process.cwd(), options.flowOrTaskName);
|
|
164
|
+
if (fs.existsSync(directPath)) {
|
|
165
|
+
tasksDir = directPath;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
tasksDir = options.flowOrTaskName;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
tasksDir = options.flowOrTaskName;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
133
176
|
const report = (0, doctor_1.runDoctor)({
|
|
134
177
|
cwd: process.cwd(),
|
|
135
|
-
tasksDir:
|
|
178
|
+
tasksDir: tasksDir || undefined,
|
|
136
179
|
executor: options.executor || undefined,
|
|
137
180
|
includeCursorAgentChecks: options.includeCursorAgentChecks,
|
|
138
181
|
});
|
package/dist/cli/doctor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,wDAA0C;AAC1C,4CAA8D;AAC9D,wDAAgE;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/logs.js
CHANGED
|
@@ -711,10 +711,19 @@ async function logs(args) {
|
|
|
711
711
|
return;
|
|
712
712
|
}
|
|
713
713
|
const config = (0, config_1.loadConfig)();
|
|
714
|
+
const originalCwd = process.cwd();
|
|
715
|
+
// Change current directory to project root for consistent path handling
|
|
716
|
+
if (config.projectRoot !== originalCwd) {
|
|
717
|
+
logger.debug(`Changing directory to project root: ${config.projectRoot}`);
|
|
718
|
+
process.chdir(config.projectRoot);
|
|
719
|
+
}
|
|
714
720
|
// Find run directory
|
|
715
721
|
let runDir = options.runDir;
|
|
722
|
+
if (runDir && runDir !== 'latest' && !path.isAbsolute(runDir)) {
|
|
723
|
+
runDir = path.resolve(originalCwd, runDir);
|
|
724
|
+
}
|
|
716
725
|
if (!runDir || runDir === 'latest') {
|
|
717
|
-
runDir = findLatestRunDir(
|
|
726
|
+
runDir = findLatestRunDir((0, config_1.getLogsDir)(config)) || undefined;
|
|
718
727
|
}
|
|
719
728
|
if (!runDir || !fs.existsSync(runDir)) {
|
|
720
729
|
console.error('No run found');
|