avil13-co 2.2.5 → 2.3.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 CHANGED
@@ -1,40 +1,60 @@
1
1
  # avil13/co
2
2
 
3
- ## Simplest way for use "git checkout"
3
+ Interactive Git branch checkout, merge and deletion.
4
4
 
5
5
  ![demo](assets/cli-demo.gif)
6
6
 
7
- Install:
7
+ ## Install
8
8
 
9
9
  ```sh
10
10
  npm install -g avil13-co
11
11
  ```
12
12
 
13
- Type alias "`co`" for switch branch.
14
-
15
- # Usage
13
+ ## Usage
16
14
 
17
15
  ```sh
18
- # Shows a list of branches that can be switched to
19
- co
16
+ co # Search for a branch and check it out
17
+ co - 1234 # Pre-fill the editable search input with "1234"
18
+ co m # Show merged branches (also: -sm, --show-merged)
19
+ co un # Show unmerged branches (also: -un, --no-merged)
20
+ co -M # Merge a selected branch (also: merge)
21
+ co -D # Delete multiple local branches (also: rm)
22
+ co -h # Show help
20
23
  ```
21
24
 
22
- ```sh
23
- # Shows help message
24
- co -h
25
- ```
25
+ Search is case-insensitive and supports subsequences; special characters are literal.
26
+ Filters also work with commands, for example `co -M - 1234` or `co -D - 1234`.
27
+ For deletion, the initial filter restricts the checkbox list.
26
28
 
27
- ```sh
28
- # Showing merged branches
29
- co m
30
- ```
29
+ ### Delete branches
31
30
 
32
- ```sh
33
- # Showing not merged branches
34
- co un
35
- ```
31
+ Use **Space** to select branches, then **Enter** to confirm the selection.
32
+ A separate confirmation defaults to **No**. Only local branches are listed;
33
+ the current branch is excluded. Like Git's `-D`, this explicitly requested
34
+ operation can delete unmerged branches. Failures are reported per branch,
35
+ without skipping the remaining selections.
36
+
37
+ ### Merge
38
+
39
+ After a successful, confirmed merge, `co` offers to delete the source branch
40
+ with **Yes** as the default (`[Y/n]`). This uses safe deletion (`git branch -d`),
41
+ not forced deletion. Remote-only branches are not offered for deletion.
42
+ A failed merge never triggers the deletion question.
43
+
44
+ ### Cancel and errors
45
+
46
+ **Ctrl+C** exits with code 130 and restores the previous terminal screen,
47
+ removing this session's interactive output. Completed Git operations are not
48
+ rolled back. On normal completion, command results remain visible.
49
+ Screen switching is only enabled in an interactive terminal.
50
+
51
+ Git errors are printed without an unhandled rejection and return exit code 1.
52
+ Git is invoked directly, without shell interpolation of branch names.
53
+
54
+ ## Development
36
55
 
37
56
  ```sh
38
- # Choosing a branch to delete
39
- co -D
57
+ npm test
58
+ npm run type-check
59
+ npm run build
40
60
  ```
