Skip to content

negoro26/pstack

v0.15.25MIT

if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence.

pstack for oh-my-pi

Lauren Tan's pstack methodology, ported to omp. 56 skills, 23 playbooks, 24 principle leaves, the poteto-mode pin, and the poteto-agent and comment-sicko agents. 53 skills are built from upstream. omp-mechanics, pstack-omp, and setup-pstack are port-owned.

Install

/marketplace add negoro26/pstack-omp
/marketplace install pstack@pstack-omp

That loads the 56 skills and both extensions, potetomode and pstackpolicy. The two agents are optional. On omp 18.1.13 a marketplace plugin's agents/ directory is scanned only through the claude-plugins discovery provider, and enabling that provider also loads every Claude Code plugin cached under ~/.claude/plugins. Link the agents into omp's native root instead:

mkdir -p ~/.omp/agent/agents
ln -s ../../plugins/node_modules/pstack/agents/poteto-agent.md  ~/.omp/agent/agents/poteto-agent.md
ln -s ../../plugins/node_modules/pstack/agents/comment-sicko.md ~/.omp/agent/agents/comment-sicko.md

node_modules/pstack is the symlink the marketplace install maintains, so /marketplace upgrade moves the agents with it. Check with a fresh session:

omp -p --no-session --thinking off "Do not call any tool. List every agent name in the task tool's Available Agents section."

Use these optional agents only when the live roster lists them; otherwise the adapter maps the role to an available worker.

Then /poteto-mode on, or alt+shift+t, or omp -p --poteto '...' for headless runs.

What the policy extension refuses

pstackpolicy loads with the plugin and needs no configuration. It registers tool_call on bash and eval, and refuses the forge mutations the playbooks only ask for in prose: gh pr merge, merge and close through gh api, gh pr close|reopen|delete, gh pr edit --base, gh pr review, merge-when-ready, gh repo delete, gh release create|delete|upload, gh secret|variable set|delete, gh workflow run --ref <trunk>, the same forge calls made with curl, and gt submit|rebase|restack. Locally it refuses git update-ref, git branch -D, git reset --hard against a remote, and git reflog expire --expire=now --all. Any git push whose refspec lands on main, master, trunk, develop, or release is refused, forced or not; a force push to a feature branch stays allowed, because that is the port's own rebase flow.

To land, set PSTACK_LANDING_GRANT=1 in the environment omp starts from. It is an environment variable and not a flag or a slash command because a flag an agent can pass is not a grant you made. The refusal names the variable, so the agent tells you exactly what to set. PORTING.md's "What omp can actually stop" carries the measurement behind the list.

What this plugin does not enforce

Subagents run with approvalMode: yolo, so a worker cannot stop to ask you a question. This plugin ships no session_stop veto, so nothing here rejects a malformed subagent result for you. The gate is the root's own: it reads each worker's result and accepts or rejects it, and a judged role runs as an independent session. If you want a hard veto on a turn that yields nothing usable, install one as a separate extension; do not expect this plugin to supply it.

What differs from upstream

Every Cursor mechanic is substituted for its omp equivalent. Cloud agents become isolated: true subagents. An out-of-session /loop wake becomes a supervised bash process carrying a unique name, observed through read proc://<name>, or a systemd user timer. The name selects service mode and cannot be combined with async: true; async is the separate finite-command path and hands back a job id. Cursor transcripts become ~/.omp/agent/sessions/, and worker output is read at agent://<id>. No skill names a vendor model. Name a capability, bind it once in modelRoles, pick the chat model with /model.

Judged roles return a typed result, not prose: arena's cross-judge, interrogate's reviewers, and reflect's synthesizer each pass an explicit outputSchema, and the verdict is read from the spawn's structured result. In shipping and babysit, GitHub PRs and issues are read through the built-in URL schemes (pr://<n>, pr://<n>/diff, issue://<n>) while the forge client stays the only writer. A refilling fan-out uses a work pool rather than a fixed batch. checkpoint is used only for what it does, which is collapsing conversation context.

PORTING.md at the repo root records every substitution and the re-sync procedure.

Model for the agent

poteto-agent ships model-free and inherits your chat model. To pin it, add model: "@poteto" to the agent file and bind poteto in modelRoles. An unbound alias fails the spawn, so bind before you add. Bind it yourself with /model, or with omp config set modelRoles '<full json>', because a dotted modelRoles.poteto key is rejected and inherit-parent resolves to No model selected, which also fails the spawn. /skill:setup-pstack will not make this binding for you: its ownership contract limits it to the three pstack_* aliases and says never to treat poteto, default, or another operator role as pstack-owned. It is still the right command for the pstack-owned aliases, and omp registers one slash command per skill as /skill:<name>, so a bare /setup-pstack is not a command.