---
name: bssh
description: "MANDATORY: Auto-load when user says 'ssh'. Persistent SSH sessions with state. NEVER use bare ssh commands."
trigger: "ssh"
version: 1.1.0
---

# bssh - Persistent SSH Sessions

## Installation

To install this skill, copy the entire directory to `~/.claude/skills/bssh/` or use the included `install.sh` script.

The bssh Python script is bundled at `~/.claude/skills/bssh/scripts/bssh`.

## Default Behavior

**IMPORTANT**: Always use bssh instead of bare `ssh` commands when executing commands on remote hosts. Only use bare ssh for interactive sessions or when bssh is explicitly not appropriate.

**CRITICAL**: When the user does NOT provide a username, pass ONLY the hostname/IP to bssh (e.g., `bssh start 192.168.1.100`). Do NOT run `whoami` or any other command to determine a username. Let SSH use its default behavior (current user or SSH config).

You have access to the `bssh` command-line tool for managing persistent SSH sessions. This tool is located at `~/.claude/skills/bssh/scripts/bssh` and maintains an open SSH connection in the background, allowing you to run multiple commands while preserving state (current directory, environment variables, etc.) between commands.

## ⚠️ CRITICAL SAFETY RULES - REMOTE SYSTEM PROTECTION ⚠️

**These remote systems are SENSITIVE. One mistake could cause significant damage. Follow these rules STRICTLY:**

### NEVER RUN DANGEROUS COMMANDS WITHOUT EXPLICIT USER PERMISSION:

**FORBIDDEN commands on remote systems (via bssh exec) without explicit user approval:**
- **ANY `sudo` command** - Requires root privileges, can break system
- `rm -rf` or `rm -rf *` - Can destroy entire directories
- `rm` with wildcards (`rm *.conf`, `rm /path/*`) - Can delete multiple critical files
- `dd` commands - Can overwrite disks/partitions
- `mkfs` or formatting commands - Can destroy filesystems
- `chmod -R` or `chown -R` - Can break permissions on entire directory trees
- `sed -i` or in-place file editing - Can corrupt configuration files
- `>` or `>>` redirects that overwrite/append to files - Can corrupt files
- Package removal commands (`yum remove`, `apt remove`, etc.) - Can break system
- Service stop/restart commands (`systemctl stop/restart`, `service restart`, etc.) - Can disrupt running systems
- Any command that modifies `/etc`, `/boot`, `/usr`, or other system directories

**REQUIRED PROCEDURE before running ANY potentially dangerous command:**
1. Stop and explain to the user EXACTLY what command you want to run
2. Explain WHY you need to run it and WHAT it will change
3. Display this warning banner:
   ```
   ⚠️⚠️⚠️ DANGEROUS REMOTE COMMAND WARNING ⚠️⚠️⚠️
   System: <hostname>
   Command: <exact command>
   Effect: <what will be changed/deleted/modified>
   Risk Level: HIGH
   
   This command will make permanent changes to the remote system.
   Type 'ALLOW' to proceed or 'CANCEL' to abort.
   ```
4. Wait for user to explicitly type "ALLOW" or similar clear consent
5. Only then execute the command

### HYBRID APPROACH - SSHFS FOR FILES, BSSH EXEC FOR COMMANDS:

**CRITICAL**: Use the correct tool for each operation:

**Use SSHFS mount (Read/Write tools) ONLY for:**
- ✅ Reading file contents with Read tool
- ✅ Writing/editing file contents with Edit/Write tools (after getting permission)

**Use BSSH EXEC for ALL other operations:**
- ✅ Running `grep`, `find`, `ls`, `cat`, `head`, `tail` on remote system
- ✅ Moving files (`mv`)
- ✅ Copying files (`cp`)
- ✅ Changing permissions (`chmod`)
- ✅ Creating directories (`mkdir`)
- ✅ Any bash command or operation

