Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "pstack",
"description": "pstack plugin catalog: skills, agents, and sticky /poteto-mode for Claude Code.",
"owner": {
"name": "Ed Heltzel",
"url": "https://github.com/edheltzel"
},
"plugins": [
{
"name": "pstack",
"source": "./",
"description": "pstack skills and agents. Claude slash skills are /pstack:do-*."
}
]
}
14 changes: 14 additions & 0 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "pstack",
"displayName": "pstack",
"version": "0.14.5",
"description": "pstack skills, agents, and sticky /poteto-mode. Claude slash skills are /pstack:do-*.",
"author": {
"name": "Ed Heltzel",
"url": "https://github.com/edheltzel"
},
"homepage": "https://github.com/edheltzel/pstack-for-omp",
"repository": "https://github.com/edheltzel/pstack-for-omp",
"license": "MIT",
"keywords": ["pstack", "poteto-mode", "skills", "omp"]
}
17 changes: 14 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# pstack

omp plugin: one factory (`extensions/pstack.ts`), skills, agents, and commands.
omp + Claude Code plugin: one factory (`extensions/pstack.ts`), Claude manifest (`.claude-plugin/plugin.json`), skills, agents.

## Codegraph

Expand Down Expand Up @@ -51,7 +51,7 @@ Closeout: re-check paths, update owning docs, refresh indexes, run verification,
## Project contracts

- Static gate (CI and local): `python3 e2e/run.py --skip-rpc` and `npm test` (Vitest).
- No `omp`, no `omp --mode rpc`, no TUI on GitHub runners. Live RPC is local only: `python3 e2e/run.py` without `--skip-rpc`.
- No `omp`, no `omp --mode rpc`, no TUI, no `claude` on GitHub runners. Live RPC is local only: `python3 e2e/run.py` without `--skip-rpc`. Host-only prove (`omp plugin doctor`, `claude plugin validate`) is documented in e2e/AGENTS.md.
- One factory. Poteto-mode is per-session, never a process-wide boolean.

## Native omp
Expand All @@ -64,6 +64,17 @@ Tell operators plugin-link only:
- Do not marketplace. Do not copy `pstack.ts` into `~/.omp/agent/extensions/`.
- Do not keep a repo `.omp/skills` symlink. Sibling `skills/` is what plugin-link discovers.

## Native Claude Code

Tell operators plugin-first only:

- Manifest: `.claude-plugin/plugin.json`. Catalog: `.claude-plugin/marketplace.json`. Skills stay at plugin-root `skills/`, not inside `.claude-plugin/`.
- Install: `claude plugin marketplace add <checkout-or-edheltzel/pstack-for-omp>` then `claude plugin install pstack@pstack`.
- This session only: `claude --plugin-dir ./`
- Slash skills: `/pstack:do-*`. Do not rename the `do-` skill set.
- Validate on a host with Claude Code: `claude plugin validate .`
- Sticky `/poteto-mode` is omp factory only. Claude uses `/pstack:do-poteto-mode`.

## Verification

