@hasna/terminal 1.3.9 → 1.4.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.
Files changed (3) hide show
  1. package/dist/cli.js +33 -6
  2. package/package.json +1 -1
  3. package/src/cli.tsx +33 -6
package/dist/cli.js CHANGED
@@ -445,12 +445,27 @@ else if (args.length > 0) {
445
445
  console.error(`blocked: ${blocked}`);
446
446
  process.exit(1);
447
447
  }
448
- // Safety: warn about irreversible commands (kill, push, rm, etc.)
448
+ // Safety: when command is irreversible, try a safer read-only alternative
449
449
  if (isIrreversible(command)) {
450
- console.error(`⚠ IRREVERSIBLE: $ ${command}`);
451
- console.error(` This command may kill processes, push code, or delete data.`);
452
- console.error(` Run directly in your shell if you're sure: ${command}`);
453
- process.exit(1);
450
+ // Try to generate a safe alternative via AI
451
+ try {
452
+ const safeCommand = await translateToCommand(`${prompt} (IMPORTANT: use ONLY read-only commands like grep, find, cat, wc, ls. Do NOT use npx, install, kill, push, sed, or any modifying command.)`, perms, []);
453
+ if (!isIrreversible(safeCommand) && !checkPermissions(safeCommand, perms)) {
454
+ console.error(`$ ${safeCommand} (safe alternative)`);
455
+ command = safeCommand;
456
+ // Continue to execution below
457
+ }
458
+ else {
459
+ console.error(`⚠ BLOCKED: $ ${command}`);
460
+ console.error(` Run directly in your shell if you're sure.`);
461
+ process.exit(1);
462
+ }
463
+ }
464
+ catch {
465
+ console.error(`⚠ BLOCKED: $ ${command}`);
466
+ console.error(` Run directly in your shell if you're sure.`);
467
+ process.exit(1);
468
+ }
454
469
  }
455
470
  // Show what we're running
456
471
  console.error(`$ ${command}`);
@@ -514,8 +529,20 @@ else if (args.length > 0) {
514
529
  console.log(`No results found for: ${prompt}`);
515
530
  process.exit(0);
516
531
  }
532
+ // Combine stdout+stderr and try AI answer framing (for audit/lint/test commands)
517
533
  const combined = errStderr && errStdout.includes(errStderr.trim()) ? errStdout : errStdout + errStderr;
518
- console.log(stripNoise(stripAnsi(combined)).cleaned);
534
+ const errorClean = stripNoise(stripAnsi(combined)).cleaned;
535
+ if (errorClean.length > 20) {
536
+ try {
537
+ const processed = await processOutput(actualCmd, errorClean, prompt);
538
+ if (processed.aiProcessed) {
539
+ console.log(processed.summary);
540
+ process.exit(e.status ?? 1);
541
+ }
542
+ }
543
+ catch { }
544
+ }
545
+ console.log(errorClean);
519
546
  process.exit(e.status ?? 1);
520
547
  }
521
548
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/terminal",
3
- "version": "1.3.9",
3
+ "version": "1.4.0",
4
4
  "description": "Smart terminal wrapper for AI agents and humans — structured output, token compression, MCP server, natural language",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.tsx CHANGED
@@ -424,12 +424,28 @@ else if (args.length > 0) {
424
424
  const blocked = checkPermissions(command, perms);
425
425
  if (blocked) { console.error(`blocked: ${blocked}`); process.exit(1); }
426
426
 
427
- // Safety: warn about irreversible commands (kill, push, rm, etc.)
427
+ // Safety: when command is irreversible, try a safer read-only alternative
428
428
  if (isIrreversible(command)) {
429
- console.error(`⚠ IRREVERSIBLE: $ ${command}`);
430
- console.error(` This command may kill processes, push code, or delete data.`);
431
- console.error(` Run directly in your shell if you're sure: ${command}`);
432
- process.exit(1);
429
+ // Try to generate a safe alternative via AI
430
+ try {
431
+ const safeCommand = await translateToCommand(
432
+ `${prompt} (IMPORTANT: use ONLY read-only commands like grep, find, cat, wc, ls. Do NOT use npx, install, kill, push, sed, or any modifying command.)`,
433
+ perms, []
434
+ );
435
+ if (!isIrreversible(safeCommand) && !checkPermissions(safeCommand, perms)) {
436
+ console.error(`$ ${safeCommand} (safe alternative)`);
437
+ command = safeCommand;
438
+ // Continue to execution below
439
+ } else {
440
+ console.error(`⚠ BLOCKED: $ ${command}`);
441
+ console.error(` Run directly in your shell if you're sure.`);
442
+ process.exit(1);
443
+ }
444
+ } catch {
445
+ console.error(`⚠ BLOCKED: $ ${command}`);
446
+ console.error(` Run directly in your shell if you're sure.`);
447
+ process.exit(1);
448
+ }
433
449
  }
434
450
 
435
451
  // Show what we're running
@@ -493,8 +509,19 @@ else if (args.length > 0) {
493
509
  console.log(`No results found for: ${prompt}`);
494
510
  process.exit(0);
495
511
  }
512
+ // Combine stdout+stderr and try AI answer framing (for audit/lint/test commands)
496
513
  const combined = errStderr && errStdout.includes(errStderr.trim()) ? errStdout : errStdout + errStderr;
497
- console.log(stripNoise(stripAnsi(combined)).cleaned);
514
+ const errorClean = stripNoise(stripAnsi(combined)).cleaned;
515
+ if (errorClean.length > 20) {
516
+ try {
517
+ const processed = await processOutput(actualCmd, errorClean, prompt);
518
+ if (processed.aiProcessed) {
519
+ console.log(processed.summary);
520
+ process.exit(e.status ?? 1);
521
+ }
522
+ } catch {}
523
+ }
524
+ console.log(errorClean);
498
525
  process.exit(e.status ?? 1);
499
526
  }
500
527
  }