package/dist/ask.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export declare const ask: (message: string, choices: string[]) => Promise<{
2
- branch: any;
1
+ export declare const ask: (message: string, choices: string[], initialFilter?: string) => Promise<{
2
+ branch: string;
3
3
  }>;
4
+ export declare function askBranches(message: string, choices: string[], filter?: string): Promise<string[]>;
4
5
  export declare function checkItem(item: string, filterString: string): boolean;
5
- export declare function sortOrder(searchString: string, name1: string, name2: string): -1 | 1;
6
+ export declare function sortOrder(searchString: string, name1: string, name2: string): number;
package/dist/ask.js CHANGED
@@ -3,50 +3,72 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.sortOrder = exports.checkItem = exports.ask = void 0;
6
+ exports.sortOrder = exports.checkItem = exports.askBranches = exports.ask = void 0;
7
7
  const inquirer_1 = __importDefault(require("inquirer"));
8
- inquirer_1.default.registerPrompt('autocomplete', require('inquirer-autocomplete-prompt'));
9
- const specSymbols = {
10
- _saveCursor: '\x1b7',
11
- _restoreCursor: '\x1b8',
12
- _clear: '\x1b[H\x1b[2J',
13
- };
14
- const ask = async (message, choices) => {
15
- const prompt = inquirer_1.default.prompt({
16
- //@ts-ignore
8
+ const prompt_1 = require("./prompt");
9
+ const AutocompletePrompt = require('inquirer-autocomplete-prompt');
10
+ class FilteredAutocompletePrompt extends AutocompletePrompt {
11
+ _run(callback) {
12
+ // `default` in the plugin selects a choice, it does not fill the input.
13
+ const filter = this.opt.initialFilter || '';
14
+ this.rl.line = filter;
15
+ this.rl.cursor = filter.length;
16
+ return super._run(callback);
17
+ }
18
+ }
19
+ inquirer_1.default.registerPrompt('autocomplete', FilteredAutocompletePrompt);
20
+ const ask = async (message, choices, initialFilter = '') => {
21
+ return (0, prompt_1.prompt)({
17
22
  type: 'autocomplete',
18
23
  name: 'branch',
19
24
  message,
20
- source(answersSoFar, input = '') {
21
- let list = choices.filter(choiceItem => checkItem(choiceItem, input));
22
- list = list.sort((a, b) => {
23
- return sortOrder(input, a, b);
24
- });
25
- return Promise.resolve(list);
26
- }
25
+ initialFilter,
26
+ source(_answers, input = initialFilter) {
27
+ return Promise.resolve(choices
28
+ .filter(choice => checkItem(choice, input))
29
+ .sort((a, b) => sortOrder(input, a, b)));
30
+ },
27
31
  });
28
- return prompt;
29
32
  };
30
33
  exports.ask = ask;
31
- //
34
+ async function askBranches(message, choices, filter = '') {
35
+ const filtered = choices.filter(choice => checkItem(choice, filter));
36
+ if (!filtered.length)
37
+ throw new Error('No branches match the filter.');
38
+ const { branches } = await (0, prompt_1.prompt)({
39
+ type: 'checkbox',
40
+ name: 'branches',
41
+ message,
42
+ choices: filtered,
43
+ validate: (selected) => selected.length > 0 || 'Select at least one branch.',
44
+ });
45
+ return branches;
46
+ }
47
+ exports.askBranches = askBranches;
32
48
  function checkItem(item, filterString) {
33
- const reg = getRegExp(filterString);
34
- return reg.test(item);
49
+ // Literal, case-insensitive subsequence matching; no user-supplied regex.
50
+ const needle = filterString.replace(/\s/g, '').toLowerCase();
51
+ const haystack = item.toLowerCase();
52
+ let position = 0;
53
+ for (const character of needle) {
54
+ position = haystack.indexOf(character, position);
55
+ if (position === -1)
56
+ return false;
57
+ position++;
58
+ }
59
+ return true;
35
60
  }
36
61
  exports.checkItem = checkItem;
37
62
  function sortOrder(searchString, name1, name2) {
38
- if (!name1.includes(searchString)) {
63
+ const search = searchString.toLowerCase();
64
+ const first = name1.toLowerCase().indexOf(search);
65
+ const second = name2.toLowerCase().indexOf(search);
66
+ if (first === second)
67
+ return 0;
68
+ if (first === -1)
39
69
  return 1;
40
- }
41
- if (!name2.includes(searchString)) {
70
+ if (second === -1)
42
71
  return -1;
43
- }
44
- if ((name2.indexOf(searchString) < name1.indexOf(searchString))) {
45
- return 1;
46
- }
47
- return -1;
72
+ return first - second;
48
73
  }
49
74
  exports.sortOrder = sortOrder;
50
- function getRegExp(filterString) {
51
- return new RegExp(filterString.split('').map(s => s.trim()).filter(Boolean).join('.*').replace('.*.*', '.*'), 'gi');
52
- }
@@ -6,5 +6,9 @@ export declare enum Commands {
6
6
  ShowMerged = 8,
7
7
  ShowUnMerged = 16
8
8
  }
9
- export declare const getWishOfUser: (firstArg?: string | undefined) => Commands;
9
+ export declare const getWishOfUser: (firstArg?: string) => Commands;
10
+ export declare function parseArgs(args?: string[]): {
11
+ command: Commands;
12
+ filter: string;
13
+ };
10
14
  export declare const getHelp: () => string;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getHelp = exports.getWishOfUser = exports.Commands = void 0;
4
- const args = process.argv.slice(2);
3
+ exports.getHelp = exports.parseArgs = exports.getWishOfUser = exports.Commands = void 0;
5
4
  var Commands;
6
5
  (function (Commands) {
7
6
  Commands[Commands["Unknown"] = 0] = "Unknown";
@@ -11,45 +10,46 @@ var Commands;
11
10
  Commands[Commands["ShowMerged"] = 8] = "ShowMerged";
12
11
  Commands[Commands["ShowUnMerged"] = 16] = "ShowUnMerged";
13
12
  })(Commands = exports.Commands || (exports.Commands = {}));
14
- ;
15
- const getWishOfUser = (firstArg) => {
16
- const arg = firstArg || args[0];
17
- switch (true) {
18
- case ['help', '-h', '--h', '--help'].includes(arg):
19
- return Commands.Help;
20
- case ['-M', 'merge'].includes(arg):
21
- return Commands.MergeBranch;
22
- case ['-D', 'rm'].includes(arg):
23
- return Commands.DeleteBranch;
24
- case ['-sm', '--show-merged'].includes(arg):
25
- return Commands.ShowMerged;
26
- case ['-un', '--no-merged'].includes(arg):
27
- return Commands.ShowUnMerged;
28
- default:
29
- return Commands.Unknown;
30
- }
13
+ const getWishOfUser = (firstArg = process.argv[2]) => {
14
+ if (['help', '-h', '--h', '--help'].includes(firstArg))
15
+ return Commands.Help;
16
+ if (['-M', 'merge'].includes(firstArg))
17
+ return Commands.MergeBranch;
18
+ if (['-D', 'rm'].includes(firstArg))
19
+ return Commands.DeleteBranch;
20
+ if (['m', '-sm', '--show-merged'].includes(firstArg))
21
+ return Commands.ShowMerged;
22
+ if (['un', '-un', '--no-merged'].includes(firstArg))
23
+ return Commands.ShowUnMerged;
24
+ return Commands.Unknown;
31
25
  };
32
26
  exports.getWishOfUser = getWishOfUser;
33
- const getHelp = () => {
34
- return `
27
+ function parseArgs(args = process.argv.slice(2)) {
28
+ const command = (0, exports.getWishOfUser)(args[0] || '');
29
+ if (!args.length)
30
+ return { command, filter: '' };
31
+ if (command === Commands.Unknown && args[0] !== '-') {
32
+ throw new Error('Unknown option: ' + args[0] + '. Use co --help.');
33
+ }
34
+ const rest = args.slice(1);
35
+ if (rest[0] === '-')
36
+ rest.shift();
37
+ return { command, filter: rest.join(' ') };
38
+ }
39
+ exports.parseArgs = parseArgs;
40
+ const getHelp = () => `
35
41
  DESCRIPTION:
36
- A console program for quickly switching between branches
37
-
38
- OPTIONS:
39
- help, -h, --h, --help
40
- Showing this message
42
+ Quickly switch, merge and delete Git branches.
41
43
 
42
- -M, merge
43
- Merge branch
44
+ USAGE:
45
+ co Select a branch to check out
46
+ co - 1234 Start with an editable search filter
47
+ co -M [- filter] Merge, then offer to delete the source branch [Y/n]
48
+ co -D [- filter] Delete multiple local branches (Space to select)
49
+ co m, -sm, --show-merged Show merged branches
50
+ co un, -un, --no-merged Show unmerged branches
51
+ co help, -h, --h, --help Show this message
44
52
 
45
- -sm, --show-merged
46
- Showing merged branches
47
-
48
- -un, --no-merged
49
- Showing not merged branches
50
-
51
- -D, rm
52
- Delete the selected branch
53
+ Ctrl+C cancels and restores the previous terminal screen.
53
54
  `;
54
- };
55
55
  exports.getHelp = getHelp;
@@ -2,15 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkoutBranch = void 0;
4
4
  const exec_1 = require("./exec");
5
- const color_1 = require("../color");
6
- //
5
+ const terminal_1 = require("../terminal");
7
6
  async function checkoutBranch(branchName) {
8
- if (!branchName) {
9
- throw new Error('No branch...');
10
- }
11
- const checkoutCommand = `git checkout ${branchName}`;
12
- console.log(' ' + color_1.clc.green('git checkout', branchName) + '\n');
13
- const checkoutCommandResult = await (0, exec_1.exec)(checkoutCommand);
14
- console.log(checkoutCommandResult);
7
+ if (!branchName)
8
+ throw new Error('No branch selected.');
9
+ (0, terminal_1.print)('git checkout ' + branchName);
10
+ (0, terminal_1.print)(await (0, exec_1.exec)(['checkout', branchName, '--']));
15
11
  }
16
12
  exports.checkoutBranch = checkoutBranch;
@@ -1 +1,2 @@
1
+ export declare function deleteBranches(branchNames: string[], confirm?: boolean, force?: boolean): Promise<void>;
1
2
  export declare function deleteBranch(branchName: string): Promise<void>;
@@ -1,30 +1,41 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.deleteBranch = void 0;
7
- const inquirer_1 = __importDefault(require("inquirer"));
3
+ exports.deleteBranch = exports.deleteBranches = void 0;
4
+ const prompt_1 = require("../prompt");
8
5
  const exec_1 = require("./exec");
9
- const color_1 = require("../color");
10
- async function deleteBranch(branchName) {
11
- if (!branchName) {
12
- throw new Error('No branch...');
6
+ const terminal_1 = require("../terminal");
7
+ async function deleteBranches(branchNames, confirm = true, force = true) {
8
+ const branches = [...new Set(branchNames)];
9
+ if (!branches.length || branches.some(branch => !branch)) {
10
+ throw new Error('No branches selected.');
11
+ }
12
+ if (confirm) {
13
+ const { answer } = await (0, prompt_1.prompt)({
14
+ type: 'confirm',
15
+ name: 'answer',
16
+ message: 'Delete these branches: ' + branches.join(', ') + '?',
17
+ default: false,
18
+ });
19
+ if (!answer) {
20
+ (0, terminal_1.print)('Branches were not deleted.');
21
+ return;
22
+ }
13
23
  }
14
- const res = await inquirer_1.default.prompt({
15
- type: 'confirm',
16
- name: 'answer',
17
- message: color_1.clc.yellow('Are you sure you want to delete the branch "') + color_1.clc.red(branchName) + color_1.clc.yellow('"?'),
18
- default: false,
19
- });
20
- if (res.answer === true) {
21
- const command = `git branch -D ${branchName}`;
22
- console.log(' ' + color_1.clc.redBg(`git branch -D ${branchName}`, '') + '\n');
23
- const checkoutCommandResult = await (0, exec_1.exec)(command);
24
- console.log(checkoutCommandResult);
25
- console.log(color_1.clc.yellow('Branch'), color_1.clc.red(branchName), color_1.clc.yellow('has been deleted'));
26
- return;
24
+ // Attempt every selected branch and report partial failures as well.
25
+ const errors = [];
26
+ for (const branch of branches) {
27
+ try {
28
+ (0, terminal_1.print)(await (0, exec_1.exec)(['branch', force ? '-D' : '-d', '--', branch]));
29
+ }
30
+ catch (error) {
31
+ errors.push(branch + ': ' + (error instanceof Error ? error.message : String(error)));
32
+ }
27
33
  }
28
- console.log(color_1.clc.yellow('The branch was not deleted'));
34
+ if (errors.length)
35
+ throw new Error(errors.join('\n'));
36
+ }
37
+ exports.deleteBranches = deleteBranches;
38
+ async function deleteBranch(branchName) {
39
+ return deleteBranches([branchName]);
29
40
  }
30
41
  exports.deleteBranch = deleteBranch;
@@ -1 +1 @@
1
- export declare function exec(command: any): Promise<string>;
1
+ export declare function exec(args: string[]): Promise<string>;
@@ -2,7 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.exec = void 0;
4
4
  const child_process_1 = require("child_process");
5
- function exec(command) {
6
- return new Promise((resolve, reject) => (0, child_process_1.exec)(command, (err, stdout) => err ? reject(err) : resolve(stdout)));
5
+ function exec(args) {
6
+ return new Promise((resolve, reject) => {
7
+ (0, child_process_1.execFile)('git', args, (error, stdout, stderr) => {
8
+ if (error) {
9
+ reject(new Error([stderr.trim(), stdout.trim()].filter(Boolean).join('\n') || error.message));
10
+ }
11
+ else {
12
+ resolve([stdout.trimEnd(), stderr.trimEnd()].filter(Boolean).join('\n'));
13
+ }
14
+ });
15
+ });
7
16
  }
8
17
  exports.exec = exec;
@@ -3,7 +3,5 @@ export declare enum BranchesType {
3
3
  Merged = 1,
4
4
  NotMerged = 2
5
5
  }
6
- /**
7
- * get branch list
8
- */
9
- export declare function getBranches(type: BranchesType): Promise<string[]>;
6
+ /** Remote origin refs are also offered for checkout/merge; deletion is local only. */
7
+ export declare function getBranches(type: BranchesType, localOnly?: boolean): Promise<string[]>;
@@ -8,40 +8,23 @@ var BranchesType;
8
8
  BranchesType[BranchesType["Merged"] = 1] = "Merged";
9
9
  BranchesType[BranchesType["NotMerged"] = 2] = "NotMerged";
10
10
  })(BranchesType = exports.BranchesType || (exports.BranchesType = {}));
11
- const commandsForGetBranches = {
12
- [BranchesType.All]: 'git branch --all',
13
- [BranchesType.Merged]: 'git branch --all --merged',
14
- [BranchesType.NotMerged]: 'git branch --all --no-merged',
15
- };
16
- /**
17
- * get branch list
18
- */
19
- function getBranches(type) {
20
- const command = commandsForGetBranches[type];
21
- return (0, exec_1.exec)(command)
22
- .then(parseBranches)
23
- .then(branches => {
24
- if (branches.length) {
25
- return branches;
26
- }
27
- throw new Error('No branches found...');
28
- });
11
+ /** Remote origin refs are also offered for checkout/merge; deletion is local only. */
12
+ async function getBranches(type, localOnly = false) {
13
+ const args = ['branch', '--format=%(refname)'];
14
+ if (!localOnly)
15
+ args.push('--all');
16
+ if (type === BranchesType.Merged)
17
+ args.push('--merged');
18
+ if (type === BranchesType.NotMerged)
19
+ args.push('--no-merged');
20
+ const stdout = await (0, exec_1.exec)(args);
21
+ const branches = [...new Set(stdout.split('\n')
22
+ .map(name => name.trim())
23
+ .filter(name => name && !/^refs\/remotes\/.+\/HEAD$/.test(name))
24
+ .map(name => name.replace(/^refs\/heads\//, '')
25
+ .replace(/^refs\/remotes\/(?:origin\/)?/, '')))];
26
+ if (!branches.length)
27
+ throw new Error('No branches found.');
28
+ return branches;
29
29
  }
30
30
  exports.getBranches = getBranches;
31
- function parseBranches(stdout) {
32
- return stdout
33
- .split('\n')
34
- .filter(s => !/\s->\s/.test(s))
35
- .map(cleanBranchName)
36
- .filter(Boolean)
37
- .filter(onlyUnique);
38
- }
39
- function cleanBranchName(name) {
40
- return name
41
- .replace(/^\*/, '')
42
- .replace(/remotes\/origin\//, '')
43
- .trim();
44
- }
45
- function onlyUnique(value, index, self) {
46
- return self.indexOf(value) === index;
47
- }
@@ -1 +1 @@
1
- export declare function getCurrentBranchName(): Promise<void>;
1
+ export declare function getCurrentBranchName(): Promise<string>;
@@ -3,8 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCurrentBranchName = void 0;
4
4
  const exec_1 = require("./exec");
5
5
  async function getCurrentBranchName() {
6
- const currentBranchName = `git rev-parse --abbrev-ref HEAD`;
7
- const stdout = await (0, exec_1.exec)(currentBranchName);
8
- console.log(stdout);
6
+ return (await (0, exec_1.exec)(['rev-parse', '--abbrev-ref', 'HEAD'])).trim();
9
7
  }
10
8
  exports.getCurrentBranchName = getCurrentBranchName;
@@ -1,44 +1,40 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.mergeBranch = void 0;
7
4
  const exec_1 = require("./exec");
8
- const color_1 = require("../color");
9
- const inquirer_1 = __importDefault(require("inquirer"));
10
- //
5
+ const get_current_branch_name_1 = require("./get-current-branch-name");
6
+ const delete_barnch_1 = require("./delete-barnch");
7
+ const terminal_1 = require("../terminal");
8
+ const prompt_1 = require("../prompt");
11
9
  async function mergeBranch(branchName) {
12
- if (!branchName) {
13
- throw new Error('No branch...');
14
- }
15
- const currentBranch = await (0, exec_1.exec)('git rev-parse --abbrev-ref HEAD');
16
- const message = [
17
- color_1.clc._blue,
18
- 'Do you want to merge branch ',
19
- color_1.clc._green,
20
- branchName,
21
- color_1.clc._blue,
22
- ' into ',
23
- color_1.clc._green,
24
- currentBranch,
25
- color_1.clc._blue,
26
- '?',
27
- color_1.clc._off,
28
- ].join('');
29
- const res = await inquirer_1.default.prompt({
10
+ if (!branchName)
11
+ throw new Error('No branch selected.');
12
+ const currentBranch = await (0, get_current_branch_name_1.getCurrentBranchName)();
13
+ if (branchName === currentBranch)
14
+ throw new Error('Cannot merge the current branch into itself.');
15
+ const { answer } = await (0, prompt_1.prompt)({
30
16
  type: 'confirm',
31
17
  name: 'answer',
32
- message,
18
+ message: 'Merge branch ' + branchName + ' into ' + currentBranch + '?',
33
19
  default: false,
34
20
  });
35
- if (res.answer === true) {
36
- const checkoutCommand = `git merge ${branchName}`;
37
- console.log(' ' + color_1.clc.green('git merge', branchName) + '\n');
38
- const checkoutCommandResult = await (0, exec_1.exec)(checkoutCommand);
39
- console.log(checkoutCommandResult);
21
+ if (!answer) {
22
+ (0, terminal_1.print)('Branch was not merged.');
40
23
  return;
41
24
  }
42
- console.log(color_1.clc.yellow('The branch was not merged'));
25
+ (0, terminal_1.print)('git merge ' + branchName);
26
+ (0, terminal_1.print)(await (0, exec_1.exec)(['merge', '--', branchName]));
27
+ // Only local branches can be deleted; never remove remote refs.
28
+ const locals = (await (0, exec_1.exec)(['for-each-ref', '--format=%(refname)', 'refs/heads/'])).split('\n');
29
+ if (!locals.includes('refs/heads/' + branchName))
30
+ return;
31
+ const { remove } = await (0, prompt_1.prompt)({
32
+ type: 'confirm',
33
+ name: 'remove',
34
+ message: 'Delete merged branch ' + branchName + '?',
35
+ default: true,
36
+ });
37
+ if (remove)
38
+ await (0, delete_barnch_1.deleteBranches)([branchName], false, false);
43
39
  }
44
40
  exports.mergeBranch = mergeBranch;
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export {};
1
+ export declare const run: () => Promise<void>;