omp packages

@justjoshn/pi-pstack0.15.36-pi.8

pstack 0.15.36 for Pi with its soft-dependency team-kit skills vendored in: rigorous agent workflows and principles as Pi skills, with the host features they use: subagents, todos, modes, plan mode, the model rule, /loop, subscriptions and routines, AskQu

GitHub Actions Published 2 hours ago MIT ~189 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pstack for Pi (pi-pstack)

pi-pstack is pstack 0.15.36 for Pi 1.5.0: rigorous agent workflows (/poteto-mode and its playbooks), the principle skills, and the review, research, and verification skills, plus the full soft-dependency team-kit set (deslop, control-cli, control-ui, CI/PR helpers, thermo-nuclear review, and the rest) vendored in so you do not install a separate team-kit package. A small extension provides the host features the skills call by name: /name skill commands, /mode, /plan, the Task subagent tool with local worktree workers, forks, and agent_status, TodoWrite, AskQuestion, the model rule, /loop, subscriptions and webhook routines, and visualize.

Get set up

  1. Clone the repository and install the package from the checkout. Pi loads a local package in place, so keep the checkout where it is.

    git clone https://github.com/just-joshn/pi-customizations.git
    cd pi-customizations
    bun install
    pi install ./extensions/pi-pstack
    

    Pi does not install dependencies for a local package, so bun install (or npm install in extensions/pi-pstack) fetches the one runtime dependency, @anthropic-ai/sandbox-runtime, which the read-only shell loads (readonly subagents and /plan). Without it everything else works, and a read-only shell command fails instead of running unsandboxed. To try it for one session without installing, run pi -e ./extensions/pi-pstack. To install the published package instead, run pi install npm:@justjoshn/pi-pstack. Installing loads pi-pstack's tools and system-prompt sections at once, but no skill runs until you invoke it. 61 workflow skills stay out of the model's automatic skill list. Setup, create-skill, and the team-kit shipping and review skills (deslop, control-cli, control-ui, CI and PR helpers, and the rest of that set) can load from your words alone.

  2. Run /setup-pstack. It lists the models the Task tool can use, asks for a reasoning budget, maps a model to each role, and writes the model rule. A new rule applies from the next request.

  3. Start real work with /poteto-mode, a goal, and a check that can pass or fail.

The guide in docs/guide/ walks through setup, /poteto-mode, understanding code, building, verifying, overnight runs, and making pstack yours.

Remove the package with pi remove ./extensions/pi-pstack. Its state lives in ~/.pi/agent/pstack/, or $PI_CODING_AGENT_DIR/pstack/ when that variable is set (written <pstack dir> below): the model rule, routine credential files under routines/, and one folder per workspace under workspaces/ with subagent transcripts, agent stores, projects, artifacts, and isolated-worker worktrees. Delete that directory to remove the state too.

Use it

You type What happens
/poteto-mode <task> The skill attaches to that one message. Every skill Pi loaded works this way: pstack's (/how, /why, /arena, /interrogate, /principle-prove-it-works, /deslop) and your own, such as a /<handle>-mode skill from /automate-me. /skill:<name> works too.
/mode poteto-mode [task] Keeps the skill in context on every turn. The footer shows a badge with the skill's icon and color metadata, such as a yellow ♛ mode: poteto-mode (other skills get ⚡). /mode off exits and /mode reports. Any loaded skill can back a mode.
/plan [task] Plan mode: the agent gets read-only tools (read, grep, find, ls, the sandboxed bash_readonly, AskQuestion, TodoWrite, agent_status, and Task, whose launches run readonly: a fresh one runs here with no worktree, and a resume or fork stays where its agent ran), investigates, and writes a plan with goal, verified steps, and risks. Writes are blocked. /plan off restores your tools so the agent can execute; /plan reports. The footer shows plan.
/loop 30m <prompt> Runs the prompt now and again 30 minutes after each run settles. Without an interval the agent picks each wake with the Loop tool, and the loop ends when it picks none and no background subagent is still running. /loop stop or Escape during a run ends it. The prompt can be a skill command, such as /loop 1h /poteto-mode run the audit tick. When a playbook says to arm /loop, the agent starts it with the Loop tool. Intervals go up to 24 days.
/routines Lists webhook routines with their URL, credential file, and status.
/setup-pstack Configures the per-role models.
/poteto-help <question> Answers a question about pstack and hands you a prompt to send.

/mode, /plan, /loop, and subscriptions need an interactive or RPC session. In the interactive / menu, skills appear under their own names next to Pi's /skill:<name> entries. Aliases work even with enableSkillCommands off. If you have a prompt template or extension command with a skill's name, yours keeps the name; Pi's built-in commands are handled before any alias.