```bash
Expand All @@ -78,7 +89,7 @@ npm test
| [extensions/AGENTS.md](extensions/AGENTS.md) | Factory `pstack.ts`; per-session poteto-mode |
| [e2e/AGENTS.md](e2e/AGENTS.md) | Static doctor/lint + Vitest; live RPC local-only via plugin-link |
| [skills/AGENTS.md](skills/AGENTS.md) | Skill tree; SKILL.md frontmatter `name` + `description` |
| [docs/AGENTS.md](docs/AGENTS.md) | original numbered `guide/`; first-run lives on README (`omp plugin link ./`) |
| [docs/AGENTS.md](docs/AGENTS.md) | original numbered `guide/`; first-run lives on README (omp plugin link + Claude plugin install) |
| [automations/AGENTS.md](automations/AGENTS.md) | Dormant Benny pack; not slash skills |

`agents/` and `commands/` have no child AGENTS.md; they follow this rail. Commands need frontmatter `description`.
79 changes: 50 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# pstack

This package is an installable omp **plugin**. From the package root, one-time `omp plugin link ./`. Later sessions (any cwd): start `omp`, type `/` (`/skill:do-…`, sticky `/poteto-mode`). Sibling `skills/` at the package root is what omp auto-discovers after link.
This package is an installable **plugin** for omp/Pi and Claude Code. Skills stay `do-*` on disk. omp exposes them as `/skill:do-…`. Claude Code exposes them as `/pstack:do-*`. Sticky `/poteto-mode` is the omp factory command.

It is not the Cursor plugin and not an official Cursor port.

Expand All @@ -16,63 +16,81 @@ Those pages are the Cursor product. This README does not retell them.

## Docs

- [The pstack guide](./docs/guide/README.md) — original numbered product tutorial (setup through recipes, plus images). On-disk skill links use `skills/do-*`; slash skills are `/skill:do-…`. `/poteto-mode` stays unprefixed.
- [The pstack guide](./docs/guide/README.md) — original numbered product tutorial (setup through recipes, plus images). On-disk skill links use `skills/do-*`. omp slash skills are `/skill:do-…`. Claude slash skills are `/pstack:do-*`. `/poteto-mode` stays unprefixed on omp.

## Automations

pstack also ships a dormant [benny automation pack](./automations/benny/). Benny triages Slack issue reports, then reproduces and fixes confirmed bugs with real UI evidence. Its files are **not** slash skills. Sibling `skills/` at the package root is the only skill tree; do not add a second one.

Setup starts at [`automations/benny/FOR_AGENTS.md`](./automations/benny/FOR_AGENTS.md). That README records the Cursor Automations host vs what omp can run.

## What omp is

[omp](https://omp.sh) is “A coding agent with the IDE wired in.”
## Load this plugin

- Home: https://omp.sh
- Install omp: `curl -fsSL https://omp.sh/install | sh`
- Source: https://github.com/can1357/oh-my-pi
- Docs: https://omp.sh/docs
- How omp can install plugins in general (not this repo’s command): https://omp.sh/docs/plugins
- Authoring: https://omp.sh/docs/extension-authoring
Clone https://github.com/edheltzel/pstack-for-omp, then pick the host.

## Load this plugin
### omp / Pi

Clone https://github.com/edheltzel/pstack, then from the package root:
Install omp from https://omp.sh if needed (`curl -fsSL https://omp.sh/install | sh`). From the package root, one-time:

```
git clone https://github.com/edheltzel/pstack.git
cd pstack
git clone https://github.com/edheltzel/pstack-for-omp.git
cd pstack-for-omp
omp plugin link ./
```

That one-time link is how later sessions (any cwd) type `/` (`/skill:do-…`, sticky `/poteto-mode`). Confirm with `omp plugin list`.
Later sessions (any cwd): start `omp`, type `/` (`/skill:do-…`, sticky `/poteto-mode`). Sibling `skills/` at the package root is what omp auto-discovers after link. Confirm with `omp plugin list`. Prove the link with `omp plugin doctor`.

Do not copy only `pstack.ts` into `~/.omp/agent/extensions/`. Do not marketplace-install this package on omp; local-link is the install path.

omp docs: https://omp.sh/docs/plugins and https://omp.sh/docs/extension-authoring.

### Claude Code

This checkout is the plugin root: `.claude-plugin/plugin.json` plus `skills/` and `agents/` beside it (not inside `.claude-plugin/`).

From the package root, add this repo as a marketplace and install:

```
claude plugin marketplace add /absolute/path/to/pstack-for-omp
claude plugin install pstack@pstack
```

From GitHub: `claude plugin marketplace add edheltzel/pstack-for-omp` then `claude plugin install pstack@pstack`.

Do not copy only `pstack.ts` into `~/.omp/agent/extensions/`.
This session only (no install record):

```
claude --plugin-dir ./
```

Claude slash skills are namespaced: `/pstack:do-how`, `/pstack:do-poteto-mode`. Validate the layout with `claude plugin validate .`. Sticky `/poteto-mode` is omp-only; on Claude run `/pstack:do-poteto-mode`.

Claude plugin docs: https://code.claude.com/docs/en/plugins.

## First steps

