@mcadam/worktree 1.0.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/LICENSE +21 -0
- package/README.md +315 -0
- package/bin/worktree.js +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +63 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +110 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/create.d.ts +2 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +75 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +90 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +82 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/components/WorktreeList.d.ts +10 -0
- package/dist/components/WorktreeList.d.ts.map +1 -0
- package/dist/components/WorktreeList.js +41 -0
- package/dist/components/WorktreeList.js.map +1 -0
- package/dist/config/detector.d.ts +4 -0
- package/dist/config/detector.d.ts.map +1 -0
- package/dist/config/detector.js +34 -0
- package/dist/config/detector.js.map +1 -0
- package/dist/config/manager.d.ts +19 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +73 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/schema.d.ts +77 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +19 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/utils/gh.d.ts +13 -0
- package/dist/utils/gh.d.ts.map +1 -0
- package/dist/utils/gh.js +41 -0
- package/dist/utils/gh.js.map +1 -0
- package/dist/utils/git.d.ts +14 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +91 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/sanitize.d.ts +3 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +13 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { render, Box, Text } from 'ink';
|
|
4
|
+
import TextInput from 'ink-text-input';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { configManager } from '../config/manager.js';
|
|
7
|
+
import { getRepoName } from '../config/detector.js';
|
|
8
|
+
function InitForm({ gitRoot, defaultName, onComplete }) {
|
|
9
|
+
const [step, setStep] = useState(0);
|
|
10
|
+
const [name, setName] = useState(defaultName);
|
|
11
|
+
const [prefix, setPrefix] = useState('');
|
|
12
|
+
const [basePath, setBasePath] = useState('../');
|
|
13
|
+
const [envPath, setEnvPath] = useState('');
|
|
14
|
+
const [installCommand, setInstallCommand] = useState('');
|
|
15
|
+
const [ideCommand, setIdeCommand] = useState('');
|
|
16
|
+
const handleSubmit = (value) => {
|
|
17
|
+
switch (step) {
|
|
18
|
+
case 0: // Name
|
|
19
|
+
setName(value || defaultName);
|
|
20
|
+
setStep(1);
|
|
21
|
+
break;
|
|
22
|
+
case 1: // Prefix
|
|
23
|
+
setPrefix(value);
|
|
24
|
+
setStep(2);
|
|
25
|
+
break;
|
|
26
|
+
case 2: // Base path
|
|
27
|
+
setBasePath(value || '../');
|
|
28
|
+
setStep(3);
|
|
29
|
+
break;
|
|
30
|
+
case 3: // Env path
|
|
31
|
+
setEnvPath(value);
|
|
32
|
+
setStep(4);
|
|
33
|
+
break;
|
|
34
|
+
case 4: // Install command
|
|
35
|
+
setInstallCommand(value);
|
|
36
|
+
setStep(5);
|
|
37
|
+
break;
|
|
38
|
+
case 5: // IDE command
|
|
39
|
+
setIdeCommand(value);
|
|
40
|
+
const config = {
|
|
41
|
+
name,
|
|
42
|
+
prefix,
|
|
43
|
+
basePath: basePath || undefined,
|
|
44
|
+
envPath: envPath || undefined,
|
|
45
|
+
installCommand: installCommand || undefined,
|
|
46
|
+
ideCommand: ideCommand || undefined,
|
|
47
|
+
};
|
|
48
|
+
onComplete(config);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const fields = [
|
|
53
|
+
{ label: 'Repository name', value: name, placeholder: defaultName },
|
|
54
|
+
{ label: 'Worktree prefix (e.g., "fe-", "be-")', value: prefix, placeholder: 'prefix-' },
|
|
55
|
+
{ label: 'Base path for worktrees', value: basePath, placeholder: '../' },
|
|
56
|
+
{ label: '.env file to copy (optional)', value: envPath, placeholder: '.env.local' },
|
|
57
|
+
{ label: 'Install command (optional)', value: installCommand, placeholder: 'pnpm install' },
|
|
58
|
+
{ label: 'IDE command (optional)', value: ideCommand, placeholder: 'cursor' },
|
|
59
|
+
];
|
|
60
|
+
const currentField = fields[step];
|
|
61
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, color: "cyan", children: ["Configure repository: ", gitRoot] }), _jsxs(Box, { marginY: 1, children: [_jsxs(Text, { children: [currentField.label, ": "] }), _jsx(TextInput, { value: step === 0 ? name :
|
|
62
|
+
step === 1 ? prefix :
|
|
63
|
+
step === 2 ? basePath :
|
|
64
|
+
step === 3 ? envPath :
|
|
65
|
+
step === 4 ? installCommand :
|
|
66
|
+
ideCommand, onChange: step === 0 ? setName :
|
|
67
|
+
step === 1 ? setPrefix :
|
|
68
|
+
step === 2 ? setBasePath :
|
|
69
|
+
step === 3 ? setEnvPath :
|
|
70
|
+
step === 4 ? setInstallCommand :
|
|
71
|
+
setIdeCommand, onSubmit: handleSubmit, placeholder: currentField.placeholder })] }), _jsx(Text, { dimColor: true, children: "Press Enter to continue, Ctrl+C to cancel" })] }));
|
|
72
|
+
}
|
|
73
|
+
export async function initCommand(gitRoot) {
|
|
74
|
+
const defaultName = await getRepoName(gitRoot);
|
|
75
|
+
return new Promise((resolve) => {
|
|
76
|
+
const { unmount } = render(_jsx(InitForm, { gitRoot: gitRoot, defaultName: defaultName, onComplete: async (config) => {
|
|
77
|
+
unmount();
|
|
78
|
+
await configManager.setRepoConfig(gitRoot, config);
|
|
79
|
+
console.log(chalk.green(`\n✨ Repository configured successfully!`));
|
|
80
|
+
console.log(chalk.gray(`Configuration saved for: ${config.name}`));
|
|
81
|
+
console.log(chalk.cyan(`🚀 You're all set! Run 'worktree <branch>' to create your first worktree!`));
|
|
82
|
+
resolve();
|
|
83
|
+
}, onCancel: () => {
|
|
84
|
+
unmount();
|
|
85
|
+
console.log(chalk.yellow('Configuration cancelled'));
|
|
86
|
+
resolve();
|
|
87
|
+
} }));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.tsx"],"names":[],"mappings":"AA2EA,wBAAsB,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CvE"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { render, Box, Text } from 'ink';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { configManager } from '../config/manager.js';
|
|
6
|
+
import { listWorktrees, removeWorktree } from '../utils/git.js';
|
|
7
|
+
import { enrichWorktreesWithPRInfo } from '../utils/gh.js';
|
|
8
|
+
import { WorktreeList } from '../components/WorktreeList.js';
|
|
9
|
+
function ListApp({ repos }) {
|
|
10
|
+
const [currentRepoIndex] = useState(0);
|
|
11
|
+
const [isDeleting, setIsDeleting] = useState(false);
|
|
12
|
+
const handleDelete = async (paths) => {
|
|
13
|
+
setIsDeleting(true);
|
|
14
|
+
const currentRepo = repos[currentRepoIndex];
|
|
15
|
+
console.log(chalk.yellow(`\n🗑️ Deleting ${paths.length} worktree${paths.length > 1 ? 's' : ''}...`));
|
|
16
|
+
let successCount = 0;
|
|
17
|
+
for (const path of paths) {
|
|
18
|
+
try {
|
|
19
|
+
await removeWorktree(path, currentRepo.repoPath);
|
|
20
|
+
successCount++;
|
|
21
|
+
console.log(chalk.green(` ✓ Removed: ${path.split('/').pop()}`));
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
console.error(chalk.red(` ✗ Failed to remove ${path}: ${error}`));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (successCount > 0) {
|
|
28
|
+
console.log(chalk.cyan(`\n✅ Successfully deleted ${successCount} worktree${successCount > 1 ? 's' : ''}!`));
|
|
29
|
+
console.log(chalk.gray(`💪 Workspace cleaned up and ready to go!`));
|
|
30
|
+
}
|
|
31
|
+
// Refresh the list after deletion
|
|
32
|
+
setTimeout(() => process.exit(0), 1500);
|
|
33
|
+
};
|
|
34
|
+
if (repos.length === 0) {
|
|
35
|
+
return (_jsx(Box, { children: _jsx(Text, { color: "yellow", children: "No configured repositories found" }) }));
|
|
36
|
+
}
|
|
37
|
+
if (isDeleting) {
|
|
38
|
+
return (_jsx(Box, { children: _jsx(Text, { color: "cyan", children: "Deleting worktrees..." }) }));
|
|
39
|
+
}
|
|
40
|
+
return (_jsx(Box, { flexDirection: "column", children: repos.map((repo) => (_jsx(WorktreeList, { worktrees: repo.worktrees, repoName: repo.repoName, repoPath: repo.repoPath, onDelete: handleDelete }, repo.repoPath))) }));
|
|
41
|
+
}
|
|
42
|
+
export async function listCommand(currentGitRoot) {
|
|
43
|
+
const allRepoConfigs = await configManager.getAllRepoConfigs();
|
|
44
|
+
const repos = [];
|
|
45
|
+
// Add current repo first if configured
|
|
46
|
+
const currentRepoConfig = allRepoConfigs[currentGitRoot];
|
|
47
|
+
if (currentRepoConfig) {
|
|
48
|
+
const worktrees = await listWorktrees(currentGitRoot);
|
|
49
|
+
await enrichWorktreesWithPRInfo(worktrees, currentGitRoot);
|
|
50
|
+
repos.push({
|
|
51
|
+
repoPath: currentGitRoot,
|
|
52
|
+
repoName: currentRepoConfig.name,
|
|
53
|
+
worktrees,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
// Add other configured repos
|
|
57
|
+
for (const [repoPath, config] of Object.entries(allRepoConfigs)) {
|
|
58
|
+
if (repoPath === currentGitRoot)
|
|
59
|
+
continue;
|
|
60
|
+
try {
|
|
61
|
+
const worktrees = await listWorktrees(repoPath);
|
|
62
|
+
await enrichWorktreesWithPRInfo(worktrees, repoPath);
|
|
63
|
+
repos.push({
|
|
64
|
+
repoPath,
|
|
65
|
+
repoName: config.name,
|
|
66
|
+
worktrees,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
// Skip repos that might have been deleted or are inaccessible
|
|
71
|
+
console.warn(chalk.yellow(`Warning: Could not access ${config.name} at ${repoPath}`));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (repos.length === 0) {
|
|
75
|
+
console.log(chalk.yellow('\n📦 No configured repositories found'));
|
|
76
|
+
console.log(chalk.cyan('👉 Run "worktree init" to configure the current repository'));
|
|
77
|
+
console.log(chalk.gray(' Then create your first worktree with "worktree <branch>"!'));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
render(_jsx(ListApp, { repos: repos }));
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Worktree } from '../utils/git.js';
|
|
2
|
+
interface WorktreeListProps {
|
|
3
|
+
worktrees: Worktree[];
|
|
4
|
+
repoName: string;
|
|
5
|
+
repoPath: string;
|
|
6
|
+
onDelete: (paths: string[]) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function WorktreeList({ worktrees, repoName, repoPath, onDelete }: WorktreeListProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=WorktreeList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorktreeList.d.ts","sourceRoot":"","sources":["../../src/components/WorktreeList.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE1C,UAAU,iBAAiB;IACzB,SAAS,EAAE,QAAQ,EAAE,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;CACpC;AAED,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,iBAAiB,2CA4E1F"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Box, Text, useInput, useApp } from 'ink';
|
|
4
|
+
export function WorktreeList({ worktrees, repoName, repoPath, onDelete }) {
|
|
5
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
6
|
+
const [checkedItems, setCheckedItems] = useState(new Set());
|
|
7
|
+
const { exit } = useApp();
|
|
8
|
+
const filteredWorktrees = worktrees.filter((w) => !w.isMain);
|
|
9
|
+
useInput((input, key) => {
|
|
10
|
+
if (key.upArrow) {
|
|
11
|
+
setSelectedIndex((prev) => Math.max(0, prev - 1));
|
|
12
|
+
}
|
|
13
|
+
else if (key.downArrow) {
|
|
14
|
+
setSelectedIndex((prev) => Math.min(filteredWorktrees.length - 1, prev + 1));
|
|
15
|
+
}
|
|
16
|
+
else if (input === ' ') {
|
|
17
|
+
const worktree = filteredWorktrees[selectedIndex];
|
|
18
|
+
if (worktree) {
|
|
19
|
+
const newChecked = new Set(checkedItems);
|
|
20
|
+
if (newChecked.has(worktree.path)) {
|
|
21
|
+
newChecked.delete(worktree.path);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
newChecked.add(worktree.path);
|
|
25
|
+
}
|
|
26
|
+
setCheckedItems(newChecked);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (key.return && checkedItems.size > 0) {
|
|
30
|
+
onDelete(Array.from(checkedItems));
|
|
31
|
+
}
|
|
32
|
+
else if (input === 'q') {
|
|
33
|
+
exit();
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
if (filteredWorktrees.length === 0) {
|
|
37
|
+
return (_jsx(Box, { flexDirection: "column", marginY: 1, children: _jsxs(Text, { color: "yellow", children: ["No worktrees found for ", repoName] }) }));
|
|
38
|
+
}
|
|
39
|
+
return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1, children: _jsxs(Text, { bold: true, color: "cyan", children: [repoName, " (", repoPath, ")"] }) }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: filteredWorktrees.map((worktree, index) => (_jsxs(Box, { children: [_jsx(Text, { color: index === selectedIndex ? 'cyan' : 'white', children: index === selectedIndex ? '❯' : ' ' }), _jsx(Text, { children: " " }), _jsx(Text, { children: checkedItems.has(worktree.path) ? '☑' : '☐' }), _jsx(Text, { children: " " }), _jsx(Text, { color: index === selectedIndex ? 'cyan' : 'white', children: worktree.branch || 'detached' }), worktree.isPushed && (_jsx(Text, { color: "green", children: " \u2713 remote" })), worktree.hasPR && (_jsxs(Text, { color: "magenta", children: [" \uD83D\uDD00 PR #", worktree.prNumber] })), !worktree.isPushed && (_jsx(Text, { color: "yellow", children: " \u26A0\uFE0F local only" }))] }, worktree.path))) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["[Space] Select [Enter] Delete Selected (", checkedItems.size, ") [Q] Quit"] }) })] }));
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=WorktreeList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorktreeList.js","sourceRoot":"","sources":["../../src/components/WorktreeList.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AAUjD,MAAM,UAAU,YAAY,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAqB;IACzF,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IACrD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAc,IAAI,GAAG,EAAE,CAAC,CAAA;IACxE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAA;IAEzB,MAAM,iBAAiB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;IAE5D,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,gBAAgB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;QACnD,CAAC;aAAM,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;YACzB,gBAAgB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;QAC9E,CAAC;aAAM,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAA;YACjD,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAA;gBACxC,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;gBAClC,CAAC;qBAAM,CAAC;oBACN,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;gBAC/B,CAAC;gBACD,eAAe,CAAC,UAAU,CAAC,CAAA;YAC7B,CAAC;QACH,CAAC;aAAM,IAAI,GAAG,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC/C,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAA;QACpC,CAAC;aAAM,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACzB,IAAI,EAAE,CAAA;QACR,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,YACpC,MAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,wCAAyB,QAAQ,IAAQ,GACzD,CACP,CAAA;IACH,CAAC;IAED,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,aACpC,KAAC,GAAG,IAAC,WAAW,EAAC,OAAO,EAAC,WAAW,EAAC,MAAM,EAAC,QAAQ,EAAE,CAAC,YACrD,MAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,MAAM,aACpB,QAAQ,QAAI,QAAQ,SAChB,GACH,EACN,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,YACrC,iBAAiB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1C,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,YACpD,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAC/B,EACP,KAAC,IAAI,oBAAS,EACd,KAAC,IAAI,cAAE,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAQ,EAC1D,KAAC,IAAI,oBAAS,EACd,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,YACpD,QAAQ,CAAC,MAAM,IAAI,UAAU,GACzB,EACN,QAAQ,CAAC,QAAQ,IAAI,CACpB,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,+BAAiB,CACrC,EACA,QAAQ,CAAC,KAAK,IAAI,CACjB,MAAC,IAAI,IAAC,KAAK,EAAC,SAAS,mCAAU,QAAQ,CAAC,QAAQ,IAAQ,CACzD,EACA,CAAC,QAAQ,CAAC,QAAQ,IAAI,CACrB,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,yCAAsB,CAC3C,KAlBO,QAAQ,CAAC,IAAI,CAmBjB,CACP,CAAC,GACE,EACN,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,MAAC,IAAI,IAAC,QAAQ,gEAC8B,YAAY,CAAC,IAAI,mBACtD,GACH,IACF,CACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/config/detector.ts"],"names":[],"mappings":"AAGA,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOpF;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBlE;AAED,wBAAsB,SAAS,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAG7E"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export async function getGitRoot(cwd = process.cwd()) {
|
|
4
|
+
try {
|
|
5
|
+
const { stdout } = await execa('git', ['rev-parse', '--show-toplevel'], { cwd });
|
|
6
|
+
return stdout.trim();
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export async function getRepoName(gitRoot) {
|
|
13
|
+
try {
|
|
14
|
+
const { stdout } = await execa('git', ['remote', 'get-url', 'origin'], { cwd: gitRoot });
|
|
15
|
+
const url = stdout.trim();
|
|
16
|
+
// Extract repo name from URL
|
|
17
|
+
// Handle both SSH and HTTPS URLs
|
|
18
|
+
const match = url.match(/[/:]([\w-]+)\/([\w-]+?)(\.git)?$/);
|
|
19
|
+
if (match) {
|
|
20
|
+
return match[2];
|
|
21
|
+
}
|
|
22
|
+
// Fallback to directory name
|
|
23
|
+
return path.basename(gitRoot);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// If no remote, use directory name
|
|
27
|
+
return path.basename(gitRoot);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export async function isGitRepo(dir = process.cwd()) {
|
|
31
|
+
const gitRoot = await getGitRoot(dir);
|
|
32
|
+
return gitRoot !== null;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/config/detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC1D,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;QAChF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe;IAC/C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAA;QACxF,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;QAEzB,6BAA6B;QAC7B,iCAAiC;QACjC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAA;QAC3D,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,6BAA6B;QAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;QACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACzD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAA;IACrC,OAAO,OAAO,KAAK,IAAI,CAAA;AACzB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { GlobalConfig, RepoConfig } from './schema.js';
|
|
2
|
+
export declare class ConfigManager {
|
|
3
|
+
private config;
|
|
4
|
+
load(): Promise<GlobalConfig>;
|
|
5
|
+
save(): Promise<void>;
|
|
6
|
+
getRepoConfig(repoPath: string): Promise<RepoConfig | null>;
|
|
7
|
+
setRepoConfig(repoPath: string, repoConfig: RepoConfig): Promise<void>;
|
|
8
|
+
removeRepoConfig(repoPath: string): Promise<void>;
|
|
9
|
+
getAllRepoConfigs(): Promise<Record<string, RepoConfig>>;
|
|
10
|
+
getEffectiveConfig(repoConfig: RepoConfig | null): {
|
|
11
|
+
basePath: string;
|
|
12
|
+
installCommand: string;
|
|
13
|
+
ideCommand: string;
|
|
14
|
+
envPath?: string;
|
|
15
|
+
};
|
|
16
|
+
updateDefaults(defaults: Partial<Pick<GlobalConfig, 'defaultBasePath' | 'defaultInstallCommand' | 'defaultIdeCommand'>>): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export declare const configManager: ConfigManager;
|
|
19
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/config/manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAsB,UAAU,EAAE,MAAM,aAAa,CAAA;AAI1E,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA4B;IAEpC,IAAI,IAAI,OAAO,CAAC,YAAY,CAAC;IAqB7B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAOrB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAK3D,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAOtE,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjD,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAK9D,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,GAAG;QACjD,QAAQ,EAAE,MAAM,CAAA;QAChB,cAAc,EAAE,MAAM,CAAA;QACtB,UAAU,EAAE,MAAM,CAAA;QAClB,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB;IAaK,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,iBAAiB,GAAG,uBAAuB,GAAG,mBAAmB,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAM9I;AAED,eAAO,MAAM,aAAa,eAAsB,CAAA"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { GlobalConfigSchema } from './schema.js';
|
|
5
|
+
const CONFIG_PATH = path.join(os.homedir(), '.worktreerc.json');
|
|
6
|
+
export class ConfigManager {
|
|
7
|
+
config = null;
|
|
8
|
+
async load() {
|
|
9
|
+
if (this.config)
|
|
10
|
+
return this.config;
|
|
11
|
+
try {
|
|
12
|
+
const exists = await fs.pathExists(CONFIG_PATH);
|
|
13
|
+
if (!exists) {
|
|
14
|
+
this.config = GlobalConfigSchema.parse({});
|
|
15
|
+
await this.save();
|
|
16
|
+
return this.config;
|
|
17
|
+
}
|
|
18
|
+
const data = await fs.readJson(CONFIG_PATH);
|
|
19
|
+
this.config = GlobalConfigSchema.parse(data);
|
|
20
|
+
return this.config;
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error('Error loading config:', error);
|
|
24
|
+
this.config = GlobalConfigSchema.parse({});
|
|
25
|
+
return this.config;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async save() {
|
|
29
|
+
if (!this.config) {
|
|
30
|
+
throw new Error('No config loaded');
|
|
31
|
+
}
|
|
32
|
+
await fs.outputJson(CONFIG_PATH, this.config, { spaces: 2 });
|
|
33
|
+
}
|
|
34
|
+
async getRepoConfig(repoPath) {
|
|
35
|
+
const config = await this.load();
|
|
36
|
+
return config.repos[repoPath] || null;
|
|
37
|
+
}
|
|
38
|
+
async setRepoConfig(repoPath, repoConfig) {
|
|
39
|
+
const config = await this.load();
|
|
40
|
+
config.repos[repoPath] = repoConfig;
|
|
41
|
+
this.config = config;
|
|
42
|
+
await this.save();
|
|
43
|
+
}
|
|
44
|
+
async removeRepoConfig(repoPath) {
|
|
45
|
+
const config = await this.load();
|
|
46
|
+
delete config.repos[repoPath];
|
|
47
|
+
this.config = config;
|
|
48
|
+
await this.save();
|
|
49
|
+
}
|
|
50
|
+
async getAllRepoConfigs() {
|
|
51
|
+
const config = await this.load();
|
|
52
|
+
return config.repos;
|
|
53
|
+
}
|
|
54
|
+
getEffectiveConfig(repoConfig) {
|
|
55
|
+
if (!this.config) {
|
|
56
|
+
throw new Error('Config not loaded');
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
basePath: repoConfig?.basePath || this.config.defaultBasePath,
|
|
60
|
+
installCommand: repoConfig?.installCommand || this.config.defaultInstallCommand,
|
|
61
|
+
ideCommand: repoConfig?.ideCommand || this.config.defaultIdeCommand,
|
|
62
|
+
envPath: repoConfig?.envPath,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
async updateDefaults(defaults) {
|
|
66
|
+
const config = await this.load();
|
|
67
|
+
Object.assign(config, defaults);
|
|
68
|
+
this.config = config;
|
|
69
|
+
await this.save();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export const configManager = new ConfigManager();
|
|
73
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/config/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const RepoConfigSchema: z.ZodObject<{
|
|
3
|
+
name: z.ZodString;
|
|
4
|
+
prefix: z.ZodString;
|
|
5
|
+
basePath: z.ZodOptional<z.ZodString>;
|
|
6
|
+
envPath: z.ZodOptional<z.ZodString>;
|
|
7
|
+
installCommand: z.ZodOptional<z.ZodString>;
|
|
8
|
+
ideCommand: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
name: string;
|
|
11
|
+
prefix: string;
|
|
12
|
+
basePath?: string | undefined;
|
|
13
|
+
envPath?: string | undefined;
|
|
14
|
+
installCommand?: string | undefined;
|
|
15
|
+
ideCommand?: string | undefined;
|
|
16
|
+
}, {
|
|
17
|
+
name: string;
|
|
18
|
+
prefix: string;
|
|
19
|
+
basePath?: string | undefined;
|
|
20
|
+
envPath?: string | undefined;
|
|
21
|
+
installCommand?: string | undefined;
|
|
22
|
+
ideCommand?: string | undefined;
|
|
23
|
+
}>;
|
|
24
|
+
export declare const GlobalConfigSchema: z.ZodObject<{
|
|
25
|
+
defaultBasePath: z.ZodDefault<z.ZodString>;
|
|
26
|
+
defaultInstallCommand: z.ZodDefault<z.ZodString>;
|
|
27
|
+
defaultIdeCommand: z.ZodDefault<z.ZodString>;
|
|
28
|
+
repos: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
29
|
+
name: z.ZodString;
|
|
30
|
+
prefix: z.ZodString;
|
|
31
|
+
basePath: z.ZodOptional<z.ZodString>;
|
|
32
|
+
envPath: z.ZodOptional<z.ZodString>;
|
|
33
|
+
installCommand: z.ZodOptional<z.ZodString>;
|
|
34
|
+
ideCommand: z.ZodOptional<z.ZodString>;
|
|
35
|
+
}, "strip", z.ZodTypeAny, {
|
|
36
|
+
name: string;
|
|
37
|
+
prefix: string;
|
|
38
|
+
basePath?: string | undefined;
|
|
39
|
+
envPath?: string | undefined;
|
|
40
|
+
installCommand?: string | undefined;
|
|
41
|
+
ideCommand?: string | undefined;
|
|
42
|
+
}, {
|
|
43
|
+
name: string;
|
|
44
|
+
prefix: string;
|
|
45
|
+
basePath?: string | undefined;
|
|
46
|
+
envPath?: string | undefined;
|
|
47
|
+
installCommand?: string | undefined;
|
|
48
|
+
ideCommand?: string | undefined;
|
|
49
|
+
}>>>;
|
|
50
|
+
}, "strip", z.ZodTypeAny, {
|
|
51
|
+
defaultBasePath: string;
|
|
52
|
+
defaultInstallCommand: string;
|
|
53
|
+
defaultIdeCommand: string;
|
|
54
|
+
repos: Record<string, {
|
|
55
|
+
name: string;
|
|
56
|
+
prefix: string;
|
|
57
|
+
basePath?: string | undefined;
|
|
58
|
+
envPath?: string | undefined;
|
|
59
|
+
installCommand?: string | undefined;
|
|
60
|
+
ideCommand?: string | undefined;
|
|
61
|
+
}>;
|
|
62
|
+
}, {
|
|
63
|
+
defaultBasePath?: string | undefined;
|
|
64
|
+
defaultInstallCommand?: string | undefined;
|
|
65
|
+
defaultIdeCommand?: string | undefined;
|
|
66
|
+
repos?: Record<string, {
|
|
67
|
+
name: string;
|
|
68
|
+
prefix: string;
|
|
69
|
+
basePath?: string | undefined;
|
|
70
|
+
envPath?: string | undefined;
|
|
71
|
+
installCommand?: string | undefined;
|
|
72
|
+
ideCommand?: string | undefined;
|
|
73
|
+
}> | undefined;
|
|
74
|
+
}>;
|
|
75
|
+
export type RepoConfig = z.infer<typeof RepoConfigSchema>;
|
|
76
|
+
export type GlobalConfig = z.infer<typeof GlobalConfigSchema>;
|
|
77
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;EAO3B,CAAA;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQ7B,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACzD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const RepoConfigSchema = z.object({
|
|
3
|
+
name: z.string().describe('Repository name for display'),
|
|
4
|
+
prefix: z.string().describe('Prefix for worktree directories (e.g., "fe-", "be-")'),
|
|
5
|
+
basePath: z.string().optional().describe('Directory to create worktrees in'),
|
|
6
|
+
envPath: z.string().optional().describe('.env file to copy to new worktrees'),
|
|
7
|
+
installCommand: z.string().optional().describe('Command to run after creating worktree'),
|
|
8
|
+
ideCommand: z.string().optional().describe('IDE command to open worktree'),
|
|
9
|
+
});
|
|
10
|
+
export const GlobalConfigSchema = z.object({
|
|
11
|
+
defaultBasePath: z.string().default('../').describe('Default directory for worktrees'),
|
|
12
|
+
defaultInstallCommand: z
|
|
13
|
+
.string()
|
|
14
|
+
.default('pnpm install')
|
|
15
|
+
.describe('Default install command'),
|
|
16
|
+
defaultIdeCommand: z.string().default('cursor').describe('Default IDE command'),
|
|
17
|
+
repos: z.record(z.string(), RepoConfigSchema).default({}).describe('Repository configurations'),
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;IACxD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC;IACnF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAC5E,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;IAC7E,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;IACxF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;CAC3E,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;IACtF,qBAAqB,EAAE,CAAC;SACrB,MAAM,EAAE;SACR,OAAO,CAAC,cAAc,CAAC;SACvB,QAAQ,CAAC,yBAAyB,CAAC;IACtC,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IAC/E,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC;CAChG,CAAC,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface PRInfo {
|
|
2
|
+
number: number;
|
|
3
|
+
headRefName: string;
|
|
4
|
+
state: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function isGhInstalled(): Promise<boolean>;
|
|
7
|
+
export declare function getPRInfo(gitRoot: string): Promise<Map<string, PRInfo>>;
|
|
8
|
+
export declare function enrichWorktreesWithPRInfo(worktrees: Array<{
|
|
9
|
+
branch?: string;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}>, gitRoot: string): Promise<void>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=gh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gh.d.ts","sourceRoot":"","sources":["../../src/utils/gh.ts"],"names":[],"mappings":"AAEA,UAAU,MAAM;IACd,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAOtD;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAyB7E;AAED,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,KAAK,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAAC,EACzD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAYf"}
|
package/dist/utils/gh.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
export async function isGhInstalled() {
|
|
3
|
+
try {
|
|
4
|
+
await execa('which', ['gh']);
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export async function getPRInfo(gitRoot) {
|
|
12
|
+
const prMap = new Map();
|
|
13
|
+
if (!(await isGhInstalled())) {
|
|
14
|
+
return prMap;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const { stdout } = await execa('gh', ['pr', 'list', '--json', 'number,headRefName,state', '--limit', '100'], { cwd: gitRoot });
|
|
18
|
+
const prs = JSON.parse(stdout);
|
|
19
|
+
for (const pr of prs) {
|
|
20
|
+
prMap.set(pr.headRefName, pr);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
// gh might not be authenticated or repo might not have GitHub remote
|
|
25
|
+
// Silently fail and return empty map
|
|
26
|
+
}
|
|
27
|
+
return prMap;
|
|
28
|
+
}
|
|
29
|
+
export async function enrichWorktreesWithPRInfo(worktrees, gitRoot) {
|
|
30
|
+
const prInfo = await getPRInfo(gitRoot);
|
|
31
|
+
for (const worktree of worktrees) {
|
|
32
|
+
if (worktree.branch) {
|
|
33
|
+
const pr = prInfo.get(worktree.branch);
|
|
34
|
+
if (pr) {
|
|
35
|
+
worktree.hasPR = true;
|
|
36
|
+
worktree.prNumber = pr.number;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=gh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gh.js","sourceRoot":"","sources":["../../src/utils/gh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAQ7B,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAA;IAEvC,IAAI,CAAC,CAAC,MAAM,aAAa,EAAE,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAC5B,IAAI,EACJ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,0BAA0B,EAAE,SAAS,EAAE,KAAK,CAAC,EACtE,EAAE,GAAG,EAAE,OAAO,EAAE,CACjB,CAAA;QAED,MAAM,GAAG,GAAa,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAExC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,qEAAqE;QACrE,qCAAqC;IACvC,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,SAAyD,EACzD,OAAe;IAEf,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAA;IAEvC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;YACtC,IAAI,EAAE,EAAE,CAAC;gBACP,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAA;gBACrB,QAAQ,CAAC,QAAQ,GAAG,EAAE,CAAC,MAAM,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface Worktree {
|
|
2
|
+
path: string;
|
|
3
|
+
branch: string;
|
|
4
|
+
commit: string;
|
|
5
|
+
isMain: boolean;
|
|
6
|
+
isPushed?: boolean;
|
|
7
|
+
hasPR?: boolean;
|
|
8
|
+
prNumber?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function createWorktree(basePath: string, worktreeName: string, branchName: string, gitRoot: string): Promise<void>;
|
|
11
|
+
export declare function listWorktrees(gitRoot: string): Promise<Worktree[]>;
|
|
12
|
+
export declare function removeWorktree(worktreePath: string, gitRoot: string): Promise<void>;
|
|
13
|
+
export declare function getAllBranches(gitRoot: string): Promise<string[]>;
|
|
14
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAqDxE;AAED,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzF;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOvE"}
|