@litmers/cursorflow-orchestrator 0.1.18 → 0.1.20

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 (68) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +25 -7
  3. package/dist/cli/clean.js +7 -6
  4. package/dist/cli/clean.js.map +1 -1
  5. package/dist/cli/index.js +5 -1
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/init.js +7 -6
  8. package/dist/cli/init.js.map +1 -1
  9. package/dist/cli/logs.js +50 -42
  10. package/dist/cli/logs.js.map +1 -1
  11. package/dist/cli/monitor.js +15 -14
  12. package/dist/cli/monitor.js.map +1 -1
  13. package/dist/cli/prepare.js +37 -20
  14. package/dist/cli/prepare.js.map +1 -1
  15. package/dist/cli/resume.js +193 -40
  16. package/dist/cli/resume.js.map +1 -1
  17. package/dist/cli/run.js +3 -2
  18. package/dist/cli/run.js.map +1 -1
  19. package/dist/cli/signal.js +7 -7
  20. package/dist/cli/signal.js.map +1 -1
  21. package/dist/core/orchestrator.d.ts +2 -1
  22. package/dist/core/orchestrator.js +48 -91
  23. package/dist/core/orchestrator.js.map +1 -1
  24. package/dist/core/runner.js +55 -20
  25. package/dist/core/runner.js.map +1 -1
  26. package/dist/utils/config.js +7 -6
  27. package/dist/utils/config.js.map +1 -1
  28. package/dist/utils/doctor.js +7 -6
  29. package/dist/utils/doctor.js.map +1 -1
  30. package/dist/utils/enhanced-logger.js +14 -11
  31. package/dist/utils/enhanced-logger.js.map +1 -1
  32. package/dist/utils/git.js +163 -10
  33. package/dist/utils/git.js.map +1 -1
  34. package/dist/utils/log-formatter.d.ts +16 -0
  35. package/dist/utils/log-formatter.js +194 -0
  36. package/dist/utils/log-formatter.js.map +1 -0
  37. package/dist/utils/path.d.ts +19 -0
  38. package/dist/utils/path.js +77 -0
  39. package/dist/utils/path.js.map +1 -0
  40. package/dist/utils/state.d.ts +4 -1
  41. package/dist/utils/state.js +11 -8
  42. package/dist/utils/state.js.map +1 -1
  43. package/dist/utils/template.d.ts +14 -0
  44. package/dist/utils/template.js +122 -0
  45. package/dist/utils/template.js.map +1 -0
  46. package/dist/utils/types.d.ts +1 -0
  47. package/package.json +1 -1
  48. package/src/cli/clean.ts +7 -6
  49. package/src/cli/index.ts +5 -1
  50. package/src/cli/init.ts +7 -6
  51. package/src/cli/logs.ts +52 -42
  52. package/src/cli/monitor.ts +15 -14
  53. package/src/cli/prepare.ts +39 -20
  54. package/src/cli/resume.ts +810 -626
  55. package/src/cli/run.ts +3 -2
  56. package/src/cli/signal.ts +7 -6
  57. package/src/core/orchestrator.ts +62 -91
  58. package/src/core/runner.ts +58 -20
  59. package/src/utils/config.ts +7 -6
  60. package/src/utils/doctor.ts +7 -6
  61. package/src/utils/enhanced-logger.ts +14 -11
  62. package/src/utils/git.ts +145 -11
  63. package/src/utils/log-formatter.ts +162 -0
  64. package/src/utils/path.ts +45 -0
  65. package/src/utils/state.ts +16 -8
  66. package/src/utils/template.ts +92 -0
  67. package/src/utils/types.ts +1 -0
  68. package/templates/basic.json +21 -0
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Ensures that a path is safe and stays within a base directory.
3
+ * Prevents path traversal attacks.
4
+ */
5
+ export declare function isSafePath(baseDir: string, ...parts: string[]): boolean;
6
+ /**
7
+ * Safely joins path parts and ensures the result is within the base directory.
8
+ * Throws an error if path traversal is detected.
9
+ *
10
+ * @param baseDir The base directory that the resulting path must be within
11
+ * @param parts Path parts to join
12
+ * @returns The joined path
13
+ * @throws Error if the resulting path is outside the base directory
14
+ */
15
+ export declare function safeJoin(baseDir: string, ...parts: string[]): string;
16
+ /**
17
+ * Normalizes a path and checks if it's absolute or relative to project root.
18
+ */
19
+ export declare function normalizePath(p: string, projectRoot: string): string;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.isSafePath = isSafePath;
37
+ exports.safeJoin = safeJoin;
38
+ exports.normalizePath = normalizePath;
39
+ const path = __importStar(require("path"));
40
+ /**
41
+ * Ensures that a path is safe and stays within a base directory.
42
+ * Prevents path traversal attacks.
43
+ */
44
+ function isSafePath(baseDir, ...parts) {
45
+ const joined = path.join(baseDir, ...parts); // nosemgrep
46
+ const resolvedBase = path.resolve(baseDir); // nosemgrep
47
+ const resolvedJoined = path.resolve(joined); // nosemgrep
48
+ return resolvedJoined.startsWith(resolvedBase);
49
+ }
50
+ /**
51
+ * Safely joins path parts and ensures the result is within the base directory.
52
+ * Throws an error if path traversal is detected.
53
+ *
54
+ * @param baseDir The base directory that the resulting path must be within
55
+ * @param parts Path parts to join
56
+ * @returns The joined path
57
+ * @throws Error if the resulting path is outside the base directory
58
+ */
59
+ function safeJoin(baseDir, ...parts) {
60
+ const joined = path.join(baseDir, ...parts); // nosemgrep
61
+ const resolvedBase = path.resolve(baseDir); // nosemgrep
62
+ const resolvedJoined = path.resolve(joined); // nosemgrep
63
+ if (!resolvedJoined.startsWith(resolvedBase)) {
64
+ throw new Error(`Potential path traversal detected: ${joined} is outside of ${baseDir}`);
65
+ }
66
+ return joined;
67
+ }
68
+ /**
69
+ * Normalizes a path and checks if it's absolute or relative to project root.
70
+ */
71
+ function normalizePath(p, projectRoot) {
72
+ if (path.isAbsolute(p)) {
73
+ return path.normalize(p);
74
+ }
75
+ return path.join(projectRoot, p); // nosemgrep
76
+ }
77
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,gCAMC;AAWD,4BAUC;AAKD,sCAKC;AA3CD,2CAA6B;AAE7B;;;GAGG;AACH,SAAgB,UAAU,CAAC,OAAe,EAAE,GAAG,KAAe;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,YAAY;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY;IACxD,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY;IAEzD,OAAO,cAAc,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,QAAQ,CAAC,OAAe,EAAE,GAAG,KAAe;IAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,YAAY;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY;IACxD,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY;IAEzD,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,sCAAsC,MAAM,kBAAkB,OAAO,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,CAAS,EAAE,WAAmB;IAC1D,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY;AAChD,CAAC"}
@@ -22,7 +22,10 @@ export declare function readLog<T = any>(logPath: string): T[];
22
22
  /**
23
23
  * Create initial lane state
24
24
  */