Host features

Feature Behavior
Task (description, prompt, subagent_type, model, run_in_background, resume, fork, fork_turns, readonly, file_attachments, environment, cloud_base_branch) Starts a separate pi --mode rpc process per subagent, so this Pi process can steer and abort it. Foreground calls return the response and an agent ID. Background calls return at once, and a <task> notification arrives after your turn ends; print and JSON runs wait for pending notifications before exiting, unless aborted. Several calls in one message run in parallel. A subagent's own subagents cannot spawn more. A run lock per agent ID keeps out a second writer, even from another Pi process (Limits notes the stale-lock race). Children inherit the parent's project-trust decision. Foreground usage counts toward the session totals. The Task card leads with the call's description, then the agent type and the model that ran.
resume Sends a follow-up to an idle agent with its context, model, type, and directory. On an agent running in this Pi process, it delivers the prompt as a steer and returns at once. A readonly or plan-mode call cannot steer a writable agent. An agent running in another Pi process is refused. This is how a playbook "messages" a worker. Pi's own /resume command reopens a chat session instead.
fork Starts a new agent whose transcript begins as a copy of an idle agent's transcript, in that agent's directory (its worktree for an isolated worker), so it sees the built checkout and uncommitted changes. Type, model, and readonly default from the source; readonly can be added, never lifted. fork_turns: N (only with fork) copies just the first N user turns. fork excludes resume, environment, and cloud_base_branch. Pi's own /fork command branches the chat session instead.
stop_agent agent_id. Stops a running subagent. One this Pi process owns gets an RPC abort, then a kill after a grace period. One another of your Pi processes owns gets a signal to the live pid in its run lock. An idle or finished agent is left alone, and the result says so.
agent_status Reads a subagent's state (running while its run lock names a live pid, idle, or missing), type, model, directory, branch, times, and last reply, without waking it. It also shows whether the agent is readonly, the agent it was forked from, its pid while running, and its transcript. Without agent_id it lists the workspace's 20 newest agents. In the root chat that includes every descendant, isolated workers too.
Subagent types generalPurpose (default), poteto-agent (a background delegate that reads poteto-mode first), and comment-sicko, read from agents/*.md. Unknown types fail with the list.
Models A Pi model spec such as claude-opus-5-5:xhigh or xai/grok-4.7:high, model parameters such as claude-opus-5-5[effort=high] or grok-4.7[fast=true] (picks a listed -fast id of that model), or inherit, inherit-parent, auto, or nothing for the parent model. A model Pi does not list, or a thinking level the model does not support, fails with the allowed list. A bare model id that several providers offer resolves to the parent chat's provider when it offers that id, and otherwise fails with the choices. Older rules that wrote claude-opus-5-5-xhigh still resolve. The system prompt's pstack_subagents section lists the types, the parent model, and the models with their levels.
Isolated workers (environment: "cloud") The subagent runs in a new git worktree at <pstack dir>/workspaces/<workspace folder>/worktrees/<agent id> on branch pstack/<agent id>, from cloud_base_branch (a local ref, else origin/<branch>) or your HEAD commit, so uncommitted changes do not reach it. The result and the card name the branch to merge, and resume and fork run in the same worktree. It fails clearly outside a git repository, in a repository with no commits, or when the base does not resolve. The worker shares the root chat's workspace state, so it sees the same projects, stores, and subagent transcripts. It also shares this machine's ports, processes, writable caches, simulators, and credentials. Assign separate ports, output directories, and writable caches to concurrent runtime lanes. swarm and orchestrate spawn worktree workers by default.
readonly: true The child gets read, grep, find, ls, TodoWrite, and a read-only bash, and no MCP. That shell runs each command in an OS sandbox (@anthropic-ai/sandbox-runtime: sandbox-exec on macOS, bubblewrap on Linux) that blocks every file write and all network access, so git log works and touch or curl fail. Where no sandbox can start, the command fails rather than running unsandboxed.
TodoWrite todos with id, content, status, and merge. The list follows the session branch and shows above the editor.
AskQuestion title, and per question id, prompt, options (id, label, optional description), and allow_multiple, through Pi's select dialog. Every question ends with Other: (type to answer); a typed answer comes back as other with its text. In print and JSON runs, including subagents, each question comes back skipped.
The model rule <pstack dir>/pstack-models.md, plain Markdown with one line per role, added to every request's system prompt. A pstack-models.mdc from an earlier version is moved there once, without its frontmatter, and kept as pstack-models.mdc.migrated.
Subscriptions subscribe_github_pr (scope pr with prUrl, repo with repo, or author with author and repo) polls with gh every 60 seconds and wakes the chat when a PR's state, head, mergeability, review decision, reviews, or comments change, or when a check concludes or its conclusion changes; the first poll is a baseline. subscribe_timer takes a name, a prompt, and a 5-field cron or delaySeconds, either with once; sessionStrategy wake_self queues a wake for this owning session. With new_session, a live owner starts a background Task and receives its notification. An offline owner permits a detached run with a recorded outcome. Re-subscribing an existing timer name returns created: false. list_subscriptions and unsubscribe manage them. The authoritative registry is <pstack dir>/durable/<workspace>/subscriptions.json. Any session in that workspace can list or cancel subscriptions. Session history does not recreate cancelled or completed subscriptions. Owner-directed events wait for the creating session rather than waking another workspace session. They expire after 7 days unless expiresInHours says otherwise (at most 30 days).
Webhook routines subscribe_webhook (name, prompt) serves http://127.0.0.1:<port>/routines/<slug> (port PSTACK_ROUTINES_PORT, default 47913, where 0 picks a free port) and keeps a random sender key in <pstack dir>/routines/<slug>/credentials.json (mode 0600). The result names the URL and the file, never the key. A JSON POST with X-Automation-Key or Authorization: Bearer returns 200 after durable acceptance. The owner receives a [routine] turn holding the prompt and a <webhook_event> block (headers, body_digest, body, timestamp_ms). HTTP 200 does not mean the owner has handled the event. Each authenticated POST is a separate event, including identical bodies. Storage failure returns 503 rather than acknowledging a lost event. A wrong key gets 401, an unknown routine 404, a method other than POST 405, a body over 64 KiB 413, and a body that is not a JSON object 400. make-bot-ui builds a page on top of this.
Durable supervisor Creating a subscription auto-starts pstack-routines-supervisor --workspace <cwd> when it is not already running. Creation waits for that subscription to arm, and webhook creation returns the bound listener's URL. The supervisor reads the durable registry, arms timers and GitHub polls, and owns the routines port. An online owner receives native Pi continuation messages. Owner-directed events accepted while the owner is offline wait for that same session to resume. Only a timer explicitly configured with sessionStrategy: "new_session" can start detached work while its owner is offline. You can still start the bin yourself. For reboot survival, run packaging/install-supervisor-unit.sh --workspace <cwd> (idempotent; installs the launchd or systemd unit from the examples under packaging/). Print and JSON runs still cannot create subscriptions.
Stores and projects The system prompt names "the current agent's store" (per session), "the root agent's store" (the main chat's, named to every subagent however deep), and the workspace's projects/ folder, where a program's Project is <slug>/notes.md (its tracker) and <slug>/store/.
visualize title, kind (bar or line), labels, series (name, values), and unit render a Unicode chart in the result and write a standalone SVG to the session's artifacts folder.
Transcripts The system prompt names this workspace's Pi session directory, the current session file, and this workspace's subagent transcripts.
Image generation Pi's codemode models.generateImages(), when codemode is on and an image model is configured; otherwise skills fall back to a Mermaid diagram.

Subagent transcripts are Pi sessions in <pstack dir>/workspaces/<workspace folder>/subagents/, with the agent ID in each file name, next to a small record that resume, fork, and agent_status read. Agent IDs belong to the workspace that started them. Children inherit your installed extensions and MCP servers, and local ones run in your working directory. Give each local subagent that writes its own git worktree, or launch it with environment: "cloud", because a child process does not isolate the filesystem. A child exits on its own if its parent Pi process dies.

Limits

  • Worktree workers run on this machine, not remote VMs. They start from committed code only and share your installed extensions, MCP servers, and network, except that a readonly worker gets no MCP servers and no network. A worktree is not a credential boundary. Concurrent runtime lanes need separate ports, output directories, and writable caches. pi-pstack never pushes their branches, though a worker can push its own. Worktrees and branches stay until you or the worktree-cleanup playbook remove them.
  • The supervisor can accept events after chat exit, but owner-directed events wait until the owning session resumes. Explicit new_session timers can spend tokens with no human watching. Detached runs do not supply the live owner's Task notification flow. For reboot survival, run packaging/install-supervisor-unit.sh --workspace <cwd>. If the supervisor cannot start, an explicitly reported in-process fallback stops when that Pi process exits. A GitHub subscription restarted after downtime takes a new baseline, so changes made while nothing was polling do not wake it. Only one listener can hold a fixed routine port. Set PSTACK_ROUTINES_PORT for another workspace, or use 0 for a free port. The listener binds 127.0.0.1, so a page served to other machines forwards through a local server, as make-bot-ui describes.
  • Event delivery is at-least-once. A process crash after Pi queues a message but before its durable acknowledgement can repeat a wake or a fresh run. Automation prompts must make external actions idempotent. Accepted events remain queued until delivery or cancellation. Expiry stops new occurrences rather than discarding accepted work. Failed detached executions retain their event for retry and expose the error in list_subscriptions. Cancelling a subscription drops pending undelivered events, but cannot undo work already handed to Pi.
  • The Benny automation pack under automations/benny/ runs on pi-pstack subscriptions. Keep its owning Pi session running for immediate handling, or resume that session to handle parked events. It needs a Slack MCP server for its Slack steps.
  • /plan uses bash_readonly for its shell rather than replacing bash, so your shell settings stay as they are outside plan mode.
  • Background subagent token usage is recorded in the child's transcript and in the usage field of the notification's details, but does not enter the parent session's totals: Pi 1.5.0 has no public API for adding a background completion's usage to the parent totals. Native tool-result usage covers synchronous nested work, not later notifications.
  • /reload, /new, and Pi's /resume and /fork commands stop running background subagents, with a warning that names how many. Continue one later with Task resume and its agent ID.
  • A print or JSON run waits for its background subagents before it exits, with no timeout of its own, unless it is aborted.
  • Subagents start the same Pi script that runs the parent (process.argv[1]), or pi from PATH. Embedding the package through the SDK in another host is not supported.
  • Depth limits apply to Task. A writable subagent can still start pi through bash, and that process is outside the depth limit and parent watchdog.
  • A child loads your installed extensions plus this package. If you run one checkout with -e while a different checkout of pi-pstack is installed, the child loads both and fails on duplicate tools; use one copy, or a separate PI_CODING_AGENT_DIR, as live:e2e does.
  • Subagents run headless in RPC mode, so an extension that asks for permission through a dialog cannot ask there.
  • The read-only shell sandboxes shell subprocesses only, and is verified on macOS and on the Ubuntu CI runner. On Linux it needs bubblewrap, socat, and ripgrep. Ubuntu 24.04 and later restrict unprivileged user namespaces: either add an AppArmor profile that grants userns to bwrap, or run sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0, which lifts the restriction for every program on the machine. The policy sets allowAllUnixSockets: true so Linux skips apply-seccomp, whose nested userns fails on GitHub-hosted runners; filesystem write denial and network denial still come from bubblewrap.
  • Whether a model follows a playbook is the model's call.
  • Workspace folders follow Pi's session-folder naming, so two paths that differ only by / versus - share a folder. Resume and fork refuse an agent whose record names the other directory. Subscription reads and mutations also reject a registry owned by the other workspace.
  • The run lock that keeps one writer per agent ID names the process writing the transcript. A lock file without a readable pid counts as held; the error names the file to delete. agent_status shows such an agent as idle. A lock whose pid is dead is taken over, and two processes that take over the same stale lock at the same moment can both succeed.
  • skills/poteto-mode/scripts/watch-pr needs Bun and installs its one dependency on first run. check-plan.mjs needs only Node. worktree-audit.sh needs rg and jq, and works with BSD (macOS) or GNU stat and date.
  • statechart runs skills/statechart/scripts/statechart on Node 22.18 to 22.x, Node 23.6 or later, Bun 1.1.5 or later, or Deno 2.0 or later. The first run installs TLC and Java through mise and needs the network. Without a SPEC it prints Give one SPEC.tla. and its usage, then exits 2.

Maintain it

The skills, agents, guide, and automation pack are this package's own files; edit them in place. They track pstack 0.15.36 in behavior. The record of the move to Pi-native text and the host features added for it is at the repository root, in parity/pi-pstack-0.15.36/ (design and decisions); earlier records are in the root's parity/pi-pstack-*. Four mechanisms Pi 1.5.0 does not export keep a hand-written implementation here: docs/native-gaps.md names each one, the evidence, and the public API that would replace it.

bun run typecheck
bun run test
bun run test:statechart                               # full compiler suite; set TLA2TOOLS and JAVA for an existing verified toolchain
bun run live:e2e -- --model deepseek/deepseek-flash      # real-model scenarios; needs credentials and gives the model under test your real auth.json (see the script header)

Licenses

The port's own code is MIT (LICENSE). pstack's files keep their MIT notice in licenses/pstack.LICENSE (© 2026 Lauren Tan), and the vendored team-kit skills and agents keep theirs in licenses/cursor-team-kit.LICENSE.