1. Install omp from https://omp.sh (`curl -fsSL https://omp.sh/install | sh`).
2. Clone this repository and, from the package root, `omp plugin link ./` (see Load this plugin). Later sessions (any cwd): `omp`, then type `/`.
3. `/poteto-mode` — enable sticky Poteto Mode for this conversation. Optional task arguments are passed through; this also sends `/skill:do-poteto-mode`.
4. Work as usual. Resume an on conversation and it stays on. `/new` starts off.
5. `/poteto-mode off` (aliases: `disable`, `stop`) — disable this conversation.
1. Install the host (omp from https://omp.sh, or Claude Code).
2. Load this plugin (see Load this plugin).
3. On omp: `/poteto-mode` — enable sticky Poteto Mode for this conversation. Optional task arguments are passed through; this also sends `/skill:do-poteto-mode`. On Claude: `/pstack:do-poteto-mode`.
4. Work as usual. On omp, resume an on conversation and it stays on. `/new` starts off.
5. `/poteto-mode off` (aliases: `disable`, `stop`) — disable this omp conversation.

If Poteto Mode was never turned on in this conversation, it is off. Mode is per conversation, not process-wide.
If Poteto Mode was never turned on in this omp conversation, it is off. Mode is per conversation, not process-wide.

The TUI status reads `pstack: poteto mode` when on. Other omp surfaces may not show it.

## Commands

| Command | What it does |
|---|---|
| `/poteto-mode` | Enable sticky Poteto Mode for this conversation. Also sends `/skill:do-poteto-mode`. |
| `/poteto-mode off` | Disable this conversation. Aliases: `disable`, `stop`. |
| `/poteto-mode` | omp factory: enable sticky Poteto Mode for this conversation. Also sends `/skill:do-poteto-mode`. |
| `/poteto-mode off` | Disable this omp conversation. Aliases: `disable`, `stop`. |

That is the live extension command. It stays unprefixed. There is no worktree command. No `hooks/` tree. No `src/` tree. No Cursor marketplace APIs.
That is the live omp extension command. It stays unprefixed. There is no worktree command. No `hooks/` tree. No `src/` tree. No Cursor marketplace APIs. Do not ship `commands/poteto-mode.md`.

## Poteto Mode (this extension)

- Enable sends `/skill:do-poteto-mode`. The `/skill:do-poteto-mode` input hook also persists enabled.
- On omp, enable sends `/skill:do-poteto-mode`. The `/skill:do-poteto-mode` input hook also persists enabled.
- Stored as a custom `pstack-mode` entry on that conversation’s session jsonl. Last `{enabled}` wins. Missing means off.
- `session_start` re-reads the jsonl. `new_session` / `/new` starts off. Resume of an on conversation stays on.
- When on, a prompt needle prepends “Pstack Poteto Mode is on…”
Expand All @@ -82,9 +100,12 @@ That is the live extension command. It stays unprefixed. There is no worktree co

## Skills

Files under `skills/` are markdown prompts. Invoke them with `/skill:do-<name>`. They are live after `omp plugin link ./` (sibling tree auto-discovered). They are not live omp functions or CLIs.
Files under `skills/` are markdown prompts. They are not live omp functions or CLIs.

- omp, after `omp plugin link ./`: `/skill:do-<name>`
- Claude Code, after plugin install: `/pstack:do-<name>`

Examples: `/skill:do-create-verification-skill`, `/skill:do-swarm`, `/skill:do-principle-build-the-lever`. Feature Map is a section in `do-create-verification-skill`, not a runner. Do not treat Feature Map, swarm, or Build the Lever as functions or CLIs.
Examples: `/skill:do-create-verification-skill` (Claude: `/pstack:do-create-verification-skill`), `/skill:do-swarm`, `/skill:do-principle-build-the-lever`. Feature Map is a section in `do-create-verification-skill`, not a runner. Do not treat Feature Map, swarm, or Build the Lever as functions or CLIs.

## License

Expand Down
10 changes: 5 additions & 5 deletions docs/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@

## Purpose

Human docs for this omp plugin. First-run is the README (`omp plugin link ./`). The numbered guide is the original pstack product tutorial. This file must not teach a second mount story.
Human docs for this plugin. First-run is the README (`omp plugin link ./` and Claude `claude plugin install pstack@pstack`). The numbered guide is the original pstack product tutorial. This file must not teach a second omp mount story (`omp -e`) or a fake installer.

## Ownership

- `guide/` — original numbered tutorial (01–10 plus images), ported from `cursor/plugins` `pstack/docs/guide/`.

## Local Contracts

- README owns first-run: `omp plugin link ./`. Do not add `docs/getting-started.md` or teach `omp -e` as an install path.
- README owns first-run for both hosts: `omp plugin link ./` and Claude plugin install (`marketplace add` + `pstack@pstack`, or `claude --plugin-dir ./`). Do not add `docs/getting-started.md` or teach `omp -e` as an install path.
- README may link the numbered guide.
- Guide on-disk skill links use `skills/do-*` so they resolve in this tree. Slash names in guide prose may still say `/how`; the live surface is `/skill:do-how`. `/poteto-mode` stays unprefixed.
- Operator install matches the root rail Native omp contract.
- Guide on-disk skill links use `skills/do-*` so they resolve in this tree. Slash names in guide prose may still say `/how`; the live omp surface is `/skill:do-how`, Claude is `/pstack:do-how`. `/poteto-mode` stays unprefixed on omp.
- Operator install matches the root rail Native omp and Native Claude Code contracts.

## Work Guidance

Port guide pages and images from upstream. Remap `../../skills/<name>/` to `../../skills/do-<name>/`. Agents tell operators plugin-link.
Port guide pages and images from upstream. Remap `../../skills/<name>/` to `../../skills/do-<name>/`. Agents tell operators plugin-link (omp) or plugin install (Claude).

## Verification

Expand Down
27 changes: 24 additions & 3 deletions docs/guide/01-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,32 @@ In this page you install the plugin, pick which models pstack uses, and run your

## Install the plugin

This package is the plugin root for both hosts. Pick one.

### omp / Pi

From the package root:

```text
omp plugin link ./
```

Confirm with `omp plugin list`.
Confirm with `omp plugin list`. Prove with `omp plugin doctor`.

The Cursor product used `/add-plugin pstack`. That is history, not how you install this package. omp marketplaces are catalogs you add (a git repo with `marketplace.json`); this package is local-link only on omp, not listed in an omp catalog.

### Claude Code

From the package root:

```text
claude plugin marketplace add /absolute/path/to/this-checkout
claude plugin install pstack@pstack
```

Or this session only: `claude --plugin-dir ./`. Validate with `claude plugin validate .`. Skills show as `/pstack:do-*`.

The Cursor product used `/add-plugin pstack`. That is history, not how you install this omp package. omp marketplaces are catalogs you add (a git repo with `marketplace.json`); this package is local-link only, not listed in a catalog.
The Claude catalog is `.claude-plugin/marketplace.json`. Skills stay at the plugin root (`skills/do-*/SKILL.md`), not inside `.claude-plugin/`.

## Pick your models

Expand All @@ -22,6 +39,8 @@ Run:
/skill:do-setup-pstack
```

On Claude Code the same skill is [`/pstack:do-setup-pstack`](../../skills/do-setup-pstack/SKILL.md).

[`/skill:do-setup-pstack`](../../skills/do-setup-pstack/SKILL.md) detects the models you have access to, shows you each role (code delegates, judgment, the review panels), and asks what you want. Answer the questions. It writes `~/.cursor/rules/pstack-models.mdc`, a small rule every pstack skill reads.

You only override what you care about. A role with no line in the rule keeps the skill's default. To restore a default later, delete that role's line, or just run `/skill:do-setup-pstack` again.
Expand All @@ -44,8 +63,10 @@ Pick something real but small, and describe it the way you'd describe it to a co
/poteto-mode add a --json flag to this command. text output stays byte-identical. verify both.
```

On Claude Code, start with `/pstack:do-poteto-mode` instead of the omp factory `/poteto-mode`.

Watch the todo list. The first item is always "read the Principles section". The rest are the matched playbook's steps copied in, the Feature playbook for this prompt. If `/poteto-mode` skips a step, the step stays in the list with `skip: <reason>`, so you can see what it chose not to do.

From here you can type normal follow-ups. `/poteto-mode` is sticky. It stays on for the conversation until you opt out by saying so.
From here you can type normal follow-ups. On omp, `/poteto-mode` is sticky. It stays on for the conversation until you opt out by saying so.

Next: [Route work through `/poteto-mode`](./02-poteto-mode.md).
2 changes: 1 addition & 1 deletion docs/guide/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The pstack guide

> This numbered guide is the original pstack product tutorial. On this omp fork, first-run is the [README](../../README.md) (`omp plugin link ./`). Slash skills are `/skill:do-…` (on-disk `skills/do-*`). `/poteto-mode` stays unprefixed.
> This numbered guide is the original pstack product tutorial. On this fork, first-run is the [README](../../README.md) (`omp plugin link ./` or Claude `claude plugin install pstack@pstack`). Slash skills are `/skill:do-…` on omp and `/pstack:do-*` on Claude (on-disk `skills/do-*`). `/poteto-mode` stays unprefixed on omp.

pstack works best when you stop micromanaging the agent. You describe what you want and how you'll know it's done. `/poteto-mode` picks the playbook, runs the other skills as the steps need them, and shows you the evidence. This guide teaches that habit with realistic prompts.

Expand Down
16 changes: 13 additions & 3 deletions e2e/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,38 @@

## Purpose

Prove the plugin without chat-only guesses. Static doctor/lint + Vitest on every PR. Live omp RPC is local-only and loads this tree with `omp plugin link ./`.
Prove the plugin without chat-only guesses. Static doctor/lint + Vitest on every PR. Live omp RPC is local-only and loads this tree with `omp plugin link ./`. Live `claude plugin validate` / `omp plugin doctor` are host-only.

## Ownership

- `run.py` — live RPC evals; `--skip-rpc` is static-only
- `ci_static.py` — doctor, frontmatter, size, product pack
- `ci_static.py` — doctor, frontmatter, size, product pack, Claude plugin layout
- `unit/` — Vitest helpers and tests
- `ci-shims/` — `node:fs` stub for `tsc` without `@types/node`

## Local Contracts

- CI and local static gate: `python3 e2e/run.py --skip-rpc` and `npm test`.
- No `omp --mode rpc` on GitHub runners.
- No `omp --mode rpc` on GitHub runners. No `claude` / `omp` install on CI.
- Do not install or run live omp / the plugin extension as a test harness on CI.
- Live RPC, when omp is present, must `omp plugin link ./` before starting. Do not pass `-e`.
- Do not keep a TypeScript copy of `ci_static.py` (no `unit/static-checks.ts`, no homemade brace parser).
- Do not keep a repo `.omp/skills` symlink. `static_install_docs` and `unit/product-capabilities.test.ts` assert filesystem absence, not only README text.
- Claude components stay at plugin root. `.claude-plugin/` may hold `plugin.json` and `marketplace.json` only — not `skills/`.

## Work Guidance

Add static cases to `ci_static.py` or `unit/`. Product-pack presence (docs/guide, automations/benny, do-swarm) lives in `ci_static.py --product` and `unit/product-capabilities.test.ts`. Add live RPC cases to `run.py` only when they stay local.

Host-only prove (needs BigMac omp/claude, not CI):

```bash
omp plugin link ./
omp plugin list
omp plugin doctor
claude plugin validate .
```

## Verification

```bash
Expand Down
13 changes: 11 additions & 2 deletions e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Static doctor/lint + Vitest on every PR. Live omp RPC evals are local-only. Not chat-only.

Static (CI and local; no omp):
Static (CI and local; no omp, no claude):

```bash
python3 e2e/run.py --skip-rpc
Expand All @@ -20,9 +20,18 @@ Each RPC run uses `--session-dir` under a temp folder and `--no-tools`.
A factory change still needs an omp restart (a fresh `omp --mode rpc` process loads the tree).
Do not run `omp --mode rpc` on GitHub runners.

Host-only prove (needs omp and/or Claude Code on the machine; not CI):

```bash
omp plugin link ./
omp plugin list
omp plugin doctor
claude plugin validate .
```

| Case | What it proves |
| --- | --- |
| `install_plugin_link` | README/AGENTS teach `omp plugin link ./`; competing stories gone |
| `install_plugin_link` | README/AGENTS teach `omp plugin link ./` and Claude plugin install; competing stories gone |
| `poteto_on` | `/poteto-mode` injects the needle and writes `pstack-mode` on this session |
| `second_turn_sticky` | Next turn still has the needle |
| `poteto_off` | `/poteto-mode off` then next turn has no needle |
Expand Down
Loading
Loading