shoud-cli 1.0.2 → 1.0.3
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/package.json +2 -2
- package/src/tools/index.js +17 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shoud-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "SHOUD Terminal Agent: Give your computer a job.",
|
|
5
5
|
"main": "bin/shoud.js",
|
|
6
6
|
"bin": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"ora": "^5.4.1"
|
|
19
19
|
},
|
|
20
20
|
"engines": {
|
|
21
|
-
"node": "
|
|
21
|
+
"node": "18.0.0"
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
24
|
"bin/",
|
package/src/tools/index.js
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const path = require('path');
|
|
4
|
-
|
|
5
|
-
// Allowed shell commands (whitelist)
|
|
6
|
-
const ALLOWED_COMMANDS = new Set([
|
|
7
|
-
'ls', 'pwd', 'cat', 'grep', 'find', 'echo',
|
|
8
|
-
'mkdir', 'rmdir', 'touch', 'head', 'tail',
|
|
9
|
-
'wc', 'sort', 'uniq', 'diff', 'patch',
|
|
10
|
-
'git' // optional, but careful
|
|
11
|
-
]);
|
|
4
|
+
const os = require('os');
|
|
12
5
|
|
|
13
6
|
// Maximum output size (1 MB)
|
|
14
7
|
const MAX_OUTPUT_SIZE = 1024 * 1024;
|
|
@@ -16,13 +9,19 @@ const MAX_OUTPUT_SIZE = 1024 * 1024;
|
|
|
16
9
|
// Get the project root (current working directory where CLI was started)
|
|
17
10
|
const PROJECT_ROOT = process.cwd();
|
|
18
11
|
|
|
12
|
+
// Determine the appropriate shell
|
|
13
|
+
function getShell() {
|
|
14
|
+
if (os.platform() === 'win32') {
|
|
15
|
+
return 'powershell.exe'; // Use PowerShell on Windows
|
|
16
|
+
}
|
|
17
|
+
return '/bin/bash'; // Use bash on Unix (Linux/macOS)
|
|
18
|
+
}
|
|
19
|
+
|
|
19
20
|
/**
|
|
20
21
|
* Sanitize a file path to ensure it stays within the project root.
|
|
21
22
|
*/
|
|
22
23
|
function sanitizePath(inputPath) {
|
|
23
|
-
// Resolve relative paths
|
|
24
24
|
const resolved = path.resolve(PROJECT_ROOT, inputPath);
|
|
25
|
-
// Ensure it starts with the project root
|
|
26
25
|
if (!resolved.startsWith(PROJECT_ROOT)) {
|
|
27
26
|
throw new Error('Path is outside the project directory.');
|
|
28
27
|
}
|
|
@@ -31,27 +30,21 @@ function sanitizePath(inputPath) {
|
|
|
31
30
|
|
|
32
31
|
/**
|
|
33
32
|
* Execute a shell command securely.
|
|
34
|
-
*
|
|
33
|
+
* No command whitelist – safety is enforced by the permission engine.
|
|
35
34
|
*/
|
|
36
35
|
function executeShell(commandString) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (parts.length === 0) throw new Error('Empty command.');
|
|
40
|
-
|
|
41
|
-
const cmd = parts[0];
|
|
42
|
-
if (!ALLOWED_COMMANDS.has(cmd)) {
|
|
43
|
-
throw new Error(`Command "${cmd}" is not allowed.`);
|
|
36
|
+
if (!commandString || commandString.trim().length === 0) {
|
|
37
|
+
throw new Error('Empty command.');
|
|
44
38
|
}
|
|
45
39
|
|
|
46
|
-
const args = parts.slice(1);
|
|
47
|
-
|
|
48
40
|
try {
|
|
49
|
-
const output =
|
|
41
|
+
const output = execSync(commandString, {
|
|
50
42
|
cwd: PROJECT_ROOT,
|
|
51
43
|
encoding: 'utf-8',
|
|
44
|
+
shell: getShell(),
|
|
52
45
|
timeout: 30000, // 30 seconds
|
|
53
46
|
maxBuffer: MAX_OUTPUT_SIZE,
|
|
54
|
-
stdio: 'pipe'
|
|
47
|
+
stdio: 'pipe',
|
|
55
48
|
});
|
|
56
49
|
return output.trim() || 'Command executed successfully with no output.';
|
|
57
50
|
} catch (err) {
|
|
@@ -86,13 +79,11 @@ function readFile(filePath) {
|
|
|
86
79
|
}
|
|
87
80
|
|
|
88
81
|
/**
|
|
89
|
-
* Write content to a file securely
|
|
90
|
-
* Ensure file is within project root.
|
|
82
|
+
* Write content to a file securely, ensuring it's within the project root.
|
|
91
83
|
*/
|
|
92
84
|
function writeFile(filePath, content) {
|
|
93
85
|
const safePath = sanitizePath(filePath);
|
|
94
86
|
try {
|
|
95
|
-
// Ensure directory exists
|
|
96
87
|
const dir = path.dirname(safePath);
|
|
97
88
|
if (!fs.existsSync(dir)) {
|
|
98
89
|
fs.mkdirSync(dir, { recursive: true });
|