pi-landstrip
Sandboxed Bash and process-backed agents for Pi
Package details
Install pi-landstrip from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-landstrip- Package
pi-landstrip- Version
0.18.26- Published
- Aug 6, 2026
- Downloads
- 14.7K/mo · 4,203/wk
- Author
- jarkkojs
- License
- Apache-2.0
- Types
- extension
- Size
- 264.9 KB
- Dependencies
- 4 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./dist/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-landstrip
pi-landstrip adds sandboxed Bash, primary agents, and process-backed subagents
to Pi. OS isolation is provided by
landstrip.
Requires Pi 0.82.0 or later and Node.js 22.19.0 or later.
Installation
pi install npm:pi-landstrip
For a manual install, add the package to global or trusted project
settings.json:
{
"packages": ["npm:pi-landstrip"]
}
The package includes native Linux, macOS, and Windows binaries for x64 and Arm64. On unsupported platforms, the extension loads with sandboxing disabled.
Behavior
AI Bash calls and shell commands entered with ! or !! run through
Landstrip. Subagents run as separate Pi RPC processes and are sandboxed unless
the sandbox is explicitly disabled.
The root Pi process is trusted. Pi filesystem tools and plugin callbacks run outside the OS sandbox. Agent permissions still control tool dispatch, but they are not an OS isolation boundary. On Linux and macOS, primary Bash reads therefore use the same host view by default; writes remain sandboxed. Subagent processes retain the configured read and write policy.
The default sandbox policy limits writes to the project and restricts worker reads within the user's home to the project and a few bootstrap files. Direct network access is blocked. When the platform permits loopback, the extension's proxy filters allowed HTTP and HTTPS domains.
When a command needs more access, Pi can allow it once, for the session, or in
the project or global policy. Project approvals go to .pi/sandbox.json and
global approvals to ~/.pi/agent/sandbox.json.
/sandboxinspects and toggles the sandbox./agentsselects agents, edits agent settings, and shows task sessions.Ctrl+Shift+Acycles visible primary agents while Pi is idle.
Disabling the sandbox
Use --no-sandbox or set enabled to false in sandbox.json:
{
"enabled": false
}
Subagents remain separate processes but lose Landstrip OS isolation. Pi warns
once per session. Trusted project config overrides global config; /sandbox
updates a project sandbox file when present, otherwise the global file.
Shell read access
"shell": { "readAccess": "host" } keeps primary Bash and !/!! reads
consistent with trusted Pi filesystem tools. Set readAccess to "policy" to
apply filesystem.denyRead and filesystem.allowRead to shell commands as an
intentional stricter boundary. Worker processes always use the filesystem read
policy. Windows always uses policy reads because its sandbox requires an explicit
read allowlist.
Permission layers
| Layer | Checked | Controls |
|---|---|---|
| Agent permission | Before a tool runs | Which tools the agent may call |
| Sandbox policy | During a command | Filesystem and network access |
An agent approval allows tool dispatch; the sandbox still applies to the resulting process.
Agents
The built-in primary agents are build and plan. The built-in subagents are
explore, general, and scout. /agents can activate, edit, or disable
configured agents.
The task tool starts a subagent. It accepts:
{
"description": "Review sandbox boundary",
"prompt": "Review the sandbox implementation and report concrete issues.",
"subagent_type": "explore",
"task_id": "optional-session-id",
"command": "optional-originating-command",
"background": false
}
description, prompt, and subagent_type are required. Foreground tasks
return their result directly. Background tasks return immediately and report
completion later. Continue a saved task with task_id; inspect it with
/agents <id>.
Workers use normal Pi resource discovery and plugin loading. Each task starts a
fresh process; continuing a task restores its saved session in a new process.
Agent deny, ask, and allow rules are checked before tool dispatch.
Model requests originate inside each worker. Workers can read Pi authentication and inherited credential environment variables. Loaded worker plugins share that access, so install only trusted plugins and use suitable credentials.
Configuration
Agent settings are read from ~/.pi/agent/settings.json and, for trusted
projects, .pi/settings.json. Sandbox settings are read from
~/.pi/agent/sandbox.json and .pi/sandbox.json.
{
"landstrip": {
"maxSubagents": 2,
"agent": {
"review": {
"description": "Review code without modifying it",
"mode": "subagent",
"prompt": "Report concrete findings.",
"permission": {
"edit": "deny",
"bash": "ask"
}
}
},
"permission": {
"task": {
"*": "deny",
"review": "allow"
}
}
}
}
landstrip.maxSubagents is the concurrency limit, from 0 to 16. Zero disables
the task tool. Agent definitions support mode, prompt, model, variant,
steps, color, hidden, disable, options, and permission rules. Modes
are primary, subagent, or all.
Pi Markdown agents are loaded from ~/.pi/agent/agents/ and .pi/agents/.
landstrip.agent settings override Markdown agents with the same name.
Project definitions override global definitions.
For example, save this advisor subagent as ~/.pi/agent/agents/advisor.md:
---
description: Escalate to a stronger reviewer for a plan, correction, or stop signal
mode: subagent
hidden: false
variant: high
permission:
'*': deny
read: allow
grep: allow
glob: allow
list: allow
---
You are an advisor model in an advisor-strategy pattern. An executor model is running a task end-to-end — calling tools, reading results, iterating toward a solution. When the executor hits a decision it cannot reasonably solve alone, it consults you for guidance via the `task` tool with `subagent_type: "advisor"`.
The executor should put the full situation in the task prompt: the goal, what it has tried, tool results that matter, current hypothesis, and the decision it needs. You may use read-only tools to verify claims against the repository when file paths are given; do not modify anything.
Return ONE of:
- a **plan** (concrete next steps the executor should take),
- a **correction** (the executor is going down a wrong path — redirect it),
- a **stop signal** (the executor should halt and escalate to the user).
Be concise, directive, and grounded in the shared context. Name files, functions, and line numbers where possible. No preamble, no apologies, no meta-commentary about being an advisor — just the guidance the executor needs.
Give advice serious weight for the executor: prefer primary-source evidence and root causes over temporary fixes. If requirements are ambiguous or contradictory, stop and say what the user must decide.
See the main Landstrip documentation
for sandbox.json fields and platform policy semantics.
Platform notes
- Linux: blocked operations can be approved while the command is running.
- macOS: a worker's Seatbelt policy is fixed at startup; restart the task to apply new filesystem access.
- Windows: the bundled policy uses standard AppContainer because Pi's Git
Bash cannot start in LPAC. Standard mode is weaker than LPAC.
windows.allowLoopbackenables the domain proxy but exposes every local loopback service. Restricted-user mode avoids that broad exemption.
Install restricted-user mode from the intended Windows host account, then restart Pi:
npx @landstrip/landstrip windows install
npx @landstrip/landstrip windows status
Remove it with npx @landstrip/landstrip windows uninstall.
Plugin API
Other Pi extensions can discover the v2 runtime with useLandstrip from
pi-landstrip/api. The runtime provides:
getContext()for sandbox and task context.registerShellProvider()for replacing POSIX shell invocation preparation.prepareProcess()for one policy-aware process launch.registerWorkerExtension()for trusted worker extensions.on()for sandbox and subagent lifecycle events.
A shell provider receives the command, working directory, composed command
environment, and abort signal. It returns an executable, arguments, minimal
launcher environment, required read paths, and optional cleanup. Landstrip adds
platform variables required by its launcher, such as Windows ProgramData.
Providers should pass the composed environment through a private temporary file,
include that file in readPaths, and remove it in dispose(); do not copy secrets
into launcherEnv. Landstrip remains responsible for starting the process, applying
policy, proxying network access, handling traps, and prompting for additional
access. Only one external provider can be active; disposing it restores the
built-in POSIX provider.
Use provideLandstripShell() to register a provider independently of extension
load order. Shell providers and worker extensions are trusted code. Workers also
receive an informational LANDSTRIP_CONTEXT environment value; it is not proof
of authorization.
Limits
At most maxSubagents tasks run concurrently. Nested task depth is capped at
3, and a nested task tool is available only when the parent agent has explicit
permission. Session switching and shutdown stop live workers.
License
pi-landstrip is licensed under Apache-2.0. See LICENSE. The
bundled @landstrip/landstrip package is licensed separately as
Apache-2.0 AND LGPL-2.1-or-later.