**DO NOT run bash commands against the sshfs mount:**
- ❌ `ls /tmp/bssh/host/sshfs/path/` - Use `bssh exec host 'ls /path/'` instead
- ❌ `grep pattern /tmp/bssh/host/sshfs/file` - Use `bssh exec host 'grep pattern /path/file'` instead
- ❌ `mv /tmp/bssh/host/sshfs/file1 /tmp/bssh/host/sshfs/file2` - Use `bssh exec host 'mv /path/file1 /path/file2'` instead
- ❌ `cp -r /tmp/bssh/host/sshfs/dir1 /tmp/bssh/host/sshfs/dir2` - Use `bssh exec host 'cp -r /path/dir1 /path/dir2'` instead

**Why this matters:**
- sshfs operations are slower and can timeout
- bash commands run natively on remote system are faster and more reliable
- File I/O through sshfs uses the Read/Write tools which are optimized for that purpose

**Example correct workflow:**
1. Find files: `bssh exec host 'find /var/log -name "*.log"'`
2. Read a file: `Read tool on /tmp/bssh/host/sshfs/var/log/app.log`
3. Edit the file: `Edit tool on /tmp/bssh/host/sshfs/var/log/app.log` (after permission)
4. List directory: `bssh exec host 'ls -la /var/log'`

### FILE EDITING ON REMOTE SYSTEMS:

**DO NOT edit ANY files on remote systems (via sshfs mount) without following this procedure:**

1. **For reading files**: Always safe, no warning needed
   - Small/medium files: Use Read tool on sshfs mount: `/tmp/bssh/<host>/sshfs/path/to/file`
   - Large files: Use `bssh exec host 'grep -C 50 pattern /path/file'` to read relevant sections with context

2. **For editing files**: ALWAYS warn first
   - Before using Edit/Write tools on sshfs-mounted files
   - Show the warning banner (as above) with the specific file path
   - Get explicit user consent with "ALLOW"

3. **For editing LARGE files (too big to read entirely via sshfs):**
   - **NEVER use `sed -i` or in-place editing commands**
   - Instead, use this safe approach:
     1. Use `bssh exec host 'grep -C 50 pattern /path/large-file'` to get context around the section you need to edit
     2. Identify the line numbers from the grep output
     3. Get user permission with warning banner
     4. Use Edit tool on `/tmp/bssh/host/sshfs/path/large-file` with the old_string and new_string from the grep context
     5. The Edit tool can handle large files efficiently by only modifying the specific section
   - This approach is MUCH SAFER than sed because:
     - You can verify the exact text before changing it
     - Edit tool validates the match exists
     - No risk of corrupting the file with wrong regex
     - User can see exactly what will change

4. **Prefer safe alternatives:**
   - Instead of `sed -i` on remote: Use `bssh exec` grep → Edit tool via sshfs → verify changes
   - Instead of `rm -rf`: Ask user to verify specific files first, then use `bssh exec host 'rm /specific/file'`
   - Instead of modifying system files directly: Read first, discuss changes with user

### EXAMPLE: Editing a large file safely

**Wrong approach (FORBIDDEN):**
```bash
bssh exec host 'sed -i "s/old_value=123/new_value=456/" /etc/large-config.conf'  # ❌ DANGEROUS
```

**Correct approach:**
```bash
# Step 1: Find the context around what you need to change
bssh exec host 'grep -C 50 "old_value" /etc/large-config.conf'

# Step 2: Get user permission (show warning banner)

# Step 3: Use Edit tool with the exact old_string from grep output
Edit tool on /tmp/bssh/host/sshfs/etc/large-config.conf
  old_string: "old_value=123"
  new_string: "new_value=456"
```

### SESSION-SPECIFIC PERMISSIONS:

**IMPORTANT**: User permission to edit files is SESSION-SPECIFIC. Just because a user allowed you to edit a file in a previous conversation does NOT mean you have permission in this session. ALWAYS ask for permission in EACH new session before making ANY changes to remote systems.

### EXAMPLE FORBIDDEN ACTIONS:

❌ `bssh exec host 'sudo systemctl restart critical-service'` - Running sudo without permission
❌ `bssh exec host 'sudo yum remove package'` - Running sudo without permission
❌ `bssh exec host 'rm -rf /tmp/*'` - Running dangerous command without warning
❌ `bssh exec host 'sed -i "s/foo/bar/" /etc/config'` - Modifying system files without approval
❌ Writing to sshfs-mounted files without warning
❌ `ls /tmp/bssh/host/sshfs/var/log/` - Running bash commands on sshfs mount
❌ `grep pattern /tmp/bssh/host/sshfs/file` - Should use bssh exec instead
❌ Assuming you can edit files because user said "yes" in a previous session

### EXAMPLE CORRECT ACTIONS:

✅ `bssh exec host 'cat /var/log/app.log'` - Reading via bssh exec is safe
✅ `bssh exec host 'ls -la /var/log'` - Running commands via bssh exec
✅ `bssh exec host 'grep pattern /path/file'` - Searching via bssh exec
✅ Using Read tool on `/tmp/bssh/host/sshfs/var/log/app.log` - Reading via sshfs is safe
✅ Asking user for permission before ANY file modification
✅ Using `bssh exec` for all bash operations, sshfs only for Read/Write tools
✅ Explaining risks before running potentially dangerous commands

## Commands

### Start a session

**With explicit username:**
```bash
~/.claude/skills/bssh/scripts/bssh start <user> <host>
```

**Without username (uses SSH defaults):**
```bash
~/.claude/skills/bssh/scripts/bssh start <host-or-ip>
```
When no username is provided, SSH will use the current local username or settings from `~/.ssh/config`. **Do NOT run whoami or other commands to determine the username - just pass the host/IP directly.**

### Execute command

**With explicit username:**
```bash
~/.claude/skills/bssh/scripts/bssh exec <user> <host> '<command>'
```

**Without username (uses SSH defaults):**
```bash
~/.claude/skills/bssh/scripts/bssh exec <host-or-ip> '<command>'
```

### Mount remote filesystem (sshfs)

**REMINDER: See "CRITICAL SAFETY RULES" section above before using sshfs for file editing.**

The sshfs command mounts the remote filesystem locally. **BY DEFAULT, this is for READING FILES ONLY.** 

**With explicit username:**
```bash
~/.claude/skills/bssh/scripts/bssh sshfs <user> <host>
```

**Without username:**
```bash
~/.claude/skills/bssh/scripts/bssh sshfs <host-or-ip>
```

This mounts the remote filesystem at `/tmp/bssh/<session-id>/sshfs/` where you can read remote files directly. The session must be in "connected" status before running sshfs.

**Usage Pattern:**
- Use `sshfs` ONLY when you need to READ or WRITE files on the remote system
- Use `exec` for all other commands (grep, ls, find, etc.) as it's more efficient
- The mount point is at `/tmp/bssh/<session-id>/sshfs/`
- The mount is automatically unmounted when you run `stop`
- **NEVER edit files without following the safety procedure in "CRITICAL SAFETY RULES" section**

### Stop a session

**With explicit username:**
```bash
~/.claude/skills/bssh/scripts/bssh stop <user> <host>
```

**Without username:**
```bash
~/.claude/skills/bssh/scripts/bssh stop <host-or-ip>
```

**NOTE:** The stop command will automatically unmount any active sshfs mount before stopping the SSH session.

### Check status

**With explicit username:**
```bash
~/.claude/skills/bssh/scripts/bssh status <user> <host>
```

**Without username:**
```bash
~/.claude/skills/bssh/scripts/bssh status <host-or-ip>
```

## Key Features

- **State Preservation**: Directory changes (cd), environment variables, and other shell state persist across commands
- **Background Process**: Maintains connection in background, no need to reconnect for each command
- **Session Management**: Each user@host combination has its own persistent session
- **Filesystem Access**: Mount remote filesystem via sshfs for reading/writing files
- **Session Files**: Stores session state in `/tmp/bssh/`

