Skip to content

Repository files navigation

pi-extension-ssh

CI Release License: MIT

Remote operations for Pi over SSH.

pi-extension-ssh turns SSH from an occasional shell escape into a repeatable Pi capability with:

  • remote session mode
  • remote tool routing
  • local audit logging
  • target profiles
  • allowlist support
  • environment guardrails
  • confirmation for prod and other protected targets

Created by Fabio Rizzo Matos · contact: fabiorizzo@vindula.com.br


Why this exists

You can already do this with plain shell commands:

ssh user@host "cd /srv/app && docker ps"

But that is not the same as giving Pi a real remote operating mode.

With this package installed, Pi can treat the remote host as the working environment itself.

That matters when you want:

  • repeatable remote sessions instead of one-off SSH hops
  • ssh-read, ssh-write, ssh-edit, ssh-bash, ssh-grep, ssh-find, ssh-ls operating remotely by default
  • an audit trail in .pi/ssh/ssh.log
  • stable target names like prod-app, staging-app, bastion-eu
  • environment-aware controls for sensitive systems

In short:

  • plain SSH = good for ad-hoc commands
  • pi-extension-ssh = good for remote operations workflows

What you get

1. Remote session mode

Run a whole Pi session against a remote host:

pi -e ./ssh.ts --ssh user@host
pi -e ./ssh.ts --ssh user@host:/remote/path
pi -e ./ssh.ts --ssh prod-app

When --ssh is active:

  • Pi resolves a remote working directory
  • ssh-read, ssh-write, ssh-edit, ssh-bash, ssh-grep, ssh-find, ssh-ls operate on the remote machine by default
  • user !commands also execute remotely
  • the status bar shows the active remote target
  • connect runs an automatic preflight check and surfaces missing remote tools early
  • the system prompt reflects the remote cwd and environment

If you explicitly want the SSH extension to override the built-in tool names (read, write, edit, bash, grep, find, ls), set this in .pi/ssh/config.json or ~/.pi/agent/ssh/config.json:

{
  "toolRoutingMode": "builtin-overrides"
}

Default:

  • toolRoutingMode: "namespaced" to avoid conflicts with tool wrappers such as pi-tool-display

2. /ssh-run

Run a one-off remote command without switching the whole session:

/ssh-run user@host:/srv/app ls -la
/ssh-run prod-app docker ps

3. Automatic preflight + manual health checks

On /ssh-connect and --ssh, the extension runs a lightweight preflight check automatically.

That verifies:

  • connectivity
  • resolved remote pwd
  • expected remote tools such as bash, cat, mkdir, base64, file, rg, and fd

You can also run the same verification on demand with:

/ssh-health
/ssh-health prod-app

4. Audit logging

SSH activity is logged locally to:

.pi/ssh/ssh.log

Each line is structured JSON and can include metadata such as:

  • remote target
  • profile
  • environment
  • mode
  • decision (executed, blocked, confirmed, denied)
  • reason

5. Profiles, allowlist, and guardrails

The package supports project-local and global SSH config files:

  • project: <project>/.pi/ssh/config.json
  • global: ~/.pi/agent/ssh/config.json

This lets you:

  • define friendly target names
  • restrict where Pi is allowed to connect
  • require confirmation for protected targets
  • block dangerous commands in certain environments
  • keep shared global targets read-only while still importing them into a project when local overrides are needed

6. TUI target management

The extension now includes a TUI-first target manager:

  • create local config with /ssh-configure
  • manage local targets with /ssh-manage
  • view both project-local and global targets in one place
  • import global targets into project-local config for safe per-project overrides

7. SSH runbooks