25
- export declare function createLaneState(laneName: string, config: RunnerConfig): LaneState;
25
+ export declare function createLaneState(laneName: string, config: RunnerConfig, tasksFile?: string, options?: {
26
+ pipelineBranch?: string;
27
+ worktreeDir?: string;
28
+ }): LaneState;
26
29
  /**
27
30
  * Update lane state
28
31
  */
@@ -50,6 +50,7 @@ exports.listLanesInRun = listLanesInRun;
50
50
  exports.getLaneStateSummary = getLaneStateSummary;
51
51
  const fs = __importStar(require("fs"));
52
52
  const path = __importStar(require("path"));
53
+ const path_1 = require("./path");
53
54
  /**
54
55
  * Save state to JSON file
55
56
  */
@@ -109,18 +110,20 @@ function readLog(logPath) {
109
110
  /**
110
111
  * Create initial lane state
111
112
  */
112
- function createLaneState(laneName, config) {
113
+ function createLaneState(laneName, config, tasksFile, options = {}) {
113
114
  return {
114
115
  label: laneName,
115
116
  status: 'pending',
116
117
  currentTaskIndex: 0,
117
118
  totalTasks: config.tasks ? config.tasks.length : 0,
118
- worktreeDir: null,
119
- pipelineBranch: null,
119
+ worktreeDir: options.worktreeDir || null,
120
+ pipelineBranch: options.pipelineBranch || null,
120
121
  startTime: Date.now(),
121
122
  endTime: null,
122
123
  error: null,
123
124
  dependencyRequest: null,
125
+ tasksFile,
126
+ dependsOn: config.dependsOn || [],
124
127
  };
125
128
  }
126
129
  /**
@@ -174,13 +177,13 @@ function getLatestRunDir(logsDir) {
174
177
  return null;
175
178
  }
176
179
  const runs = fs.readdirSync(logsDir)
177
- .filter(f => fs.statSync(path.join(logsDir, f)).isDirectory())
180
+ .filter(f => fs.statSync((0, path_1.safeJoin)(logsDir, f)).isDirectory())
178
181
  .sort()
179
182
  .reverse();
180
183
  if (runs.length === 0) {
181
184
  return null;
182
185
  }
183
- return path.join(logsDir, runs[0]);
186
+ return (0, path_1.safeJoin)(logsDir, runs[0]);
184
187
  }
185
188
  /**
186
189
  * List all lanes in a run directory
@@ -190,11 +193,11 @@ function listLanesInRun(runDir) {
190
193
  return [];
191
194
  }
192
195
  return fs.readdirSync(runDir)
193
- .filter(f => fs.statSync(path.join(runDir, f)).isDirectory())
196
+ .filter(f => fs.statSync((0, path_1.safeJoin)(runDir, f)).isDirectory())
194
197
  .map(laneName => ({
195
198
  name: laneName,
196
- dir: path.join(runDir, laneName),
197
- statePath: path.join(runDir, laneName, 'state.json'),
199
+ dir: (0, path_1.safeJoin)(runDir, laneName),
200
+ statePath: (0, path_1.safeJoin)(runDir, laneName, 'state.json'),
198
201
  }));
199
202
  }
200
203
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/utils/state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/utils/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Template loading utilities for CursorFlow
3
+ */
4
+ /**
5
+ * Fetch remote template from URL
6
+ */
7
+ export declare function fetchRemoteTemplate(url: string): Promise<any>;
8
+ /**
9
+ * Resolve template from various sources:
10
+ * 1. URL (starts with http:// or https://)
11
+ * 2. Built-in template (name without .json)
12
+ * 3. Local file path
13
+ */
14
+ export declare function resolveTemplate(templatePath: string): Promise<any>;
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /**
3
+ * Template loading utilities for CursorFlow
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.fetchRemoteTemplate = fetchRemoteTemplate;
40
+ exports.resolveTemplate = resolveTemplate;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const https = __importStar(require("https"));
44
+ const http = __importStar(require("http"));
45
+ const logger = __importStar(require("./logger"));
46
+ const path_1 = require("./path");
47
+ const config_1 = require("./config");
48
+ /**
49
+ * Fetch remote template from URL
50
+ */
51
+ async function fetchRemoteTemplate(url) {
52
+ return new Promise((resolve, reject) => {
53
+ const protocol = url.startsWith('https') ? https : http;
54
+ protocol.get(url, (res) => {
55
+ if (res.statusCode !== 200) {
56
+ reject(new Error(`Failed to fetch template from ${url}: Status ${res.statusCode}`));
57
+ return;
58
+ }
59
+ let data = '';
60
+ res.on('data', (chunk) => {
61
+ data += chunk;
62
+ });
63
+ res.on('end', () => {
64
+ try {
65
+ resolve(JSON.parse(data));
66
+ }
67
+ catch (e) {
68
+ reject(new Error(`Failed to parse template JSON from ${url}: ${e}`));
69
+ }
70
+ });
71
+ }).on('error', (err) => {
72
+ reject(new Error(`Network error while fetching template from ${url}: ${err.message}`));
73
+ });
74
+ });
75
+ }
76
+ /**
77
+ * Resolve template from various sources:
78
+ * 1. URL (starts with http:// or https://)
79
+ * 2. Built-in template (name without .json)
80
+ * 3. Local file path
81
+ */
82
+ async function resolveTemplate(templatePath) {
83
+ // 1. Remote URL
84
+ if (templatePath.startsWith('http://') || templatePath.startsWith('https://')) {
85
+ logger.info(`Fetching remote template: ${templatePath}`);
86
+ return fetchRemoteTemplate(templatePath);
87
+ }
88
+ // 2. Built-in template
89
+ // Search in templates/ directory of the project root
90
+ try {
91
+ const projectRoot = (0, config_1.findProjectRoot)();
92
+ const builtInPath = (0, path_1.safeJoin)(projectRoot, 'templates', templatePath.endsWith('.json') ? templatePath : `${templatePath}.json`);
93
+ if (fs.existsSync(builtInPath)) {
94
+ logger.info(`Using built-in template: ${templatePath}`);
95
+ return JSON.parse(fs.readFileSync(builtInPath, 'utf8'));
96
+ }
97
+ }
98
+ catch (e) {
99
+ // Ignore error if project root not found, try other methods
100
+ }
101
+ // Fallback for built-in templates relative to the module (for installed package)
102
+ const templatesDir = path.resolve(__dirname, '../../templates');
103
+ const templateFileName = templatePath.endsWith('.json') ? templatePath : `${templatePath}.json`;
104
+ const modulePath = (0, path_1.safeJoin)(templatesDir, templateFileName);
105
+ if (fs.existsSync(modulePath)) {
106
+ logger.info(`Using module template: ${templatePath}`);
107
+ return JSON.parse(fs.readFileSync(modulePath, 'utf8'));
108
+ }
109
+ // 3. Local file path
110
+ const localPath = (0, path_1.safeJoin)(process.cwd(), templatePath);
111
+ if (fs.existsSync(localPath)) {
112
+ logger.info(`Using local template: ${templatePath}`);
113
+ try {
114
+ return JSON.parse(fs.readFileSync(localPath, 'utf8'));
115
+ }
116
+ catch (e) {
117
+ throw new Error(`Failed to parse local template ${templatePath}: ${e}`);
118
+ }
119
+ }
120
+ throw new Error(`Template not found: ${templatePath}. It must be a URL, a built-in template name, or a local file path.`);
121
+ }
122
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/utils/template.ts"],"names":[],"mappings":"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"}
@@ -167,6 +167,7 @@ export interface RunnerConfig {
167
167
  tasks: Task[];
168
168
  dependsOn?: string[];
169
169
  pipelineBranch?: string;
170
+ worktreeDir?: string;
170
171
  branchPrefix?: string;
171
172
  worktreeRoot?: string;
172
173
  baseBranch?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litmers/cursorflow-orchestrator",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "Git worktree-based parallel AI agent orchestration system for Cursor",
5
5
  "main": "dist/cli/index.js",
6
6
  "bin": {
package/src/cli/clean.ts CHANGED
@@ -9,6 +9,7 @@ import * as path from 'path';
9
9
  import * as logger from '../utils/logger';
10
10
  import * as git from '../utils/git';
11
11
  import { loadConfig, getLogsDir, getTasksDir } from '../utils/config';
12
+ import { safeJoin } from '../utils/path';
12
13
 
13
14
  interface CleanOptions {
14
15
  type?: string;
@@ -105,7 +106,7 @@ async function cleanWorktrees(config: any, repoRoot: string, options: CleanOptio
105
106
  logger.info('\nChecking worktrees...');
106
107
  const worktrees = git.listWorktrees(repoRoot);
107
108
 
108
- const worktreeRoot = path.join(repoRoot, config.worktreeRoot || '_cursorflow/worktrees');
109
+ const worktreeRoot = safeJoin(repoRoot, config.worktreeRoot || '_cursorflow/worktrees');
109
110
  let toRemove = worktrees.filter(wt => {
110
111
  // Skip main worktree
111
112
  if (wt.path === repoRoot) return false;
@@ -226,9 +227,9 @@ async function cleanLogs(config: any, options: CleanOptions) {
226
227
  const entries = fs.readdirSync(logsDir, { withFileTypes: true });
227
228
  let items = entries.map(entry => ({
228
229
  name: entry.name,
229
- path: path.join(logsDir, entry.name),
230
+ path: safeJoin(logsDir, entry.name),
230
231
  isDir: entry.isDirectory(),
231
- mtime: getModTime(path.join(logsDir, entry.name))
232
+ mtime: getModTime(safeJoin(logsDir, entry.name))
232
233
  }));
233
234
 
234
235
  if (items.length <= 1) {
@@ -288,9 +289,9 @@ async function cleanTasks(config: any, options: CleanOptions) {
288
289
  .filter(entry => entry.name !== 'example')
289
290
  .map(entry => ({
290
291
  name: entry.name,
291
- path: path.join(tasksDir, entry.name),
292
+ path: safeJoin(tasksDir, entry.name),
292
293
  isDir: entry.isDirectory(),
293
- mtime: getModTime(path.join(tasksDir, entry.name))
294
+ mtime: getModTime(safeJoin(tasksDir, entry.name))
294
295
  }));
295
296
 
296
297
  if (items.length <= 1) {
@@ -325,7 +326,7 @@ async function cleanTasks(config: any, options: CleanOptions) {
325
326
  const entries = fs.readdirSync(tasksDir, { withFileTypes: true });
326
327
  for (const entry of entries) {
327
328
  if (entry.name === 'example') continue;
328
- const itemPath = path.join(tasksDir, entry.name);
329
+ const itemPath = safeJoin(tasksDir, entry.name);
329
330
  logger.info(` Removing task: ${entry.name}...`);
330
331
  fs.rmSync(itemPath, { recursive: true, force: true });
331
332
  }
package/src/cli/index.ts CHANGED
@@ -34,10 +34,11 @@ function printHelp(): void {
34
34
 
35
35
  \x1b[1mCOMMANDS\x1b[0m
36
36
  \x1b[33minit\x1b[0m [options] Initialize CursorFlow in project
37
+ \x1b[33msetup\x1b[0m [options] Install Cursor IDE commands
37
38
  \x1b[33mprepare\x1b[0m <feature> [opts] Prepare task directory and JSON files
38
39
  \x1b[33mrun\x1b[0m <tasks-dir> [options] Run orchestration (DAG-based)
39
40
  \x1b[33mmonitor\x1b[0m [run-dir] [options] \x1b[36mInteractive\x1b[0m lane dashboard
40
- \x1b[33mclean\x1b[0m <type> [options] Clean branches/worktrees/logs
41
+ \x1b[33mclean\x1b[0m <type> [options] Clean branches/worktrees/logs/tasks
41
42
  \x1b[33mresume\x1b[0m [lane] [options] Resume lane(s) - use --all for batch resume
42
43
  \x1b[33mdoctor\x1b[0m [options] Check environment and preflight
43
44
  \x1b[33msignal\x1b[0m <lane> <msg> Directly intervene in a running lane
@@ -54,6 +55,9 @@ function printHelp(): void {
54
55
  $ \x1b[32mcursorflow prepare NewFeature --lanes 3\x1b[0m
55
56
  $ \x1b[32mcursorflow run _cursorflow/tasks/MyFeature/\x1b[0m
56
57
  $ \x1b[32mcursorflow monitor latest\x1b[0m
58
+ $ \x1b[32mcursorflow logs --all --follow\x1b[0m
59
+ $ \x1b[32mcursorflow resume --all\x1b[0m
60
+ $ \x1b[32mcursorflow doctor\x1b[0m
57
61
  $ \x1b[32mcursorflow models\x1b[0m
58
62
 
59
63
  \x1b[1mDOCUMENTATION\x1b[0m
package/src/cli/init.ts CHANGED
@@ -9,6 +9,7 @@ import * as path from 'path';
9
9
  import * as logger from '../utils/logger';
10
10
  import { findProjectRoot, createDefaultConfig, CursorFlowConfig } from '../utils/config';
11
11
  import { setupCommands } from './setup-commands';
12
+ import { safeJoin } from '../utils/path';
12
13
 
13
14
  interface InitOptions {
14
15
  example: boolean;
@@ -84,8 +85,8 @@ Examples:
84
85
  }
85
86
 
86
87
  function createDirectories(projectRoot: string, config: CursorFlowConfig): void {
87
- const tasksDir = path.join(projectRoot, config.tasksDir);
88
- const logsDir = path.join(projectRoot, config.logsDir);
88
+ const tasksDir = safeJoin(projectRoot, config.tasksDir);
89
+ const logsDir = safeJoin(projectRoot, config.logsDir);
89
90
 
90
91
  if (!fs.existsSync(tasksDir)) {
91
92
  fs.mkdirSync(tasksDir, { recursive: true });
@@ -103,7 +104,7 @@ function createDirectories(projectRoot: string, config: CursorFlowConfig): void
103
104
  }
104
105
 
105
106
  function createExampleTasks(projectRoot: string, config: CursorFlowConfig): void {
106
- const exampleDir = path.join(projectRoot, config.tasksDir, 'example');
107
+ const exampleDir = safeJoin(projectRoot, config.tasksDir, 'example');
107
108
 
108
109
  if (!fs.existsSync(exampleDir)) {
109
110
  fs.mkdirSync(exampleDir, { recursive: true });
@@ -134,13 +135,13 @@ Create a simple hello.txt file with a greeting message.
134
135
  ]
135
136
  };
136
137
 
137
- const taskPath = path.join(exampleDir, '01-hello.json');
138
+ const taskPath = safeJoin(exampleDir, '01-hello.json');
138
139
  fs.writeFileSync(taskPath, JSON.stringify(exampleTask, null, 2) + '\n', 'utf8');
139
140
 
140
141
  logger.success(`Created example task: ${path.relative(projectRoot, taskPath)}`);
141
142
 
142
143
  // Create README
143
- const readmePath = path.join(exampleDir, 'README.md');
144
+ const readmePath = safeJoin(exampleDir, 'README.md');
144
145
  const readme = `# Example Task
145
146
 
146
147
  This is an example CursorFlow task to help you get started.
@@ -172,7 +173,7 @@ cursorflow run ${config.tasksDir}/example/
172
173
  * Add _cursorflow to .gitignore
173
174
  */
174
175
  function updateGitignore(projectRoot: string): void {
175
- const gitignorePath = path.join(projectRoot, '.gitignore');
176
+ const gitignorePath = safeJoin(projectRoot, '.gitignore');
176
177
  const entry = '_cursorflow/';
177
178
 
178
179
  // Try to read existing .gitignore (avoid TOCTOU by reading directly)