omp packages

pi-work-modes0.1.0-rc.1

Workflow modes for Pi with tool policies and best-effort shell filters

jameslindfors Published 26 days ago MIT ~171 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

pi-work-modes

File-defined workflow modes for pi: named profiles (plan, reviewer, explorer) that adjust tool availability, optionally apply best-effort shell filters, and inject short instructions from plain markdown files.

This extension is not a sandbox. Instructions and hidden tools are workflow guidance, not a guarantee against side effects. shell: false blocks recognized built-in shell calls through Pi; shell text filters are heuristic and do not secure arbitrary commands, third-party tools, or effects outside Pi's tool-call hook.

Default is the absence of a mode. No active mode = vanilla pi: zero extra tokens, tools unchanged, empty footer.

Install (30 seconds)

pi install npm:pi-work-modes

Then, in any pi session:

/mode plan        # planning workflow (built-in write/shell tools blocked)
/mode default     # back to vanilla pi

Or start a session straight into a mode:

pi --plan
pi --reviewer
pi --explorer

Plan and reviewer disable Pi's built-in write and shell tools. Other extensions and side effects outside Pi's normal tool-call path are not controlled; use an OS sandbox separately if you need that security boundary.

npm: is Pi's registry-source syntax. Pi defaults to npm for package dependency installs. To make Pi use the repository's pinned pnpm, set "npmCommand": ["corepack", "pnpm@11.25.0"] in ~/.pi/agent/settings.json. This repository uses pnpm for development, tests, packing, and publishing.

Update: pi update · Remove: pi remove npm:pi-work-modes

What a mode is

One markdown file per mode. The file is the documentation:

  • Frontmatter (YAML) — structured config, validated at load (name, optional tools, optional experimental model / thinking).
  • Body (markdown) — the mode's instructions, injected verbatim into the session while the mode is active.
---
name: reviewer
tools:
  deny: [edit, write]
  shell: false
# model: provider/model-id   # (experimental)
# thinking: high             # (experimental)
---
You are in reviewer mode — a review workflow with built-in write/shell tools blocked.
Produce severity-tagged findings (blocker/major/nit)…

When a mode is active:

  1. Toolset — edit/write drop out of the prompt; the exact prior toolset is restored on clear (including other extensions' tools).
  2. Instructions — the body is injected as a hidden message, kept to a single copy so it never accumulates.
  3. Tool-call policy — configured tools are filtered from the active list and blocked by Pi's tool_call hook if invoked anyway. shell: false blocks both recognized shell names (bash, powershell) regardless of which platform registers them. Optional bashAllow/bashDeny filters are best-effort text heuristics only; they are not a shell parser or security boundary.
  4. UI — footer label + one-line notification on every switch.
  5. Persistence — the mode is recorded in the session; /resume restores it quietly (no toast, no duplicate history entry) along with the pre-mode model/thinking, so clearing after a resume reverts to what you had before the mode. pi --plan at startup wins over a persisted mode.

User interface

Command / key Behavior
/mode Show current mode + available modes
/mode <name> Switch to mode (error + list if unknown)
/mode default Clear mode → vanilla pi
/mode new <name> Open an editor with a full-file template; validated + written to your modes dir
/mode reload Re-discover mode files; re-apply the active mode if its file changed
pi --plan, pi --reviewer, pi --explorer Start the session in that mode (one flag per bundled mode)
Ctrl+Shift+M Cycle: default → next mode → … → default

Where modes live (priority low → high)

  1. Bundled — shipped with this package (modes/): plan, reviewer, explorer.
  2. Global — ~/.pi/agent/modes/*.md (override PI_CODING_AGENT_DIR).
  3. Project — .pi/modes/*.md in the project (trust-gated; overrides the others).

On a name collision the higher source wins — e.g. put your own plan.md in .pi/modes/ to override the bundled one.

Token cost

  • No mode active: 0 tokens, empty footer.
  • Mode active: exactly one hidden message (~100–300 tokens), prefix-cached after the first turn. The injected body is byte-stable (no timestamps), so provider prefix caching is preserved.

Writing your own modes

Ask pi to write one — the bundled writing-modes skill is the authoring contract — or use /mode new <name>. Rules:

  • kebab-case name; filename stem == name field. Names that collide with /mode subcommands (new, reload, default) or contain whitespace are rejected at load — they could never be addressed via /mode.
  • Declare the actual workflow and a concise output format.
  • Use tools.shell: false when the workflow needs no shell. This hides and blocks Pi's recognized built-in shell calls but is not an OS sandbox.
  • bashAllow/bashDeny are optional best-effort text filters only; do not describe them as read-only enforcement.
  • model / thinking are experimental: applied on entry, restored on clear.

See docs/MODE-FORMAT.md for the full format spec, docs/ARCHITECTURE.md for how it works, and docs/RELEASING.md for the tag-triggered Gitea publish flow.

Development

No build step — pi loads the raw TypeScript via jiti. Use the pinned pnpm version from package.json. Requires Node.js 22.19+ and Pi 0.85.x (minimum 0.85.1). Linux is the only advertised OS target for now; CI covers Node 22.19 and 24. Windows/macOS support is deferred until runners and smoke tests are available. See the smoke-test checklist before a release.

corepack enable pnpm
pnpm install --frozen-lockfile
pnpm test
pnpm run typecheck

Quick manual test: pi -e ./src/index.ts (in a scratch project, e.g. the .pi/ dir in this repo).

Troubleshooting

  • Footer empty but I expected a mode — the mode file may have failed to parse; run /mode reload and check the warnings.
  • A blocked edit shows a reason — that's the guardrail working; the reason string tells you how to exit (/mode default).
  • /mode suffixes (/mode:1) — another extension also registers mode; both are available under their suffixed names.

License

MIT