wt-manager 1.4.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 +343 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +26 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/clean.d.ts +3 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +339 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +12 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +202 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/new.d.ts +3 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +147 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/remove.d.ts +3 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +192 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/wt.d.ts +3 -0
- package/dist/commands/wt.d.ts.map +1 -0
- package/dist/commands/wt.js +78 -0
- package/dist/commands/wt.js.map +1 -0
- package/dist/commands/wtclean.d.ts +3 -0
- package/dist/commands/wtclean.d.ts.map +1 -0
- package/dist/commands/wtclean.js +190 -0
- package/dist/commands/wtclean.js.map +1 -0
- package/dist/commands/wtlist.d.ts +3 -0
- package/dist/commands/wtlist.d.ts.map +1 -0
- package/dist/commands/wtlist.js +202 -0
- package/dist/commands/wtlist.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/clipboard.js +23 -0
- package/dist/utils/clipboard.js.map +1 -0
- package/dist/utils/git.d.ts +45 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +202 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/github.d.ts +21 -0
- package/dist/utils/github.d.ts.map +1 -0
- package/dist/utils/github.js +113 -0
- package/dist/utils/github.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import { mkdir, stat } from 'node:fs/promises';
|
|
3
|
+
import { basename } from 'node:path';
|
|
4
|
+
export async function getMainWorktreePath() {
|
|
5
|
+
const { stdout } = await execa('git', ['worktree', 'list']);
|
|
6
|
+
const firstLine = stdout.split('\n')[0];
|
|
7
|
+
return firstLine.split(/\s+/)[0];
|
|
8
|
+
}
|
|
9
|
+
export async function getRepoName() {
|
|
10
|
+
const mainWorktreePath = await getMainWorktreePath();
|
|
11
|
+
return basename(mainWorktreePath);
|
|
12
|
+
}
|
|
13
|
+
export async function getDefaultBranch() {
|
|
14
|
+
try {
|
|
15
|
+
const { stdout } = await execa('git', ['symbolic-ref', 'refs/remotes/origin/HEAD']);
|
|
16
|
+
return stdout.replace('refs/remotes/origin/', '');
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return 'develop';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export async function fetchOrigin() {
|
|
23
|
+
await execa('git', ['fetch', 'origin']);
|
|
24
|
+
}
|
|
25
|
+
export async function listWorktrees() {
|
|
26
|
+
const { stdout } = await execa('git', ['worktree', 'list', '--porcelain']);
|
|
27
|
+
const worktrees = [];
|
|
28
|
+
const lines = stdout.trim().split('\n');
|
|
29
|
+
let current = {};
|
|
30
|
+
for (const line of lines) {
|
|
31
|
+
if (line.startsWith('worktree ')) {
|
|
32
|
+
if (current.path) {
|
|
33
|
+
worktrees.push(current);
|
|
34
|
+
}
|
|
35
|
+
current = { path: line.substring(9), isMain: false };
|
|
36
|
+
}
|
|
37
|
+
else if (line.startsWith('HEAD ')) {
|
|
38
|
+
current.commit = line.substring(5);
|
|
39
|
+
}
|
|
40
|
+
else if (line.startsWith('branch ')) {
|
|
41
|
+
current.branch = line.substring(7).replace('refs/heads/', '');
|
|
42
|
+
}
|
|
43
|
+
else if (line === 'bare') {
|
|
44
|
+
current.isMain = true;
|
|
45
|
+
}
|
|
46
|
+
else if (line === '') {
|
|
47
|
+
if (current.path) {
|
|
48
|
+
worktrees.push(current);
|
|
49
|
+
current = {};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (current.path) {
|
|
54
|
+
worktrees.push(current);
|
|
55
|
+
}
|
|
56
|
+
if (worktrees.length > 0) {
|
|
57
|
+
worktrees[0].isMain = true;
|
|
58
|
+
}
|
|
59
|
+
return worktrees;
|
|
60
|
+
}
|
|
61
|
+
export async function ensureDir(path) {
|
|
62
|
+
await mkdir(path, { recursive: true });
|
|
63
|
+
}
|
|
64
|
+
export async function createWorktree(branchName, worktreePath, baseBranch) {
|
|
65
|
+
await execa('git', ['worktree', 'add', '-b', branchName, worktreePath, baseBranch]);
|
|
66
|
+
}
|
|
67
|
+
export async function removeWorktree(path, force) {
|
|
68
|
+
const args = ['worktree', 'remove', path];
|
|
69
|
+
if (force) {
|
|
70
|
+
args.push('--force');
|
|
71
|
+
}
|
|
72
|
+
await execa('git', args);
|
|
73
|
+
}
|
|
74
|
+
export async function deleteBranch(branch, force) {
|
|
75
|
+
const flag = force ? '-D' : '-d';
|
|
76
|
+
await execa('git', ['branch', flag, branch]);
|
|
77
|
+
}
|
|
78
|
+
export async function branchExists(branch) {
|
|
79
|
+
const { stdout } = await execa('git', ['branch', '--list', branch]);
|
|
80
|
+
return stdout.trim().length > 0;
|
|
81
|
+
}
|
|
82
|
+
export async function isBranchMerged(_branch, _baseBranch = 'main') {
|
|
83
|
+
throw new Error('TODO: Implementation pending');
|
|
84
|
+
}
|
|
85
|
+
export async function getRemoteUrl(remote = 'origin') {
|
|
86
|
+
const { stdout } = await execa('git', ['remote', 'get-url', remote]);
|
|
87
|
+
return stdout.trim();
|
|
88
|
+
}
|
|
89
|
+
export async function getWorktreeStatus(_path) {
|
|
90
|
+
throw new Error('TODO: Implementation pending');
|
|
91
|
+
}
|
|
92
|
+
export async function getCreationTime(path) {
|
|
93
|
+
try {
|
|
94
|
+
const stats = await stat(path);
|
|
95
|
+
return stats.birthtimeMs;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export async function hasUncommittedChanges(path) {
|
|
102
|
+
try {
|
|
103
|
+
const { stdout } = await execa('git', ['-C', path, 'status', '--porcelain']);
|
|
104
|
+
return stdout.trim().length > 0;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export async function getAheadBehind(branch, baseBranch) {
|
|
111
|
+
try {
|
|
112
|
+
const aheadResult = await execa('git', [
|
|
113
|
+
'rev-list',
|
|
114
|
+
'--count',
|
|
115
|
+
`${baseBranch}..${branch}`,
|
|
116
|
+
]);
|
|
117
|
+
const behindResult = await execa('git', [
|
|
118
|
+
'rev-list',
|
|
119
|
+
'--count',
|
|
120
|
+
`${branch}..${baseBranch}`,
|
|
121
|
+
]);
|
|
122
|
+
return {
|
|
123
|
+
ahead: parseInt(aheadResult.stdout, 10) || 0,
|
|
124
|
+
behind: parseInt(behindResult.stdout, 10) || 0,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return { ahead: 0, behind: 0 };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export async function getCurrentWorktreePath() {
|
|
132
|
+
const { stdout } = await execa('git', ['rev-parse', '--show-toplevel']);
|
|
133
|
+
return stdout.trim();
|
|
134
|
+
}
|
|
135
|
+
export function isPathInWorktree(currentPath, worktreePath) {
|
|
136
|
+
return currentPath.startsWith(worktreePath);
|
|
137
|
+
}
|
|
138
|
+
export async function getWorktreeChanges(path) {
|
|
139
|
+
try {
|
|
140
|
+
const { stdout } = await execa('git', ['-C', path, 'status', '--porcelain']);
|
|
141
|
+
const lines = stdout.trim().split('\n').filter(Boolean);
|
|
142
|
+
const modified = [];
|
|
143
|
+
const untracked = [];
|
|
144
|
+
for (const line of lines) {
|
|
145
|
+
if (line.startsWith('??')) {
|
|
146
|
+
untracked.push(line);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
modified.push(line);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return { modified, untracked };
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return { modified: [], untracked: [] };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export async function getGitDiff(path) {
|
|
159
|
+
try {
|
|
160
|
+
const { stdout: unstagedDiff } = await execa('git', ['-C', path, 'diff', '--color']);
|
|
161
|
+
const { stdout: stagedDiff } = await execa('git', ['-C', path, 'diff', '--cached', '--color']);
|
|
162
|
+
const parts = [];
|
|
163
|
+
if (stagedDiff.trim())
|
|
164
|
+
parts.push(stagedDiff);
|
|
165
|
+
if (unstagedDiff.trim())
|
|
166
|
+
parts.push(unstagedDiff);
|
|
167
|
+
return parts.join('\n');
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return '';
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
export async function forceRemoveDirectory(path) {
|
|
174
|
+
const { rm } = await import('node:fs/promises');
|
|
175
|
+
await rm(path, { recursive: true, force: true });
|
|
176
|
+
}
|
|
177
|
+
export async function pruneWorktrees() {
|
|
178
|
+
await execa('git', ['worktree', 'prune']);
|
|
179
|
+
}
|
|
180
|
+
export async function hasUnpushedCommits(branch) {
|
|
181
|
+
try {
|
|
182
|
+
const { stdout: remoteBranch } = await execa('git', [
|
|
183
|
+
'rev-parse',
|
|
184
|
+
'--abbrev-ref',
|
|
185
|
+
`${branch}@{upstream}`,
|
|
186
|
+
]);
|
|
187
|
+
if (!remoteBranch.trim()) {
|
|
188
|
+
return { hasUnpushed: false, noRemote: true };
|
|
189
|
+
}
|
|
190
|
+
const { stdout } = await execa('git', [
|
|
191
|
+
'rev-list',
|
|
192
|
+
'--count',
|
|
193
|
+
`${remoteBranch.trim()}..${branch}`,
|
|
194
|
+
]);
|
|
195
|
+
const unpushedCount = parseInt(stdout.trim(), 10);
|
|
196
|
+
return { hasUnpushed: unpushedCount > 0, noRemote: false };
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
return { hasUnpushed: false, noRemote: true };
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Octokit } from 'octokit';
|
|
2
|
+
export declare function isGhCliAvailable(): Promise<{
|
|
3
|
+
available: boolean;
|
|
4
|
+
authenticated: boolean;
|
|
5
|
+
error?: string;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function getOctokit(): Promise<Octokit>;
|
|
8
|
+
export declare function getPRStatus(owner: string, repo: string, branch: string): Promise<{
|
|
9
|
+
number: number;
|
|
10
|
+
state: 'open' | 'closed' | 'merged';
|
|
11
|
+
title: string;
|
|
12
|
+
url: string;
|
|
13
|
+
isDraft: boolean;
|
|
14
|
+
checksStatus?: 'success' | 'failure' | 'pending' | 'none';
|
|
15
|
+
} | null>;
|
|
16
|
+
export declare function isBranchMerged(_owner: string, _repo: string, _branch: string): Promise<boolean>;
|
|
17
|
+
export declare function parseGitHubRepo(remoteUrl: string): {
|
|
18
|
+
owner: string;
|
|
19
|
+
repo: string;
|
|
20
|
+
} | null;
|
|
21
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/utils/github.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAMjC,wBAAsB,gBAAgB,IAAI,OAAO,CAAC;IAChD,SAAS,EAAE,OAAO,CAAA;IAClB,aAAa,EAAE,OAAO,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC,CA0BD;AAMD,wBAAsB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAQnD;AAKD,wBAAsB,WAAW,CAC/B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IACT,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;CAC1D,GAAG,IAAI,CAAC,CA+DR;AAKD,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC,CAMlB;AAKD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAczF"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Octokit } from 'octokit';
|
|
2
|
+
import { execa } from 'execa';
|
|
3
|
+
export async function isGhCliAvailable() {
|
|
4
|
+
try {
|
|
5
|
+
await execa('gh', ['--version']);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return {
|
|
9
|
+
available: false,
|
|
10
|
+
authenticated: false,
|
|
11
|
+
error: 'gh CLI not installed',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
await execa('gh', ['auth', 'status']);
|
|
16
|
+
return {
|
|
17
|
+
available: true,
|
|
18
|
+
authenticated: true,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return {
|
|
23
|
+
available: true,
|
|
24
|
+
authenticated: false,
|
|
25
|
+
error: 'gh CLI not authenticated',
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export async function getOctokit() {
|
|
30
|
+
try {
|
|
31
|
+
const { stdout } = await execa('gh', ['auth', 'token']);
|
|
32
|
+
const token = stdout.trim();
|
|
33
|
+
return new Octokit({ auth: token });
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
throw new Error('GitHub CLI not authenticated. Run: gh auth login');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export async function getPRStatus(owner, repo, branch) {
|
|
40
|
+
try {
|
|
41
|
+
const octokit = await getOctokit();
|
|
42
|
+
const { data: prs } = await octokit.rest.pulls.list({
|
|
43
|
+
owner,
|
|
44
|
+
repo,
|
|
45
|
+
head: `${owner}:${branch}`,
|
|
46
|
+
state: 'all',
|
|
47
|
+
per_page: 1,
|
|
48
|
+
});
|
|
49
|
+
if (prs.length === 0) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
const pr = prs[0];
|
|
53
|
+
let state;
|
|
54
|
+
if (pr.merged_at) {
|
|
55
|
+
state = 'merged';
|
|
56
|
+
}
|
|
57
|
+
else if (pr.state === 'closed') {
|
|
58
|
+
state = 'closed';
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
state = 'open';
|
|
62
|
+
}
|
|
63
|
+
let checksStatus = 'none';
|
|
64
|
+
try {
|
|
65
|
+
const { data: checkRuns } = await octokit.rest.checks.listForRef({
|
|
66
|
+
owner,
|
|
67
|
+
repo,
|
|
68
|
+
ref: pr.head.sha,
|
|
69
|
+
});
|
|
70
|
+
if (checkRuns.total_count > 0) {
|
|
71
|
+
const conclusions = checkRuns.check_runs.map((run) => run.conclusion);
|
|
72
|
+
if (conclusions.some((c) => c === 'failure')) {
|
|
73
|
+
checksStatus = 'failure';
|
|
74
|
+
}
|
|
75
|
+
else if (conclusions.every((c) => c === 'success')) {
|
|
76
|
+
checksStatus = 'success';
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
checksStatus = 'pending';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
checksStatus = 'none';
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
number: pr.number,
|
|
88
|
+
state,
|
|
89
|
+
title: pr.title,
|
|
90
|
+
url: pr.html_url,
|
|
91
|
+
isDraft: pr.draft || false,
|
|
92
|
+
checksStatus,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export async function isBranchMerged(_owner, _repo, _branch) {
|
|
100
|
+
throw new Error('TODO: Implementation pending');
|
|
101
|
+
}
|
|
102
|
+
export function parseGitHubRepo(remoteUrl) {
|
|
103
|
+
const sshMatch = remoteUrl.match(/git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
|
|
104
|
+
if (sshMatch) {
|
|
105
|
+
return { owner: sshMatch[1], repo: sshMatch[2] };
|
|
106
|
+
}
|
|
107
|
+
const httpsMatch = remoteUrl.match(/https:\/\/github\.com\/([^/]+)\/(.+?)(?:\.git)?$/);
|
|
108
|
+
if (httpsMatch) {
|
|
109
|
+
return { owner: httpsMatch[1], repo: httpsMatch[2] };
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/utils/github.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wt-manager",
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "CLI tool for managing Git worktrees efficiently with GitHub integration",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"wt": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/",
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/daviddurika/git-worktree-manager.git"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/daviddurika/git-worktree-manager/issues"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/daviddurika/git-worktree-manager#readme",
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"dev": "tsc --watch",
|
|
27
|
+
"lint": "eslint src --ext .ts",
|
|
28
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
29
|
+
"format:check": "prettier --check \"src/**/*.ts\"",
|
|
30
|
+
"prepublishOnly": "npm run build",
|
|
31
|
+
"post-worktree-created": "npm install"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"git",
|
|
35
|
+
"worktree",
|
|
36
|
+
"cli",
|
|
37
|
+
"github",
|
|
38
|
+
"developer-tools"
|
|
39
|
+
],
|
|
40
|
+
"author": "David Durika",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22.0.0"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@inquirer/prompts": "^8.0.2",
|
|
47
|
+
"chalk": "^5.3.0",
|
|
48
|
+
"commander": "^12.1.0",
|
|
49
|
+
"execa": "^9.5.2",
|
|
50
|
+
"octokit": "^4.0.2",
|
|
51
|
+
"ora": "^8.1.1"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/node": "^22.10.1",
|
|
55
|
+
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
|
56
|
+
"@typescript-eslint/parser": "^8.15.0",
|
|
57
|
+
"eslint": "^9.15.0",
|
|
58
|
+
"prettier": "^3.3.3",
|
|
59
|
+
"typescript": "^5.7.2"
|
|
60
|
+
}
|
|
61
|
+
}
|