@lsst/pik-plugin-worktree 0.5.0 → 0.5.2

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { worktreePlugin } from './lib/plugin.js';
2
2
  export type { WorktreeConfig } from './lib/types.js';
3
- export { git, getRepoRoot, getCurrentBranch, isClean, listWorktrees, createWorktree, removeWorktree, listBranches, branchExists, type Worktree, } from './lib/git.js';
3
+ export { getGit, getRepoRoot, getCurrentBranch, isClean, listWorktrees, createWorktree, removeWorktree, listBranches, branchExists, deleteBranch, isWorktree, type Worktree, } from './lib/git.js';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EACL,GAAG,EACH,WAAW,EACX,gBAAgB,EAChB,OAAO,EACP,aAAa,EACb,cAAc,EACd,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,KAAK,QAAQ,GACd,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EACL,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,OAAO,EACP,aAAa,EACb,cAAc,EACd,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,KAAK,QAAQ,GACd,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,39 +1,31 @@
1
- import { Command } from "commander";
2
- import { select, input, confirm } from "@inquirer/prompts";
1
+ import { select, input, confirm, Separator } from "@inquirer/prompts";
3
2
  import pc from "picocolors";
3
+ import { Command } from "commander";
4
4
  import { basename, resolve, relative } from "path";
5
5
  import { execSync } from "child_process";
6
6
  import { existsSync, mkdirSync, copyFileSync } from "fs";
7
7
  import { glob } from "glob";
8
8
  import { loadConfig } from "@lsst/pik-core";
