@marcfargas/pi-tramp

TRAMP-like transparent remote execution for pi — tools execute remotely, pi stays local

Package details

extension

Install @marcfargas/pi-tramp from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@marcfargas/pi-tramp
Package
@marcfargas/pi-tramp
Version
0.2.0
Published
Feb 22, 2026
Downloads
36/mo · 11/wk
Author
marcfargas
License
MIT
Types
extension
Size
282.5 KB
Dependencies
1 dependency · 1 peer
Pi manifest JSON
{
  "extensions": [
    "./src/extension.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-tramp

TRAMP-like transparent remote execution for pi.

Pi stays local (brain). Tools (read, write, edit, bash) execute on remote targets via SSH or Docker.

Quick Start

# Install
npm install @marcfargas/pi-tramp

# Add to pi
pi -e pi-tramp

Then use the target tool in a pi session:

> target add myserver --config {"type":"ssh","host":"user@myserver.example.com","shell":"bash"}
> target switch myserver
# All tool calls now execute on myserver

Configuration

Interactive (target tool)

The fastest way — add targets on the fly:

> target add dev --config {"type":"ssh","host":"user@dev.example.com","cwd":"/home/user/project","shell":"bash"}
> target switch dev

File-based (targets.json)

Create .pi/targets.json in your project (or ~/.pi/targets.json globally):

{
  "default": "dev",
  "targets": {
    "dev": {
      "type": "ssh",
      "host": "user@dev-server.example.com",
      "cwd": "/home/user/project",
      "shell": "bash"
    },
    "staging": {
      "type": "ssh",
      "host": "deploy@staging.example.com",
      "identityFile": "~/.ssh/staging_key",
      "cwd": "/opt/app",
      "shell": "bash"
    },
    "docker-dev": {
      "type": "docker",
      "container": "my-dev-container",
      "cwd": "/workspace"
    }
  }
}

Project config overrides global by target name. The default target auto-connects on session start.

Transport Types

SSH

{
  "type": "ssh",
  "host": "user@hostname",
  "port": 22,
  "identityFile": "~/.ssh/id_ed25519",
  "cwd": "/remote/working/directory",
  "shell": "pwsh",
  "timeout": 60000
}
  • Keys only — no password auth (SSH agent or identityFile)
  • Persistent connection — single SSH process, sentinel protocol for command demarcation
  • shell is required — set "shell": "bash" for Linux/macOS targets, "shell": "pwsh" for Windows/PowerShell targets
  • cwd is optional — if omitted, it resolves to the remote home directory on connect
  • Uses Windows SSH (C:\Windows\System32\OpenSSH\ssh.exe) on Windows for agent access

pwsh targets (Windows servers, PowerShell hosts)

When "shell": "pwsh" is configured, pi-tramp:

  1. Connects with a clean -NoProfile -NonInteractive session
  2. Wraps all commands in pwsh-compatible syntax
  3. Uses .NET APIs for file I/O ([IO.File]::ReadAllBytes, [Convert]::ToBase64String)

Set "shell": "pwsh" for any target running Windows PowerShell or PowerShell 7+.

Docker

{
  "type": "docker",
  "container": "container-name-or-id",
  "cwd": "/workspace",
  "shell": "bash",
  "timeout": 30000
}
  • One-shot — each command is a separate docker exec
  • Shell selection — uses configured shell when provided; otherwise resolves container shell on connect
  • cwd is optional — defaults to container's home directory

Usage

Once a target is active, all tool calls automatically route there:

You: Read src/index.ts
→ reads /home/user/project/src/index.ts on dev-server

You: Run the tests
→ executes on dev-server via SSH

You: Edit src/config.ts, change the port to 8080
→ reads remote file, applies edit, writes back (CRLF-safe)

Target Management

The target tool supports:

Action Description
target list Show available targets and which is active
target switch <name> Switch to a target (or "local" for local)
target status Show connection health for all targets
target add <name> --config <json> Add a dynamic target (not persisted)
target remove <name> Remove a dynamic target

Status Bar

When a target is active, the footer shows:

  • 🔗 SSH targets with host, shell, and platform
  • 🐳 Docker targets with container name and shell

Context Injection

On target switch, pi-tramp:

  1. Modifies the system prompt with target info (type, shell, platform, CWD)
  2. Reads remote .pi/AGENTS.md (if present, max 100 lines) and injects it
  3. Updates the status bar

Config Reference

Target Config Fields

Field Type Required Default Description
type "ssh" | "docker" Transport type
host string SSH only user@hostname
port number 22 SSH port
identityFile string Path to SSH private key
container string Docker only Container name or ID
cwd string home dir Remote working directory
shell "bash" | "sh" | "pwsh" SSH: ✅ Shell to use: "bash" for Linux/macOS, "pwsh" for Windows
timeout number (ms) SSH: 60000, Docker: 30000 Command timeout

Targets File

{
  "default": "target-name",
  "targets": {
    "name": { /* target config */ }
  }
}
  • default — auto-connect on session start ("local" or omit for no default)
  • "local" is a reserved name — means "no remote target"
  • Target names: alphanumeric, dashes, underscores

Public API (trampExec)

Other pi extensions can execute commands on remote targets:

import { trampExec } from "@marcfargas/pi-tramp";

// Execute on current target
const result = await trampExec("ls -la");
console.log(result.stdout);

// Execute on a specific target
const result = await trampExec("hostname", { target: "staging" });

// With timeout and abort
const controller = new AbortController();
const result = await trampExec("make build", {
  timeout: 120000,
  signal: controller.signal,
});

Architecture

┌─────────────────────────────────────────────────┐
│ pi (local)                                       │
│                                                   │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐       │
│  │ read     │  │ write    │  │ edit     │  bash  │
│  │ override │  │ override │  │ override │  ...   │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘       │
│       │              │              │              │
│  ┌────▼──────────────▼──────────────▼────┐       │
│  │         operations-remote              │       │
│  │   (ReadOps, WriteOps, EditOps, Bash)   │       │
│  └────────────────┬──────────────────────┘       │
│                    │                               │
│  ┌────────────────▼──────────────────────┐       │
│  │          ConnectionPool                │       │
│  │    (lazy connect, cache, reconnect)    │       │
│  └────┬───────────────────────┬──────────┘       │
│       │                       │                   │
│  ┌────▼─────┐           ┌────▼─────┐            │
│  │ SSH      │           │ Docker   │            │
│  │Transport │           │Transport │            │
│  │(sentinel)│           │(one-shot)│            │
│  └──────────┘           └──────────┘            │
└─────────────────────────────────────────────────┘

Key design decisions:

  • Serial command queue — prevents concurrent SSH session corruption
  • Sentinel protocol — UUID markers delimit command output in persistent SSH
  • Explicit shell configshell is required for SSH; no probe/reconnect overhead
  • Base64 for file I/O — reliable binary transfer (bash: base64, pwsh: .NET APIs)
  • CRLF handling — pi's edit tool transparently normalizes line endings for matching, then restores original endings on write
  • 10MB file limit — clear errors for oversized files
  • POSIX single-quote escaping — works across bash/sh/dash/zsh/ash

Limitations

  • SSH keys only — no password authentication
  • No port forwarding — Phase 2
  • No WSL or PSRemote transports — Phase 2
  • 10MB max file size — for read/write operations
  • BashDriver requires base64 — available in full Git for Windows and Linux coreutils, not in MinGit
  • PS 5.1 Unicode — Windows PowerShell 5.1's console can't round-trip all Unicode via stdout (pwsh 7.2+ works fine)

Development

# Install dependencies
npm install

# Unit tests (no Docker required)
npm test

# Integration tests — Linux containers (requires Docker)
docker build -t pi-tramp-ssh-test test/fixtures/ssh-server/
docker run -d --name pi-tramp-ssh-test -p 2222:22 pi-tramp-ssh-test
npm run test:integration

# Integration tests — Windows containers (CI only, requires windows-latest runner)
# Set PI_TRAMP_TARGET_OS=windows for Windows container tests

# Lint + type check
npm run lint
npm run typecheck

CI Matrix

Runner Tests
ubuntu-latest × Node 20/22/24 Unit tests
windows-latest × Node 20/22/24 Unit tests
ubuntu-latest Integration: Docker×bash, Docker×pwsh, SSH×bash, SSH×pwsh (Linux container)
windows-latest Integration: Docker×bash, Docker×pwsh, SSH×bash, SSH×pwsh (Windows container)

License

MIT