You can store runbooks in:

  • project: <project>/.pi/ssh/runbooks/*.{md,markdown,json}
  • global: ~/.pi/agent/ssh/runbooks/*.{md,markdown,json}

Markdown runbooks use frontmatter plus fenced command blocks, which makes them easier to read and review.

Runbooks let you:

  • define repeatable operational checklists
  • bind a default target to a named workflow
  • preview steps before execution
  • require per-runbook or per-step confirmation
  • pass parameters such as service, container, and path
  • pass extra generic parameters with --param key=value or inline flags like --release=2026.03.23
  • keep execution tied to the same SSH guardrails and logs

Install

From GitHub

pi install git:github.com/vindulaintranet/pi-extension-ssh

Pin to a release tag

pi install git:github.com/vindulaintranet/pi-extension-ssh@v0.1.6

From a local path

pi install /absolute/path/to/pi-extension-ssh

After installing, restart Pi or run:

/reload

Quick start

Ad-hoc remote command

/ssh-run user@host:/srv/app docker ps

Full remote session

pi -e ./ssh.ts --ssh user@host:/srv/app

Interactive profile connection

/ssh-connect

If no targets exist yet, the extension can now open a TUI wizard and create .pi/ssh/config.json for you.

After that, use /ssh-manage to add, edit, remove, review, filter/search, import, or connect targets without manually opening the JSON first.

SSH operations context

/ssh-context
/ssh-health
/ssh-summary
/ssh-runbooks
/ssh-runbook
/ssh-disconnect

Profile-based session

Add a config file:

{
  "allowlist": ["staging-app", "prod-app"],
  "targets": {
    "staging-app": {
      "remote": "ops@staging-host",
      "cwd": "/srv/app",
      "environment": "staging"
    },
    "prod-app": {
      "remote": "ops@prod-host",
      "cwd": "/srv/app",
      "environment": "prod",
      "requiresConfirmation": true,
      "aliases": ["production"]
    }
  },
  "environmentPolicies": {
    "prod": {
      "requiresConfirmation": true,
      "confirmWriteOperations": true,
      "confirmMutatingCommands": true,
      "blockedCommands": [
        "rm -rf",
        "git reset --hard",
        "terraform destroy"
      ]
    }
  }
}

Then run:

pi -e ./ssh.ts --ssh prod-app

List configured targets with:

/ssh-targets

Create a project-local SSH config through the TUI:

/ssh-configure

Manage project-local SSH targets through the TUI:

/ssh-manage

The manager shows both:

  • project-local targets you can edit here
  • global targets that are read-only here, but importable into the project
  • a filter/search flow so large target sets are easier to navigate

Operational commands

  • /ssh-configure — create .pi/ssh/config.json through a TUI wizard
  • /ssh-manage — add, edit, remove, review, filter/search, connect, and import global targets into project-local config from the TUI
  • /ssh-connect — choose a configured target interactively or pass one explicitly; offers config creation when none exist
  • /ssh-disconnect — leave the active SSH session target
  • /ssh-context — inspect the active target, policies, preflight status, and log path
  • /ssh-health [target] — verify connectivity and required remote tools on demand
  • /ssh-summary [--format text|markdown|json|raw] [--output <path>] [--last] [--include-entries] [--raw] — review or export the current/recent SSH session summary, including runbook reports when present
  • /ssh-runbook-report [name] [--format text|markdown|json] [--output <path>] [--last] — export just the runbook execution report(s) from the current or most recent session
  • /ssh-runbooks [query|--filter <query>] — list or filter available project-local and global SSH runbooks
  • /ssh-runbook <name> [--target <target>] [--service <name>] [--container <name>] [--path <path>] [--param key=value] [--filter <query>] — preview and execute a named SSH runbook with parameter overrides
  • /ssh-targets — list project-local and global profiles with source markers
  • /ssh-run <target> <command> — run one explicit remote command without switching the whole session

Example summary exports:

/ssh-summary
/ssh-summary --format markdown --include-entries --output .pi/ssh/reports/latest.md
/ssh-summary --format json --output .pi/ssh/reports/latest.json --last
/ssh-summary --raw --output .pi/ssh/reports/latest.jsonl --last

Example runbook usage:

/ssh-runbooks
/ssh-runbooks prod
/ssh-runbook prod-health-check --container app --param release=2026.03.23
/ssh-runbook staging-deploy-smoke --target staging-app --service web --path /srv/app
/ssh-runbook-report --format markdown --output .pi/ssh/reports/runbooks.md

Commercial / real-world use cases

Production app operations

Use profile-based access such as prod-app with confirmation and blocked commands for safer incident work.

Staging debugging

Point Pi at staging-app and let it inspect logs, config, and code remotely with normal tools.

Bastion-based admin work

Keep SSH targets named and documented instead of relying on remembered shell snippets.

Managed customer environments

Use target profiles per customer/tenant/region and maintain a local audit trail of remote activity.


Example config

This inline example is a compact illustration.

If you want copy-paste-ready templates for common setups, use the files in examples/:

{
  "allowlist": ["prod-app", "staging-app", "bastion-eu"],
  "targets": {
    "prod-app": {
      "remote": "ops@prod-host",
      "cwd": "/srv/app",
      "environment": "prod",
      "requiresConfirmation": true,
      "aliases": ["production"]
    },
    "staging-app": {
      "remote": "ops@staging-host",
      "cwd": "/srv/app",
      "environment": "staging"
    },
    "bastion-eu": {
      "remote": "admin@bastion-eu",
      "cwd": "/home/admin",
      "environment": "default"
    }
  },
  "environmentPolicies": {
    "prod": {
      "requiresConfirmation": true,
      "confirmWriteOperations": true,
      "confirmMutatingCommands": true,
      "blockedCommands": [
        "rm -rf",
        "git reset --hard",
        "terraform destroy",
        "shutdown",
        "reboot"
      ]
    }
  }
}

Enterprise local/global pattern

A practical enterprise setup is:

  • keep shared targets such as bastions, platform hosts, and approved base profiles in the global config
  • keep project-specific names, cwd values, aliases, and overrides in the local project config
  • keep shared operational runbooks in the global runbook directory and project-specific runbooks in the project runbook directory
  • prefer Markdown+frontmatter runbooks for human review, and keep JSON as an escape hatch for more structured cases
  • use /ssh-manage to view both layers and import a global target into the project when you need a local override

That gives you:

  • shared platform defaults
  • safer per-project customization
  • clearer ownership of what is centrally managed vs locally editable

Enterprise-oriented features included

This package already includes the agreed enterprise track features:

  • allowlist
  • host profiles
  • remote grep / find / ls
  • guardrails by environment
  • structured logs
  • confirmation for prod

Requirements

  • SSH key-based authentication
  • bash on the remote host
  • remote utilities used by the extension:
    • cat
    • test
    • mkdir
    • base64
    • file
    • rg for remote grep
    • fd for remote find

Current limitations

  • remote find currently expects fd on the remote host
  • remote grep currently expects rg on the remote host
  • target handling is config-driven; this version includes TUI setup and target management, but still keeps JSON as the source of truth
  • the TUI manager edits only project-local config; global targets are visible and importable, but remain read-only there
  • runbooks support Markdown+frontmatter and JSON, but this version does not yet provide advanced templating, branching, or variable typing
  • logs are structured JSONL locally, but no external export sink is included yet
  • historical summaries are session-scoped; this version does not provide arbitrary cross-session analytics

Validation

npm install
npm run validate

This runs:

  • unit tests for SSH parsing, config loading, allowlist/policy behavior, logging, command building, and truncation
  • bundle validation for the Pi extension entrypoint
  • package validation with npm pack --dry-run

Contributing and releasing

See:


License

MIT

About

Pi package for remote operations over SSH with audit logging and enterprise guardrails

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages