@startanaicompany/cli 1.9.1 → 1.9.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/CLAUDE.md +216 -7
- package/README.md +39 -8
- package/package.json +1 -1
- package/src/commands/db.js +15 -2
- package/src/commands/exec.js +24 -15
package/CLAUDE.md
CHANGED
|
@@ -6,7 +6,7 @@ This file provides guidance to Claude Code when working with the SAAC CLI codeba
|
|
|
6
6
|
|
|
7
7
|
SAAC CLI is the official command-line interface for StartAnAiCompany.com. Built with Node.js and Commander.js, it interfaces with a wrapper API that manages Coolify deployments.
|
|
8
8
|
|
|
9
|
-
**Current Version:** 1.
|
|
9
|
+
**Current Version:** 1.9.3
|
|
10
10
|
|
|
11
11
|
## Development Commands
|
|
12
12
|
|
|
@@ -63,6 +63,55 @@ try {
|
|
|
63
63
|
}
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
### Polling Mechanism Pattern (v1.9.0)
|
|
67
|
+
|
|
68
|
+
Used for async operations (exec, db commands):
|
|
69
|
+
|
|
70
|
+
```javascript
|
|
71
|
+
async function pollForResult(applicationUuid, commandId, commandType, maxWaitSeconds = 120) {
|
|
72
|
+
const startTime = Date.now();
|
|
73
|
+
const pollInterval = 1000; // 1 second
|
|
74
|
+
|
|
75
|
+
while (true) {
|
|
76
|
+
const elapsed = (Date.now() - startTime) / 1000;
|
|
77
|
+
|
|
78
|
+
if (elapsed > maxWaitSeconds) {
|
|
79
|
+
throw new Error(`Command timed out after ${maxWaitSeconds} seconds`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
const result = await api.getDbCommandResult(applicationUuid, commandType, commandId);
|
|
84
|
+
|
|
85
|
+
if (result.status === 'completed') {
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (result.status === 'failed') {
|
|
90
|
+
const errorMsg = result.result?.error || result.error || 'Command failed';
|
|
91
|
+
throw new Error(errorMsg);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Still pending, wait and retry
|
|
95
|
+
await new Promise(resolve => setTimeout(resolve, pollInterval));
|
|
96
|
+
} catch (error) {
|
|
97
|
+
// If error is not a 404 (command not found yet), rethrow
|
|
98
|
+
if (error.response?.status !== 404) {
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
// 404 means command not processed yet, keep polling
|
|
102
|
+
await new Promise(resolve => setTimeout(resolve, pollInterval));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Key points:**
|
|
109
|
+
- Universal polling endpoint: `/db/result/:commandId`
|
|
110
|
+
- 1-second poll interval
|
|
111
|
+
- 120-second default timeout
|
|
112
|
+
- Handles 404 (command not ready yet) vs other errors
|
|
113
|
+
- Returns result object with status, result, timestamps
|
|
114
|
+
|
|
66
115
|
## Authentication Flow
|
|
67
116
|
|
|
68
117
|
### Session Tokens (Primary Method)
|
|
@@ -110,14 +159,29 @@ SSE streaming implementation:
|
|
|
110
159
|
**Commands:** `git connect/list/disconnect`
|
|
111
160
|
**Flow:** Browser OAuth → CLI polls every 2s → Connection saved (AES-256-GCM encrypted)
|
|
112
161
|
|
|
113
|
-
### Remote Execution (v1.
|
|
162
|
+
### Remote Execution (v1.9.1)
|
|
114
163
|
```bash
|
|
115
164
|
saac exec "npm run migrate" # Execute command
|
|
116
165
|
saac exec --history # View history
|
|
117
166
|
```
|
|
167
|
+
**Implementation:** SSE command channel with polling mechanism
|
|
118
168
|
**Security:** Command allowlist, dangerous pattern detection, rate limiting (30/5min)
|
|
169
|
+
**Performance:** ~500ms average response time
|
|
119
170
|
|
|
120
|
-
|
|
171
|
+
### Database Management (v1.9.0)
|
|
172
|
+
```bash
|
|
173
|
+
saac db list # List database containers
|
|
174
|
+
saac db sql "SELECT * FROM users" # Execute SQL query (read-only)
|
|
175
|
+
saac db sql "INSERT INTO..." --write # Write operation (requires flag)
|
|
176
|
+
saac db sql "SELECT..." --db mydb # Target specific database
|
|
177
|
+
saac db redis GET mykey # Execute Redis command
|
|
178
|
+
saac db info # Show database connection info
|
|
179
|
+
```
|
|
180
|
+
**Implementation:** SSE command channel with universal polling endpoint
|
|
181
|
+
**Security:** Read-only by default, --write flag for modifications, rate limiting (60/5min)
|
|
182
|
+
**Performance:** ~1s average response time
|
|
183
|
+
|
|
184
|
+
## API Endpoints (v1.9.0)
|
|
121
185
|
|
|
122
186
|
```
|
|
123
187
|
POST /api/v1/users/register
|
|
@@ -128,7 +192,16 @@ PATCH /api/v1/applications/:uuid
|
|
|
128
192
|
POST /api/v1/applications/:uuid/deploy
|
|
129
193
|
GET /api/v1/applications/:uuid/logs # ?follow=true for SSE
|
|
130
194
|
GET /api/v1/applications/:uuid/env/export
|
|
131
|
-
|
|
195
|
+
|
|
196
|
+
# Remote Execution (v1.9.1)
|
|
197
|
+
POST /api/v1/applications/:uuid/exec # Queue command
|
|
198
|
+
GET /api/v1/applications/:uuid/db/result/:commandId # Universal polling
|
|
199
|
+
|
|
200
|
+
# Database Management (v1.9.0)
|
|
201
|
+
GET /api/v1/applications/:uuid/db/containers
|
|
202
|
+
GET /api/v1/applications/:uuid/db/info # Instant response
|
|
203
|
+
POST /api/v1/applications/:uuid/db/sql # Queue SQL query
|
|
204
|
+
POST /api/v1/applications/:uuid/db/redis # Queue Redis command
|
|
132
205
|
|
|
133
206
|
# OAuth (no /api/v1 prefix)
|
|
134
207
|
GET /oauth/authorize
|
|
@@ -142,7 +215,7 @@ GET /oauth/poll/:session_id
|
|
|
142
215
|
3. **delete message:** Use `app.name` not `result.application_name`
|
|
143
216
|
4. **organization_id:** Added required `--org` flag to create command
|
|
144
217
|
|
|
145
|
-
## Testing Methodology
|
|
218
|
+
## Testing Methodology
|
|
146
219
|
|
|
147
220
|
**Process:**
|
|
148
221
|
1. Test ONE feature at a time
|
|
@@ -151,12 +224,29 @@ GET /oauth/poll/:session_id
|
|
|
151
224
|
4. Fix bugs immediately
|
|
152
225
|
5. Move to next feature
|
|
153
226
|
|
|
154
|
-
**
|
|
227
|
+
**Comprehensive tests completed:**
|
|
155
228
|
- Authentication, auto-login, API keys
|
|
156
229
|
- Git OAuth, application management
|
|
157
230
|
- Environment/domain, logs, streaming
|
|
231
|
+
- Database management (SQL queries, Redis commands)
|
|
232
|
+
- Remote execution (allowed/blocked commands)
|
|
233
|
+
- Error handling and user experience
|
|
158
234
|
- Real app testing (golden-68-rekrytering-9jsq1e)
|
|
159
235
|
|
|
236
|
+
**v1.9.0 Database Testing:**
|
|
237
|
+
- Created test_users table with INSERT/SELECT operations
|
|
238
|
+
- Tested PostgreSQL meta-queries (list databases, tables, schemas)
|
|
239
|
+
- Tested Redis commands (PING, SET, GET, HGETALL)
|
|
240
|
+
- Created new database (test_cli_db) with products table
|
|
241
|
+
- Validated --write flag enforcement
|
|
242
|
+
- Validated --db flag for targeting specific databases
|
|
243
|
+
|
|
244
|
+
**v1.9.1/v1.9.2 Exec Testing:**
|
|
245
|
+
- Tested allowed commands (npm, node, ls, cat, pwd)
|
|
246
|
+
- Tested blocked commands (whoami, ps, kill)
|
|
247
|
+
- Validated error messages and UX improvements
|
|
248
|
+
- Confirmed ~500ms average response time
|
|
249
|
+
|
|
160
250
|
## Publishing Checklist
|
|
161
251
|
|
|
162
252
|
1. Test all new features with live backend
|
|
@@ -166,8 +256,56 @@ GET /oauth/poll/:session_id
|
|
|
166
256
|
5. Git commit and push
|
|
167
257
|
6. `npm publish --access public`
|
|
168
258
|
|
|
169
|
-
##
|
|
259
|
+
## Release Notes
|
|
170
260
|
|
|
261
|
+
### Version 1.9.3 (Current)
|
|
262
|
+
**Bug Fixes:**
|
|
263
|
+
- Fixed SQL query crash when querying tables with text fields containing special characters
|
|
264
|
+
- Backend now returns structured JSON format (`columns` and `rows` arrays) instead of raw CSV
|
|
265
|
+
- Added fallback to CSV parsing for backward compatibility
|
|
266
|
+
- Handles commas, newlines, and Swedish characters in text fields correctly
|
|
267
|
+
|
|
268
|
+
### Version 1.9.2
|
|
269
|
+
**Bug Fixes:**
|
|
270
|
+
- Fixed exec error handling to use correct backend field (`data.error` not `data.message`)
|
|
271
|
+
- Improved error messages for blocked commands
|
|
272
|
+
- Updated allowed commands list to match backend implementation
|
|
273
|
+
|
|
274
|
+
### Version 1.9.1
|
|
275
|
+
**Improvements:**
|
|
276
|
+
- Fixed `saac exec` to use SSE command channel with polling
|
|
277
|
+
- Migrated from direct docker exec to daemon-based execution
|
|
278
|
+
- Average response time improved to ~500ms (from 30s timeout)
|
|
279
|
+
|
|
280
|
+
### Version 1.9.0
|
|
281
|
+
**New Features:**
|
|
282
|
+
- **Database Management Commands:**
|
|
283
|
+
- `saac db list` - List database containers (postgres, redis, etc.)
|
|
284
|
+
- `saac db sql <query>` - Execute SQL queries (read-only by default)
|
|
285
|
+
- `saac db redis <command>` - Execute Redis commands
|
|
286
|
+
- `saac db info` - Show database connection information
|
|
287
|
+
- Read-only by default with `--write` flag for modifications
|
|
288
|
+
- `--db` flag to target specific databases
|
|
289
|
+
- Rate limiting: 60 queries per 5 minutes
|
|
290
|
+
- Universal polling endpoint for all async operations
|
|
291
|
+
|
|
292
|
+
**Implementation:**
|
|
293
|
+
- Created `src/commands/db.js` (416 lines)
|
|
294
|
+
- Added 5 new API client methods in `src/lib/api.js`
|
|
295
|
+
- Polling mechanism with 1s interval, 120s timeout
|
|
296
|
+
- Formatted table output for query results
|
|
297
|
+
|
|
298
|
+
### Version 1.8.0
|
|
299
|
+
**Improvements:**
|
|
300
|
+
- Made deploy streaming the default behavior
|
|
301
|
+
- Improved deploy command performance
|
|
302
|
+
|
|
303
|
+
### Version 1.7.0
|
|
304
|
+
**New Features:**
|
|
305
|
+
- Deploy streaming support
|
|
306
|
+
- No-cache deployment option
|
|
307
|
+
|
|
308
|
+
### Version 1.6.0
|
|
171
309
|
**New Features:**
|
|
172
310
|
- SSE streaming for real-time logs (`--follow`)
|
|
173
311
|
- Log type filtering (`--type access/runtime/build`)
|
|
@@ -184,6 +322,40 @@ GET /oauth/poll/:session_id
|
|
|
184
322
|
- `saac create` requires `--org` flag
|
|
185
323
|
- `saac keys show` removed
|
|
186
324
|
|
|
325
|
+
## Key Files & Structure
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
saac-cli/
|
|
329
|
+
├── bin/
|
|
330
|
+
│ └── saac.js # CLI entry point, all command definitions
|
|
331
|
+
├── src/
|
|
332
|
+
│ ├── commands/
|
|
333
|
+
│ │ ├── auth.js # login, logout, register, verify
|
|
334
|
+
│ │ ├── create.js # create applications
|
|
335
|
+
│ │ ├── db.js # database management (v1.9.0)
|
|
336
|
+
│ │ ├── deploy.js # deploy command
|
|
337
|
+
│ │ ├── exec.js # remote execution (v1.9.1)
|
|
338
|
+
│ │ ├── git.js # Git OAuth
|
|
339
|
+
│ │ ├── keys.js # API key management
|
|
340
|
+
│ │ ├── logs.js # log streaming (v1.6.0)
|
|
341
|
+
│ │ └── ... # other commands
|
|
342
|
+
│ └── lib/
|
|
343
|
+
│ ├── api.js # Axios client, all API methods
|
|
344
|
+
│ ├── config.js # Config management, auth checking
|
|
345
|
+
│ └── logger.js # Formatted output utilities
|
|
346
|
+
├── package.json # Version, dependencies, bin script
|
|
347
|
+
├── README.md # Public documentation
|
|
348
|
+
└── CLAUDE.md # AI agent instructions (this file)
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**Critical files for new features:**
|
|
352
|
+
1. `bin/saac.js` - Add new command definitions
|
|
353
|
+
2. `src/commands/<feature>.js` - Implement command logic
|
|
354
|
+
3. `src/lib/api.js` - Add API client methods
|
|
355
|
+
4. `package.json` - Update version number
|
|
356
|
+
5. `README.md` - Document public-facing features
|
|
357
|
+
6. `CLAUDE.md` - Update AI agent instructions
|
|
358
|
+
|
|
187
359
|
## Dependencies
|
|
188
360
|
|
|
189
361
|
- axios, chalk, commander, conf, inquirer, ora, boxen, table, validator, dotenv, open, ws
|
|
@@ -215,8 +387,45 @@ GET /oauth/poll/:session_id
|
|
|
215
387
|
- Show FULL API keys when displayed (they're only shown once)
|
|
216
388
|
- Same for session tokens during verification
|
|
217
389
|
|
|
390
|
+
**Database command patterns:**
|
|
391
|
+
- Always use `--write` flag for INSERT, UPDATE, DELETE, DROP, TRUNCATE
|
|
392
|
+
- Use `--db` flag to target specific databases (defaults to env vars)
|
|
393
|
+
- Format query results as tables using `table` package
|
|
394
|
+
- Handle CSV output from backend (comma-separated rows)
|
|
395
|
+
|
|
396
|
+
**Exec error handling (v1.9.2):**
|
|
397
|
+
- 400 errors = command not allowed (show clear message with allowlist)
|
|
398
|
+
- 408 errors = timeout (suggest increasing --timeout)
|
|
399
|
+
- 429 errors = rate limit exceeded (30 commands per 5 minutes)
|
|
400
|
+
- 503 errors = container not running
|
|
401
|
+
- Backend error field is `data.error` (not `data.message`)
|
|
402
|
+
- Show full backend error message with context
|
|
403
|
+
|
|
404
|
+
## HIVE Collaboration
|
|
405
|
+
|
|
406
|
+
**Agent Names:**
|
|
407
|
+
- CLI Developer: `saac-saac-clitool-developer`
|
|
408
|
+
- Backend Developer: `saac-owndockermachine-backend-developer`
|
|
409
|
+
- Workspace Backend: `saac-workspace-backend-developer`
|
|
410
|
+
- Orchestrator: `saac-orchestrator-backend-developer`
|
|
411
|
+
|
|
412
|
+
**Collaboration Workflow:**
|
|
413
|
+
1. Poll HIVE regularly when implementing new features
|
|
414
|
+
2. Coordinate with backend developers for API changes
|
|
415
|
+
3. Validate implementations with backend team
|
|
416
|
+
4. Share knowledge and best practices with other agents
|
|
417
|
+
5. Document all architectural decisions
|
|
418
|
+
|
|
419
|
+
**Example Communication:**
|
|
420
|
+
- Request API endpoint specifications
|
|
421
|
+
- Confirm error response formats
|
|
422
|
+
- Validate security patterns
|
|
423
|
+
- Share implementation guides for other teams
|
|
424
|
+
- Debug issues collaboratively
|
|
425
|
+
|
|
218
426
|
## MailHog & Testing
|
|
219
427
|
|
|
220
428
|
- MailHog URL: https://mailhog.goryan.io
|
|
221
429
|
- Default domain: `{subdomain}.startanaicompany.com`
|
|
222
430
|
- Git server: https://git.startanaicompany.com
|
|
431
|
+
- Test app: golden-68-rekrytering-9jsq1e
|
package/README.md
CHANGED
|
@@ -1472,17 +1472,19 @@ Run one-off commands inside your container without opening an interactive shell.
|
|
|
1472
1472
|
Execute a single command in the remote container.
|
|
1473
1473
|
|
|
1474
1474
|
```bash
|
|
1475
|
-
# Run
|
|
1475
|
+
# Run npm commands
|
|
1476
1476
|
saac exec "npm run db:migrate"
|
|
1477
|
+
saac exec "npm test"
|
|
1478
|
+
saac exec "npm run build"
|
|
1477
1479
|
|
|
1478
|
-
# Check
|
|
1480
|
+
# Check versions
|
|
1479
1481
|
saac exec "node --version"
|
|
1482
|
+
saac exec "npm --version"
|
|
1480
1483
|
|
|
1481
|
-
#
|
|
1482
|
-
saac exec "
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
saac exec "ps aux"
|
|
1484
|
+
# File operations
|
|
1485
|
+
saac exec "ls -la"
|
|
1486
|
+
saac exec "cat package.json"
|
|
1487
|
+
saac exec "pwd"
|
|
1486
1488
|
|
|
1487
1489
|
# Custom working directory
|
|
1488
1490
|
saac exec "npm test" --workdir /app/src
|
|
@@ -1495,6 +1497,34 @@ saac exec "npm run build" --timeout 300
|
|
|
1495
1497
|
- `--workdir <path>` - Working directory (default: `/app`)
|
|
1496
1498
|
- `--timeout <seconds>` - Timeout in seconds (default: 30, max: 300)
|
|
1497
1499
|
|
|
1500
|
+
**Security & Command Allowlist:**
|
|
1501
|
+
|
|
1502
|
+
For security, only specific commands are allowed. Commands are executed via the SSE command channel with ~500ms response time.
|
|
1503
|
+
|
|
1504
|
+
**Allowed Commands:**
|
|
1505
|
+
- **Node.js:** npm, node, npx, yarn, pnpm
|
|
1506
|
+
- **Python:** python, python3, pip, pip3, poetry
|
|
1507
|
+
- **Ruby:** bundle, rake, rails, ruby
|
|
1508
|
+
- **Shell:** sh, bash, echo, cat, ls, pwd, env
|
|
1509
|
+
- **Database:** psql, mysql, mongosh
|
|
1510
|
+
- **Build:** go, cargo, make, cmake
|
|
1511
|
+
|
|
1512
|
+
**Blocked for Security:**
|
|
1513
|
+
- System commands: `whoami`, `ps`, `top`, `kill`
|
|
1514
|
+
- Destructive operations: `rm`, `chmod`, `chown`
|
|
1515
|
+
- Advanced shell features: pipes (`|`), redirects (`>`), command substitution
|
|
1516
|
+
|
|
1517
|
+
**Rate Limit:** 60 commands per 5 minutes per user
|
|
1518
|
+
|
|
1519
|
+
If you try a blocked command, you'll see a clear error message:
|
|
1520
|
+
```
|
|
1521
|
+
✖ Command not allowed
|
|
1522
|
+
|
|
1523
|
+
✗ This command is blocked for security reasons
|
|
1524
|
+
|
|
1525
|
+
⚠ Command 'whoami' is not in allowlist. Allowed commands: ...
|
|
1526
|
+
```
|
|
1527
|
+
|
|
1498
1528
|
**Example output:**
|
|
1499
1529
|
```bash
|
|
1500
1530
|
$ saac exec "npm run db:migrate"
|
|
@@ -2451,7 +2481,8 @@ saac shell
|
|
|
2451
2481
|
**Workaround:** Use `saac exec` for one-off commands:
|
|
2452
2482
|
```bash
|
|
2453
2483
|
saac exec "npm run migrate"
|
|
2454
|
-
saac exec "
|
|
2484
|
+
saac exec "node --version"
|
|
2485
|
+
saac exec "ls -la"
|
|
2455
2486
|
```
|
|
2456
2487
|
|
|
2457
2488
|
### General Debugging
|
package/package.json
CHANGED
package/src/commands/db.js
CHANGED
|
@@ -166,8 +166,21 @@ async function sql(query, options) {
|
|
|
166
166
|
spin.succeed('Query executed');
|
|
167
167
|
logger.newline();
|
|
168
168
|
|
|
169
|
-
if (result.result && result.result.
|
|
170
|
-
//
|
|
169
|
+
if (result.result && result.result.format === 'json') {
|
|
170
|
+
// New format: structured JSON with columns and rows
|
|
171
|
+
const { columns, rows } = result.result;
|
|
172
|
+
|
|
173
|
+
if (columns && rows && rows.length > 0) {
|
|
174
|
+
// Build table data with header row
|
|
175
|
+
const tableData = [columns, ...rows];
|
|
176
|
+
console.log(table(tableData));
|
|
177
|
+
logger.newline();
|
|
178
|
+
logger.info(`Rows returned: ${rows.length}`);
|
|
179
|
+
} else {
|
|
180
|
+
logger.info('Query returned no results');
|
|
181
|
+
}
|
|
182
|
+
} else if (result.result && result.result.output) {
|
|
183
|
+
// Fallback: old CSV format (if daemon parsing failed)
|
|
171
184
|
const csvData = result.result.output;
|
|
172
185
|
const rows = csvData.trim().split('\n').map(row => row.split(','));
|
|
173
186
|
|
package/src/commands/exec.js
CHANGED
|
@@ -111,27 +111,36 @@ async function exec(command, options = {}) {
|
|
|
111
111
|
|
|
112
112
|
spin.succeed('Command executed');
|
|
113
113
|
} catch (error) {
|
|
114
|
-
spin.fail('Command
|
|
114
|
+
spin.fail('Command not allowed');
|
|
115
115
|
|
|
116
116
|
if (error.response?.status === 400) {
|
|
117
|
-
const data = error.response.data;
|
|
117
|
+
const data = error.response.data || {};
|
|
118
118
|
logger.newline();
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
// Show clear "command not allowed" message for all 400 errors
|
|
121
|
+
logger.error('This command is blocked for security reasons');
|
|
122
|
+
|
|
123
|
+
// Show backend error message if available (note: field is 'error', not 'message')
|
|
124
|
+
if (data.error) {
|
|
122
125
|
logger.newline();
|
|
123
|
-
logger.warn(data.
|
|
124
|
-
|
|
125
|
-
if (data.message.includes('not in allowlist')) {
|
|
126
|
-
logger.newline();
|
|
127
|
-
logger.info('Allowed commands include:');
|
|
128
|
-
logger.log(' Node.js: npm, node, npx, yarn, pnpm');
|
|
129
|
-
logger.log(' Python: python, python3, pip, poetry');
|
|
130
|
-
logger.log(' Ruby: bundle, rake, rails');
|
|
131
|
-
logger.log(' Shell: sh, bash, echo, cat, ls, pwd');
|
|
132
|
-
logger.log(' Database: psql, mysql, mongosh');
|
|
133
|
-
}
|
|
126
|
+
logger.warn(data.error);
|
|
134
127
|
}
|
|
128
|
+
|
|
129
|
+
logger.newline();
|
|
130
|
+
logger.info('Allowed commands include:');
|
|
131
|
+
logger.log(' Node.js: npm, node, npx, yarn, pnpm');
|
|
132
|
+
logger.log(' Python: python, python3, pip, poetry');
|
|
133
|
+
logger.log(' Ruby: bundle, rake, rails, ruby');
|
|
134
|
+
logger.log(' Shell: sh, bash, echo, cat, ls, pwd, env');
|
|
135
|
+
logger.log(' Database: psql, mysql, mongosh');
|
|
136
|
+
logger.log(' Build: go, cargo, make, cmake');
|
|
137
|
+
logger.newline();
|
|
138
|
+
logger.info('Blocked for security:');
|
|
139
|
+
logger.log(' System commands: whoami, ps, top, kill');
|
|
140
|
+
logger.log(' Destructive operations: rm, chmod, chown');
|
|
141
|
+
logger.log(' Advanced shell features: pipes (|), redirects (>), command substitution');
|
|
142
|
+
|
|
143
|
+
process.exit(1);
|
|
135
144
|
} else if (error.response?.status === 408) {
|
|
136
145
|
logger.newline();
|
|
137
146
|
logger.error('Command execution timed out');
|