@litmers/cursorflow-orchestrator 0.1.3 → 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.
Files changed (90) hide show
  1. package/CHANGELOG.md +17 -7
  2. package/README.md +33 -2
  3. package/commands/cursorflow-doctor.md +24 -0
  4. package/commands/cursorflow-signal.md +19 -0
  5. package/dist/cli/clean.d.ts +5 -0
  6. package/dist/cli/clean.js +57 -0
  7. package/dist/cli/clean.js.map +1 -0
  8. package/dist/cli/doctor.d.ts +15 -0
  9. package/dist/cli/doctor.js +139 -0
  10. package/dist/cli/doctor.js.map +1 -0
  11. package/dist/cli/index.d.ts +6 -0
  12. package/dist/cli/index.js +125 -0
  13. package/dist/cli/index.js.map +1 -0
  14. package/dist/cli/init.d.ts +7 -0
  15. package/dist/cli/init.js +302 -0
  16. package/dist/cli/init.js.map +1 -0
  17. package/dist/cli/monitor.d.ts +8 -0
  18. package/dist/cli/monitor.js +210 -0
  19. package/dist/cli/monitor.js.map +1 -0
  20. package/dist/cli/resume.d.ts +5 -0
  21. package/dist/cli/resume.js +128 -0
  22. package/dist/cli/resume.js.map +1 -0
  23. package/dist/cli/run.d.ts +5 -0
  24. package/dist/cli/run.js +128 -0
  25. package/dist/cli/run.js.map +1 -0
  26. package/dist/cli/setup-commands.d.ts +23 -0
  27. package/dist/cli/setup-commands.js +234 -0
  28. package/dist/cli/setup-commands.js.map +1 -0
  29. package/dist/cli/signal.d.ts +7 -0
  30. package/dist/cli/signal.js +99 -0
  31. package/dist/cli/signal.js.map +1 -0
  32. package/dist/core/orchestrator.d.ts +47 -0
  33. package/dist/core/orchestrator.js +192 -0
  34. package/dist/core/orchestrator.js.map +1 -0
  35. package/dist/core/reviewer.d.ts +60 -0
  36. package/dist/core/reviewer.js +239 -0
  37. package/dist/core/reviewer.js.map +1 -0
  38. package/dist/core/runner.d.ts +51 -0
  39. package/dist/core/runner.js +499 -0
  40. package/dist/core/runner.js.map +1 -0
  41. package/dist/utils/config.d.ts +31 -0
  42. package/dist/utils/config.js +198 -0
  43. package/dist/utils/config.js.map +1 -0
  44. package/dist/utils/cursor-agent.d.ts +61 -0
  45. package/dist/utils/cursor-agent.js +263 -0
  46. package/dist/utils/cursor-agent.js.map +1 -0
  47. package/dist/utils/doctor.d.ts +63 -0
  48. package/dist/utils/doctor.js +280 -0
  49. package/dist/utils/doctor.js.map +1 -0
  50. package/dist/utils/git.d.ts +131 -0
  51. package/dist/utils/git.js +272 -0
  52. package/dist/utils/git.js.map +1 -0
  53. package/dist/utils/logger.d.ts +68 -0
  54. package/dist/utils/logger.js +158 -0
  55. package/dist/utils/logger.js.map +1 -0
  56. package/dist/utils/state.d.ts +65 -0
  57. package/dist/utils/state.js +216 -0
  58. package/dist/utils/state.js.map +1 -0
  59. package/dist/utils/types.d.ts +118 -0
  60. package/dist/utils/types.js +6 -0
  61. package/dist/utils/types.js.map +1 -0
  62. package/examples/README.md +155 -0
  63. package/examples/demo-project/README.md +262 -0
  64. package/examples/demo-project/_cursorflow/tasks/demo-test/01-create-utils.json +18 -0
  65. package/examples/demo-project/_cursorflow/tasks/demo-test/02-add-tests.json +18 -0
  66. package/examples/demo-project/_cursorflow/tasks/demo-test/README.md +109 -0
  67. package/package.json +71 -61
  68. package/scripts/ai-security-check.js +11 -4
  69. package/scripts/local-security-gate.sh +76 -0
  70. package/src/cli/{clean.js → clean.ts} +11 -5
  71. package/src/cli/doctor.ts +127 -0
  72. package/src/cli/{index.js → index.ts} +27 -16
  73. package/src/cli/{init.js → init.ts} +26 -18
  74. package/src/cli/{monitor.js → monitor.ts} +57 -44
  75. package/src/cli/resume.ts +119 -0
  76. package/src/cli/run.ts +109 -0
  77. package/src/cli/{setup-commands.js → setup-commands.ts} +38 -18
  78. package/src/cli/signal.ts +89 -0
  79. package/src/core/{orchestrator.js → orchestrator.ts} +44 -26
  80. package/src/core/{reviewer.js → reviewer.ts} +36 -29
  81. package/src/core/{runner.js → runner.ts} +125 -76
  82. package/src/utils/{config.js → config.ts} +17 -25
  83. package/src/utils/{cursor-agent.js → cursor-agent.ts} +38 -47
  84. package/src/utils/doctor.ts +312 -0
  85. package/src/utils/{git.js → git.ts} +70 -56
  86. package/src/utils/{logger.js → logger.ts} +170 -178
  87. package/src/utils/{state.js → state.ts} +30 -38
  88. package/src/utils/types.ts +134 -0
  89. package/src/cli/resume.js +0 -31
  90. package/src/cli/run.js +0 -51
