@camaradesuk/git-worktree-tools 1.12.0 → 1.14.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/README.md +14 -14
- package/dist/api/create.d.ts.map +1 -1
- package/dist/api/create.js +30 -4
- package/dist/api/create.js.map +1 -1
- package/dist/cli/lswt.js +4 -0
- package/dist/cli/lswt.js.map +1 -1
- package/dist/cli/newpr.d.ts.map +1 -1
- package/dist/cli/newpr.js +53 -31
- package/dist/cli/newpr.js.map +1 -1
- package/dist/cli/prs.d.ts.map +1 -1
- package/dist/cli/prs.js +34 -2
- package/dist/cli/prs.js.map +1 -1
- package/dist/cli/wt/config.d.ts.map +1 -1
- package/dist/cli/wt/config.js +62 -58
- package/dist/cli/wt/config.js.map +1 -1
- package/dist/cli/wt/list.d.ts.map +1 -1
- package/dist/cli/wt/list.js +5 -0
- package/dist/cli/wt/list.js.map +1 -1
- package/dist/cli/wt/prs.d.ts.map +1 -1
- package/dist/cli/wt/prs.js +2 -0
- package/dist/cli/wt/prs.js.map +1 -1
- package/dist/cli/wtconfig.js +135 -107
- package/dist/cli/wtconfig.js.map +1 -1
- package/dist/cli/wtstate.js +27 -7
- package/dist/cli/wtstate.js.map +1 -1
- package/dist/lib/ai/gemini-api-provider.d.ts +31 -0
- package/dist/lib/ai/gemini-api-provider.d.ts.map +1 -0
- package/dist/lib/ai/gemini-api-provider.js +100 -0
- package/dist/lib/ai/gemini-api-provider.js.map +1 -0
- package/dist/lib/ai/index.d.ts +1 -0
- package/dist/lib/ai/index.d.ts.map +1 -1
- package/dist/lib/ai/index.js +1 -0
- package/dist/lib/ai/index.js.map +1 -1
- package/dist/lib/ai/provider-manager.d.ts +1 -0
- package/dist/lib/ai/provider-manager.d.ts.map +1 -1
- package/dist/lib/ai/provider-manager.js +12 -0
- package/dist/lib/ai/provider-manager.js.map +1 -1
- package/dist/lib/ai/types.d.ts +2 -2
- package/dist/lib/ai/types.d.ts.map +1 -1
- package/dist/lib/ai/types.js.map +1 -1
- package/dist/lib/cleanpr/index.d.ts +2 -1
- package/dist/lib/cleanpr/index.d.ts.map +1 -1
- package/dist/lib/cleanpr/index.js +3 -1
- package/dist/lib/cleanpr/index.js.map +1 -1
- package/dist/lib/cleanpr/worktree-info.d.ts +0 -4
- package/dist/lib/cleanpr/worktree-info.d.ts.map +1 -1
- package/dist/lib/cleanpr/worktree-info.js +2 -28
- package/dist/lib/cleanpr/worktree-info.js.map +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +21 -2
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/lswt/formatters.d.ts +0 -4
- package/dist/lib/lswt/formatters.d.ts.map +1 -1
- package/dist/lib/lswt/formatters.js +0 -14
- package/dist/lib/lswt/formatters.js.map +1 -1
- package/dist/lib/lswt/index.d.ts +2 -1
- package/dist/lib/lswt/index.d.ts.map +1 -1
- package/dist/lib/lswt/index.js +3 -1
- package/dist/lib/lswt/index.js.map +1 -1
- package/dist/lib/lswt/types.d.ts +2 -0
- package/dist/lib/lswt/types.d.ts.map +1 -1
- package/dist/lib/lswt/worktree-info.d.ts.map +1 -1
- package/dist/lib/lswt/worktree-info.js +3 -2
- package/dist/lib/lswt/worktree-info.js.map +1 -1
- package/dist/lib/prs/command.d.ts.map +1 -1
- package/dist/lib/prs/command.js +22 -16
- package/dist/lib/prs/command.js.map +1 -1
- package/dist/lib/worktree-setup.d.ts +32 -0
- package/dist/lib/worktree-setup.d.ts.map +1 -0
- package/dist/lib/worktree-setup.js +114 -0
- package/dist/lib/worktree-setup.js.map +1 -0
- package/dist/lib/worktree-utils.d.ts +32 -0
- package/dist/lib/worktree-utils.d.ts.map +1 -0
- package/dist/lib/worktree-utils.js +101 -0
- package/dist/lib/worktree-utils.js.map +1 -0
- package/package.json +1 -1
- package/schemas/worktreerc.schema.json +2 -2
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worktree parent directory auto-setup
|
|
3
|
+
*
|
|
4
|
+
* When worktreeParent resolves to a path inside the repo, automatically:
|
|
5
|
+
* 1. Create the directory (with confirmation in interactive mode)
|
|
6
|
+
* 2. Add it to .gitignore
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { logger } from './logger.js';
|
|
11
|
+
import { promptConfirm } from './prompts.js';
|
|
12
|
+
/**
|
|
13
|
+
* Check if a path is inside the repo root
|
|
14
|
+
*/
|
|
15
|
+
function isInsideRepo(dirPath, repoRoot) {
|
|
16
|
+
let resolved = path.resolve(dirPath);
|
|
17
|
+
let resolvedRoot = path.resolve(repoRoot);
|
|
18
|
+
if (process.platform === 'win32') {
|
|
19
|
+
resolved = resolved.toLowerCase();
|
|
20
|
+
resolvedRoot = resolvedRoot.toLowerCase();
|
|
21
|
+
}
|
|
22
|
+
return resolved.startsWith(resolvedRoot + path.sep) || resolved === resolvedRoot;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get the relative path from repo root for gitignore entry.
|
|
26
|
+
* Always uses forward slashes regardless of platform (.gitignore standard).
|
|
27
|
+
*/
|
|
28
|
+
function getGitignoreEntry(dirPath, repoRoot) {
|
|
29
|
+
return path.relative(repoRoot, dirPath).replace(/\\/g, '/');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Check if a gitignore entry already exists
|
|
33
|
+
*/
|
|
34
|
+
function gitignoreContains(gitignorePath, entry) {
|
|
35
|
+
if (!fs.existsSync(gitignorePath)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const content = fs.readFileSync(gitignorePath, 'utf8');
|
|
39
|
+
const regex = new RegExp(`^\\/?${entry.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*$`, 'm');
|
|
40
|
+
return regex.test(content);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Add an entry to .gitignore
|
|
44
|
+
*/
|
|
45
|
+
function addToGitignore(gitignorePath, entry) {
|
|
46
|
+
let content = '';
|
|
47
|
+
if (fs.existsSync(gitignorePath)) {
|
|
48
|
+
content = fs.readFileSync(gitignorePath, 'utf8');
|
|
49
|
+
}
|
|
50
|
+
const addition = `# git-worktree-tools worktree directory\n${entry}\n`;
|
|
51
|
+
const trimmed = content.trimEnd();
|
|
52
|
+
content = trimmed ? trimmed + '\n\n' + addition : addition;
|
|
53
|
+
fs.writeFileSync(gitignorePath, content, 'utf8');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Ensure the worktree parent directory exists and is gitignored (if inside repo).
|
|
57
|
+
*
|
|
58
|
+
* Only acts when the resolved parent dir is inside the repo root.
|
|
59
|
+
* In interactive mode, prompts for confirmation before making changes.
|
|
60
|
+
* In non-interactive mode, proceeds automatically.
|
|
61
|
+
*/
|
|
62
|
+
export async function ensureWorktreeParentDir(options) {
|
|
63
|
+
const { resolvedParentDir, repoRoot, interactive } = options;
|
|
64
|
+
const result = {
|
|
65
|
+
created: false,
|
|
66
|
+
gitignoreUpdated: false,
|
|
67
|
+
declined: false,
|
|
68
|
+
};
|
|
69
|
+
// Only act for in-repo directories
|
|
70
|
+
if (!isInsideRepo(resolvedParentDir, repoRoot)) {
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
const dirExists = fs.existsSync(resolvedParentDir);
|
|
74
|
+
const gitignorePath = path.join(repoRoot, '.gitignore');
|
|
75
|
+
const gitignoreEntry = getGitignoreEntry(resolvedParentDir, repoRoot);
|
|
76
|
+
// If parent dir IS the repo root, relative path is empty — nothing to gitignore
|
|
77
|
+
if (!gitignoreEntry) {
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
const alreadyIgnored = gitignoreContains(gitignorePath, gitignoreEntry);
|
|
81
|
+
// Nothing to do
|
|
82
|
+
if (dirExists && alreadyIgnored) {
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
// Prompt in interactive mode
|
|
86
|
+
if (interactive && (!dirExists || !alreadyIgnored)) {
|
|
87
|
+
const actions = [];
|
|
88
|
+
if (!dirExists) {
|
|
89
|
+
actions.push(`create \`${gitignoreEntry}/\``);
|
|
90
|
+
}
|
|
91
|
+
if (!alreadyIgnored) {
|
|
92
|
+
actions.push(`add \`${gitignoreEntry}\` to .gitignore`);
|
|
93
|
+
}
|
|
94
|
+
const confirmed = await promptConfirm(`Will ${actions.join(' and ')}. Continue?`, true);
|
|
95
|
+
if (!confirmed) {
|
|
96
|
+
result.declined = true;
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Create directory
|
|
101
|
+
if (!dirExists) {
|
|
102
|
+
fs.mkdirSync(resolvedParentDir, { recursive: true });
|
|
103
|
+
result.created = true;
|
|
104
|
+
logger.info(`Created worktree directory: ${gitignoreEntry}/`);
|
|
105
|
+
}
|
|
106
|
+
// Update .gitignore
|
|
107
|
+
if (!alreadyIgnored) {
|
|
108
|
+
addToGitignore(gitignorePath, gitignoreEntry);
|
|
109
|
+
result.gitignoreUpdated = true;
|
|
110
|
+
logger.info(`Added ${gitignoreEntry} to .gitignore`);
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=worktree-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree-setup.js","sourceRoot":"","sources":["../../src/lib/worktree-setup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAoB7C;;GAEG;AACH,SAAS,YAAY,CAAC,OAAe,EAAE,QAAgB;IACrD,IAAI,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QAClC,YAAY,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;IAC5C,CAAC;IACD,OAAO,QAAQ,CAAC,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,YAAY,CAAC;AACnF,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,OAAe,EAAE,QAAgB;IAC1D,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,aAAqB,EAAE,KAAa;IAC7D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC3F,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,aAAqB,EAAE,KAAa;IAC1D,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACjC,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,QAAQ,GAAG,4CAA4C,KAAK,IAAI,CAAC;IACvE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAClC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC3D,EAAE,CAAC,aAAa,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAoC;IAEpC,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAE7D,MAAM,MAAM,GAA+B;QACzC,OAAO,EAAE,KAAK;QACd,gBAAgB,EAAE,KAAK;QACvB,QAAQ,EAAE,KAAK;KAChB,CAAC;IAEF,mCAAmC;IACnC,IAAI,CAAC,YAAY,CAAC,iBAAiB,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC/C,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;IACnD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACxD,MAAM,cAAc,GAAG,iBAAiB,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IAEtE,gFAAgF;IAChF,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,cAAc,GAAG,iBAAiB,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IAExE,gBAAgB;IAChB,IAAI,SAAS,IAAI,cAAc,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,6BAA6B;IAC7B,IAAI,WAAW,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QACnD,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,YAAY,cAAc,KAAK,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC,SAAS,cAAc,kBAAkB,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,QAAQ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QAExF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;YACvB,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,EAAE,CAAC,SAAS,CAAC,iBAAiB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,+BAA+B,cAAc,GAAG,CAAC,CAAC;IAChE,CAAC;IAED,oBAAoB;IACpB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;QAC9C,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,SAAS,cAAc,gBAAgB,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared worktree utilities used by lswt, cleanpr, and other tools
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Options for PR number extraction
|
|
6
|
+
*/
|
|
7
|
+
export interface ExtractPrNumberOptions {
|
|
8
|
+
/** Configured worktree naming pattern */
|
|
9
|
+
worktreePattern?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Extract PR number from a worktree path using config-aware pattern matching.
|
|
13
|
+
*
|
|
14
|
+
* Resolution chain:
|
|
15
|
+
* 1. Configured pattern (if provided)
|
|
16
|
+
* 2. Default pattern ({repo}.pr{number})
|
|
17
|
+
*
|
|
18
|
+
* For async extraction with gh CLI fallback, use extractPrNumberAsync.
|
|
19
|
+
*/
|
|
20
|
+
export declare function extractPrNumber(worktreePath: string, options?: ExtractPrNumberOptions): number | null;
|
|
21
|
+
/**
|
|
22
|
+
* Extract PR number with gh CLI fallback.
|
|
23
|
+
*
|
|
24
|
+
* Resolution chain:
|
|
25
|
+
* 1. Configured pattern
|
|
26
|
+
* 2. Default pattern
|
|
27
|
+
* 3. gh CLI: look up branch from git worktree list, query gh pr list --head <branch>
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractPrNumberAsync(worktreePath: string, options?: ExtractPrNumberOptions & {
|
|
30
|
+
cwd?: string;
|
|
31
|
+
}): Promise<number | null>;
|
|
32
|
+
//# sourceMappingURL=worktree-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree-utils.d.ts","sourceRoot":"","sources":["../../src/lib/worktree-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,yCAAyC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA8BD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,sBAA2B,GACnC,MAAM,GAAG,IAAI,CA8Bf;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,sBAAsB,GAAG;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GACtD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA4BxB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared worktree utilities used by lswt, cleanpr, and other tools
|
|
3
|
+
*/
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import { DEFAULT_WORKTREE_PATTERN } from './constants.js';
|
|
6
|
+
import * as github from './github.js';
|
|
7
|
+
import * as git from './git.js';
|
|
8
|
+
import { logger } from './logger.js';
|
|
9
|
+
/**
|
|
10
|
+
* Convert a worktree naming pattern to a regex for PR number extraction.
|
|
11
|
+
* Replaces {number} with a capture group and other placeholders with .*
|
|
12
|
+
*/
|
|
13
|
+
function patternToRegex(pattern) {
|
|
14
|
+
if (!pattern.includes('{number}')) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
// Escape regex special characters first, then replace placeholders
|
|
18
|
+
let regexStr = pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
19
|
+
// Now replace escaped placeholder sequences
|
|
20
|
+
regexStr = regexStr.replace('\\{repo\\}', '.*?');
|
|
21
|
+
regexStr = regexStr.replace('\\{number\\}', '(\\d+)');
|
|
22
|
+
regexStr = regexStr.replace('\\{branch\\}', '.*?');
|
|
23
|
+
regexStr = regexStr.replace('\\{slug\\}', '.*?');
|
|
24
|
+
// Anchor to full string
|
|
25
|
+
regexStr = `^${regexStr}$`;
|
|
26
|
+
try {
|
|
27
|
+
return new RegExp(regexStr);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Extract PR number from a worktree path using config-aware pattern matching.
|
|
35
|
+
*
|
|
36
|
+
* Resolution chain:
|
|
37
|
+
* 1. Configured pattern (if provided)
|
|
38
|
+
* 2. Default pattern ({repo}.pr{number})
|
|
39
|
+
*
|
|
40
|
+
* For async extraction with gh CLI fallback, use extractPrNumberAsync.
|
|
41
|
+
*/
|
|
42
|
+
export function extractPrNumber(worktreePath, options = {}) {
|
|
43
|
+
if (!worktreePath) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const name = path.basename(worktreePath);
|
|
47
|
+
// 1. Try configured pattern
|
|
48
|
+
if (options.worktreePattern) {
|
|
49
|
+
const regex = patternToRegex(options.worktreePattern);
|
|
50
|
+
if (regex) {
|
|
51
|
+
const match = name.match(regex);
|
|
52
|
+
if (match) {
|
|
53
|
+
return parseInt(match[1], 10);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// 2. Try default pattern (skip if same as configured)
|
|
58
|
+
if (options.worktreePattern !== DEFAULT_WORKTREE_PATTERN) {
|
|
59
|
+
const defaultRegex = patternToRegex(DEFAULT_WORKTREE_PATTERN);
|
|
60
|
+
if (defaultRegex) {
|
|
61
|
+
const match = name.match(defaultRegex);
|
|
62
|
+
if (match) {
|
|
63
|
+
return parseInt(match[1], 10);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Extract PR number with gh CLI fallback.
|
|
71
|
+
*
|
|
72
|
+
* Resolution chain:
|
|
73
|
+
* 1. Configured pattern
|
|
74
|
+
* 2. Default pattern
|
|
75
|
+
* 3. gh CLI: look up branch from git worktree list, query gh pr list --head <branch>
|
|
76
|
+
*/
|
|
77
|
+
export async function extractPrNumberAsync(worktreePath, options = {}) {
|
|
78
|
+
// Try synchronous extraction first
|
|
79
|
+
const syncResult = extractPrNumber(worktreePath, options);
|
|
80
|
+
if (syncResult !== null) {
|
|
81
|
+
return syncResult;
|
|
82
|
+
}
|
|
83
|
+
// 3. gh CLI fallback: find branch for this worktree, then query GitHub
|
|
84
|
+
try {
|
|
85
|
+
const worktrees = git.listWorktrees(options.cwd);
|
|
86
|
+
const resolvedPath = path.resolve(worktreePath);
|
|
87
|
+
const wt = worktrees.find((w) => path.resolve(w.path) === resolvedPath);
|
|
88
|
+
if (wt?.branch) {
|
|
89
|
+
logger.debug(`Falling back to gh CLI for PR extraction: branch=${wt.branch}`);
|
|
90
|
+
const prInfo = github.getPrByBranch(wt.branch, options.cwd);
|
|
91
|
+
if (prInfo) {
|
|
92
|
+
return prInfo.number;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
logger.debug('gh CLI fallback for PR extraction failed: %s', error instanceof Error ? error.message : String(error));
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=worktree-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree-utils.js","sourceRoot":"","sources":["../../src/lib/worktree-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAUrC;;;GAGG;AACH,SAAS,cAAc,CAAC,OAAe;IACrC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mEAAmE;IACnE,IAAI,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAE9D,4CAA4C;IAC5C,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACjD,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACtD,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACnD,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAEjD,wBAAwB;IACxB,QAAQ,GAAG,IAAI,QAAQ,GAAG,CAAC;IAE3B,IAAI,CAAC;QACH,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAC7B,YAAoB,EACpB,UAAkC,EAAE;IAEpC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEzC,4BAA4B;IAC5B,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACtD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IAED,sDAAsD;IACtD,IAAI,OAAO,CAAC,eAAe,KAAK,wBAAwB,EAAE,CAAC;QACzD,MAAM,YAAY,GAAG,cAAc,CAAC,wBAAwB,CAAC,CAAC;QAC9D,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACvC,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,YAAoB,EACpB,UAAqD,EAAE;IAEvD,mCAAmC;IACnC,MAAM,UAAU,GAAG,eAAe,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC1D,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,uEAAuE;IACvE,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,YAAY,CAAC,CAAC;QAExE,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,oDAAoD,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;YAC5D,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,MAAM,CAAC,MAAM,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CACV,8CAA8C,EAC9C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camaradesuk/git-worktree-tools",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "Git worktree workflow tools: create PRs, manage worktrees, sync configs. Cross-platform CLI for Windows, macOS, and Linux.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
"worktreePattern": {
|
|
34
34
|
"type": "string",
|
|
35
35
|
"default": "{repo}.pr{number}",
|
|
36
|
-
"description": "Worktree directory naming pattern. Placeholders: {repo}, {number}, {branch}, {slug}
|
|
36
|
+
"description": "Worktree directory naming pattern. Placeholders: {repo}, {number}, {branch}, {slug}. {slug} is the branch name after the first '/', made filesystem-safe. Doubled or trailing separators (., -, _) are cleaned automatically."
|
|
37
37
|
},
|
|
38
38
|
"worktreeParent": {
|
|
39
39
|
"type": "string",
|
|
40
40
|
"default": "..",
|
|
41
|
-
"description": "Parent directory for worktrees (absolute or relative to repo root)"
|
|
41
|
+
"description": "Parent directory for worktrees (absolute or relative to repo root). When the resolved path is inside the repository, the directory will be auto-created and added to .gitignore."
|
|
42
42
|
},
|
|
43
43
|
"syncPatterns": {
|
|
44
44
|
"type": "array",
|