quick-sh 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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 YoungChou
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,226 @@
1
+ # Quick Shell
2
+
3
+ [![npm version](https://badge.fury.io/js/@youngchou%2Fquick-sh.svg)](https://badge.fury.io/js/@youngchou%2Fquick-sh)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ A local script management tool for quick execution of JavaScript and Shell scripts with advanced alias support.
7
+
8
+ [中文文档](./README-zh.md) | English
9
+
10
+ ## Features
11
+
12
+ - 🚀 **Quick Execution**: Run local scripts with simple `q script-name` command
13
+ - 📁 **Multiple Formats**: Support JavaScript (.js), Shell scripts (.sh), and directories
14
+ - 🔗 **Advanced Aliases**: Configure custom aliases with relative paths, absolute paths, and system commands
15
+ - 📝 **Parameter Forwarding**: Pass arguments transparently to your scripts
16
+ - 🎯 **Smart Priority**: Alias config > Script files > System commands
17
+ - ⚡ **Global Access**: Install once, use anywhere
18
+ - 🧪 **Comprehensive Testing**: 16 automated test cases ensure reliability
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install -g @youngchou/quick-sh
24
+ ```
25
+
26
+ After installation, you can use the `q` command globally.
27
+
28
+ ## Quick Start
29
+
30
+ ### 1. Set Script Directory
31
+
32
+ ```bash
33
+ # Set your script directory
34
+ q -path /path/to/your/scripts
35
+
36
+ # Check current status
37
+ q -list
38
+ ```
39
+
40
+ ### 2. Run Scripts
41
+
42
+ ```bash
43
+ # Run a JavaScript file
44
+ q myscript
45
+
46
+ # Run a shell script
47
+ q deploy.sh
48
+
49
+ # Run with parameters
50
+ q backup --target /data --compress
51
+
52
+ # Execute directory (looks for index.js or index.sh)
53
+ q myproject
54
+ ```
55
+
56
+ ### 3. Configure Aliases
57
+
58
+ Create or edit `config.json` in your script directory:
59
+
60
+ ```json
61
+ {
62
+ "aliases": {
63
+ "deploy": {
64
+ "bin": "./deploy/index.js"
65
+ },
66
+ "backup": {
67
+ "bin": "/usr/local/bin/backup.sh"
68
+ },
69
+ "start": {
70
+ "bin": "npm start"
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ ## Commands
77
+
78
+ | Command | Description | Example |
79
+ |---------|-------------|---------|
80
+ | `q -path <dir>` | Set script directory | `q -path ~/scripts` |
81
+ | `q -list` | Show current status and available scripts | `q -list` |
82
+ | `q -help` | Display help information | `q -help` |
83
+ | `q <script>` | Execute script or alias | `q deploy` |
84
+
85
+ ## Alias Configuration
86
+
87
+ ### Supported Alias Types
88
+
89
+ 1. **Relative Path**: Relative to script directory
90
+ ```json
91
+ {
92
+ "aliases": {
93
+ "deploy": {"bin": "./deploy/index.js"}
94
+ }
95
+ }
96
+ ```
97
+
98
+ 2. **Absolute Path**: Full system path
99
+ ```json
100
+ {
101
+ "aliases": {
102
+ "backup": {"bin": "/usr/local/bin/backup.sh"}
103
+ }
104
+ }
105
+ ```
106
+
107
+ 3. **System Command**: Execute system commands
108
+ ```json
109
+ {
110
+ "aliases": {
111
+ "list": {"bin": "ls -la"},
112
+ "findnode": {"bin": "which node"}
113
+ }
114
+ }
115
+ ```
116
+
117
+ ### Execution Priority
118
+
119
+ 1. **Alias Configuration** (highest priority)
120
+ 2. **Script Files** (medium priority)
121
+ 3. **System Commands** (lowest priority)
122
+
123
+ ## Parameter Forwarding
124
+
125
+ All parameters are transparently forwarded to target scripts:
126
+
127
+ ```bash
128
+ # These parameters will be passed to the script
129
+ q deploy --env production --verbose
130
+ q backup /data/important --compress
131
+ ```
132
+
133
+ In your script, access parameters normally:
134
+ - **JavaScript**: `process.argv`
135
+ - **Shell**: `$1`, `$2`, etc.
136
+
137
+ ## Examples
138
+
139
+ ### Directory Structure
140
+ ```
141
+ ~/scripts/
142
+ ├── config.json
143
+ ├── deploy.js
144
+ ├── backup.sh
145
+ └── utils/
146
+ └── index.js
147
+ ```
148
+
149
+ ### config.json
150
+ ```json
151
+ {
152
+ "aliases": {
153
+ "deploy": {"bin": "./deploy.js"},
154
+ "util": {"bin": "./utils"},
155
+ "backup": {"bin": "./backup.sh"},
156
+ "start": {"bin": "npm start"}
157
+ }
158
+ }
159
+ ```
160
+
161
+ ### Usage
162
+ ```bash
163
+ # Execute via alias
164
+ q deploy --env prod
165
+
166
+ # Execute shell script
167
+ q backup.sh /data
168
+
169
+ # Execute directory (looks for utils/index.js)
170
+ q utils --help
171
+
172
+ # System command via alias
173
+ q start
174
+ ```
175
+
176
+ ## Development
177
+
178
+ ### Testing
179
+
180
+ ```bash
181
+ # Run all tests
182
+ npm test
183
+
184
+ # Manual testing with example scripts
185
+ npm run test:manual
186
+ ```
187
+
188
+ ### Project Structure
189
+
190
+ ```
191
+ quick-sh/
192
+ ├── bin/ # CLI entry point
193
+ ├── lib/ # Core modules
194
+ │ ├── config.js # Configuration management
195
+ │ ├── executor.js # Script execution
196
+ │ ├── help.js # Help text
197
+ │ ├── script-manager.js # Main logic
198
+ │ └── utils.js # Utilities
199
+ ├── test/ # Test suite
200
+ └── examples/ # Example scripts
201
+ ```
202
+
203
+ ## Requirements
204
+
205
+ - Node.js >= 14.0.0
206
+ - npm or yarn
207
+
208
+ ## Contributing
209
+
210
+ 1. Fork the repository
211
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
212
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
213
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
214
+ 5. Open a Pull Request
215
+
216
+ ## License
217
+
218
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
219
+
220
+ ## Author
221
+
222
+ - **YoungChou** - *Initial work*
223
+
224
+ ## Support
225
+
226
+ If you encounter any issues or have questions, please [open an issue](https://github.com/YoungChou/quick-sh/issues) on GitHub.
package/bin/cli.js ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { program } = require('commander');
4
+ const { setPath } = require('../lib/config');
5
+ const { executeScript, showStatus } = require('../lib/script-manager');
6
+ const { showHelp } = require('../lib/help');
7
+
8
+ // 自定义命令处理 - 在 commander.js 解析之前拦截
9
+ const args = process.argv.slice(2);
10
+
11
+ if (args.length > 0) {
12
+ const firstArg = args[0];
13
+
14
+ // 处理内置命令
15
+ if (firstArg === '-path' && args.length >= 2) {
16
+ setPath(args[1]);
17
+ return;
18
+ }
19
+
20
+ if (firstArg === '-list' || firstArg === '-l') {
21
+ showStatus();
22
+ return;
23
+ }
24
+
25
+ if (firstArg === '-help' || firstArg === '-h') {
26
+ showHelp();
27
+ return;
28
+ }
29
+ }
30
+
31
+ // 设置命令行程序
32
+ program
33
+ .name('q')
34
+ .description('Quick Shell - Local script management tool')
35
+ .version('1.0.0');
36
+
37
+ // 默认命令:执行脚本
38
+ program
39
+ .argument('[script]', 'Script name to execute')
40
+ .argument('[args...]', 'Arguments to pass to the script')
41
+ .action(async (script, args) => {
42
+ if (!script) {
43
+ await showStatus();
44
+ return;
45
+ }
46
+ await executeScript(script, args || []);
47
+ });
48
+
49
+ program.parse();
package/lib/config.js ADDED
@@ -0,0 +1,71 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const os = require('os');
4
+
5
+ // 配置文件路径
6
+ const CONFIG_DIR = path.join(os.homedir(), '.quick-sh');
7
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
8
+
9
+ // 确保配置目录存在
10
+ async function ensureConfigDir() {
11
+ await fs.ensureDir(CONFIG_DIR);
12
+ }
13
+
14
+ // 读取全局配置
15
+ async function readConfig() {
16
+ try {
17
+ await ensureConfigDir();
18
+ if (await fs.pathExists(CONFIG_FILE)) {
19
+ return await fs.readJson(CONFIG_FILE);
20
+ }
21
+ return {};
22
+ } catch (error) {
23
+ return {};
24
+ }
25
+ }
26
+
27
+ // 写入全局配置
28
+ async function writeConfig(config) {
29
+ try {
30
+ await ensureConfigDir();
31
+ await fs.writeJson(CONFIG_FILE, config, { spaces: 2 });
32
+ } catch (error) {
33
+ console.error('Error writing config:', error.message);
34
+ }
35
+ }
36
+
37
+ // 读取脚本目录中的alias配置
38
+ async function readAliasConfig(scriptPath) {
39
+ try {
40
+ const aliasConfigPath = path.join(scriptPath, 'config.json');
41
+ if (await fs.pathExists(aliasConfigPath)) {
42
+ return await fs.readJson(aliasConfigPath);
43
+ }
44
+ return {};
45
+ } catch (error) {
46
+ return {};
47
+ }
48
+ }
49
+
50
+ // 设置脚本路径
51
+ async function setPath(scriptPath) {
52
+ const absolutePath = path.resolve(scriptPath);
53
+
54
+ if (!await fs.pathExists(absolutePath)) {
55
+ console.error(`Path does not exist: ${absolutePath}`);
56
+ process.exit(1);
57
+ }
58
+
59
+ const config = await readConfig();
60
+ config.scriptPath = absolutePath;
61
+ await writeConfig(config);
62
+
63
+ console.log(`Script path set to: ${absolutePath}`);
64
+ }
65
+
66
+ module.exports = {
67
+ readConfig,
68
+ writeConfig,
69
+ readAliasConfig,
70
+ setPath
71
+ };
@@ -0,0 +1,98 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const { spawn } = require('child_process');
4
+
5
+ // 执行文件
6
+ async function executeFile(filePath, args = []) {
7
+ const ext = path.extname(filePath);
8
+ const fileName = path.basename(filePath);
9
+
10
+ console.log(`Executing: ${fileName}${args.length > 0 ? ' with args: ' + args.join(' ') : ''}`);
11
+
12
+ try {
13
+ if (ext === '.js' || ext === '.mjs') {
14
+ // 使用spawn来保持交互性
15
+ const child = spawn('node', [filePath, ...args], {
16
+ stdio: 'inherit',
17
+ cwd: path.dirname(filePath)
18
+ });
19
+
20
+ child.on('close', (code) => {
21
+ process.exit(code);
22
+ });
23
+
24
+ } else if (ext === '.sh') {
25
+ // 确保shell脚本有执行权限
26
+ try {
27
+ await fs.chmod(filePath, 0o755);
28
+ } catch (error) {
29
+ // 忽略权限设置错误
30
+ }
31
+
32
+ const child = spawn('sh', [filePath, ...args], {
33
+ stdio: 'inherit',
34
+ cwd: path.dirname(filePath)
35
+ });
36
+
37
+ child.on('close', (code) => {
38
+ process.exit(code);
39
+ });
40
+
41
+ } else {
42
+ console.error(`Unsupported file type: ${ext}`);
43
+ process.exit(1);
44
+ }
45
+ } catch (error) {
46
+ console.error(`Error executing script: ${error.message}`);
47
+ process.exit(1);
48
+ }
49
+ }
50
+
51
+ // 从目录执行脚本
52
+ async function executeFromDirectory(dirPath, args = []) {
53
+ const possibleFiles = [
54
+ path.join(dirPath, 'index.js'),
55
+ path.join(dirPath, 'index.sh'),
56
+ path.join(dirPath, 'index.mjs')
57
+ ];
58
+
59
+ let targetFile = null;
60
+ for (const file of possibleFiles) {
61
+ if (await fs.pathExists(file)) {
62
+ targetFile = file;
63
+ break;
64
+ }
65
+ }
66
+
67
+ if (!targetFile) {
68
+ console.error(`No index.js, index.sh, or index.mjs found in directory: ${dirPath}`);
69
+ process.exit(1);
70
+ }
71
+
72
+ await executeFile(targetFile, args);
73
+ }
74
+
75
+ // 执行系统命令
76
+ async function executeSystemCommand(command, args = []) {
77
+ console.log(`Executing system command: ${command}${args.length > 0 ? ' with args: ' + args.join(' ') : ''}`);
78
+
79
+ const child = spawn(command, args, {
80
+ stdio: 'inherit',
81
+ cwd: process.cwd()
82
+ });
83
+
84
+ child.on('close', (code) => {
85
+ process.exit(code);
86
+ });
87
+
88
+ child.on('error', (error) => {
89
+ console.error(`Error executing system command: ${error.message}`);
90
+ process.exit(1);
91
+ });
92
+ }
93
+
94
+ module.exports = {
95
+ executeFile,
96
+ executeFromDirectory,
97
+ executeSystemCommand
98
+ };
package/lib/help.js ADDED
@@ -0,0 +1,62 @@
1
+ // 显示帮助信息
2
+ function showHelp() {
3
+ console.log(`
4
+ 🚀 Quick Shell - Local Script Management Tool
5
+
6
+ DESCRIPTION:
7
+ Quick Shell (q) is a command-line tool that helps you manage and execute
8
+ local scripts quickly. It supports JavaScript (.js, .mjs), Shell (.sh)
9
+ scripts, and directory-based scripts.
10
+
11
+ USAGE:
12
+ q [command] [options]
13
+ q <script> [args...]
14
+
15
+ COMMANDS:
16
+ -path <directory> Set the script directory path
17
+ -list, -l Show current configuration and available scripts
18
+ -help, -h Show this help message
19
+ --version, -V Show version number
20
+
21
+ SCRIPT EXECUTION:
22
+ q <script> Execute a script by name
23
+ q <script> [args] Execute a script with arguments
24
+
25
+ EXAMPLES:
26
+ # Setup
27
+ q -path /path/to/scripts Set script directory
28
+ q -list View current configuration
29
+
30
+ # Execute scripts
31
+ q hello Run hello.js or hello.sh
32
+ q backup /src /dest Run backup script with arguments
33
+ q deploy production --verbose Run deploy script with multiple args
34
+ q my-folder Run index.js/index.sh from my-folder/
35
+
36
+ SUPPORTED FILE TYPES:
37
+ .js, .mjs JavaScript files (executed with node)
38
+ .sh Shell scripts (executed with sh)
39
+ directories Looks for index.js, index.sh, or index.mjs
40
+
41
+ ALIAS CONFIGURATION:
42
+ Create a config.json file in your script directory to define aliases:
43
+
44
+ {
45
+ "chat": {"bin": "./chat/src/main.js"}, // Relative path
46
+ "python3": "/usr/bin/python3", // Absolute path
47
+ "w": "which" // System command
48
+ }
49
+
50
+ Execution priority: Alias config > Script files > System commands
51
+
52
+ CONFIGURATION:
53
+ Global config: ~/.quick-sh/config.json
54
+ Alias config: <script-path>/config.json
55
+
56
+ For more information, visit: https://github.com/your-repo/quick-sh
57
+ `);
58
+ }
59
+
60
+ module.exports = {
61
+ showHelp
62
+ };
@@ -0,0 +1,153 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const { readConfig, readAliasConfig } = require('./config');
4
+ const { executeFile, executeFromDirectory, executeSystemCommand } = require('./executor');
5
+ const { checkSystemCommand } = require('./utils');
6
+
7
+ // 执行脚本(核心逻辑,包含alias处理和优先级)
8
+ async function executeScript(scriptName, args = []) {
9
+ const config = await readConfig();
10
+
11
+ if (!config.scriptPath) {
12
+ console.error('No script path configured. Use "q -path <directory>" to set one.');
13
+ process.exit(1);
14
+ }
15
+
16
+ // 优先级1: 检查alias配置
17
+ const aliasConfig = await readAliasConfig(config.scriptPath);
18
+ if (aliasConfig[scriptName]) {
19
+ const aliasValue = aliasConfig[scriptName];
20
+
21
+ if (typeof aliasValue === 'string') {
22
+ // 字符串值:可能是绝对路径或系统命令
23
+ if (path.isAbsolute(aliasValue)) {
24
+ // 绝对路径
25
+ if (await fs.pathExists(aliasValue)) {
26
+ console.log(`Executing alias (absolute path): ${aliasValue}`);
27
+ await executeFile(aliasValue, args);
28
+ return;
29
+ } else {
30
+ console.error(`Alias target not found: ${aliasValue}`);
31
+ process.exit(1);
32
+ }
33
+ } else {
34
+ // 系统命令
35
+ if (await checkSystemCommand(aliasValue)) {
36
+ await executeSystemCommand(aliasValue, args);
37
+ return;
38
+ } else {
39
+ console.error(`System command not found: ${aliasValue}`);
40
+ process.exit(1);
41
+ }
42
+ }
43
+ } else if (aliasValue && typeof aliasValue === 'object' && aliasValue.bin) {
44
+ // 对象值:相对路径配置
45
+ const relativePath = aliasValue.bin;
46
+ const fullPath = path.resolve(config.scriptPath, relativePath);
47
+
48
+ if (await fs.pathExists(fullPath)) {
49
+ console.log(`Executing alias (relative path): ${relativePath}`);
50
+ await executeFile(fullPath, args);
51
+ return;
52
+ } else {
53
+ console.error(`Alias target not found: ${fullPath}`);
54
+ process.exit(1);
55
+ }
56
+ } else {
57
+ console.error(`Invalid alias configuration for: ${scriptName}`);
58
+ process.exit(1);
59
+ }
60
+ }
61
+
62
+ // 优先级2: 检查path中的文件(原有逻辑)
63
+ const scriptPath = path.join(config.scriptPath, scriptName);
64
+
65
+ // 检查是否是文件夹
66
+ if (await fs.pathExists(scriptPath) && (await fs.stat(scriptPath)).isDirectory()) {
67
+ await executeFromDirectory(scriptPath, args);
68
+ return;
69
+ }
70
+
71
+ // 检查不同的文件扩展名
72
+ const possibleFiles = [
73
+ scriptPath,
74
+ `${scriptPath}.js`,
75
+ `${scriptPath}.sh`,
76
+ `${scriptPath}.mjs`
77
+ ];
78
+
79
+ let targetFile = null;
80
+ for (const file of possibleFiles) {
81
+ if (await fs.pathExists(file)) {
82
+ targetFile = file;
83
+ break;
84
+ }
85
+ }
86
+
87
+ if (targetFile) {
88
+ await executeFile(targetFile, args);
89
+ return;
90
+ }
91
+
92
+ // 优先级3: 检查系统可执行命令
93
+ if (await checkSystemCommand(scriptName)) {
94
+ await executeSystemCommand(scriptName, args);
95
+ return;
96
+ }
97
+
98
+ console.error(`Command not found: ${scriptName}`);
99
+ console.error(`Looked in:`);
100
+ console.error(` - Alias config: ${path.join(config.scriptPath, 'config.json')}`);
101
+ console.error(` - Script directory: ${config.scriptPath}`);
102
+ console.error(` - System PATH`);
103
+ process.exit(1);
104
+ }
105
+
106
+ // 显示当前配置和可用脚本
107
+ async function showStatus() {
108
+ const config = await readConfig();
109
+
110
+ if (config.scriptPath) {
111
+ console.log(`Current script path: ${config.scriptPath}`);
112
+
113
+ // 列出可用的脚本
114
+ try {
115
+ const files = await fs.readdir(config.scriptPath);
116
+ const scripts = [];
117
+
118
+ for (const file of files) {
119
+ const filePath = path.join(config.scriptPath, file);
120
+ const stat = await fs.stat(filePath);
121
+
122
+ if (stat.isDirectory()) {
123
+ // 检查目录是否包含index文件
124
+ const indexFiles = ['index.js', 'index.sh', 'index.mjs'];
125
+ for (const indexFile of indexFiles) {
126
+ if (await fs.pathExists(path.join(filePath, indexFile))) {
127
+ scripts.push(`${file}/ (${indexFile})`);
128
+ break;
129
+ }
130
+ }
131
+ } else if (file.endsWith('.js') || file.endsWith('.sh') || file.endsWith('.mjs')) {
132
+ scripts.push(file);
133
+ }
134
+ }
135
+
136
+ if (scripts.length > 0) {
137
+ console.log('\nAvailable scripts:');
138
+ scripts.forEach(script => console.log(` - ${script}`));
139
+ } else {
140
+ console.log('\nNo executable scripts found.');
141
+ }
142
+ } catch (error) {
143
+ console.error('Error reading script directory:', error.message);
144
+ }
145
+ } else {
146
+ console.log('No script path configured. Use "q -path <directory>" to set one.');
147
+ }
148
+ }
149
+
150
+ module.exports = {
151
+ executeScript,
152
+ showStatus
153
+ };
package/lib/utils.js ADDED
@@ -0,0 +1,18 @@
1
+ const { execSync } = require('child_process');
2
+
3
+ // 检查系统命令是否存在
4
+ async function checkSystemCommand(command) {
5
+ try {
6
+ const isWindows = process.platform === 'win32';
7
+ const whichCommand = isWindows ? 'where' : 'which';
8
+
9
+ execSync(`${whichCommand} ${command}`, { stdio: 'ignore' });
10
+ return true;
11
+ } catch (error) {
12
+ return false;
13
+ }
14
+ }
15
+
16
+ module.exports = {
17
+ checkSystemCommand
18
+ };
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "quick-sh",
3
+ "version": "1.0.0",
4
+ "description": "A local script management tool for quick execution of JavaScript and Shell scripts with alias support",
5
+ "main": "lib/script-manager.js",
6
+ "bin": {
7
+ "q": "bin/cli.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "lib/",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "test": "node test/test.js",
17
+ "test:manual": "echo \"Run manual tests with: q test-args, q test-args.sh, q test-dir\"",
18
+ "prepublishOnly": "npm test"
19
+ },
20
+ "keywords": [
21
+ "shell",
22
+ "script",
23
+ "cli",
24
+ "automation",
25
+ "local-scripts",
26
+ "alias",
27
+ "command-line",
28
+ "script-manager",
29
+ "javascript",
30
+ "bash",
31
+ "quick-execution"
32
+ ],
33
+ "author": "YoungChou <your-email@example.com>",
34
+ "license": "MIT",
35
+ "engines": {
36
+ "node": ">=14.0.0"
37
+ },
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/YoungChou/quick-sh.git"
41
+ },
42
+ "homepage": "https://github.com/YoungChou/quick-sh#readme",
43
+ "bugs": {
44
+ "url": "https://github.com/YoungChou/quick-sh/issues"
45
+ },
46
+ "dependencies": {
47
+ "commander": "^9.0.0",
48
+ "fs-extra": "^11.0.0"
49
+ },
50
+ "devDependencies": {},
51
+ "preferGlobal": true,
52
+ "directories": {
53
+ "example": "examples",
54
+ "lib": "lib",
55
+ "test": "test"
56
+ }
57
+ }