@@ -0,0 +1,280 @@
1
+ "use strict";
2
+ /**
3
+ * CursorFlow Doctor - environment and preflight checks
4
+ *
5
+ * This module provides actionable diagnostics for common run failures:
6
+ * - Not inside a Git work tree
7
+ * - Missing `origin` remote (required for pushing lane branches)
8
+ * - Missing Git worktree support
9
+ * - Missing base branch referenced by lane task files
10
+ * - Missing/invalid tasks directory
11
+ * - Missing Cursor Agent setup (optional)
12
+ */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.runDoctor = runDoctor;
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const git = __importStar(require("./git"));
51
+ const cursor_agent_1 = require("./cursor-agent");
52
+ const setup_commands_1 = require("../cli/setup-commands");
53
+ function addIssue(issues, issue) {
54
+ issues.push(issue);
55
+ }
56
+ function resolveRepoRoot(cwd) {
57
+ const res = git.runGitResult(['rev-parse', '--show-toplevel'], { cwd });
58
+ if (!res.success || !res.stdout)
59
+ return null;
60
+ return res.stdout;
61
+ }
62
+ function isInsideGitWorktree(cwd) {
63
+ const res = git.runGitResult(['rev-parse', '--is-inside-work-tree'], { cwd });
64
+ return res.success && res.stdout.trim() === 'true';
65
+ }
66
+ function hasAtLeastOneCommit(repoRoot) {
67
+ const res = git.runGitResult(['rev-parse', '--verify', 'HEAD'], { cwd: repoRoot });
68
+ return res.success;
69
+ }
70
+ function hasOriginRemote(repoRoot) {
71
+ const res = git.runGitResult(['remote', 'get-url', 'origin'], { cwd: repoRoot });
72
+ return res.success && !!res.stdout;
73
+ }
74
+ function hasWorktreeSupport(repoRoot) {
75
+ const res = git.runGitResult(['worktree', 'list'], { cwd: repoRoot });
76
+ if (res.success)
77
+ return { ok: true };
78
+ return { ok: false, details: res.stderr || res.stdout || 'git worktree failed' };
79
+ }
80
+ function branchExists(repoRoot, branchName) {
81
+ // rev-parse --verify works for both branches and tags; restrict to heads first.
82
+ const headRes = git.runGitResult(['show-ref', '--verify', `refs/heads/${branchName}`], { cwd: repoRoot });
83
+ if (headRes.success)
84
+ return true;
85
+ const anyRes = git.runGitResult(['rev-parse', '--verify', branchName], { cwd: repoRoot });
86
+ return anyRes.success;
87
+ }
88
+ function readLaneJsonFiles(tasksDir) {
89
+ const files = fs
90
+ .readdirSync(tasksDir)
91
+ .filter(f => f.endsWith('.json'))
92
+ .sort()
93
+ .map(f => path.join(tasksDir, f));
94
+ return files.map(p => {
95
+ const raw = fs.readFileSync(p, 'utf8');
96
+ const json = JSON.parse(raw);
97
+ return { path: p, json };
98
+ });
99
+ }
100
+ function collectBaseBranchesFromLanes(lanes, defaultBaseBranch) {
101
+ const set = new Set();
102
+ for (const lane of lanes) {
103
+ const baseBranch = String(lane.json?.baseBranch || defaultBaseBranch || 'main').trim();
104
+ if (baseBranch)
105
+ set.add(baseBranch);
106
+ }
107
+ return Array.from(set);
108
+ }
109
+ /**
110
+ * Run doctor checks.
111
+ *
112
+ * If `tasksDir` is provided, additional preflight checks are performed:
113
+ * - tasks directory existence and JSON validity
114
+ * - baseBranch referenced by lanes exists locally
115
+ */
116
+ function runDoctor(options = {}) {
117
+ const cwd = options.cwd || process.cwd();
118
+ const issues = [];
119
+ const context = {
120
+ cwd,
121
+ executor: options.executor,
122
+ };
123
+ // 1) Git repository checks
124
+ if (!isInsideGitWorktree(cwd)) {
125
+ addIssue(issues, {
126
+ id: 'git.not_repo',
127
+ severity: 'error',
128
+ title: 'Not a Git repository',
129
+ message: 'Current directory is not inside a Git work tree. CursorFlow requires Git to create worktrees and branches.',
130
+ fixes: [
131
+ 'cd into your repository root (or any subdirectory inside it)',
132
+ 'If this is a new project: git init && git commit --allow-empty -m "chore: initial commit"',
133
+ ],
134
+ });
135
+ return { ok: false, issues, context };
136
+ }
137
+ const repoRoot = resolveRepoRoot(cwd) || undefined;
138
+ context.repoRoot = repoRoot;
139
+ const gitCwd = repoRoot || cwd;
140
+ if (!hasAtLeastOneCommit(gitCwd)) {
141
+ addIssue(issues, {
142
+ id: 'git.no_commits',
143
+ severity: 'error',
144
+ title: 'Repository has no commits',
145
+ message: 'CursorFlow needs at least one commit (HEAD) to create worktrees and new branches.',
146
+ fixes: ['git commit --allow-empty -m "chore: initial commit"'],
147
+ });
148
+ }
149
+ if (!hasOriginRemote(gitCwd)) {
150
+ addIssue(issues, {
151
+ id: 'git.no_origin',
152
+ severity: 'error',
153
+ title: "Missing remote 'origin'",
154
+ message: "Remote 'origin' is not configured. CursorFlow pushes lane branches to 'origin' during execution.",
155
+ fixes: [
156
+ 'git remote add origin <your-repo-url>',
157
+ 'git remote -v # verify remotes',
158
+ ],
159
+ });
160
+ }
161
+ const wt = hasWorktreeSupport(gitCwd);
162
+ if (!wt.ok) {
163
+ addIssue(issues, {
164
+ id: 'git.worktree_unavailable',
165
+ severity: 'error',
166
+ title: 'Git worktree not available',
167
+ message: 'Git worktree support is required, but `git worktree` failed.',
168
+ fixes: [
169
+ 'Upgrade Git (worktrees require Git >= 2.5)',
170
+ 'Ensure the repository is not corrupted',
171
+ ],
172
+ details: wt.details,
173
+ });
174
+ }
175
+ // 2) Tasks-dir checks (optional; used by `cursorflow run` preflight)
176
+ if (options.tasksDir) {
177
+ const tasksDirAbs = path.isAbsolute(options.tasksDir)
178
+ ? options.tasksDir
179
+ : path.resolve(cwd, options.tasksDir);
180
+ context.tasksDir = tasksDirAbs;
181
+ if (!fs.existsSync(tasksDirAbs)) {
182
+ addIssue(issues, {
183
+ id: 'tasks.missing_dir',
184
+ severity: 'error',
185
+ title: 'Tasks directory not found',
186
+ message: `Tasks directory does not exist: ${tasksDirAbs}`,
187
+ fixes: [
188
+ 'Double-check the path you passed to `cursorflow run`',
189
+ 'If needed, run: cursorflow init --example',
190
+ ],
191
+ });
192
+ }
193
+ else {
194
+ let lanes = [];
195
+ try {
196
+ lanes = readLaneJsonFiles(tasksDirAbs);
197
+ }
198
+ catch (error) {
199
+ addIssue(issues, {
200
+ id: 'tasks.invalid_json',
201
+ severity: 'error',
202
+ title: 'Invalid lane JSON file',
203
+ message: `Failed to read/parse lane JSON files in: ${tasksDirAbs}`,
204
+ details: error?.message ? String(error.message) : String(error),
205
+ fixes: ['Validate JSON syntax for each lane file (*.json)'],
206
+ });
207
+ lanes = [];
208
+ }
209
+ if (lanes.length === 0) {
210
+ addIssue(issues, {
211
+ id: 'tasks.no_lanes',
212
+ severity: 'error',
213
+ title: 'No lane files found',
214
+ message: `No lane task files (*.json) found in: ${tasksDirAbs}`,
215
+ fixes: ['Ensure the tasks directory contains one or more lane JSON files'],
216
+ });
217
+ }
218
+ else {
219
+ const baseBranches = collectBaseBranchesFromLanes(lanes, 'main');
220
+ for (const baseBranch of baseBranches) {
221
+ if (!branchExists(gitCwd, baseBranch)) {
222
+ addIssue(issues, {
223
+ id: `git.missing_base_branch.${baseBranch}`,
224
+ severity: 'error',
225
+ title: `Missing base branch: ${baseBranch}`,
226
+ message: `Lane files reference baseBranch "${baseBranch}", but it does not exist locally.`,
227
+ fixes: [
228
+ 'git fetch origin --prune',
229
+ `Or update lane JSON baseBranch to an existing branch`,
230
+ ],
231
+ });
232
+ }
233
+ }
234
+ }
235
+ }
236
+ }
237
+ // 3) Cursor Agent checks (optional)
238
+ const includeCursor = options.includeCursorAgentChecks !== false;
239
+ if (includeCursor && (options.executor || 'cursor-agent') === 'cursor-agent') {
240
+ if (!(0, cursor_agent_1.checkCursorAgentInstalled)()) {
241
+ addIssue(issues, {
242
+ id: 'cursor_agent.missing',
243
+ severity: 'error',
244
+ title: 'cursor-agent CLI not installed',
245
+ message: 'cursor-agent is required for local execution.',
246
+ fixes: ['npm install -g @cursor/agent', 'cursor-agent --version'],
247
+ });
248
+ }
249
+ else {
250
+ const auth = (0, cursor_agent_1.checkCursorAuth)();
251
+ if (!auth.authenticated) {
252
+ addIssue(issues, {
253
+ id: 'cursor_agent.not_authenticated',
254
+ severity: 'error',
255
+ title: 'Cursor authentication required',
256
+ message: auth.message,
257
+ details: auth.details || auth.error,
258
+ fixes: [
259
+ 'Open Cursor IDE and sign in',
260
+ 'Verify AI features work in the IDE',
261
+ 'Re-run: cursorflow doctor',
262
+ ],
263
+ });
264
+ }
265
+ }
266
+ }
267
+ // 4) IDE Integration checks
268
+ if (!(0, setup_commands_1.areCommandsInstalled)()) {
269
+ addIssue(issues, {
270
+ id: 'ide.commands_missing',
271
+ severity: 'warn',
272
+ title: 'Cursor IDE commands not installed',
273
+ message: 'CursorFlow slash commands (e.g., /cursorflow-run) are missing or outdated.',
274
+ fixes: ['cursorflow-setup --force', 'or run `cursorflow run` to auto-install'],
275
+ });
276
+ }
277
+ const ok = issues.every(i => i.severity !== 'error');
278
+ return { ok, issues, context };
279
+ }
280
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/utils/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Git utilities for CursorFlow
3
+ */
4
+ export interface GitRunOptions {
5
+ cwd?: string;
6
+ silent?: boolean;
7
+ }
8
+ export interface GitResult {
9
+ exitCode: number;
10
+ stdout: string;
11
+ stderr: string;
12
+ success: boolean;
13
+ }
14
+ export interface WorktreeInfo {
15
+ path: string;
16
+ branch?: string;
17
+ head?: string;
18
+ }
19
+ export interface ChangedFile {
20
+ status: string;
21
+ file: string;
22
+ }
23
+ export interface CommitInfo {
24
+ hash: string;
25
+ shortHash: string;
26
+ author: string;
27
+ authorEmail: string;
28
+ timestamp: number;
29
+ subject: string;
30
+ }
31
+ /**
32
+ * Run git command and return output
33
+ */
34
+ export declare function runGit(args: string[], options?: GitRunOptions): string;
35
+ /**
36
+ * Run git command and return result object
37
+ */
38
+ export declare function runGitResult(args: string[], options?: GitRunOptions): GitResult;
39
+ /**
40
+ * Get current branch name
41
+ */
42
+ export declare function getCurrentBranch(cwd?: string): string;
43
+ /**
44
+ * Get repository root directory
45
+ */
46
+ export declare function getRepoRoot(cwd?: string): string;
47
+ /**
48
+ * Check if directory is a git repository
49
+ */
50
+ export declare function isGitRepo(cwd?: string): boolean;
51
+ /**
52
+ * Check if worktree exists
53
+ */
54
+ export declare function worktreeExists(worktreePath: string, cwd?: string): boolean;
55
+ /**
56
+ * Create worktree
57
+ */
58
+ export declare function createWorktree(worktreePath: string, branchName: string, options?: {
59
+ cwd?: string;
60
+ baseBranch?: string;
61
+ }): string;
62
+ /**
63
+ * Remove worktree
64
+ */
65
+ export declare function removeWorktree(worktreePath: string, options?: {
66
+ cwd?: string;
67
+ force?: boolean;
68
+ }): void;
69
+ /**
70
+ * List all worktrees
71
+ */
72
+ export declare function listWorktrees(cwd?: string): WorktreeInfo[];
73
+ /**
74
+ * Check if there are uncommitted changes
75
+ */
76
+ export declare function hasUncommittedChanges(cwd?: string): boolean;
77
+ /**
78
+ * Get list of changed files
79
+ */
80
+ export declare function getChangedFiles(cwd?: string): ChangedFile[];
81
+ /**
82
+ * Create commit
83
+ */
84
+ export declare function commit(message: string, options?: {
85
+ cwd?: string;
86
+ addAll?: boolean;
87
+ }): void;
88
+ /**
89
+ * Push to remote
90
+ */
91
+ export declare function push(branchName: string, options?: {
92
+ cwd?: string;
93
+ force?: boolean;
94
+ setUpstream?: boolean;
95
+ }): void;
96
+ /**
97
+ * Fetch from remote
98
+ */
99
+ export declare function fetch(options?: {
100
+ cwd?: string;
101
+ prune?: boolean;
102
+ }): void;
103
+ /**
104
+ * Check if branch exists (local or remote)
105
+ */
106
+ export declare function branchExists(branchName: string, options?: {
107
+ cwd?: string;
108
+ remote?: boolean;
109
+ }): boolean;
110
+ /**
111
+ * Delete branch
112
+ */
113
+ export declare function deleteBranch(branchName: string, options?: {
114
+ cwd?: string;
115
+ force?: boolean;
116
+ remote?: boolean;
117
+ }): void;
118
+ /**
119
+ * Merge branch
120
+ */
121
+ export declare function merge(branchName: string, options?: {
122
+ cwd?: string;
123
+ noFf?: boolean;
124
+ message?: string | null;
125
+ }): void;
126
+ /**
127
+ * Get commit info
128
+ */
129
+ export declare function getCommitInfo(commitHash: string, options?: {
130
+ cwd?: string;
131
+ }): CommitInfo | null;
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ /**
3
+ * Git utilities for CursorFlow
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runGit = runGit;
7
+ exports.runGitResult = runGitResult;
8
+ exports.getCurrentBranch = getCurrentBranch;
9
+ exports.getRepoRoot = getRepoRoot;
10
+ exports.isGitRepo = isGitRepo;
11
+ exports.worktreeExists = worktreeExists;
12
+ exports.createWorktree = createWorktree;
13
+ exports.removeWorktree = removeWorktree;
14
+ exports.listWorktrees = listWorktrees;
15
+ exports.hasUncommittedChanges = hasUncommittedChanges;
16
+ exports.getChangedFiles = getChangedFiles;
17
+ exports.commit = commit;
18
+ exports.push = push;
19
+ exports.fetch = fetch;
20
+ exports.branchExists = branchExists;
21
+ exports.deleteBranch = deleteBranch;
22
+ exports.merge = merge;
23
+ exports.getCommitInfo = getCommitInfo;
24
+ const child_process_1 = require("child_process");
25
+ /**
26
+ * Run git command and return output
27
+ */
28
+ function runGit(args, options = {}) {
29
+ const { cwd, silent = false } = options;
30
+ try {
31
+ const result = (0, child_process_1.spawnSync)('git', args, {
32
+ cwd: cwd || process.cwd(),
33
+ encoding: 'utf8',
34
+ stdio: silent ? 'pipe' : 'inherit',
35
+ });
36
+ if (result.status !== 0 && !silent) {
37
+ throw new Error(`Git command failed: git ${args.join(' ')}\n${result.stderr || ''}`);
38
+ }
39
+ return result.stdout ? result.stdout.trim() : '';
40
+ }
41
+ catch (error) {
42
+ if (silent) {
43
+ return '';
44
+ }
45
+ throw error;
46
+ }
47
+ }
48
+ /**
49
+ * Run git command and return result object
50
+ */
51
+ function runGitResult(args, options = {}) {
52
+ const { cwd } = options;
53
+ const result = (0, child_process_1.spawnSync)('git', args, {
54
+ cwd: cwd || process.cwd(),
55
+ encoding: 'utf8',
56
+ stdio: 'pipe',
57
+ });
58
+ return {
59
+ exitCode: result.status ?? 1,
60
+ stdout: (result.stdout || '').toString().trim(),
61
+ stderr: (result.stderr || '').toString().trim(),
62
+ success: result.status === 0,
63
+ };
64
+ }
65
+ /**
66
+ * Get current branch name
67
+ */
68
+ function getCurrentBranch(cwd) {
69
+ return runGit(['rev-parse', '--abbrev-ref', 'HEAD'], { cwd, silent: true });
70
+ }
71
+ /**
72
+ * Get repository root directory
73
+ */
74
+ function getRepoRoot(cwd) {
75
+ return runGit(['rev-parse', '--show-toplevel'], { cwd, silent: true });
76
+ }
77
+ /**
78
+ * Check if directory is a git repository
79
+ */
80
+ function isGitRepo(cwd) {
81
+ const result = runGitResult(['rev-parse', '--git-dir'], { cwd });
82
+ return result.success;
83
+ }
84
+ /**
85
+ * Check if worktree exists
86
+ */
87
+ function worktreeExists(worktreePath, cwd) {
88
+ const result = runGitResult(['worktree', 'list'], { cwd });
89
+ if (!result.success)
90
+ return false;
91
+ return result.stdout.includes(worktreePath);
92
+ }
93
+ /**
94
+ * Create worktree
95
+ */
96
+ function createWorktree(worktreePath, branchName, options = {}) {
97
+ const { cwd, baseBranch = 'main' } = options;
98
+ // Check if branch already exists
99
+ const branchExists = runGitResult(['rev-parse', '--verify', branchName], { cwd }).success;
100
+ if (branchExists) {
101
+ // Branch exists, checkout to worktree
102
+ runGit(['worktree', 'add', worktreePath, branchName], { cwd });
103
+ }
104
+ else {
105
+ // Create new branch from base
106
+ runGit(['worktree', 'add', '-b', branchName, worktreePath, baseBranch], { cwd });
107
+ }
108
+ return worktreePath;
109
+ }
110
+ /**
111
+ * Remove worktree
112
+ */
113
+ function removeWorktree(worktreePath, options = {}) {
114
+ const { cwd, force = false } = options;
115
+ const args = ['worktree', 'remove', worktreePath];
116
+ if (force) {
117
+ args.push('--force');
118
+ }
119
+ runGit(args, { cwd });
120
+ }
121
+ /**
122
+ * List all worktrees
123
+ */
124
+ function listWorktrees(cwd) {
125
+ const result = runGitResult(['worktree', 'list', '--porcelain'], { cwd });
126
+ if (!result.success)
127
+ return [];
128
+ const worktrees = [];
129
+ const lines = result.stdout.split('\n');
130
+ let current = {};
131
+ for (const line of lines) {
132
+ if (line.startsWith('worktree ')) {
133
+ if (current.path) {
134
+ worktrees.push(current);
135
+ }
136
+ current = { path: line.slice(9) };
137
+ }
138
+ else if (line.startsWith('branch ')) {
139
+ current.branch = line.slice(7);
140
+ }
141
+ else if (line.startsWith('HEAD ')) {
142
+ current.head = line.slice(5);
143
+ }
144
+ }
145
+ if (current.path) {
146
+ worktrees.push(current);
147
+ }
148
+ return worktrees;
149
+ }
150
+ /**
151
+ * Check if there are uncommitted changes
152
+ */
153
+ function hasUncommittedChanges(cwd) {
154
+ const result = runGitResult(['status', '--porcelain'], { cwd });
155
+ return result.success && result.stdout.length > 0;
156
+ }
157
+ /**
158
+ * Get list of changed files
159
+ */
160
+ function getChangedFiles(cwd) {
161
+ const result = runGitResult(['status', '--porcelain'], { cwd });
162
+ if (!result.success)
163
+ return [];
164
+ return result.stdout
165
+ .split('\n')
166
+ .filter(line => line.trim())
167
+ .map(line => {
168
+ const status = line.slice(0, 2);
169
+ const file = line.slice(3);
170
+ return { status, file };
171
+ });
172
+ }
173
+ /**
174
+ * Create commit
175
+ */
176
+ function commit(message, options = {}) {
177
+ const { cwd, addAll = true } = options;
178
+ if (addAll) {
179
+ runGit(['add', '-A'], { cwd });
180
+ }
181
+ runGit(['commit', '-m', message], { cwd });
182
+ }
183
+ /**
184
+ * Push to remote
185
+ */
186
+ function push(branchName, options = {}) {
187
+ const { cwd, force = false, setUpstream = false } = options;
188
+ const args = ['push'];
189
+ if (force) {
190
+ args.push('--force');
191
+ }
192
+ if (setUpstream) {
193
+ args.push('-u', 'origin', branchName);
194
+ }
195
+ else {
196
+ args.push('origin', branchName);
197
+ }
198
+ runGit(args, { cwd });
199
+ }
200
+ /**
201
+ * Fetch from remote
202
+ */
203
+ function fetch(options = {}) {
204
+ const { cwd, prune = true } = options;
205
+ const args = ['fetch', 'origin'];
206
+ if (prune) {
207
+ args.push('--prune');
208
+ }
209
+ runGit(args, { cwd });
210
+ }
211
+ /**
212
+ * Check if branch exists (local or remote)
213
+ */
214
+ function branchExists(branchName, options = {}) {
215
+ const { cwd, remote = false } = options;
216
+ if (remote) {
217
+ const result = runGitResult(['ls-remote', '--heads', 'origin', branchName], { cwd });
218
+ return result.success && result.stdout.length > 0;
219
+ }
220
+ else {
221
+ const result = runGitResult(['rev-parse', '--verify', branchName], { cwd });
222
+ return result.success;
223
+ }
224
+ }
225
+ /**
226
+ * Delete branch
227
+ */
228
+ function deleteBranch(branchName, options = {}) {
229
+ const { cwd, force = false, remote = false } = options;
230
+ if (remote) {
231
+ runGit(['push', 'origin', '--delete', branchName], { cwd });
232
+ }
233
+ else {
234
+ const args = ['branch', force ? '-D' : '-d', branchName];
235
+ runGit(args, { cwd });
236
+ }
237
+ }
238
+ /**
239
+ * Merge branch
240
+ */
241
+ function merge(branchName, options = {}) {
242
+ const { cwd, noFf = false, message = null } = options;
243
+ const args = ['merge'];
244
+ if (noFf) {
245
+ args.push('--no-ff');
246
+ }
247
+ if (message) {
248
+ args.push('-m', message);
249
+ }
250
+ args.push(branchName);
251
+ runGit(args, { cwd });
252
+ }
253
+ /**
254
+ * Get commit info
255
+ */
256
+ function getCommitInfo(commitHash, options = {}) {
257
+ const { cwd } = options;
258
+ const format = '--format=%H%n%h%n%an%n%ae%n%at%n%s';
259
+ const result = runGitResult(['show', '-s', format, commitHash], { cwd });
260
+ if (!result.success)
261
+ return null;
262
+ const lines = result.stdout.split('\n');
263
+ return {
264
+ hash: lines[0] || '',
265
+ shortHash: lines[1] || '',
266
+ author: lines[2] || '',
267
+ authorEmail: lines[3] || '',
268
+ timestamp: parseInt(lines[4] || '0'),
269
+ subject: lines[5] || '',
270
+ };
271
+ }
272
+ //# sourceMappingURL=git.js.map