- Shell 83.5%
- TypeScript 15.6%
- Dockerfile 0.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| addons | ||
| bin | ||
| defaults | ||
| docker | ||
| .gitignore | ||
| install.sh | ||
| package.json | ||
| README.md | ||
| VERSION | ||
pis
pis is a small user-level wrapper for the Pi coding agent with explicit access
profiles.
The important choice is not “which backend”, but “how much access should the agent get?”
Profiles
pis [args...] # default: project profile
pis project [args...] # Docker sandbox, current project mounted read/write
pis inspect [args...] # host read-only inspection: read/grep/find/ls only
pis host [args...] # unrestricted host runtime, full access as your user
Recommended use:
pis/pis projectfor normal project work.pis inspectwhen you want the agent to look around the host without write or shell access.pis hostonly when you intentionally want full system-wide access.
project uses Docker internally. inspect and host use a Pi npm runtime
managed by pis under ~/.local/share/pis/runtime.
Install
From a local checkout:
git clone <repo-url> pis
cd pis
./install.sh
Install/update wrapper files, the bundled package catalog, and managed configuration without installing runtimes or Pi packages:
./install.sh --no-build
The installer is idempotent. It updates the wrapper, Dockerfile, package
catalog, managed global instructions, and pi-subagents defaults, but it does
not delete sessions or overwrite an existing ~/.config/pis/config. The
repository versions of defaults/AGENTS.md and
defaults/subagents-config.json are authoritative. The subagent model fragment
is merged into PIS_AGENT_DIR/settings.json, preserving unrelated Pi settings
and unrelated fields in each agent override.
Usage
pis # project profile, pass args to pi
pis --version # pi --version in project profile
pis project --version # same, explicit project profile
pis inspect "read /etc/hosts"
pis host "help me debug my shell config"
pis setup # install/build project + host runtimes and packages
pis setup --no-build # create directories/config only
pis setup project # build Docker runtime and install packages
pis setup host # install host runtime and packages
pis runtime update # update Docker image + host runtime
pis runtime update project # update Docker image only
pis runtime update host # update host runtime only
pis runtime versions # show wrapper/project/host versions
pis doctor # check setup for all profiles
pis info # print resolved config for current project
pis sessions-path # print current project's host session dir
pis help # wrapper help
pis runtime ... manages the project and host Pi runtimes. Plain Pi package
commands pass through to Pi in the default project profile:
pis install npm:@foo/pi-tools
pis update --extensions
pis list
Bundled add-ons
pis setup installs four npm packages and this repository as a Pi git package:
npm:pi-web-access
npm:pi-btw
npm:pi-codex-limit
npm:pi-subagents
git:https://github.com/MrQvic/pis.git
The git package exposes the two extensions under addons/extensions/. Pi stores
all five packages in the shared agent directory, so project and host profiles
load the same resources. The legacy copied extension files are removed after a
successful setup.
After add-on changes are pushed, update every configured machine through Pi's normal package mechanism, then reload a running session:
pis update --extensions
# Run /reload inside an existing Pi session, or restart it.
./install.sh --no-build refreshes the wrapper, package catalog, and managed
configuration, but it does not install Pi packages. A new installation still
needs pis setup (or ./install.sh) once to install and register the packages.
Paths
~/.local/bin/pis executable
~/.config/pis/config user config
~/.config/pis/docker/Dockerfile project profile Dockerfile
~/.local/share/pis/ data root
~/.local/share/pis/agent/ shared Pi agent state, instructions, add-ons
~/.local/share/pis/bundled-packages.txt package catalog installed by pis
~/.local/share/pis/managed-AGENTS.md source for global instructions
~/.local/share/pis/managed-subagents-config.json operational subagent defaults
~/.local/share/pis/managed-subagents-settings.json model-routing settings fragment
~/.local/share/pis/sessions/<key>/ per-project sessions
~/.local/share/pis/runtime/ host/inspect npm runtime
~/.local/share/pis/docker-home/ project Docker HOME
~/.local/share/pis/project-map.json project key -> host path map
State model:
agent/is shared by all profiles. Project Docker mounts it at the same absolute path as on the host and all profiles pass it asPI_CODING_AGENT_DIR.defaults/AGENTS.mdin the repository is the authoritative source for global instructions. The installer stages it asmanaged-AGENTS.md;pis setupcopies it to the resolved agent directory, replacing the previous file.defaults/subagents-config.jsonis copied toPIS_AGENT_DIR/extensions/subagent/config.json. The model routing fromdefaults/subagents-settings.jsonis deep-merged into the global Pisettings.json; repository values win only for keys present in the fragment.sessions/<key>/is per project. Project Docker mounts only the current project's session directory at the same absolute path as on the host and all profiles pass it asPI_CODING_AGENT_SESSION_DIR.- Project Docker bind-mounts the current project at the same absolute path as on
the host and uses that as its workdir. This keeps Pi's stored session
cwdidentical between profiles, so--continue/--resumesee the same sessions. runtime/contains the host/inspect npm install of Pi.docker-home/is only the Docker profile'sHOME. It is not the source of truth for Pi agent state.
No previous state is imported automatically. pis owns its state under
~/.local/share/pis.
Configuration
Subagent defaults
pis setup caps concurrent top-level async runs at two, defaults parallel
workflows to two concurrent children, stores run artifacts with the Pi session
instead of in the working tree, and applies this model routing:
| Agent | Model | Thinking |
|---|---|---|
scout |
openai-codex/gpt-5.6-luna |
low |
researcher |
openai-codex/gpt-5.6-luna |
medium |
worker |
openai-codex/gpt-5.6-luna |
high |
delegate |
openai-codex/gpt-5.6-luna |
high |
reviewer |
openai-codex/gpt-5.6-sol |
high |
oracle |
openai-codex/gpt-5.6-sol |
xhigh |
Other agents default to GPT-5.6 Luna with medium thinking. Run /reload
after setup when changing these defaults inside an existing Pi session.
Wrapper configuration
Default config file:
# ~/.config/pis/config
# PIS_IMAGE=pis:latest
# PIS_AGENT_DIR=~/.local/share/pis/agent
# PIS_RUNTIME_DIR=~/.local/share/pis/runtime
Useful environment overrides:
PIS_CONFIG_DIR=~/.config/pis
PIS_DATA_DIR=~/.local/share/pis
PIS_AGENT_DIR=~/.local/share/pis/agent
PIS_RUNTIME_DIR=~/.local/share/pis/runtime
PIS_PI_PACKAGE=@earendil-works/pi-coding-agent@latest
PIS_PI_CMD=/custom/path/to/pi
PIS_IMAGE=pis:latest
PIS_SESSION_DIR=~/.local/share/pis/sessions
PIS_DOCKER_HOME=~/.local/share/pis/docker-home
PIS_MEMORY=2g
PIS_CPUS=2
PIS_BACKEND from older versions is ignored. Use profiles instead:
project, inspect, or host.
Safety notes
The project profile does not mount the Docker socket and does not use
privileged mode. It uses a read-only container filesystem, drops capabilities,
and limits pids/CPU/RAM.
The current working directory is still a read/write bind mount. Pi can modify or delete files in the current project. Use git/worktrees/WIP commits when working on important changes.
The inspect profile runs on the host but forces:
--no-extensions --tools read,grep,find,ls
It cannot run bash or use edit/write. Explicit tool/extension override
flags, --export, and Pi package/config commands that can modify state are
rejected. It still runs as your user and can read files your user can read.
The host profile has no pis sandbox. It runs pi as your user in the current
directory and can access anything your user account can access.
Development
Source layout:
addons/extensions/
addons/packages.txt
defaults/AGENTS.md
defaults/subagents-config.json
defaults/subagents-settings.json
bin/pis
docker/Dockerfile
install.sh
package.json
README.md
VERSION
After wrapper, package-catalog, global-instruction, or subagent-default changes, reinstall the managed files locally:
./install.sh --no-build
After extension changes are pushed, update the installed git package:
pis update --extensions