## Usage Patterns

### Basic workflow with explicit user@host:
```bash
# Start session
~/.claude/skills/bssh/scripts/bssh start user remote.host.com

# Change directory - state persists!
~/.claude/skills/bssh/scripts/bssh exec user remote.host.com 'cd /var/www'

# Run command in that directory
~/.claude/skills/bssh/scripts/bssh exec user remote.host.com 'pwd'  # Shows /var/www
~/.claude/skills/bssh/scripts/bssh exec user remote.host.com 'ls'   # Lists files in /var/www

# Clean up when done
~/.claude/skills/bssh/scripts/bssh stop user remote.host.com
```

### Using just IP address (no username - SSH uses defaults):
```bash
# Start session - DO NOT run whoami or other commands to get username!
~/.claude/skills/bssh/scripts/bssh start 192.168.1.100

# Execute commands
~/.claude/skills/bssh/scripts/bssh exec 192.168.1.100 'pwd'
~/.claude/skills/bssh/scripts/bssh exec 192.168.1.100 'ls'

# Clean up
~/.claude/skills/bssh/scripts/bssh stop 192.168.1.100
```

### Using SSH config hostnames:
```bash
# Start session with SSH config hostname (uses config for user and IP)
~/.claude/skills/bssh/scripts/bssh start device123

# Execute commands
~/.claude/skills/bssh/scripts/bssh exec device123 'cd /var/www'
~/.claude/skills/bssh/scripts/bssh exec device123 'pwd'

# Clean up
~/.claude/skills/bssh/scripts/bssh stop device123
```

### Using sshfs to read remote files:
```bash
# Start and connect
~/.claude/skills/bssh/scripts/bssh start device123

# Mount the filesystem (ONLY when needed to read/write files)
~/.claude/skills/bssh/scripts/bssh sshfs device123

# Now you can read files at /tmp/bssh/device123/sshfs/
# For example: cat /tmp/bssh/device123/sshfs/etc/config.txt

# IMPORTANT: Before editing ANY files, warn the user and get explicit permission!

# Clean up (automatically unmounts sshfs)
~/.claude/skills/bssh/scripts/bssh stop device123
```

### Check before starting:
```bash
# Check if session already exists (works with any format)
~/.claude/skills/bssh/scripts/bssh status 192.168.1.100
~/.claude/skills/bssh/scripts/bssh status device123
~/.claude/skills/bssh/scripts/bssh status user remote.host.com

# If not connected, start it
~/.claude/skills/bssh/scripts/bssh start 192.168.1.100
```

## When to Use

### Use bssh exec when:
- Running commands that don't require file I/O (grep, ls, find, ps, etc.)
- User needs to run multiple commands on a remote server
- Commands depend on state changes (cd to directory, set env vars, etc.)
- User wants to avoid reconnecting for each command
- Working with remote git repositories, build processes, or multi-step operations

### Use bssh sshfs when:
- **ONLY** when you need to read or write files on the remote system
- User asks to read a specific file's contents
- User asks to edit/modify a file (AFTER getting explicit permission with warning!)
- Need to copy files to/from the remote system

**Do NOT use sshfs by default.** Only use it when file I/O is specifically needed.

### Username handling:
- If user provides explicit username: use `bssh start user host`
- If user provides ONLY IP/hostname: use `bssh start host` (DO NOT look up username with whoami or other commands)
- If user provides SSH config hostname: use `bssh start hostname`

### Use regular ssh when:
- Only running a single command
- No state needs to persist
- Interactive terminal is required

## Important Notes

- Always quote the command argument to bssh exec to prevent local shell expansion
- Sessions run in background - use `stop` to clean up when done
- Each user@host pair can have one persistent session
- Commands timeout after 30 seconds by default
- Exit codes from remote commands are preserved
- sshfs mounts are automatically unmounted when stopping the session
- Prefer `exec` over `sshfs` for commands that don't need file I/O
