@litmers/cursorflow-orchestrator 0.1.5 → 0.1.6
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 +15 -6
- package/README.md +33 -2
- package/commands/cursorflow-doctor.md +24 -0
- package/commands/cursorflow-signal.md +19 -0
- package/dist/cli/doctor.d.ts +15 -0
- package/dist/cli/doctor.js +139 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.js +5 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/resume.d.ts +1 -1
- package/dist/cli/resume.js +80 -10
- package/dist/cli/resume.js.map +1 -1
- package/dist/cli/run.js +59 -5
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/setup-commands.d.ts +4 -0
- package/dist/cli/setup-commands.js +16 -0
- package/dist/cli/setup-commands.js.map +1 -1
- package/dist/cli/signal.d.ts +7 -0
- package/dist/cli/signal.js +99 -0
- package/dist/cli/signal.js.map +1 -0
- package/dist/core/runner.d.ts +3 -1
- package/dist/core/runner.js +54 -30
- package/dist/core/runner.js.map +1 -1
- package/dist/utils/doctor.d.ts +63 -0
- package/dist/utils/doctor.js +280 -0
- package/dist/utils/doctor.js.map +1 -0
- package/dist/utils/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/cli/doctor.ts +127 -0
- package/src/cli/index.ts +5 -0
- package/src/cli/resume.ts +94 -12
- package/src/cli/run.ts +62 -7
- package/src/cli/setup-commands.ts +19 -0
- package/src/cli/signal.ts +89 -0
- package/src/core/runner.ts +57 -30
- package/src/utils/doctor.ts +312 -0
- package/src/utils/types.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,16 +5,25 @@ 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
|
-
## [
|
|
8
|
+
## [0.1.6] - 2025-12-21
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
|
-
-
|
|
12
|
-
-
|
|
11
|
+
- `cursorflow doctor` command for environment validation and pre-flight checks
|
|
12
|
+
- `cursorflow signal` command for real-time lane intervention (Intercommander)
|
|
13
|
+
- Auto-installation of Cursor IDE commands on `cursorflow run`
|
|
14
|
+
- Full implementation of `cursorflow resume` to pick up from failed tasks
|
|
15
|
+
- `/cursorflow-doctor` and `/cursorflow-signal` IDE commands
|
|
13
16
|
|
|
14
|
-
###
|
|
15
|
-
- Improved
|
|
17
|
+
### Fixed
|
|
18
|
+
- Improved robustness of Git and worktree management
|
|
19
|
+
- Better error messages for missing origin remotes and Cursor authentication
|
|
20
|
+
- Resolved issues with `runTasks` not being able to restart from specific indices
|
|
16
21
|
|
|
17
|
-
## [0.1.
|
|
22
|
+
## [0.1.5] - 2025-12-20
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- Repository-specific Cursor rules (`.cursorrules`)
|
|
26
|
+
- Improved ignore patterns for Git and worktrees
|
|
18
27
|
|
|
19
28
|
## [1.0.0] - TBD
|
|
20
29
|
|
package/README.md
CHANGED
|
@@ -150,6 +150,8 @@ Type `/` in Cursor chat and use:
|
|
|
150
150
|
- `/cursorflow-monitor` - monitor runs
|
|
151
151
|
- `/cursorflow-clean` - clean resources
|
|
152
152
|
- `/cursorflow-resume` - resume a lane
|
|
153
|
+
- `/cursorflow-doctor` - verify environment
|
|
154
|
+
- `/cursorflow-signal` - intervene in a lane
|
|
153
155
|
- `/cursorflow-review` - configure or check reviews
|
|
154
156
|
|
|
155
157
|
## CLI Commands
|
|
@@ -195,10 +197,39 @@ cursorflow clean <type> [options]
|
|
|
195
197
|
### Resume
|
|
196
198
|
```bash
|
|
197
199
|
cursorflow resume <lane> [options]
|
|
198
|
-
--
|
|
199
|
-
--restart Restart from
|
|
200
|
+
--run-dir <path> Specify run directory
|
|
201
|
+
--restart Restart from task 1
|
|
200
202
|
```
|
|
201
203
|
|
|
204
|
+
### Doctor
|
|
205
|
+
```bash
|
|
206
|
+
cursorflow doctor [options]
|
|
207
|
+
--tasks-dir <path> Validate specific lane tasks
|
|
208
|
+
--json Output in JSON format
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Signal (Intervention)
|
|
212
|
+
```bash
|
|
213
|
+
cursorflow signal <lane> <message>
|
|
214
|
+
--run-dir <path> Specify run directory
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## 🚀 Deployment & Updates
|
|
218
|
+
|
|
219
|
+
### For Maintainers
|
|
220
|
+
To release a new version to NPM:
|
|
221
|
+
1. Ensure your working directory is clean on the `main` branch.
|
|
222
|
+
2. Run the release script:
|
|
223
|
+
```bash
|
|
224
|
+
./scripts/release.sh [patch|minor|major]
|
|
225
|
+
```
|
|
226
|
+
3. The script will bump the version, update CHANGELOG, and push a tag to trigger GitHub Actions.
|
|
227
|
+
|
|
228
|
+
### For Users
|
|
229
|
+
To update to the latest version and refresh IDE commands:
|
|
230
|
+
1. Update the package: `npm install -g @litmers/cursorflow-orchestrator`
|
|
231
|
+
2. Refresh Cursor commands: `cursorflow-setup --force`
|
|
232
|
+
|
|
202
233
|
## Configuration
|
|
203
234
|
|
|
204
235
|
### Config file (cursorflow.config.js)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# /cursorflow-doctor
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Verify that the current environment is properly configured for CursorFlow.
|
|
5
|
+
|
|
6
|
+
## Usage
|
|
7
|
+
1. Type `/cursorflow-doctor` in the chat.
|
|
8
|
+
2. The agent will check:
|
|
9
|
+
- Git repository status
|
|
10
|
+
- 'origin' remote availability
|
|
11
|
+
- Git worktree support
|
|
12
|
+
- Cursor Agent installation and authentication
|
|
13
|
+
- Task directory and lane file validity (if a path is provided)
|
|
14
|
+
|
|
15
|
+
## Context
|
|
16
|
+
Use this command whenever:
|
|
17
|
+
- You are setting up a new project with CursorFlow.
|
|
18
|
+
- A `cursorflow run` fails with environment-related errors.
|
|
19
|
+
- You want to verify your Cursor authentication status.
|
|
20
|
+
|
|
21
|
+
## Example
|
|
22
|
+
"Check if my environment is ready for CursorFlow."
|
|
23
|
+
"Run cursorflow doctor on the _cursorflow/tasks/my-feature/ directory."
|
|
24
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# /cursorflow-signal
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Directly intervene in a running lane to provide guidance, corrections, or emergency stops.
|
|
5
|
+
|
|
6
|
+
## Usage
|
|
7
|
+
1. Type `/cursorflow-signal <lane-name> <your-message>` in the chat.
|
|
8
|
+
2. The message will be injected into the lane's conversation as a high-priority system instruction.
|
|
9
|
+
|
|
10
|
+
## Context
|
|
11
|
+
Use this command when:
|
|
12
|
+
- You see an agent making a repeated mistake in the monitor.
|
|
13
|
+
- You want to provide specific implementation guidance mid-task.
|
|
14
|
+
- You need to tell the agent to stop or change direction without killing the process.
|
|
15
|
+
|
|
16
|
+
## Example
|
|
17
|
+
"Send a signal to lane-1: 'Stop using library X, use library Y instead.'"
|
|
18
|
+
"Intervene in backend-lane: 'The database schema changed, please pull the latest main branch.'"
|
|
19
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CursorFlow doctor command
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* cursorflow doctor [options]
|
|
6
|
+
*
|
|
7
|
+
* Options:
|
|
8
|
+
* --json Output machine-readable JSON
|
|
9
|
+
* --tasks-dir <path> Also validate lane files (run preflight)
|
|
10
|
+
* --executor <type> cursor-agent | cloud
|
|
11
|
+
* --no-cursor Skip Cursor Agent install/auth checks
|
|
12
|
+
* --help, -h Show help
|
|
13
|
+
*/
|
|
14
|
+
declare function doctor(args: string[]): Promise<void>;
|
|
15
|
+
export = doctor;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CursorFlow doctor command
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* cursorflow doctor [options]
|
|
7
|
+
*
|
|
8
|
+
* Options:
|
|
9
|
+
* --json Output machine-readable JSON
|
|
10
|
+
* --tasks-dir <path> Also validate lane files (run preflight)
|
|
11
|
+
* --executor <type> cursor-agent | cloud
|
|
12
|
+
* --no-cursor Skip Cursor Agent install/auth checks
|
|
13
|
+
* --help, -h Show help
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
const logger = __importStar(require("../utils/logger"));
|
|
49
|
+
const doctor_1 = require("../utils/doctor");
|
|
50
|
+
function printHelp() {
|
|
51
|
+
console.log(`
|
|
52
|
+
Usage: cursorflow doctor [options]
|
|
53
|
+
|
|
54
|
+
Verify your environment is ready for CursorFlow runs.
|
|
55
|
+
|
|
56
|
+
Options:
|
|
57
|
+
--json Output machine-readable JSON
|
|
58
|
+
--tasks-dir <path> Also validate lane files (run preflight)
|
|
59
|
+
--executor <type> cursor-agent | cloud
|
|
60
|
+
--no-cursor Skip Cursor Agent install/auth checks
|
|
61
|
+
--help, -h Show help
|
|
62
|
+
|
|
63
|
+
Examples:
|
|
64
|
+
cursorflow doctor
|
|
65
|
+
cursorflow doctor --tasks-dir _cursorflow/tasks/demo-test/
|
|
66
|
+
cursorflow doctor --json
|
|
67
|
+
`);
|
|
68
|
+
}
|
|
69
|
+
function parseArgs(args) {
|
|
70
|
+
const tasksDirIdx = args.indexOf('--tasks-dir');
|
|
71
|
+
const executorIdx = args.indexOf('--executor');
|
|
72
|
+
const options = {
|
|
73
|
+
json: args.includes('--json'),
|
|
74
|
+
tasksDir: tasksDirIdx >= 0 ? (args[tasksDirIdx + 1] || null) : null,
|
|
75
|
+
executor: executorIdx >= 0 ? (args[executorIdx + 1] || null) : null,
|
|
76
|
+
includeCursorAgentChecks: !args.includes('--no-cursor'),
|
|
77
|
+
};
|
|
78
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
79
|
+
printHelp();
|
|
80
|
+
process.exit(0);
|
|
81
|
+
}
|
|
82
|
+
return options;
|
|
83
|
+
}
|
|
84
|
+
function printHumanReport(report) {
|
|
85
|
+
logger.section('🩺 CursorFlow Doctor');
|
|
86
|
+
logger.info(`cwd: ${report.context.cwd}`);
|
|
87
|
+
if (report.context.repoRoot)
|
|
88
|
+
logger.info(`repo: ${report.context.repoRoot}`);
|
|
89
|
+
if (report.context.tasksDir)
|
|
90
|
+
logger.info(`tasks: ${report.context.tasksDir}`);
|
|
91
|
+
if (report.issues.length === 0) {
|
|
92
|
+
logger.success('All checks passed');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
for (const issue of report.issues) {
|
|
96
|
+
const header = `${issue.title} (${issue.id})`;
|
|
97
|
+
if (issue.severity === 'error') {
|
|
98
|
+
logger.error(header, '❌');
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
logger.warn(header, '⚠️');
|
|
102
|
+
}
|
|
103
|
+
console.log(` ${issue.message}`);
|
|
104
|
+
if (issue.details) {
|
|
105
|
+
console.log(` Details: ${issue.details}`);
|
|
106
|
+
}
|
|
107
|
+
if (issue.fixes && issue.fixes.length > 0) {
|
|
108
|
+
console.log(' Fix:');
|
|
109
|
+
for (const fix of issue.fixes) {
|
|
110
|
+
console.log(` - ${fix}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
console.log('');
|
|
114
|
+
}
|
|
115
|
+
if (report.ok) {
|
|
116
|
+
logger.success('Doctor completed with warnings');
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
logger.error('Doctor found blocking issues');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function doctor(args) {
|
|
123
|
+
const options = parseArgs(args);
|
|
124
|
+
const report = (0, doctor_1.runDoctor)({
|
|
125
|
+
cwd: process.cwd(),
|
|
126
|
+
tasksDir: options.tasksDir || undefined,
|
|
127
|
+
executor: options.executor || undefined,
|
|
128
|
+
includeCursorAgentChecks: options.includeCursorAgentChecks,
|
|
129
|
+
});
|
|
130
|
+
if (options.json) {
|
|
131
|
+
console.log(JSON.stringify(report, null, 2));
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
printHumanReport(report);
|
|
135
|
+
}
|
|
136
|
+
process.exit(report.ok ? 0 : 1);
|
|
137
|
+
}
|
|
138
|
+
module.exports = doctor;
|
|
139
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -45,6 +45,8 @@ const COMMANDS = {
|
|
|
45
45
|
monitor: require('./monitor'),
|
|
46
46
|
clean: require('./clean'),
|
|
47
47
|
resume: require('./resume'),
|
|
48
|
+
doctor: require('./doctor'),
|
|
49
|
+
signal: require('./signal'),
|
|
48
50
|
};
|
|
49
51
|
function printHelp() {
|
|
50
52
|
console.log(`
|
|
@@ -58,6 +60,8 @@ Commands:
|
|
|
58
60
|
monitor [run-dir] [options] Monitor lane execution
|
|
59
61
|
clean <type> [options] Clean branches/worktrees/logs
|
|
60
62
|
resume <lane> [options] Resume interrupted lane
|
|
63
|
+
doctor [options] Check environment and preflight
|
|
64
|
+
signal <lane> <msg> Directly intervene in a running lane
|
|
61
65
|
|
|
62
66
|
Global Options:
|
|
63
67
|
--config <path> Config file path
|
|
@@ -69,6 +73,7 @@ Examples:
|
|
|
69
73
|
cursorflow run _cursorflow/tasks/MyFeature/
|
|
70
74
|
cursorflow monitor --watch
|
|
71
75
|
cursorflow clean branches --all
|
|
76
|
+
cursorflow doctor
|
|
72
77
|
|
|
73
78
|
Documentation:
|
|
74
79
|
https://github.com/eungjin-cigro/cursorflow#readme
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqGM,oBAAI;AAnGb,wDAA0C;AAK1C,qDAAqD;AACrD,MAAM,QAAQ,GAA8B;IAC1C,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC;IACvB,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC;CAC5B,CAAC;AAEF,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BX,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxE,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,YAAY,EAAE,CAAC;QACf,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;IAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAElC,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IAEtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,oBAAoB,WAAW,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5B,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;QACnB,MAAM,CAAC,KAAK,CAAC,gBAAgB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9C,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,kBAAe,IAAI,CAAC"}
|
package/dist/cli/resume.d.ts
CHANGED
package/dist/cli/resume.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* CursorFlow resume command
|
|
3
|
+
* CursorFlow resume command
|
|
4
4
|
*/
|
|
5
5
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
6
|
if (k2 === undefined) k2 = k;
|
|
@@ -35,24 +35,94 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
return result;
|
|
36
36
|
};
|
|
37
37
|
})();
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const child_process_1 = require("child_process");
|
|
38
41
|
const logger = __importStar(require("../utils/logger"));
|
|
42
|
+
const config_1 = require("../utils/config");
|
|
43
|
+
const state_1 = require("../utils/state");
|
|
39
44
|
function parseArgs(args) {
|
|
45
|
+
const runDirIdx = args.indexOf('--run-dir');
|
|
40
46
|
return {
|
|
41
|
-
lane: args
|
|
42
|
-
runDir: null,
|
|
47
|
+
lane: args.find(a => !a.startsWith('--')) || null,
|
|
48
|
+
runDir: runDirIdx >= 0 ? args[runDirIdx + 1] || null : null,
|
|
43
49
|
clean: args.includes('--clean'),
|
|
44
50
|
restart: args.includes('--restart'),
|
|
45
51
|
};
|
|
46
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Find the latest run directory
|
|
55
|
+
*/
|
|
56
|
+
function findLatestRunDir(logsDir) {
|
|
57
|
+
const runsDir = path.join(logsDir, 'runs');
|
|
58
|
+
if (!fs.existsSync(runsDir))
|
|
59
|
+
return null;
|
|
60
|
+
const runs = fs.readdirSync(runsDir)
|
|
61
|
+
.filter(d => d.startsWith('run-'))
|
|
62
|
+
.sort()
|
|
63
|
+
.reverse();
|
|
64
|
+
return runs.length > 0 ? path.join(runsDir, runs[0]) : null;
|
|
65
|
+
}
|
|
47
66
|
async function resume(args) {
|
|
48
|
-
logger.section('🔁 Resuming Lane');
|
|
49
67
|
const options = parseArgs(args);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
68
|
+
const config = (0, config_1.loadConfig)();
|
|
69
|
+
const logsDir = (0, config_1.getLogsDir)(config);
|
|
70
|
+
if (!options.lane) {
|
|
71
|
+
throw new Error('Lane name required (e.g., cursorflow resume lane-1)');
|
|
72
|
+
}
|
|
73
|
+
let runDir = options.runDir;
|
|
74
|
+
if (!runDir) {
|
|
75
|
+
runDir = findLatestRunDir(logsDir);
|
|
76
|
+
}
|
|
77
|
+
if (!runDir || !fs.existsSync(runDir)) {
|
|
78
|
+
throw new Error(`Run directory not found: ${runDir || 'latest'}`);
|
|
79
|
+
}
|
|
80
|
+
const laneDir = path.join(runDir, 'lanes', options.lane);
|
|
81
|
+
const statePath = path.join(laneDir, 'state.json');
|
|
82
|
+
if (!fs.existsSync(statePath)) {
|
|
83
|
+
throw new Error(`Lane state not found at ${statePath}. Is the lane name correct?`);
|
|
84
|
+
}
|
|
85
|
+
const state = (0, state_1.loadState)(statePath);
|
|
86
|
+
if (!state) {
|
|
87
|
+
throw new Error(`Failed to load state from ${statePath}`);
|
|
88
|
+
}
|
|
89
|
+
if (!state.tasksFile || !fs.existsSync(state.tasksFile)) {
|
|
90
|
+
throw new Error(`Original tasks file not found: ${state.tasksFile}. Resume impossible without task definition.`);
|
|
91
|
+
}
|
|
92
|
+
logger.section(`🔁 Resuming Lane: ${options.lane}`);
|
|
93
|
+
logger.info(`Run: ${path.basename(runDir)}`);
|
|
94
|
+
logger.info(`Tasks: ${state.tasksFile}`);
|
|
95
|
+
logger.info(`Starting from task index: ${options.restart ? 0 : state.currentTaskIndex}`);
|
|
96
|
+
const runnerPath = require.resolve('../core/runner');
|
|
97
|
+
const runnerArgs = [
|
|
98
|
+
runnerPath,
|
|
99
|
+
state.tasksFile,
|
|
100
|
+
'--run-dir', laneDir,
|
|
101
|
+
'--start-index', options.restart ? '0' : String(state.currentTaskIndex),
|
|
102
|
+
];
|
|
103
|
+
logger.info(`Spawning runner process...`);
|
|
104
|
+
const child = (0, child_process_1.spawn)('node', runnerArgs, {
|
|
105
|
+
stdio: 'inherit',
|
|
106
|
+
env: process.env,
|
|
107
|
+
});
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
child.on('exit', (code) => {
|
|
110
|
+
if (code === 0) {
|
|
111
|
+
logger.success(`Lane ${options.lane} completed successfully`);
|
|
112
|
+
resolve();
|
|
113
|
+
}
|
|
114
|
+
else if (code === 2) {
|
|
115
|
+
logger.warn(`Lane ${options.lane} blocked on dependency change`);
|
|
116
|
+
resolve();
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
reject(new Error(`Lane ${options.lane} failed with exit code ${code}`));
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
child.on('error', (error) => {
|
|
123
|
+
reject(new Error(`Failed to start runner: ${error.message}`));
|
|
124
|
+
});
|
|
125
|
+
});
|
|
56
126
|
}
|
|
57
127
|
module.exports = resume;
|
|
58
128
|
//# sourceMappingURL=resume.js.map
|
package/dist/cli/resume.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../src/cli/resume.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,wDAA0C;
|
|
1
|
+
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../src/cli/resume.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/run.js
CHANGED
|
@@ -37,8 +37,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
})();
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
39
|
const fs = __importStar(require("fs"));
|
|
40
|
+
const logger = __importStar(require("../utils/logger"));
|
|
40
41
|
const orchestrator_1 = require("../core/orchestrator");
|
|
41
42
|
const config_1 = require("../utils/config");
|
|
43
|
+
const doctor_1 = require("../utils/doctor");
|
|
44
|
+
const setup_commands_1 = require("./setup-commands");
|
|
42
45
|
function parseArgs(args) {
|
|
43
46
|
const tasksDir = args.find(a => !a.startsWith('--'));
|
|
44
47
|
const executorIdx = args.indexOf('--executor');
|
|
@@ -46,23 +49,74 @@ function parseArgs(args) {
|
|
|
46
49
|
tasksDir,
|
|
47
50
|
dryRun: args.includes('--dry-run'),
|
|
48
51
|
executor: executorIdx >= 0 ? args[executorIdx + 1] || null : null,
|
|
52
|
+
skipDoctor: args.includes('--skip-doctor') || args.includes('--no-doctor'),
|
|
49
53
|
};
|
|
50
54
|
}
|
|
51
55
|
async function run(args) {
|
|
52
56
|
const options = parseArgs(args);
|
|
57
|
+
// Auto-setup Cursor commands if missing or outdated
|
|
58
|
+
if (!(0, setup_commands_1.areCommandsInstalled)()) {
|
|
59
|
+
logger.info('Installing missing or outdated Cursor IDE commands...');
|
|
60
|
+
try {
|
|
61
|
+
(0, setup_commands_1.setupCommands)({ silent: true });
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
// Non-blocking
|
|
65
|
+
}
|
|
66
|
+
}
|
|
53
67
|
if (!options.tasksDir) {
|
|
54
68
|
console.log('\nUsage: cursorflow run <tasks-dir> [options]');
|
|
55
69
|
throw new Error('Tasks directory required');
|
|
56
70
|
}
|
|
57
|
-
if (!fs.existsSync(options.tasksDir)) {
|
|
58
|
-
throw new Error(`Tasks directory not found: ${options.tasksDir}`);
|
|
59
|
-
}
|
|
60
71
|
const config = (0, config_1.loadConfig)();
|
|
72
|
+
const logsDir = (0, config_1.getLogsDir)(config);
|
|
73
|
+
// Resolve tasks dir:
|
|
74
|
+
// - Prefer the exact path if it exists relative to cwd
|
|
75
|
+
// - Otherwise, fall back to projectRoot-relative path for better ergonomics
|
|
76
|
+
const tasksDir = path.isAbsolute(options.tasksDir)
|
|
77
|
+
? options.tasksDir
|
|
78
|
+
: (fs.existsSync(options.tasksDir)
|
|
79
|
+
? path.resolve(process.cwd(), options.tasksDir)
|
|
80
|
+
: path.join(config.projectRoot, options.tasksDir));
|
|
81
|
+
if (!fs.existsSync(tasksDir)) {
|
|
82
|
+
throw new Error(`Tasks directory not found: ${tasksDir}`);
|
|
83
|
+
}
|
|
84
|
+
// Preflight checks (doctor)
|
|
85
|
+
if (!options.skipDoctor) {
|
|
86
|
+
const report = (0, doctor_1.runDoctor)({
|
|
87
|
+
cwd: process.cwd(),
|
|
88
|
+
tasksDir,
|
|
89
|
+
executor: options.executor || config.executor,
|
|
90
|
+
includeCursorAgentChecks: true,
|
|
91
|
+
});
|
|
92
|
+
if (!report.ok) {
|
|
93
|
+
logger.section('🛑 Pre-flight check failed');
|
|
94
|
+
for (const issue of report.issues) {
|
|
95
|
+
const header = `${issue.title} (${issue.id})`;
|
|
96
|
+
if (issue.severity === 'error') {
|
|
97
|
+
logger.error(header, '❌');
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
logger.warn(header, '⚠️');
|
|
101
|
+
}
|
|
102
|
+
console.log(` ${issue.message}`);
|
|
103
|
+
if (issue.details)
|
|
104
|
+
console.log(` Details: ${issue.details}`);
|
|
105
|
+
if (issue.fixes?.length) {
|
|
106
|
+
console.log(' Fix:');
|
|
107
|
+
for (const fix of issue.fixes)
|
|
108
|
+
console.log(` - ${fix}`);
|
|
109
|
+
}
|
|
110
|
+
console.log('');
|
|
111
|
+
}
|
|
112
|
+
throw new Error('Pre-flight checks failed. Run `cursorflow doctor` for details.');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
61
115
|
try {
|
|
62
|
-
await (0, orchestrator_1.orchestrate)(
|
|
116
|
+
await (0, orchestrator_1.orchestrate)(tasksDir, {
|
|
63
117
|
executor: options.executor || config.executor,
|
|
64
118
|
pollInterval: config.pollInterval * 1000,
|
|
65
|
-
runDir: path.join(
|
|
119
|
+
runDir: path.join(logsDir, 'runs', `run-${Date.now()}`),
|
|
66
120
|
});
|
|
67
121
|
}
|
|
68
122
|
catch (error) {
|
package/dist/cli/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,2CAA6B;AAC7B,uCAAyB;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,4 +16,8 @@ export declare function setupCommands(options?: SetupOptions): {
|
|
|
16
16
|
export declare function uninstallCommands(options?: SetupOptions): {
|
|
17
17
|
removed: number;
|
|
18
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Check if commands are already installed
|
|
21
|
+
*/
|
|
22
|
+
export declare function areCommandsInstalled(): boolean;
|
|
19
23
|
export {};
|
|
@@ -40,6 +40,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
41
|
exports.setupCommands = setupCommands;
|
|
42
42
|
exports.uninstallCommands = uninstallCommands;
|
|
43
|
+
exports.areCommandsInstalled = areCommandsInstalled;
|
|
43
44
|
const fs = __importStar(require("fs"));
|
|
44
45
|
const path = __importStar(require("path"));
|
|
45
46
|
const logger = __importStar(require("../utils/logger"));
|
|
@@ -189,6 +190,21 @@ function uninstallCommands(options = {}) {
|
|
|
189
190
|
}
|
|
190
191
|
return { removed };
|
|
191
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Check if commands are already installed
|
|
195
|
+
*/
|
|
196
|
+
function areCommandsInstalled() {
|
|
197
|
+
const projectRoot = (0, config_1.findProjectRoot)();
|
|
198
|
+
const targetDir = path.join(projectRoot, '.cursor', 'commands', 'cursorflow');
|
|
199
|
+
const sourceDir = getCommandsSourceDir();
|
|
200
|
+
if (!fs.existsSync(targetDir) || !fs.existsSync(sourceDir)) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
const sourceFiles = fs.readdirSync(sourceDir).filter(f => f.endsWith('.md'));
|
|
204
|
+
const targetFiles = fs.readdirSync(targetDir).filter(f => f.endsWith('.md'));
|
|
205
|
+
// Basic check: do we have all the files from source in target?
|
|
206
|
+
return sourceFiles.every(f => targetFiles.includes(f));
|
|
207
|
+
}
|
|
192
208
|
async function main(args) {
|
|
193
209
|
const options = parseArgs(args);
|
|
194
210
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-commands.js","sourceRoot":"","sources":["../../src/cli/setup-commands.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEH,sCA0EC;AAED,8CAqCC;
|
|
1
|
+
{"version":3,"file":"setup-commands.js","sourceRoot":"","sources":["../../src/cli/setup-commands.ts"],"names":[],"mappings":"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"}
|