9
- function git(args, cwd) {
10
- try {
11
- return execSync(`git ${args.join(" ")}`, {
12
- cwd,
13
- encoding: "utf-8",
14
- stdio: ["pipe", "pipe", "pipe"]
15
- }).trim();
16
- } catch (error) {
17
- const err = error;
18
- const gitError = new Error(
19
- err.stderr?.toString().trim() || err.message
20
- );
21
- gitError.stderr = err.stderr?.toString();
22
- throw gitError;
23
- }
9
+ import { simpleGit } from "simple-git";
10
+ function getGit(cwd) {
11
+ return simpleGit(cwd);
24
12
  }
25
- function getRepoRoot(cwd) {
26
- return git(["rev-parse", "--show-toplevel"], cwd);
13
+ async function getRepoRoot(cwd) {
14
+ const git = getGit(cwd);
15
+ return (await git.revparse(["--show-toplevel"])).trim();
27
16
  }
28
- function getCurrentBranch(cwd) {
29
- return git(["rev-parse", "--abbrev-ref", "HEAD"], cwd);
17
+ async function getCurrentBranch(cwd) {
18
+ const git = getGit(cwd);
19
+ return (await git.revparse(["--abbrev-ref", "HEAD"])).trim();
30
20
  }
31
- function isClean(cwd) {
32
- const status = git(["status", "--porcelain"], cwd);
33
- return status === "";
21
+ async function isClean(cwd) {
22
+ const git = getGit(cwd);
23
+ const status = await git.status();
24
+ return status.isClean();
34
25
  }
35
- function listWorktrees(cwd) {
36
- const output = git(["worktree", "list", "--porcelain"], cwd);
26
+ async function listWorktrees(cwd) {
27
+ const git = getGit(cwd);
28
+ const output = await git.raw(["worktree", "list", "--porcelain"]);
37
29
  if (!output) return [];
38
30
  const worktrees = [];
39
31
  let current = {};
@@ -63,7 +55,8 @@ function listWorktrees(cwd) {
63
55
  }
64
56
  return worktrees;
65
57
  }
66
- function createWorktree(path, branch, options, cwd) {
58
+ async function createWorktree(path, branch, options, cwd) {
59
+ const git = getGit(cwd);
67
60
  const args = ["worktree", "add"];
68
61
  if (options?.newBranch) {
69
62
  args.push("-b", branch);
@@ -74,36 +67,56 @@ function createWorktree(path, branch, options, cwd) {
74
67
  } else {
75
68
  args.push(path, branch);
76
69
  }
77
- git(args, cwd);
70
+ await git.raw(args);
78
71
  }
79
- function removeWorktree(path, force, cwd) {
72
+ async function removeWorktree(path, force, cwd) {
73
+ const git = getGit(cwd);
80
74
  const args = ["worktree", "remove"];
81
75
  if (force) {
82
76
  args.push("--force");
83
77
  }
84
78
  args.push(path);
85
- git(args, cwd);
79
+ await git.raw(args);
86
80
  }
87
- function listBranches(cwd) {
88
- const output = git(["branch", "--format=%(refname:short)"], cwd);
89
- return output.split("\n").filter(Boolean);
81
+ async function listBranches(cwd) {
82
+ const git = getGit(cwd);
83
+ const result = await git.branchLocal();
84
+ return result.all;
90
85
  }
91
- function branchExists(branch, cwd) {
86
+ async function branchExists(branch, cwd) {
87
+ const git = getGit(cwd);
92
88
  try {
93
- git(["rev-parse", "--verify", branch], cwd);
89
+ await git.revparse(["--verify", branch]);
94
90
  return true;
95
91
  } catch {
96
92
  return false;
97
93
  }
98
94
  }
95
+ async function deleteBranch(branch, force, cwd) {
96
+ const git = getGit(cwd);
97
+ if (force) {
98
+ await git.branch(["-D", branch]);
99
+ } else {
100
+ await git.branch(["-d", branch]);
101
+ }
102
+ }
103
+ async function isWorktree(path) {
104
+ const git = getGit(path);
105
+ try {
106
+ const gitDir = await git.revparse(["--git-dir"]);
107
+ return gitDir.includes(".git/worktrees/");
108
+ } catch {
109
+ return false;
110
+ }
111
+ }
99
112
  const createCommand = new Command("create").alias("add").description("Create a new worktree").argument("[name]", "Name for the worktree directory").option("-b, --branch <branch>", "Branch to checkout (or create with -n)").option("-n, --new", "Create a new branch").action(async (name, options) => {
100
113
  try {
101
- const repoRoot = getRepoRoot();
114
+ const repoRoot = await getRepoRoot();
102
115
  const config = await loadConfig(repoRoot);
103
116
  const worktreeConfig = config?.worktree ?? {};
104
- const currentBranch = getCurrentBranch(repoRoot);
105
- const branches = listBranches(repoRoot);
106
- const existingWorktrees = listWorktrees(repoRoot);
117
+ const currentBranch = await getCurrentBranch(repoRoot);
118
+ const branches = await listBranches(repoRoot);
119
+ const existingWorktrees = await listWorktrees(repoRoot);
107
120
  const existingPaths = new Set(existingWorktrees.map((w) => w.path));
108
121
  let branch = options.branch;
109
122
  let isNewBranch = options.new ?? false;
@@ -119,9 +132,9 @@ const createCommand = new Command("create").alias("add").description("Create a n
119
132
  isNewBranch = true;
120
133
  branch = await input({
121
134
  message: "New branch name:",
122
- validate: (value) => {
135
+ validate: async (value) => {
123
136
  if (!value.trim()) return "Branch name is required";
124
- if (branchExists(value, repoRoot)) return "Branch already exists";
137
+ if (await branchExists(value, repoRoot)) return "Branch already exists";
125
138
  return true;
126
139
  }
127
140
  });
@@ -165,7 +178,7 @@ const createCommand = new Command("create").alias("add").description("Create a n
165
178
  process.exit(1);
166
179
  }
167
180
  console.log(pc.dim(`Creating worktree at ${worktreePath}...`));
168
- createWorktree(
181
+ await createWorktree(
169
182
  worktreePath,
170
183
  branch,
171
184
  { newBranch: isNewBranch, baseBranch: currentBranch },
@@ -223,8 +236,8 @@ const createCommand = new Command("create").alias("add").description("Create a n
223
236
  });
224
237
  const listCommand = new Command("list").alias("ls").description("List all worktrees").option("--json", "Output in JSON format").action(async (options) => {
225
238
  try {
226
- const repoRoot = getRepoRoot();
227
- const worktrees = listWorktrees(repoRoot);
239
+ const repoRoot = await getRepoRoot();
240
+ const worktrees = await listWorktrees(repoRoot);
228
241
  if (options.json) {
229
242
  console.log(JSON.stringify(worktrees, null, 2));
230
243
  return;
@@ -252,8 +265,8 @@ const listCommand = new Command("list").alias("ls").description("List all worktr
252
265
  });
253
266
  const removeCommand = new Command("remove").alias("rm").description("Remove a worktree").argument("[path]", "Path to the worktree to remove").option("-f, --force", "Force removal even if worktree is dirty").option("-D, --delete-branch", "Also delete the branch").action(async (pathArg, options) => {
254
267
  try {
255
- const repoRoot = getRepoRoot();
256
- const worktrees = listWorktrees(repoRoot);
268
+ const repoRoot = await getRepoRoot();
269
+ const worktrees = await listWorktrees(repoRoot);
257
270
  const removableWorktrees = worktrees.filter((w) => !w.isMain);
258
271
  if (removableWorktrees.length === 0) {
259
272
  console.log(pc.yellow("No removable worktrees found"));
@@ -295,7 +308,7 @@ const removeCommand = new Command("remove").alias("rm").description("Remove a wo
295
308
  return;
296
309
  }
297
310
  console.log(pc.dim("Removing worktree..."));
298
- removeWorktree(targetWorktree.path, options.force, repoRoot);
311
+ await removeWorktree(targetWorktree.path, options.force, repoRoot);
299
312
  console.log(pc.green(`✓ Removed worktree ${relativePath}`));
300
313
  if (options.deleteBranch && targetWorktree.branch) {
301
314
  const shouldDeleteBranch = await confirm({
@@ -304,7 +317,7 @@ const removeCommand = new Command("remove").alias("rm").description("Remove a wo
304
317
  });
305
318
  if (shouldDeleteBranch) {
306
319
  try {
307
- git(["branch", "-D", targetWorktree.branch], repoRoot);
320
+ await deleteBranch(targetWorktree.branch, true, repoRoot);
308
321
  console.log(pc.green(`✓ Deleted branch ${targetWorktree.branch}`));
309
322
  } catch (error) {
310
323
  if (error instanceof Error) {
@@ -323,6 +336,7 @@ const removeCommand = new Command("remove").alias("rm").description("Remove a wo
323
336
  process.exit(1);
324
337
  }
325
338
  });
339
+ const BACK_VALUE = /* @__PURE__ */ Symbol("back");
326
340
  const worktreePlugin = {
327
341
  name: "Worktree",
328
342
  description: "Manage git worktrees",
@@ -334,17 +348,52 @@ const worktreePlugin = {
334
348
  worktreeCmd.addCommand(listCommand);
335
349
  worktreeCmd.addCommand(removeCommand);
336
350
  worktreeCmd.action(async () => {
337
- await createCommand.parseAsync([], { from: "user" });
351
+ while (true) {
352
+ let action;
353
+ try {
354
+ action = await select({
355
+ message: "Worktree actions",
356
+ choices: [
357
+ { name: "Create worktree", value: "create" },
358
+ { name: "List worktrees", value: "list" },
359
+ { name: "Remove worktree", value: "remove" },
360
+ new Separator(),
361
+ { name: pc.dim("← Back"), value: BACK_VALUE }
362
+ ]
363
+ });
364
+ } catch (error) {
365
+ if (error instanceof Error && error.name === "ExitPromptError") {
366
+ return;
367
+ }
368
+ throw error;
369
+ }
370
+ if (action === BACK_VALUE) {
371
+ return;
372
+ }
373
+ switch (action) {
374
+ case "create":
375
+ await createCommand.parseAsync([], { from: "user" });
376
+ break;
377
+ case "list":
378
+ await listCommand.parseAsync([], { from: "user" });
379
+ break;
380
+ case "remove":
381
+ await removeCommand.parseAsync([], { from: "user" });
382
+ break;
383
+ }
384
+ }
338
385
  });
339
386
  }
340
387
  };
341
388
  export {
342
389
  branchExists,
343
390
  createWorktree,
391
+ deleteBranch,
344
392
  getCurrentBranch,
393
+ getGit,
345
394
  getRepoRoot,
346
- git,
347
395
  isClean,
396
+ isWorktree,
348
397
  listBranches,
349
398
  listWorktrees,
350
399
  removeWorktree,
package/dist/lib/git.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { SimpleGit } from 'simple-git';
1
2
  export interface Worktree {
2
3
  path: string;
3
4
  branch: string;
@@ -5,58 +6,51 @@ export interface Worktree {
5
6
  isBare: boolean;
6
7
  isMain: boolean;
7
8
  }
8
- export interface GitError extends Error {
9
- stderr?: string;
10
- }
11
- /**
12
- * Execute a git command and return stdout
13
- */
14
- export declare function git(args: string[], cwd?: string): string;
15
9
  /**
16
- * Execute a git command asynchronously with live output
10
+ * Get a simple-git instance for the given directory
17
11
  */
18
- export declare function gitAsync(args: string[], cwd?: string): Promise<{
19
- code: number;
20
- stdout: string;
21
- stderr: string;
22
- }>;
12
+ export declare function getGit(cwd?: string): SimpleGit;
23
13
  /**
24
14
  * Get the root directory of the git repository
25
15
  */
26
- export declare function getRepoRoot(cwd?: string): string;
16
+ export declare function getRepoRoot(cwd?: string): Promise<string>;
27
17
  /**
28
18
  * Get the current branch name
29
19
  */
30
- export declare function getCurrentBranch(cwd?: string): string;
20
+ export declare function getCurrentBranch(cwd?: string): Promise<string>;
31
21
  /**
32
22
  * Check if working directory is clean
33
23
  */
34
- export declare function isClean(cwd?: string): boolean;
24
+ export declare function isClean(cwd?: string): Promise<boolean>;
35
25
  /**
36
26
  * List all worktrees
37
27
  */
38
- export declare function listWorktrees(cwd?: string): Worktree[];
28
+ export declare function listWorktrees(cwd?: string): Promise<Worktree[]>;
39
29
  /**
40
30
  * Create a new worktree
41
31
  */
42
32
  export declare function createWorktree(path: string, branch: string, options?: {
43
33
  newBranch?: boolean;
44
34
  baseBranch?: string;
45
- }, cwd?: string): void;
35
+ }, cwd?: string): Promise<void>;
46
36
  /**
47
37
  * Remove a worktree
48
38
  */
49
- export declare function removeWorktree(path: string, force?: boolean, cwd?: string): void;
39
+ export declare function removeWorktree(path: string, force?: boolean, cwd?: string): Promise<void>;
50
40
  /**
51
41
  * Get list of local branches
52
42
  */
53
- export declare function listBranches(cwd?: string): string[];
43
+ export declare function listBranches(cwd?: string): Promise<string[]>;
54
44
  /**
55
45
  * Check if a branch exists
56
46
  */
57
- export declare function branchExists(branch: string, cwd?: string): boolean;
47
+ export declare function branchExists(branch: string, cwd?: string): Promise<boolean>;
48
+ /**
49
+ * Delete a branch
50
+ */
51
+ export declare function deleteBranch(branch: string, force?: boolean, cwd?: string): Promise<void>;
58
52
  /**
59
53
  * Check if path is inside a git worktree
60
54
  */
61
- export declare function isWorktree(path: string): boolean;
55
+ export declare function isWorktree(path: string): Promise<boolean>;
62
56
  //# sourceMappingURL=git.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,QAAS,SAAQ,KAAK;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAexD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAwB3D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAG7C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAmCtD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EACtD,GAAG,CAAC,EAAE,MAAM,GACX,IAAI,CAcN;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAOhF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAGnD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAOlE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQhD"}
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,SAAS,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAE9C;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGpE;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI5D;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAoCrE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EACtD,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAIlE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,OAAO,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAS/D"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/lib/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAKhD,eAAO,MAAM,cAAc,EAAE,SAsB5B,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/lib/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAShD,eAAO,MAAM,cAAc,EAAE,SA2D5B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lsst/pik-plugin-worktree",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Git worktree management plugin for pik CLI",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,10 +27,11 @@
27
27
  "!**/*.tsbuildinfo"
28
28
  ],
29
29
  "dependencies": {
30
- "@lsst/pik-core": "*",
31
30
  "@inquirer/prompts": "^8.1.0",
31
+ "@lsst/pik-core": "*",
32
32
  "commander": "^14.0.2",
33
33
  "glob": "^10.5.0",
34
- "picocolors": "^1.1.1"
34
+ "picocolors": "^1.1.1",
35
+ "simple-git": "^3.30.0"
35
36
  }
36
37
  }