abt 2.0.0 → 3.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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npm -v)"
5
+ ]
6
+ }
7
+ }
@@ -0,0 +1,117 @@
1
+ # Copilot Instructions
2
+
3
+ ## Design Direction
4
+
5
+ If this is a UI project, and if you must make UX decisions...
6
+
7
+ The visual language is ultra-flat and ultra-premium: no shadows, no gradients. Depth and hierarchy come entirely from background colors (surfaces), borders, white space, typography, font colors, and accent colors. The result should feel like it was designed by the top designers at Figma, Stripe, or Google — calm, confident, precise.
8
+
9
+ When you encounter a component or element that has not yet been styled, style it to that standard. Make it world-class gorgeous. But stay inside the system: do not introduce shadows, gradients, or any design ideas that conflict with the flat, premium feel described above.
10
+
11
+ All styling is custom CSS. Every value comes from the design tokens defined in `ink.css`, when present. When `ink.css` is present, never hardcode colors, spacing, radii, shadows, or typography values unless they are not in `ink.css` and need to be. Each component has a sibling CSS file, and class names are kebab-case with no underscores. Avoid inline styles unless explicitly required.
12
+
13
+ ## Agent Behavior
14
+
15
+ Do not run build, lint, typecheck, or test commands unless explicitly asked. Do the dev work; I handle validation. You may clean up code adjacent to code you touch if it doesn't follow these rules.
16
+
17
+ ## Core Principle
18
+
19
+ Optimize for low cognitive load, not fewer lines. Every meaningful computation gets a descriptive variable name. Code should read top-to-bottom like a sequence of short, clear sentences — explicit, flat, and difficult to misinterpret. Eliminate questions for the next maintainer; never make them mentally unpack nested logic, dense conditionals, or clever inline expressions.
20
+
21
+ ## Control Flow
22
+
23
+ Keep code flat. Use early returns instead of `else` or `else if` — those keywords never appear in this codebase. Avoid nesting; the next maintainer should rarely go more than one block deep. Never put logic inside conditional parentheses — compute the condition first, name it, then test the name. One-line `if` bodies omit braces; multi-line bodies use them. Never use `while` loops or `for i++` loops; use `for...of` or simple `map`/`filter`/`find`. Avoid dense collection chains and `reduce` unless it's clearly the most readable option.
24
+
25
+ ```ts
26
+ const getLabel = (count: number): string => {
27
+ const isEmpty = count === 0
28
+ if (isEmpty) return 'No items'
29
+
30
+ const isSingle = count === 1
31
+ if (isSingle) return 'One item'
32
+
33
+ return `${count} items`
34
+ }
35
+ ```
36
+
37
+ ## Functions
38
+
39
+ Arrow functions only — never the `function` keyword, never classes. Always use block bodies with explicit `return`; no implicit arrow returns. Prefer small, modular functions with narrow concerns: a 15-line function that pushes data through a series of small named functions beats one 80-line function.
40
+
41
+ ## Variables Over Inline Logic
42
+
43
+ Never embed meaningful logic in JSX, return statements, function arguments, or conditions. Compute first, name the result, use the name.
44
+
45
+ ```ts
46
+ const hasItems = cart.items.length > 0
47
+ const isCheckoutEnabled = hasItems && isUserLoggedIn
48
+ const buttonLabel = isCheckoutEnabled ? 'Checkout' : 'Add items to cart'
49
+ ```
50
+
51
+ Ternaries are allowed only when simple and assigned to a named variable. Never nest ternaries.
52
+
53
+ ## Naming
54
+
55
+ Keystrokes are free — never abbreviate. Booleans begin with an interrogative (`is`, `has`, `can`, `should`, `was`, `will`, `does`) so they read like questions. Functions begin with a verb (`get`, `check`, `build`, `validate`, `handle`). Never use `e`, `evt`, `i`, `idx`, `err`, `res`, `req`, `cfg`, `fn`, or similar. Avoid vague names like `data`, `item`, or `temp` unless context makes the meaning completely obvious. Prefer domain-specific names.
56
+
57
+ ## TypeScript
58
+
59
+ Use `type`, never `interface`. Suffix all custom type names with `T`. Never use `enum` — use `as const` objects:
60
+
61
+ ```ts
62
+ const UserStatus = {
63
+ active: 'active',
64
+ inactive: 'inactive'
65
+ } as const
66
+
67
+ type UserStatusT = (typeof UserStatus)[keyof typeof UserStatus]
68
+ ```
69
+
70
+ Prefer precise types, avoid `any`, avoid assertions, and use type-only imports for types. Avoid generic abstractions unless they materially improve clarity.
71
+
72
+ ## Destructuring
73
+
74
+ Never destructure function parameters or component props. Instead, access their values through their source reference with dot notation. This preserves source context and makes relationships obvious.
75
+
76
+ ```ts
77
+ const createUser = (input: CreateUserInputT): UserT => {
78
+ const displayName = `${input.firstName} ${input.lastName}`
79
+ return { id: crypto.randomUUID(), firstName: input.firstName, displayName }
80
+ }
81
+ ```
82
+
83
+ ## React
84
+
85
+ Function components only, narrow responsibility, shallow render logic. Access everything through `props` with dot notation, not destructuring. Compute all named values before the JSX. No business logic, inline computation, nested conditional rendering, or large anonymous functions inside markup. Extract small components when JSX becomes hard to scan.
86
+
87
+ ```tsx
88
+ type SubmitButtonPropsT = {
89
+ isFormValid: boolean
90
+ isSubmitting: boolean
91
+ }
92
+
93
+ const SubmitButton = (props: SubmitButtonPropsT) => {
94
+ const canSubmit = props.isFormValid && !props.isSubmitting
95
+ const buttonLabel = props.isSubmitting ? 'Submitting...' : 'Submit'
96
+
97
+ return (
98
+ <button className='submit-button' disabled={!canSubmit}>
99
+ {buttonLabel}
100
+ </button>
101
+ )
102
+ }
103
+ ```
104
+
105
+ Prefer `datass` for shared state and `useDatass` for local component state instead of reaching for `useState`. Do not use React Context for shared application state unless explicitly required.
106
+
107
+ ## Async and Errors
108
+
109
+ Keep async code flat. Prefer `await` over promise chains, name results and errors descriptively, and return early on failure. Never swallow errors silently, and avoid broad catches unless the function can handle the error meaningfully.
110
+
111
+ ## Comments
112
+
113
+ Use comments sparingly — names and structure should explain the code. Comment only for intent, constraints, or non-obvious behavior. Place a comment before a function if its complexity isn't obvious from the name. Use `//` single-line comments only, never `/* */`, broken at roughly 60 characters per line.
114
+
115
+ ## Checklist
116
+
117
+ Before finalizing, verify the code: uses arrow functions with explicit returns; uses `type` with `T` suffixes and `as const` objects instead of enums; no `else`/`else if`, no `while` or `for i++` loops, no classes; names every meaningful computation; abbreviates nothing, camelCase class names, sibling CSS files.
package/README.md CHANGED
@@ -1,23 +1,29 @@
1
- # abt
2
-
3
- > A tool that makes it simple as fuck to find and execute npm scripts.
4
-
5
- ```sh
6
- npm i -g abt
7
- ```
8
-
9
- ## Usage
10
-
11
- ```sh
12
- abt
13
- ```
14
-
15
- abt will show you a list of your scripts and allow you to run them. That is all there is to it.
16
-
17
- ![example](https://cdn.rawgit.com/colshacol/abt/332691ed/example.png)
18
-
19
- ### Notes
20
-
21
- _abt is not guaranteed to work on Node < 8.1_
22
-
23
- _and don't even get me started on all the things I don't guarantee about Windows_
1
+ # abt
2
+
3
+ CLI tool to list, select, and execute npm scripts. (Cross platform.)
4
+
5
+ ```sh
6
+ npm i -g abt
7
+ ```
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ abt
13
+ ```
14
+
15
+ abt will show you a list of your scripts and allow you to run them. That is all there is to it.
16
+
17
+ ![example](https://cdn.rawgit.com/colshacol/abt/332691ed/example.png)
18
+
19
+ ## Changelog
20
+
21
+ ### 3.0.0 (06/28/2026)
22
+
23
+ Redid the whole thing because turns out it didn't actually work
24
+ on Windows after all. But now it damn sure does.
25
+
26
+ ### 2.0.0 (03/29/2025)
27
+
28
+ Updated so it should work on Windows, Mac, Linux, whatever.
29
+ Removed a ton of dependencies. Reduced codebase by like a billion times.
package/bin/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/bin/index.js CHANGED
@@ -1,36 +1,106 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
-
4
- var _ink = _interopRequireWildcard(require("ink"));
5
-
6
- var _yargs = _interopRequireDefault(require("yargs"));
7
-
8
- var _Provider = require("./components/Provider");
9
-
10
- var _App = require("./components/App");
11
-
12
- var _handleArgs = require("./utilities/handleArgs");
13
-
14
- var _child_process = require("child_process");
15
-
16
- var _yargs$argv;
17
-
18
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
-
20
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
21
-
22
- let unmount;
23
-
24
- const onExit = scriptName => {
25
- unmount();
26
- (0, _child_process.spawnSync)(`npm`, ['run', scriptName], {
27
- cwd: process.cwd(),
28
- env: process.env,
29
- stdio: [0, 0, process.stderr]
30
- });
31
- };
32
-
33
- unmount = _ink.default.render((0, _ink.h)(_App.App, {
34
- onExit: onExit,
35
- appVars: (_yargs$argv = _yargs.default.argv, (0, _handleArgs.handleArgs)(_yargs$argv))
36
- }));
2
+ import path from 'node:path';
3
+ import fs from 'node:fs';
4
+ import inquirer from 'inquirer';
5
+ import findPkg from 'find-pkg';
6
+ import { execa } from 'execa';
7
+ const pkgPath = await findPkg(process.cwd());
8
+ if (!pkgPath) {
9
+ console.error('abt: no package.json found in this directory or any parent.');
10
+ process.exit(1);
11
+ }
12
+ const pkgString = fs.readFileSync(pkgPath, 'utf-8');
13
+ const pkg = JSON.parse(pkgString);
14
+ const PackageManager = {
15
+ npm: 'npm',
16
+ pnpm: 'pnpm',
17
+ yarn: 'yarn',
18
+ bun: 'bun'
19
+ };
20
+ const dim = (text) => {
21
+ return `${text}`;
22
+ };
23
+ // Choose the package manager the project actually uses so the
24
+ // selected script runs the way the author intended.
25
+ const detectPackageManager = (projectDir) => {
26
+ const hasPnpmLock = fs.existsSync(path.join(projectDir, 'pnpm-lock.yaml'));
27
+ if (hasPnpmLock)
28
+ return PackageManager.pnpm;
29
+ const hasYarnLock = fs.existsSync(path.join(projectDir, 'yarn.lock'));
30
+ if (hasYarnLock)
31
+ return PackageManager.yarn;
32
+ const hasBunLock = fs.existsSync(path.join(projectDir, 'bun.lockb'));
33
+ if (hasBunLock)
34
+ return PackageManager.bun;
35
+ return PackageManager.npm;
36
+ };
37
+ // Align the command after each name into a tidy second column.
38
+ const buildScriptChoices = (scriptsByName) => {
39
+ const scriptNames = Object.keys(scriptsByName);
40
+ const nameLengths = scriptNames.map(scriptName => scriptName.length);
41
+ const longestNameLength = Math.max(...nameLengths);
42
+ const columnWidth = longestNameLength + 4;
43
+ return scriptNames.map(scriptName => {
44
+ const command = scriptsByName[scriptName];
45
+ const padding = ' '.repeat(columnWidth - scriptName.length);
46
+ const label = `${scriptName}${padding}${dim(command)}`;
47
+ return { name: label, value: scriptName };
48
+ });
49
+ };
50
+ const promptForScript = async (choices) => {
51
+ const answer = await inquirer.prompt([
52
+ {
53
+ type: 'list',
54
+ name: 'scriptName',
55
+ message: '[ abt ∆ choose a script ]',
56
+ choices,
57
+ pageSize: 12,
58
+ loop: false
59
+ }
60
+ ]);
61
+ return answer.scriptName;
62
+ };
63
+ // Run the script with inherited stdio so the child process owns
64
+ // the terminal completely — prompts and colored output all work.
65
+ const runScript = async (scriptName) => {
66
+ const projectDir = path.dirname(pkgPath);
67
+ const packageManager = detectPackageManager(projectDir);
68
+ console.log(dim(`\n› ${packageManager} run ${scriptName}\n`));
69
+ const result = await execa(packageManager, ['run', scriptName], {
70
+ cwd: projectDir,
71
+ stdio: 'inherit',
72
+ reject: false
73
+ });
74
+ const exitCode = result.exitCode ?? 0;
75
+ process.exit(exitCode);
76
+ };
77
+ const main = async () => {
78
+ const scriptsByName = pkg.scripts ?? {};
79
+ const scriptNames = Object.keys(scriptsByName);
80
+ const hasNoScripts = scriptNames.length === 0;
81
+ if (hasNoScripts) {
82
+ console.log('abt: no scripts found in package.json.');
83
+ process.exit(0);
84
+ }
85
+ const choices = buildScriptChoices(scriptsByName);
86
+ const selectedScript = await promptForScript(choices);
87
+ await runScript(selectedScript);
88
+ };
89
+ // Ctrl+C out of the prompt should exit quietly, not crash.
90
+ const handleError = (error) => {
91
+ const wasCancelled = error instanceof Error && error.name === 'ExitPromptError';
92
+ if (wasCancelled) {
93
+ console.log('');
94
+ process.exit(0);
95
+ }
96
+ const message = error instanceof Error ? error.message : String(error);
97
+ console.error(`abt: ${message}`);
98
+ process.exit(1);
99
+ };
100
+ try {
101
+ await main();
102
+ }
103
+ catch (error) {
104
+ handleError(error);
105
+ }
106
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "abt",
3
- "version": "2.0.0",
4
- "description": "A CLI tool to view and execute npm scripts.",
3
+ "version": "3.0.0",
4
+ "description": "CLI tool to list, select, and run npm scripts.",
5
+ "type": "module",
5
6
  "main": "./bin/index.js",
6
- "repository": "https://github.com/colshacol/abt",
7
- "author": "Colton Colcleasure <colshacol@gmail.com>",
7
+ "repository": "https://github.com/tasteee/abt",
8
+ "author": "Rockie Colcleasure <rokkicolcleasure@gmail.com>",
8
9
  "license": "MIT",
9
10
  "preferGlobal": true,
10
11
  "bin": {
@@ -12,61 +13,19 @@
12
13
  },
13
14
  "scripts": {
14
15
  "start": "node bin",
15
- "test": "test",
16
- "test-error": "fest",
17
- "build": "babel src --out-dir bin",
18
- "precommit": "pretty-quick --staged",
16
+ "build": "tsc",
17
+ "typecheck": "tsc --noEmit",
19
18
  "build-run": "npm run build && npm start"
20
19
  },
21
20
  "devDependencies": {
22
- "@babel/cli": "^7.0.0-beta.41",
23
- "@babel/core": "^7.0.0-beta.42",
24
- "@babel/plugin-proposal-async-generator-functions": "^7.0.0-beta.41",
25
- "@babel/plugin-proposal-class-properties": "^7.0.0-beta.41",
26
- "@babel/plugin-proposal-decorators": "^7.0.0-beta.41",
27
- "@babel/plugin-proposal-do-expressions": "^7.0.0-beta.41",
28
- "@babel/plugin-proposal-export-default-from": "^7.0.0-beta.41",
29
- "@babel/plugin-proposal-export-namespace-from": "^7.0.0-beta.41",
30
- "@babel/plugin-proposal-function-bind": "^7.0.0-beta.41",
31
- "@babel/plugin-proposal-function-sent": "^7.0.0-beta.41",
32
- "@babel/plugin-proposal-logical-assignment-operators": "^7.0.0-beta.41",
33
- "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0-beta.41",
34
- "@babel/plugin-proposal-numeric-separator": "^7.0.0-beta.41",
35
- "@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.42",
36
- "@babel/plugin-proposal-optional-catch-binding": "^7.0.0-beta.41",
37
- "@babel/plugin-proposal-optional-chaining": "^7.0.0-beta.41",
38
- "@babel/plugin-proposal-pipeline-operator": "^7.0.0-beta.41",
39
- "@babel/plugin-proposal-throw-expressions": "^7.0.0-beta.41",
40
- "@babel/plugin-proposal-unicode-property-regex": "^7.0.0-beta.41",
41
- "@babel/plugin-syntax-dynamic-import": "^7.0.0-beta.41",
42
- "@babel/plugin-syntax-import-meta": "^7.0.0-beta.41",
43
- "@babel/plugin-transform-react-jsx": "^7.0.0-beta.42",
44
- "@babel/plugin-transform-spread": "^7.0.0-beta.42",
45
- "@babel/preset-env": "^7.0.0-beta.41",
46
- "@babel/preset-flow": "^7.0.0-beta.42",
47
- "@babel/preset-react": "^7.0.0-beta.41",
48
- "@babel/preset-stage-0": "^7.0.0-beta.41",
49
- "@babel/register": "^7.0.0-beta.41",
50
- "babel-core": "^7.0.0-0",
51
- "babel-jest": "^23.0.0-alpha.0",
52
- "babel-plugin-jsx-control-statements": "^3.2.8",
53
- "flow-bin": "^0.68.0",
54
- "husky": "^0.14.3",
55
- "jest": "^22.4.2",
21
+ "@types/node": "^26.0.1",
56
22
  "prettier": "^1.11.1",
57
- "pretty-quick": "^1.4.1"
23
+ "typescript": "^6.0.3"
58
24
  },
59
25
  "dependencies": {
60
- "arr-rotate": "^1.0.0",
61
- "figures": "^2.0.0",
62
- "ink": "^0.5.0",
63
- "ink-spaces": "^0.0.1",
64
- "ink-spinner": "^2.0.0",
65
- "is-empty": "^1.2.0",
66
- "lodash.isequal": "^4.5.0",
67
- "prettyjson": "^1.2.1",
68
- "regenerator-runtime": "^0.12.0",
69
- "shelljs": "^0.8.2",
70
- "yargs": "^12.0.0"
26
+ "@types/find-pkg": "^2.0.0",
27
+ "execa": "^9.6.1",
28
+ "find-pkg": "^2.0.0",
29
+ "inquirer": "^12.5.0"
71
30
  }
72
31
  }
package/tsconfig.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "compilerOptions": {
3
+ /* Language & environment */
4
+ "target": "ES2022",
5
+ "lib": ["ES2022"],
6
+ "types": ["node"],
7
+
8
+ /* Modules (ESM, Node-native resolution) */
9
+ "module": "NodeNext",
10
+ "moduleResolution": "NodeNext",
11
+ "resolveJsonModule": true,
12
+
13
+ /* Emit */
14
+ "rootDir": "src",
15
+ "outDir": "bin",
16
+ "declaration": true,
17
+ "sourceMap": true,
18
+ "removeComments": false,
19
+
20
+ /* Interop */
21
+ "esModuleInterop": true,
22
+ "allowSyntheticDefaultImports": true,
23
+ "forceConsistentCasingInFileNames": true,
24
+
25
+ /* Type checking */
26
+ "strict": true,
27
+ "noUnusedLocals": true,
28
+ "noUnusedParameters": true,
29
+ "noFallthroughCasesInSwitch": true,
30
+ "skipLibCheck": true
31
+ },
32
+ "include": ["src/**/*"],
33
+ "exclude": ["node_modules", "bin"]
34
+ }
@@ -1,104 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.App = void 0;
5
-
6
- var _ink = _interopRequireWildcard(require("ink"));
7
-
8
- var _inkSpaces = require("ink-spaces");
9
-
10
- var _inkSpinner = _interopRequireDefault(require("ink-spinner"));
11
-
12
- var _isEmpty = _interopRequireDefault(require("is-empty"));
13
-
14
- var _SelectInput = _interopRequireDefault(require("./SelectInput"));
15
-
16
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
-
18
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
19
-
20
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
21
-
22
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
23
-
24
- const generateScriptItems = scripts => {
25
- const scriptPairs = Object.entries(scripts);
26
- const sortedByNameLength = scriptPairs.sort((a, b) => {
27
- return a[0].length < b[0].length;
28
- });
29
- const totalNameLength = sortedByNameLength[0][0].length + 5;
30
- const items = scriptPairs.reduce((final, [name, script]) => {
31
- const stringLength = totalNameLength - name.length;
32
- const x = Array(stringLength < 0 ? 5 : stringLength).fill(' ').join('');
33
- const item = {
34
- name: name + x,
35
- script
36
- };
37
- final.push(item);
38
- return final;
39
- }, []);
40
- return items.sort((a, b) => {
41
- return a.name[0] > b.name[0];
42
- });
43
- };
44
-
45
- class App extends _ink.default.Component {
46
- constructor(...args) {
47
- super(...args);
48
-
49
- _defineProperty(this, "state", {});
50
-
51
- _defineProperty(this, "onSelect", item => {
52
- this.props.onExit(item.name.trim());
53
- });
54
- }
55
-
56
- componentDidMount() {
57
- const {
58
- packageJsonPath
59
- } = this.props.appVars;
60
-
61
- const pkg = require(packageJsonPath);
62
-
63
- this.scripts = generateScriptItems(pkg.scripts);
64
- this.setState(_objectSpread({}, pkg));
65
- }
66
-
67
- render(props, state) {
68
- return (0, _ink.h)("div", null, state.EXEC ? (0, _ink.h)(_ink.Color, null) : (0, _isEmpty.default)(state) ? [(0, _ink.h)(_inkSpaces.BlankLines, {
69
- count: 1,
70
- key: "0"
71
- }), (0, _ink.h)(_inkSpinner.default, {
72
- green: true,
73
- key: "1"
74
- }), (0, _ink.h)(_ink.Color, {
75
- key: "2"
76
- }, "Loading scripts.")] : !(0, _isEmpty.default)(state) ? [(0, _ink.h)(_inkSpaces.BlankLines, {
77
- count: 1,
78
- key: "0"
79
- }), (0, _ink.h)(_ink.Color, {
80
- key: "1"
81
- }, "[ abt \u2206 choose a script ]"), (0, _ink.h)(_inkSpaces.BlankLines, {
82
- count: 1,
83
- key: "2"
84
- }), (0, _ink.h)(_inkSpaces.BlankLines, {
85
- count: 1,
86
- key: "3"
87
- }), (0, _ink.h)("div", {
88
- key: "4"
89
- }, (0, _ink.h)(_SelectInput.default, {
90
- items: this.scripts,
91
- onSelect: this.onSelect,
92
- itemComponent: Item
93
- }))] : null);
94
- }
95
-
96
- }
97
-
98
- exports.App = App;
99
-
100
- const Item = props => {
101
- return (0, _ink.h)("span", null, (0, _ink.h)(_ink.Color, {
102
- green: true
103
- }, props.name), (0, _ink.h)(_ink.Color, null, props.script));
104
- };
@@ -1,31 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.Provider = void 0;
5
-
6
- var _ink = require("ink");
7
-
8
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
9
-
10
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
-
12
- function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
13
-
14
- class Provider extends _ink.Component {
15
- render(props, state, context) {
16
- return props.children;
17
- }
18
-
19
- getChildContext() {
20
- const _this$props = this.props,
21
- {
22
- children
23
- } = _this$props,
24
- props = _objectWithoutProperties(_this$props, ["children"]);
25
-
26
- return _objectSpread({}, props);
27
- }
28
-
29
- }
30
-
31
- exports.Provider = Provider;
@@ -1,163 +0,0 @@
1
- 'use strict';
2
-
3
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
4
-
5
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
-
7
- const {
8
- h,
9
- Color,
10
- Component
11
- } = require('ink');
12
-
13
- const PropTypes = require('prop-types');
14
-
15
- const isEqual = require('lodash.isequal');
16
-
17
- const figures = require('figures');
18
-
19
- const arrRotate = require('arr-rotate');
20
-
21
- const noop = () => {};
22
-
23
- const Indicator = ({
24
- isSelected
25
- }) => {
26
- if (!isSelected) {
27
- return ' ';
28
- }
29
-
30
- return h(Color, {
31
- blue: true
32
- }, `${figures.pointer} `);
33
- };
34
-
35
- Indicator.propTypes = {
36
- isSelected: PropTypes.bool.isRequired
37
- };
38
-
39
- const Item = ({
40
- isSelected,
41
- label
42
- }) => h(Color, {
43
- blue: isSelected
44
- }, label);
45
-
46
- Item.propTypes = {
47
- isSelected: PropTypes.bool.isRequired,
48
- label: PropTypes.string.isRequired
49
- };
50
-
51
- class SelectInput extends Component {
52
- constructor(props) {
53
- super(props);
54
- this.state = {
55
- rotateIndex: 0,
56
- selectedIndex: 0
57
- };
58
- this.handleKeyPress = this.handleKeyPress.bind(this);
59
- }
60
-
61
- render({
62
- items,
63
- indicatorComponent,
64
- itemComponent,
65
- limit
66
- }, {
67
- rotateIndex,
68
- selectedIndex
69
- }) {
70
- const slicedItems = typeof limit === 'number' ? arrRotate(items, rotateIndex).slice(0, limit) : items;
71
- return slicedItems.map((item, index) => {
72
- const isSelected = index === selectedIndex;
73
- return h("div", {
74
- key: item.value
75
- }, h(indicatorComponent, {
76
- isSelected
77
- }), h(itemComponent, _objectSpread({}, item, {
78
- isSelected
79
- })));
80
- });
81
- }
82
-
83
- componentDidMount() {
84
- process.stdin.on('keypress', this.handleKeyPress);
85
- }
86
-
87
- componentWillUnmount() {
88
- process.stdin.removeListener('keypress', this.handleKeyPress);
89
- }
90
-
91
- componentWillReceiveProps(nextProps) {
92
- if (!isEqual(this.props.items, nextProps.items)) {
93
- this.setState({
94
- rotateIndex: 0,
95
- selectedIndex: 0
96
- });
97
- }
98
- }
99
-
100
- handleKeyPress(_, key) {
101
- const {
102
- items,
103
- focus,
104
- limit,
105
- onSelect
106
- } = this.props;
107
- const {
108
- rotateIndex,
109
- selectedIndex
110
- } = this.state;
111
- const hasLimit = typeof limit === 'number';
112
-
113
- if (focus === false) {
114
- return;
115
- }
116
-
117
- if (key.name === 'up' || key.name === 'k') {
118
- const lastIndex = (hasLimit ? limit : items.length) - 1;
119
- const atFirstIndex = selectedIndex === 0;
120
- const nextIndex = hasLimit ? selectedIndex : lastIndex;
121
- this.setState({
122
- rotateIndex: atFirstIndex ? rotateIndex + 1 : rotateIndex,
123
- selectedIndex: atFirstIndex ? nextIndex : selectedIndex - 1
124
- });
125
- }
126
-
127
- if (key.name === 'down' || key.name === 'j') {
128
- const atLastIndex = selectedIndex === (hasLimit ? limit : items.length) - 1;
129
- const nextIndex = hasLimit ? selectedIndex : 0;
130
- this.setState({
131
- rotateIndex: atLastIndex ? rotateIndex - 1 : rotateIndex,
132
- selectedIndex: atLastIndex ? nextIndex : selectedIndex + 1
133
- });
134
- }
135
-
136
- if (key.name === 'return') {
137
- const slicedItems = hasLimit ? arrRotate(items, rotateIndex).slice(0, limit) : items;
138
- onSelect(slicedItems[selectedIndex]);
139
- }
140
- }
141
-
142
- }
143
-
144
- SelectInput.propTypes = {
145
- items: PropTypes.array,
146
- focus: PropTypes.bool,
147
- indicatorComponent: PropTypes.func,
148
- itemComponent: PropTypes.func,
149
- limit: PropTypes.number,
150
- onSelect: PropTypes.func
151
- };
152
- SelectInput.defaultProps = {
153
- items: [],
154
- focus: true,
155
- indicatorComponent: Indicator,
156
- itemComponent: Item,
157
- limit: null,
158
- onSelect: noop
159
- };
160
- module.exports = exports = SelectInput; // eslint-disable-line no-multi-assign
161
-
162
- exports.Indicator = Indicator;
163
- exports.Item = Item;
package/bin/consts.js DELETED
@@ -1 +0,0 @@
1
- "use strict";
@@ -1,17 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.handleArgs = void 0;
5
-
6
- const handleArgs = args => {
7
- const _propertyPath = args._[0] || '.scripts';
8
-
9
- const propertyPath = _propertyPath === '.DD' ? 'devDependencies' : _propertyPath === '.PD' ? 'peerDependencies' : _propertyPath === '.D' ? 'dependencies' : _propertyPath === '.V' ? 'version' : _propertyPath.slice(1);
10
- return {
11
- packageJsonPath: `${process.env.PWD}/package.json`,
12
- pwd: process.env.PWD,
13
- propertyPath
14
- };
15
- };
16
-
17
- exports.handleArgs = handleArgs;