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
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"name": "pstack",
"source": "./plugins/pstack",
"description": "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. Original pstack by Lauren Tan (poteto).",
"version": "0.9.76"
"version": "0.9.77"
}
]
}
11 changes: 11 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

This file is the release changelog, with one `## <version> - <title>` entry per release, newest first. The Cursor-to-Claude rewrite rules live in [`tools/substitutions.json`](tools/substitutions.json), and the [sync boundary](CONTRIBUTING.md#the-sync-boundary) in `CONTRIBUTING.md` defines how a change to upstream's skill content is declared.

## 0.9.77 - pstack-herdr: move the Herdr scripts into their own folder

The Herdr scripts move from the flat `poteto-mode/scripts/` directory into `poteto-mode/scripts/herdr/`, following upstream's layout for `orch/` and `watch-pr/`, where a tool's folder carries its name and the files inside drop it:

- `herdr-dispatch.ts` is now `herdr/dispatch.ts`.
- `herdr-config.ts` is now `herdr/config.ts`.
- `configure-herdr.ts` is now `herdr/configure.ts`.
- Each test moves beside its script.

The scripts keep the shared `bootstrap.ts`, `package.json`, and `tsconfig.json`, and their behavior does not change. `herdr-tools.md`, `setup-pstack`, the Agent gate, `HERDR.md`, the tests, and CI's Herdr dispatch job name the new paths. A session that started before the update and still runs an old path gets a missing-file error from `bun` until it reads `herdr-tools.md` again.

## 0.9.76 - pstack-herdr: merge pstack-claude 0.9.75

This release merges `michael-denyer/pstack-claude` 0.9.70 through 0.9.75 into the fork. It brings in the GitHub Copilot runtime (plugin manifest, hooks, `copilot-tools.md`, and the Copilot setup path), the `/poteto-help` skill and the `cursor/plugins` pin at `2cbf585` (v0.15.13), Feature delegates whose worktrees start from the branch's `HEAD`, per-task fallback todolists, bounded Autopilot verify rounds, and fail-closed fixes in `watch-pr`, `orch`, `worktree-audit`, `sync`, and the release gate. The fork keeps the Herdr dispatcher, `--next`, the Agent gate, routes, and the real Herdr CI job. Upstream touched none of them.
Expand Down
4 changes: 2 additions & 2 deletions CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ Names for the concepts this repo's design discussions keep reaching for. Archite
- **Role** — a named unit of delegated work with its own model choice (`arena runners`, `how critics`, `swarm workers`). The role vocabulary lives in `models.json` and surfaces in `setup-pstack`'s sheet.
- **Herdr route** — the Herdr-side model policy in `~/.config/pstack-herdr/routes.yaml`, written by `setup-pstack` inside Herdr. It maps each Herdr role (`explorer`, `reviewer`, ...) to a pool of profiles. Separate from the override sheet: Herdr workers never read `pstack-models.md`.
- **Profile** — one worker configuration in a Herdr route: CLI kind, full model ID, optional effort, optional config home. Several workers can share one profile and its account limits.
- **Dispatcher** — `herdr-dispatch.ts`. Starts a worker in a Herdr pane, delivers the prompt, waits, reads the output, and closes the pane. Everything `herdr-tools.md` maps a native `Agent` call to.
- **Dispatcher** — `herdr/dispatch.ts`. Starts a worker in a Herdr pane, delivers the prompt, waits, reads the output, and closes the pane. Everything `herdr-tools.md` maps a native `Agent` call to.
- **Handoff** — a `--wait` dispatch that returns `working`, `blocked`, or `unknown` and leaves the pane open. `--collect` finishes a `working` handoff and closes the pane.
- **Drain** — collecting background workers with `herdr-dispatch.ts --next <names...>`, which blocks until the first settles and lists the rest as pending. The orchestrator calls it again with the pending names instead of sleeping between checks.
- **Drain** — collecting background workers with `herdr/dispatch.ts --next <names...>`, which blocks until the first settles and lists the rest as pending. The orchestrator calls it again with the pending names instead of sleeping between checks.
- **Panel** — the three-model diverse panel the multi-model skills (`arena`, `architect`, `interrogate`, `how`) run by default. One fact in `models.json`; the generator stamps every copy and fails on strays.
- **Prompt stub** — an optional Codex slash command that invokes a skill. The generator writes it under `.codex-plugin/prompts/` using the skill's row in the [slash-command reference](docs/reference.md#slash-commands). Native skill discovery works without it.
- **Menu description** — the short description in a public skill's row in the [slash-command reference](docs/reference.md#slash-commands). Codex displays it in the slash menu. The skill's frontmatter `description` tells the agent when to invoke it.
Expand Down
10 changes: 5 additions & 5 deletions HERDR.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Herdr runtime

When `HERDR_ENV=1`, pstack delegates through [`herdr-dispatch.ts`](plugins/pstack/skills/poteto-mode/scripts/herdr-dispatch.ts) instead of the native `Agent` tool. pstack still decides decomposition, roles, isolation, synthesis, review, and verification. The dispatcher owns the worker's pane from creation to cleanup. [`herdr-tools.md`](plugins/pstack/skills/poteto-mode/references/herdr-tools.md) is the per-skill mapping agents read. This file is the contract behind it.
When `HERDR_ENV=1`, pstack delegates through [`herdr/dispatch.ts`](plugins/pstack/skills/poteto-mode/scripts/herdr/dispatch.ts) instead of the native `Agent` tool. pstack still decides decomposition, roles, isolation, synthesis, review, and verification. The dispatcher owns the worker's pane from creation to cleanup. [`herdr-tools.md`](plugins/pstack/skills/poteto-mode/references/herdr-tools.md) is the per-skill mapping agents read. This file is the contract behind it.

## Roles

Expand All @@ -18,7 +18,7 @@ When `HERDR_ENV=1`, pstack delegates through [`herdr-dispatch.ts`](plugins/pstac

## Routing

`/setup-pstack` writes `~/.config/pstack-herdr/routes.yaml` through `configure-herdr.ts`. Do not edit it by hand. [`config/routes.example.yaml`](config/routes.example.yaml) shows the format.
`/setup-pstack` writes `~/.config/pstack-herdr/routes.yaml` through `herdr/configure.ts`. Do not edit it by hand. [`config/routes.example.yaml`](config/routes.example.yaml) shows the format.

- A **profile** names a CLI (`kind: claude` or `codex`), a `model`, an optional `effort`, and optional `env`.
- A **role** names a pool of profiles and a `strategy`. `first` always takes the first profile. `spread` hashes the worker name over the pool. `--kind` keeps only the pool's profiles of that CLI before the strategy runs.
Expand All @@ -35,7 +35,7 @@ The caller's `--cwd` is the isolation boundary. Read-only workers may share a ch
## Dispatch lifecycle

```sh
bun <poteto-mode>/scripts/herdr-dispatch.ts \
bun <poteto-mode>/scripts/herdr/dispatch.ts \
--role implementation \
--name feature-worker \
--prompt-file /tmp/feature-brief.md \
Expand All @@ -50,12 +50,12 @@ bun <poteto-mode>/scripts/herdr-dispatch.ts \
5. The dispatcher appends a marker line, `[pstack-herdr turn <name>-<time>]`, to every Codex prompt. A Codex worker's turn ends when the rollout that quotes the marker, under the worker's `$CODEX_HOME/sessions`, records `task_complete` after it, whatever Herdr reports. The prompt also counts as delivered once that rollout quotes the marker. Herdr 0.9.2+ reads a finished Codex turn as `unknown`, and 0.9.1 can read a running one as `idle`. The dispatcher polls the rollout, returns `done` with the turn's final message as the output, and reports `working` while the rollout shows the turn still open. The dispatch saves the pane, sessions directory, marker, and start time to `$TMPDIR/pstack-herdr/<name>.json` before it types the prompt, so `--collect` checks the same turn.
6. A verified worker's output is read and its pane closed. `--keep-pane` keeps it open.

`working`, `blocked`, and `unknown` panes stay open. `blocked` means the worker is waiting on an approval or question, so inspect it. `unknown` is not completion. Finish a `working` worker with `herdr-dispatch.ts --collect --name <name>`, which waits, reads the output, and closes the pane once it is done. A dispatch or `--collect` stopped by SIGTERM, SIGINT, or SIGHUP while waiting closes the worker's pane first. SIGKILL cannot be caught and leaves the pane open.
`working`, `blocked`, and `unknown` panes stay open. `blocked` means the worker is waiting on an approval or question, so inspect it. `unknown` is not completion. Finish a `working` worker with `herdr/dispatch.ts --collect --name <name>`, which waits, reads the output, and closes the pane once it is done. A dispatch or `--collect` stopped by SIGTERM, SIGINT, or SIGHUP while waiting closes the worker's pane first. SIGKILL cannot be caught and leaves the pane open.

For parallel fan-out, start every dispatcher process without `--wait`, then collect them with `--next`:

```sh
bun <poteto-mode>/scripts/herdr-dispatch.ts --next worker-a worker-b worker-c --timeout 600000
bun <poteto-mode>/scripts/herdr/dispatch.ts --next worker-a worker-b worker-c --timeout 600000
```

`--next` blocks until the first named worker settles, reads and closes every worker that has, and prints `{"settled": [...], "pending": [...]}`. Call it again with the `pending` names until none are left. Each Claude worker's status change reaches it through a Herdr `events.subscribe` stream on `HERDR_SOCKET_PATH`, so it wakes when the status changes. Reading the output and closing the pane takes under a second more. A Codex worker's rollout is read every second. Without the socket, it reads every second. `--next` only watches: a stopped `--next`, or one whose budget ends, leaves every worker open. It works the same from a Claude Code or a Codex orchestrator, so neither needs a sleep loop.
Expand Down
2 changes: 1 addition & 1 deletion NOTICE.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Summary of structural changes inherited by this fork:

This fork adds Herdr as an execution transport. Playbooks keep their native spawn language; `references/herdr-tools.md` is the Herdr translation the same way `codex-tools.md` is the Codex translation. Herdr-specific authored files include:

- `plugins/pstack/skills/poteto-mode/scripts/herdr-dispatch.ts`
- `plugins/pstack/skills/poteto-mode/scripts/herdr/dispatch.ts`
- `plugins/pstack/skills/poteto-mode/references/herdr-tools.md`
- `config/routes.example.yaml`
- `tests/herdr-runtime.test.mjs`
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Use poteto-mode to fix the search filter resetting when I change pages.
| Layer | Owns |
| --- | --- |
| pstack skills | decomposition, roles, worktree isolation, synthesis, review, verification |
| [`herdr-dispatch.ts`](plugins/pstack/skills/poteto-mode/scripts/herdr-dispatch.ts) | pane creation, profile environment, CLI startup, prompt delivery, waiting, output reads, pane cleanup, delegation depth |
| [`herdr/dispatch.ts`](plugins/pstack/skills/poteto-mode/scripts/herdr/dispatch.ts) | pane creation, profile environment, CLI startup, prompt delivery, waiting, output reads, pane cleanup, delegation depth |
| [`herdr-agent-gate.sh`](plugins/pstack/hooks/herdr-agent-gate.sh) | on Claude Code, denies the native `Agent` tool inside Herdr and returns the dispatcher command |
| Herdr | panes, agent status, visibility |
| Claude Code, Codex | the delegated work |
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.9.76
0.9.77
2 changes: 1 addition & 1 deletion docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ Install dependencies for the workflows you use:
| Dependency | When you need it |
| --- | --- |
| GitHub CLI, `gh` | PR monitoring and shipping. Authenticate with `gh auth login`. |
| Bun | The bundled `watch-pr`, `orch`, and `herdr-dispatch.ts` scripts. Their bootstrap installs script dependencies on first run. |
| Bun | The bundled `watch-pr`, `orch`, and `herdr` scripts. Their bootstrap installs script dependencies on first run. |
| Herdr | Visible delegated workers. See [HERDR.md](../HERDR.md). |
| Graphite CLI, `gt` | The Orchestrate playbook and `orch` stack frontier. Shipping and autopilot playbooks use `gh` or Origin's CLI when available. |
| `plugin-dev` | Claude Code skill-authoring guidance used by `automate-me`, `reflect`, and `poteto-mode`. |
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "pstack",
"private": true,
"version": "0.9.76",
"version": "0.9.77",
"description": "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. Pi package of the Claude Code plugin; skills are shared, tool names resolve via skills/poteto-mode/references/pi-tools.md. Original pstack by Lauren Tan (poteto).",
"author": {
"name": "Michael Denyer",
Expand Down
2 changes: 1 addition & 1 deletion plugins/pstack/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "pstack",
"displayName": "pstack (Claude Code port)",
"version": "0.9.76",
"version": "0.9.77",
"description": "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. Ported from cursor/plugins/pstack to Claude Code. Original pstack by Lauren Tan (poteto).",
"author": {
"name": "Michael Denyer",
Expand Down
2 changes: 1 addition & 1 deletion plugins/pstack/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pstack",
"version": "0.9.76",
"version": "0.9.77",
"description": "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. Codex port of the Claude Code plugin; skills are shared, tool names resolve via skills/poteto-mode/references/codex-tools.md. Original pstack by Lauren Tan (poteto).",
"author": {
"name": "Michael Denyer",
Expand Down
2 changes: 1 addition & 1 deletion plugins/pstack/.github/plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "pstack",
"displayName": "pstack (GitHub Copilot port)",
"version": "0.9.76",
"version": "0.9.77",
"description": "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. Ported from cursor/plugins/pstack to GitHub Copilot CLI and app. Original pstack by Lauren Tan (poteto).",
"author": {
"name": "Michael Denyer",
Expand Down
8 changes: 4 additions & 4 deletions plugins/pstack/hooks/herdr-agent-gate.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#!/usr/bin/env bash
# PreToolUse gate on the Agent tool. Inside Herdr, delegation goes through
# herdr-dispatch.ts; outside Herdr, or when the dispatcher cannot run, the
# herdr/dispatch.ts; outside Herdr, or when the dispatcher cannot run, the
# native Agent tool stays available.
set -u

if [ "${HERDR_ENV:-}" != "1" ]; then exit 0; fi
if [ "${PSTACK_HERDR_ALLOW_NATIVE_AGENT:-}" = "1" ]; then exit 0; fi

plugin_root="${CLAUDE_PLUGIN_ROOT:-}"
dispatcher="${plugin_root}/skills/poteto-mode/scripts/herdr-dispatch.ts"
dispatcher="${plugin_root}/skills/poteto-mode/scripts/herdr/dispatch.ts"
mapping="${plugin_root}/skills/poteto-mode/references/herdr-tools.md"

json_string() {
Expand All @@ -31,15 +31,15 @@ deny() {
}

if ! command -v herdr >/dev/null 2>&1; then
allow_with_note "HERDR_ENV=1 but herdr is not on PATH, so this delegation uses the native Agent tool. Put the herdr binary on PATH to route it through herdr-dispatch.ts."
allow_with_note "HERDR_ENV=1 but herdr is not on PATH, so this delegation uses the native Agent tool. Put the herdr binary on PATH to route it through herdr/dispatch.ts."
fi

bun_bin="$(command -v bun 2>/dev/null || true)"
if [ -z "$bun_bin" ] && [ -x "${HOME:-}/.bun/bin/bun" ]; then
bun_bin="${HOME:-}/.bun/bin/bun"
fi
if [ -z "$bun_bin" ]; then
allow_with_note "HERDR_ENV=1 but bun is not installed, so this delegation uses the native Agent tool. Install bun (https://bun.sh) to route it through herdr-dispatch.ts."
allow_with_note "HERDR_ENV=1 but bun is not installed, so this delegation uses the native Agent tool. Install bun (https://bun.sh) to route it through herdr/dispatch.ts."
fi

if [ ! -r "$dispatcher" ]; then
Expand Down
10 changes: 5 additions & 5 deletions plugins/pstack/skills/poteto-mode/references/herdr-tools.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Herdr execution mapping

When `HERDR_ENV=1`, pstack delegation uses the executable `scripts/herdr-dispatch.ts`. Do not use Claude Code `Agent`/`Task` or Codex `spawn_agent` for a delegation that this dispatcher can represent.
When `HERDR_ENV=1`, pstack delegation uses the executable `scripts/herdr/dispatch.ts`. Do not use Claude Code `Agent`/`Task` or Codex `spawn_agent` for a delegation that this dispatcher can represent.

This is a structural runtime rule, not a session-start hint. Skills and playbooks keep their native spawn language. This file is the translation, the same way `codex-tools.md` is the Codex translation.

Expand All @@ -14,7 +14,7 @@ A `PreToolUse` hook on `Agent` (`herdr-agent-gate.sh` under the plugin hooks dir

| pstack / Claude action | Herdr equivalent |
|------------------------|------------------|
| Dispatch a subagent (`Agent` / `Task`) | `herdr-dispatch.ts` |
| Dispatch a subagent (`Agent` / `Task`) | `herdr/dispatch.ts` |
| Dispatch N parallel subagents in one turn | N dispatcher processes launched concurrently without `--wait`, then `--next` |
| `subagent_type` | ignored; pass the semantic pstack `--role` |
| `model` | omit unless overriding; `--role` selects a profile from `~/.config/pstack-herdr/routes.yaml` |
Expand All @@ -28,7 +28,7 @@ A `PreToolUse` hook on `Agent` (`herdr-agent-gate.sh` under the plugin hooks dir
Write substantial worker prompts to a temporary file, then invoke:

```bash
bun <poteto-mode>/scripts/herdr-dispatch.ts \
bun <poteto-mode>/scripts/herdr/dispatch.ts \
--role <role> \
--name <unique-agent-name> \
--prompt-file <brief.md> \
Expand All @@ -47,7 +47,7 @@ For parallel fan-out, launch dispatcher processes concurrently rather than dispa
Never sleep and re-check a worker. Block on `--next` instead:

```bash
bun <poteto-mode>/scripts/herdr-dispatch.ts --next <name> [<name> ...] --timeout <ms>
bun <poteto-mode>/scripts/herdr/dispatch.ts --next <name> [<name> ...] --timeout <ms>
```

It returns as soon as any named worker settles. Herdr pushes each worker's status changes to it, and it reads a Codex worker's rollout every second. It reads and closes every worker that has settled, then prints `{"settled": [...], "pending": [...]}`. Each `settled` entry has the same fields as a `--collect` result, or `agent` and `error` when that worker could not be read. Act on each settled entry, then call `--next` again with the `pending` names until none are left. A budget that ends with nothing settled returns an empty `settled` and every name in `pending`. `--next` only watches. A stopped `--next` or one whose budget ends leaves every worker open, so a shell tool's own timeout loses no work. Pass each name to one `--next` at a time.
Expand Down Expand Up @@ -85,7 +85,7 @@ With `--wait`, the dispatcher returns JSON containing the Herdr agent name, pane
`blocked: true` is not completion. Inspect the worker in Herdr and resolve the approval or question. `unknown` is not proof of completion; it is the status Herdr reported. `working` means the wait budget ran out with the worker still running. The dispatcher leaves `working`, `blocked`, and `unknown` panes open. Finish a `working` worker through the dispatcher, not raw `herdr` commands, so its pane closes when it is done:

```bash
bun <poteto-mode>/scripts/herdr-dispatch.ts --collect --name <agent-name> --timeout <ms>
bun <poteto-mode>/scripts/herdr/dispatch.ts --collect --name <agent-name> --timeout <ms>
```

It returns the same settled JSON without `profile` and `depth`, and leaves the pane open again if the worker is still running when the budget ends. Close a pane with `herdr pane close <pane>` only when the work is no longer wanted. A dispatcher stopped by SIGTERM, SIGINT, or SIGHUP while it waits on a worker, in a dispatch or a `--collect`, closes that worker's pane before it exits; SIGKILL cannot be caught and still leaks the pane.
Expand Down
Loading
Loading