@edgedive/cli 0.1.8 → 0.2.0
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-dev.log +3 -3
- package/dist/commands/local.d.ts +2 -1
- package/dist/commands/local.d.ts.map +1 -1
- package/dist/commands/local.js +17 -9
- package/dist/commands/local.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/git-utils.d.ts +5 -0
- package/dist/utils/git-utils.d.ts.map +1 -1
- package/dist/utils/git-utils.js +59 -0
- package/dist/utils/git-utils.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/local.ts +33 -13
- package/src/index.ts +11 -3
- package/src/utils/git-utils.ts +66 -0
package/.turbo/turbo-build.log
CHANGED
package/.turbo/turbo-dev.log
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
> @edgedive/cli@0.1.
|
|
2
|
+
> @edgedive/cli@0.1.8 dev /Users/nimesh/edgedive/nimesh-workstream-2/packages/edgedive-cli
|
|
3
3
|
> tsc --watch
|
|
4
4
|
|
|
5
|
-
[2J[3J[H[[
|
|
5
|
+
[2J[3J[H[[90m4:52:03 PM[0m] Starting compilation in watch mode...
|
|
6
6
|
|
|
7
|
-
[[
|
|
7
|
+
[[90m4:52:04 PM[0m] Found 0 errors. Watching for file changes.
|
|
8
8
|
|
package/dist/commands/local.d.ts
CHANGED
|
@@ -5,7 +5,8 @@ interface LocalOptions {
|
|
|
5
5
|
prUrl?: string;
|
|
6
6
|
issueUrl?: string;
|
|
7
7
|
threadUrl?: string;
|
|
8
|
+
worktree?: boolean;
|
|
8
9
|
}
|
|
9
|
-
export declare function localCommand({ prUrl, issueUrl, threadUrl }: LocalOptions): Promise<void>;
|
|
10
|
+
export declare function localCommand({ prUrl, issueUrl, threadUrl, worktree, }: LocalOptions): Promise<void>;
|
|
10
11
|
export {};
|
|
11
12
|
//# sourceMappingURL=local.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/commands/local.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/commands/local.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,YAAY,CAAC,EACjC,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8K9B"}
|
package/dist/commands/local.js
CHANGED
|
@@ -7,7 +7,7 @@ import { EdgediveApiClient } from '../api/client.js';
|
|
|
7
7
|
import { SessionDownloader } from '../utils/session-downloader.js';
|
|
8
8
|
import { GitUtils } from '../utils/git-utils.js';
|
|
9
9
|
import { launchClaudeSession } from '../utils/claude-launcher.js';
|
|
10
|
-
export async function localCommand({ prUrl, issueUrl, threadUrl }) {
|
|
10
|
+
export async function localCommand({ prUrl, issueUrl, threadUrl, worktree, }) {
|
|
11
11
|
const configManager = new ConfigManager();
|
|
12
12
|
const apiClient = new EdgediveApiClient(configManager);
|
|
13
13
|
const downloader = new SessionDownloader();
|
|
@@ -89,21 +89,29 @@ export async function localCommand({ prUrl, issueUrl, threadUrl }) {
|
|
|
89
89
|
process.exit(1);
|
|
90
90
|
}
|
|
91
91
|
console.log(chalk.green(`✅ Using repository at ${repoInfo.rootPath}`));
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
// Ensure PR branch is checked out locally
|
|
92
|
+
// Ensure PR branch is checked out locally or in a worktree
|
|
93
|
+
let workingPath = repoInfo.rootPath;
|
|
95
94
|
try {
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
if (worktree) {
|
|
96
|
+
workingPath = await GitUtils.ensureBranchInWorktree(sessionData.repository.branch, repoInfo.rootPath);
|
|
97
|
+
console.log(chalk.green(`✅ Created worktree for branch ${sessionData.repository.branch} at ${workingPath}`));
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
await GitUtils.ensureBranchCheckedOut(sessionData.repository.branch, repoInfo.rootPath);
|
|
101
|
+
console.log(chalk.green(`✅ Checked out branch ${sessionData.repository.branch}`));
|
|
102
|
+
}
|
|
98
103
|
}
|
|
99
104
|
catch (error) {
|
|
100
|
-
console.error(chalk.red(`\n❌ Failed to checkout branch ${sessionData.repository.branch}: ${error.message}\n`));
|
|
105
|
+
console.error(chalk.red(`\n❌ Failed to ${worktree ? 'create worktree for' : 'checkout'} branch ${sessionData.repository.branch}: ${error.message}\n`));
|
|
101
106
|
console.log(chalk.yellow('Resolve the git issue above and rerun the local command.'));
|
|
102
107
|
process.exit(1);
|
|
103
108
|
}
|
|
109
|
+
// Download session files into Claude projects directory
|
|
110
|
+
// Use workingPath so the session goes to the correct directory (worktree path if --worktree is used)
|
|
111
|
+
const { claudeSessionId, claudeSessionPath } = await downloader.downloadSession(sessionData, workingPath);
|
|
104
112
|
console.log(chalk.blue(`\n🚀 Launching Claude session ${claudeSessionId}...\n`));
|
|
105
113
|
try {
|
|
106
|
-
const sessionEndInfo = await launchClaudeSession(claudeSessionId,
|
|
114
|
+
const sessionEndInfo = await launchClaudeSession(claudeSessionId, workingPath);
|
|
107
115
|
console.log(chalk.green('\n✅ Claude session closed. Happy debugging!\n'));
|
|
108
116
|
// Upload Claude session file back to server
|
|
109
117
|
// Use the session info from the SessionEnd hook if available, otherwise fall back to original path
|
|
@@ -111,7 +119,7 @@ export async function localCommand({ prUrl, issueUrl, threadUrl }) {
|
|
|
111
119
|
}
|
|
112
120
|
catch (error) {
|
|
113
121
|
console.error(chalk.red(`\n❌ Failed to start Claude automatically: ${error.message}\n`));
|
|
114
|
-
console.log(chalk.yellow(`You can resume manually with: claude -r ${claudeSessionId} (from ${
|
|
122
|
+
console.log(chalk.yellow(`You can resume manually with: claude -r ${claudeSessionId} (from ${workingPath})`));
|
|
115
123
|
process.exit(1);
|
|
116
124
|
}
|
|
117
125
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/commands/local.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAyB,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/commands/local.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,7 @@ program
|
|
|
34
34
|
.option('--pr-url <prUrl>', 'GitHub PR URL to load locally')
|
|
35
35
|
.option('--issue-url <issueUrl>', 'Linear issue URL to load locally')
|
|
36
36
|
.option('--thread-url <threadUrl>', 'Slack thread URL to load locally')
|
|
37
|
+
.option('--worktree', 'Create branch in a worktree instead of checking out')
|
|
37
38
|
.action(async (options) => {
|
|
38
39
|
await localCommand(options);
|
|
39
40
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE/C,MAAM,CAAC,MAAM,EAAE,CAAC;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,iDAAiD,CAAC;KAC9D,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAEhC,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,YAAY,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2BAA2B,CAAC;KACxC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,kBAAkB,EAAE,+BAA+B,CAAC;KAC3D,MAAM,CAAC,wBAAwB,EAAE,kCAAkC,CAAC;KACpE,MAAM,CAAC,0BAA0B,EAAE,kCAAkC,CAAC;KACtE,MAAM,CAAC,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE/C,MAAM,CAAC,MAAM,EAAE,CAAC;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,iDAAiD,CAAC;KAC9D,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAEhC,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,YAAY,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2BAA2B,CAAC;KACxC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,kBAAkB,EAAE,+BAA+B,CAAC;KAC3D,MAAM,CAAC,wBAAwB,EAAE,kCAAkC,CAAC;KACpE,MAAM,CAAC,0BAA0B,EAAE,kCAAkC,CAAC;KACtE,MAAM,CAAC,YAAY,EAAE,qDAAqD,CAAC;KAC3E,MAAM,CACL,KAAK,EAAE,OAKN,EAAE,EAAE;IACH,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC,CACF,CAAC;AAEJ,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -6,5 +6,10 @@ export declare class GitUtils {
|
|
|
6
6
|
static getRepoRoot(cwd: string): Promise<string>;
|
|
7
7
|
static verifyRepoMatches(expectedOwner: string, expectedName: string, cwd: string): Promise<RepoVerification>;
|
|
8
8
|
static ensureBranchCheckedOut(branch: string, rootPath: string): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Ensure a branch exists in a git worktree at a sibling directory.
|
|
11
|
+
* Returns the path to the worktree.
|
|
12
|
+
*/
|
|
13
|
+
static ensureBranchInWorktree(branch: string, rootPath: string): Promise<string>;
|
|
9
14
|
}
|
|
10
15
|
//# sourceMappingURL=git-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../../src/utils/git-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../../src/utils/git-utils.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAuBD,qBAAa,QAAQ;WACN,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAIzC,iBAAiB,CAC5B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,gBAAgB,CAAC;WAuBf,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkDpF;;;OAGG;WACU,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA2DvF"}
|
package/dist/utils/git-utils.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { promisify } from 'util';
|
|
2
2
|
import { exec as execCb } from 'child_process';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as fs from 'fs/promises';
|
|
3
5
|
const exec = promisify(execCb);
|
|
4
6
|
function parseGithubRemote(remoteUrl) {
|
|
5
7
|
const patterns = [/github\.com[:/](?<owner>[^/]+)\/(?<repo>[^/.]+)(?:\.git)?$/];
|
|
@@ -82,5 +84,62 @@ export class GitUtils {
|
|
|
82
84
|
await runGit(`checkout -b ${branch}`, rootPath);
|
|
83
85
|
}
|
|
84
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Ensure a branch exists in a git worktree at a sibling directory.
|
|
89
|
+
* Returns the path to the worktree.
|
|
90
|
+
*/
|
|
91
|
+
static async ensureBranchInWorktree(branch, rootPath) {
|
|
92
|
+
// Sanitize branch name for directory: replace slashes with dashes
|
|
93
|
+
const sanitizedBranchName = branch.replace(/\//g, '-');
|
|
94
|
+
// Calculate worktree path as sibling directory
|
|
95
|
+
const parentDir = path.dirname(rootPath);
|
|
96
|
+
const worktreePath = path.join(parentDir, sanitizedBranchName);
|
|
97
|
+
// Check if worktree already exists
|
|
98
|
+
try {
|
|
99
|
+
await fs.access(worktreePath);
|
|
100
|
+
// Worktree directory exists, verify it's a valid git worktree
|
|
101
|
+
try {
|
|
102
|
+
await runGit('rev-parse --git-dir', worktreePath);
|
|
103
|
+
// It's a valid git directory, return the path
|
|
104
|
+
return worktreePath;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Directory exists but is not a git worktree
|
|
108
|
+
throw new Error(`Directory ${worktreePath} already exists but is not a git worktree. ` +
|
|
109
|
+
`Please remove it or choose a different branch name.`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Worktree doesn't exist, we'll create it
|
|
114
|
+
}
|
|
115
|
+
// Check if local branch exists
|
|
116
|
+
const localBranchExists = await exec(`git rev-parse --verify ${branch}`, { cwd: rootPath })
|
|
117
|
+
.then(() => true)
|
|
118
|
+
.catch(() => false);
|
|
119
|
+
// Try to fetch from remote
|
|
120
|
+
let remoteBranchExists = false;
|
|
121
|
+
try {
|
|
122
|
+
await runGit(`fetch origin ${branch}`, rootPath);
|
|
123
|
+
await runGit(`rev-parse --verify origin/${branch}`, rootPath);
|
|
124
|
+
remoteBranchExists = true;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
remoteBranchExists = false;
|
|
128
|
+
}
|
|
129
|
+
// Create worktree based on what exists
|
|
130
|
+
if (localBranchExists) {
|
|
131
|
+
// Local branch exists, create worktree from it
|
|
132
|
+
await runGit(`worktree add "${worktreePath}" ${branch}`, rootPath);
|
|
133
|
+
}
|
|
134
|
+
else if (remoteBranchExists) {
|
|
135
|
+
// Remote branch exists, create worktree tracking it
|
|
136
|
+
await runGit(`worktree add --track -b ${branch} "${worktreePath}" origin/${branch}`, rootPath);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
// Neither exists, create new branch in worktree from current HEAD
|
|
140
|
+
await runGit(`worktree add -b ${branch} "${worktreePath}"`, rootPath);
|
|
141
|
+
}
|
|
142
|
+
return worktreePath;
|
|
143
|
+
}
|
|
85
144
|
}
|
|
86
145
|
//# sourceMappingURL=git-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-utils.js","sourceRoot":"","sources":["../../src/utils/git-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,IAAI,IAAI,MAAM,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"git-utils.js","sourceRoot":"","sources":["../../src/utils/git-utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/commands/local.ts
CHANGED
|
@@ -13,9 +13,15 @@ interface LocalOptions {
|
|
|
13
13
|
prUrl?: string;
|
|
14
14
|
issueUrl?: string;
|
|
15
15
|
threadUrl?: string;
|
|
16
|
+
worktree?: boolean;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
export async function localCommand({
|
|
19
|
+
export async function localCommand({
|
|
20
|
+
prUrl,
|
|
21
|
+
issueUrl,
|
|
22
|
+
threadUrl,
|
|
23
|
+
worktree,
|
|
24
|
+
}: LocalOptions): Promise<void> {
|
|
19
25
|
const configManager = new ConfigManager();
|
|
20
26
|
const apiClient = new EdgediveApiClient(configManager);
|
|
21
27
|
const downloader = new SessionDownloader();
|
|
@@ -124,30 +130,44 @@ export async function localCommand({ prUrl, issueUrl, threadUrl }: LocalOptions)
|
|
|
124
130
|
|
|
125
131
|
console.log(chalk.green(`✅ Using repository at ${repoInfo.rootPath}`));
|
|
126
132
|
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
sessionData,
|
|
130
|
-
repoInfo.rootPath
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
// Ensure PR branch is checked out locally
|
|
133
|
+
// Ensure PR branch is checked out locally or in a worktree
|
|
134
|
+
let workingPath = repoInfo.rootPath;
|
|
134
135
|
try {
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
if (worktree) {
|
|
137
|
+
workingPath = await GitUtils.ensureBranchInWorktree(
|
|
138
|
+
sessionData.repository.branch,
|
|
139
|
+
repoInfo.rootPath
|
|
140
|
+
);
|
|
141
|
+
console.log(
|
|
142
|
+
chalk.green(
|
|
143
|
+
`✅ Created worktree for branch ${sessionData.repository.branch} at ${workingPath}`
|
|
144
|
+
)
|
|
145
|
+
);
|
|
146
|
+
} else {
|
|
147
|
+
await GitUtils.ensureBranchCheckedOut(sessionData.repository.branch, repoInfo.rootPath);
|
|
148
|
+
console.log(chalk.green(`✅ Checked out branch ${sessionData.repository.branch}`));
|
|
149
|
+
}
|
|
137
150
|
} catch (error: any) {
|
|
138
151
|
console.error(
|
|
139
152
|
chalk.red(
|
|
140
|
-
`\n❌ Failed to checkout branch ${sessionData.repository.branch}: ${error.message}\n`
|
|
153
|
+
`\n❌ Failed to ${worktree ? 'create worktree for' : 'checkout'} branch ${sessionData.repository.branch}: ${error.message}\n`
|
|
141
154
|
)
|
|
142
155
|
);
|
|
143
156
|
console.log(chalk.yellow('Resolve the git issue above and rerun the local command.'));
|
|
144
157
|
process.exit(1);
|
|
145
158
|
}
|
|
146
159
|
|
|
160
|
+
// Download session files into Claude projects directory
|
|
161
|
+
// Use workingPath so the session goes to the correct directory (worktree path if --worktree is used)
|
|
162
|
+
const { claudeSessionId, claudeSessionPath } = await downloader.downloadSession(
|
|
163
|
+
sessionData,
|
|
164
|
+
workingPath
|
|
165
|
+
);
|
|
166
|
+
|
|
147
167
|
console.log(chalk.blue(`\n🚀 Launching Claude session ${claudeSessionId}...\n`));
|
|
148
168
|
|
|
149
169
|
try {
|
|
150
|
-
const sessionEndInfo = await launchClaudeSession(claudeSessionId,
|
|
170
|
+
const sessionEndInfo = await launchClaudeSession(claudeSessionId, workingPath);
|
|
151
171
|
console.log(chalk.green('\n✅ Claude session closed. Happy debugging!\n'));
|
|
152
172
|
|
|
153
173
|
// Upload Claude session file back to server
|
|
@@ -161,7 +181,7 @@ export async function localCommand({ prUrl, issueUrl, threadUrl }: LocalOptions)
|
|
|
161
181
|
console.error(chalk.red(`\n❌ Failed to start Claude automatically: ${error.message}\n`));
|
|
162
182
|
console.log(
|
|
163
183
|
chalk.yellow(
|
|
164
|
-
`You can resume manually with: claude -r ${claudeSessionId} (from ${
|
|
184
|
+
`You can resume manually with: claude -r ${claudeSessionId} (from ${workingPath})`
|
|
165
185
|
)
|
|
166
186
|
);
|
|
167
187
|
process.exit(1);
|
package/src/index.ts
CHANGED
|
@@ -43,8 +43,16 @@ program
|
|
|
43
43
|
.option('--pr-url <prUrl>', 'GitHub PR URL to load locally')
|
|
44
44
|
.option('--issue-url <issueUrl>', 'Linear issue URL to load locally')
|
|
45
45
|
.option('--thread-url <threadUrl>', 'Slack thread URL to load locally')
|
|
46
|
-
.
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
.option('--worktree', 'Create branch in a worktree instead of checking out')
|
|
47
|
+
.action(
|
|
48
|
+
async (options: {
|
|
49
|
+
prUrl?: string;
|
|
50
|
+
issueUrl?: string;
|
|
51
|
+
threadUrl?: string;
|
|
52
|
+
worktree?: boolean;
|
|
53
|
+
}) => {
|
|
54
|
+
await localCommand(options);
|
|
55
|
+
}
|
|
56
|
+
);
|
|
49
57
|
|
|
50
58
|
program.parse();
|
package/src/utils/git-utils.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { promisify } from 'util';
|
|
2
2
|
import { exec as execCb } from 'child_process';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as fs from 'fs/promises';
|
|
3
5
|
|
|
4
6
|
const exec = promisify(execCb);
|
|
5
7
|
|
|
@@ -110,4 +112,68 @@ export class GitUtils {
|
|
|
110
112
|
await runGit(`checkout -b ${branch}`, rootPath);
|
|
111
113
|
}
|
|
112
114
|
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Ensure a branch exists in a git worktree at a sibling directory.
|
|
118
|
+
* Returns the path to the worktree.
|
|
119
|
+
*/
|
|
120
|
+
static async ensureBranchInWorktree(branch: string, rootPath: string): Promise<string> {
|
|
121
|
+
// Sanitize branch name for directory: replace slashes with dashes
|
|
122
|
+
const sanitizedBranchName = branch.replace(/\//g, '-');
|
|
123
|
+
|
|
124
|
+
// Calculate worktree path as sibling directory
|
|
125
|
+
const parentDir = path.dirname(rootPath);
|
|
126
|
+
const worktreePath = path.join(parentDir, sanitizedBranchName);
|
|
127
|
+
|
|
128
|
+
// Check if worktree already exists
|
|
129
|
+
try {
|
|
130
|
+
await fs.access(worktreePath);
|
|
131
|
+
// Worktree directory exists, verify it's a valid git worktree
|
|
132
|
+
try {
|
|
133
|
+
await runGit('rev-parse --git-dir', worktreePath);
|
|
134
|
+
// It's a valid git directory, return the path
|
|
135
|
+
return worktreePath;
|
|
136
|
+
} catch {
|
|
137
|
+
// Directory exists but is not a git worktree
|
|
138
|
+
throw new Error(
|
|
139
|
+
`Directory ${worktreePath} already exists but is not a git worktree. ` +
|
|
140
|
+
`Please remove it or choose a different branch name.`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
} catch {
|
|
144
|
+
// Worktree doesn't exist, we'll create it
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Check if local branch exists
|
|
148
|
+
const localBranchExists = await exec(`git rev-parse --verify ${branch}`, { cwd: rootPath })
|
|
149
|
+
.then(() => true)
|
|
150
|
+
.catch(() => false);
|
|
151
|
+
|
|
152
|
+
// Try to fetch from remote
|
|
153
|
+
let remoteBranchExists = false;
|
|
154
|
+
try {
|
|
155
|
+
await runGit(`fetch origin ${branch}`, rootPath);
|
|
156
|
+
await runGit(`rev-parse --verify origin/${branch}`, rootPath);
|
|
157
|
+
remoteBranchExists = true;
|
|
158
|
+
} catch {
|
|
159
|
+
remoteBranchExists = false;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Create worktree based on what exists
|
|
163
|
+
if (localBranchExists) {
|
|
164
|
+
// Local branch exists, create worktree from it
|
|
165
|
+
await runGit(`worktree add "${worktreePath}" ${branch}`, rootPath);
|
|
166
|
+
} else if (remoteBranchExists) {
|
|
167
|
+
// Remote branch exists, create worktree tracking it
|
|
168
|
+
await runGit(
|
|
169
|
+
`worktree add --track -b ${branch} "${worktreePath}" origin/${branch}`,
|
|
170
|
+
rootPath
|
|
171
|
+
);
|
|
172
|
+
} else {
|
|
173
|
+
// Neither exists, create new branch in worktree from current HEAD
|
|
174
|
+
await runGit(`worktree add -b ${branch} "${worktreePath}"`, rootPath);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return worktreePath;
|
|
178
|
+
}
|
|
113
179
|
}
|