Skip to content
Draft
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
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,24 @@ jobs:
run: |
git diff --check
git diff --exit-code -- upstream/
verify-macos:
# Case-insensitive filesystem: catches tracked paths that differ only by case.
runs-on: macos-15
steps:
- uses: actions/checkout@v7.0.1
- name: Check the checkout is complete
run: test -z "$(git status --porcelain)"
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.13"
- name: Test runtime diagnostics
run: python3 -m unittest discover -s tests -v
- name: Build skills and verify license notices
run: |
python3 tools/pstack_opencodex.py build
cmp LICENSE dist/LICENSE
cmp upstream/LICENSE dist/LICENSE.pstack
- name: Check whitespace and upstream preservation
run: |
git diff --check
git diff --exit-code -- upstream/
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Issues and pull requests are welcome. Include the command or workflow you used,

## Make a change

- Keep `upstream/` identical to the source pinned in `UPSTREAM`. Use the sync command to update it.
- Keep `upstream/` identical to the source pinned in `UPSTREAM.lock`. Use the sync command to update it.
- Put harness instructions and patches in `overlay/`, and Python tooling in `tools/`.
- Keep `dist/` out of Git. It is generated and contains local absolute paths.
- Use English for project documentation and Conventional Commits for commit messages.
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This is an independent community adaptation. It is not an official Cursor, OpenA
- Python 3.11 or later; the Python tools use only the standard library.
- Git and `patch` on your `PATH`.
- Codex configured through opencodex, with an available model catalog.
- Additional tools required by the workflow you choose: GitHub CLI (`gh`) for GitHub operations, Bun for pstack's TypeScript scripts, and Graphite (`gt`) for Orchestrate. Orchestrate also requires `gt auth` and `gt init`.
- Additional tools required by the workflow you choose: GitHub CLI (`gh`) for GitHub operations and Bun for pstack's TypeScript scripts, including Orchestrate's `orch`. When the Origin CLI (`origin`) is installed and can resolve the repository, pstack uses it instead of `gh`. Graphite (`gt`) is no longer required.

## Quick start

Expand Down Expand Up @@ -79,7 +79,9 @@ A native ChatGPT V2 parent can produce encrypted tasks that routed children cann
- Adds a pointer to `dist/HARNESS.md` at the start of each skill, except `principle-*` skills.
- Adds Codex's `allow_implicit_invocation: false` policy for upstream skills marked `disable-model-invocation: true`.
- Normalizes skill names to directory names such as `poteto-mode`.
- Copies upstream's `README.md` and `docs/` into `dist/` unmodified, so links from `poteto-help` and the guide resolve. `docs/harness/claude-code.md` there is upstream's Claude Code adapter; `dist/HARNESS.md` replaces it for Codex. Upstream's `plugin.json` and `.cursor-plugin/` manifests are not copied.
- Applies the patches in `overlay/patches/`, stopping if a patch no longer applies.
- Rewrites `poteto-help` for Codex: install steps that keep an existing skills folder, `$skill` invocation, no Custom Modes, `~/.codex/pstack-models.md`, and no `make-bot-ui`.
- Excludes `make-bot-ui`, which depends on Cursor automations and Grok Bots.
- Includes both this project's and upstream pstack's MIT license notices in `dist/`.

Expand All @@ -89,11 +91,11 @@ The harness maps Cursor cloud-agent steps to local workers. Available tools and

| Path | Purpose |
| --- | --- |
| `UPSTREAM` | Source repository, subtree, and pinned commit. |
| `UPSTREAM.lock` | Source repository, subtree, and pinned commit. |
| `upstream/` | Unmodified copy of `cursor/plugins/pstack`. |
| `overlay/` | Harness instructions, patches, exclusions, and model example. |
| `tools/` | Build, install, synchronization, and diagnostic tools. |
| `tests/` | Runtime diagnostic tests using temporary configurations and catalogs. |
| `tests/` | Build, patch, and runtime diagnostic tests using temporary directories, configurations, and catalogs. |
| `dist/` | Generated skills, harness, build metadata, and license notices; ignored by Git. |

## Update upstream
Expand Down Expand Up @@ -125,7 +127,7 @@ python3 -m unittest discover -s tests -v
python3 tools/pstack_opencodex.py build
```

Tests cover V1/V2 compatibility, disabled models, configuration/session mismatches, experimental mitigations, CLI exit codes, and preservation of input settings. They use temporary files and do not contact providers. A passing suite does not establish live delegation compatibility.
Tests cover the build (shipped skills, exact patch application, `poteto-help` links, the patched worktree audit), upstream default models against a synthetic catalog, V1/V2 compatibility, disabled models, configuration/session mismatches, experimental mitigations, CLI exit codes, and preservation of input settings. They use temporary files, do not install skills, and do not contact providers. A passing suite does not establish live delegation compatibility.

See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.

Expand Down
2 changes: 1 addition & 1 deletion UPSTREAM → UPSTREAM.lock
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
repo=https://github.com/cursor/plugins.git
path=pstack
ref=12d587dfb20741cafc376c42c696c5f6e2a64487
ref=88d47514b82e7c44f00f2b2a72ff6dd12158038c
21 changes: 19 additions & 2 deletions overlay/HARNESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ pstack was written for Cursor. This file maps its tools, paths, and model names
- Subagent definitions: `{{PSTACK_DIST}}/agents/poteto-agent.md` and `{{PSTACK_DIST}}/agents/comment-sicko.md`.
- Skill folders: `.agents/skills/` in the repository for project skills such as a generated `verify-<app>`, and `~/.agents/skills/` for user skills.
- Cursor paths in pstack text map as follows. `.cursor/skills/` is `.agents/skills/`. `~/.cursor/skills/` is `~/.agents/skills/`, and Codex also reads `~/.codex/skills/`. `~/.cursor/plugins/` is `~/.codex/plugins/`. Project rules under `.cursor/rules/` are the repository's `AGENTS.md` files. `~/.cursor/projects/<slug>/agent-transcripts/` is covered under Transcripts. For worktrees under `.cursor/worktrees/`, use `git worktree list`, which finds worktrees wherever they live.
- This build is not installed as a plugin. Where pstack text searches `~/.cursor/plugins/` for a pstack file, or picks the copy whose `.cursor-plugin/plugin.json` has the highest `version`, read the file under `{{PSTACK_DIST}}` instead.
- `{{PSTACK_DIST}}/README.md` and `{{PSTACK_DIST}}/docs/` are unmodified copies of upstream's README and docs, so they describe Cursor. `{{PSTACK_DIST}}/docs/harness/claude-code.md` is upstream's Claude Code adapter. It does not apply to Codex; this file takes its place.

## Subagents

- `Task` means Codex's `spawn_agent`. Use the collaboration tools actually exposed by the session. In the desktop surface, `wait_agent` waits for mailbox updates; read the delivered messages and final answers to collect results. `send_message` sends a message without starting an idle agent, `followup_task` assigns more work and starts an idle agent, and `interrupt_agent` stops its current turn while keeping it available. Interruption is not closure. Use `send_input`, `wait`, or `close_agent` only on hosts that expose those tools; do not invent absent tools.
- Pass the prompt as `message`, and set `model` and `reasoning_effort` as described under Models. Drop `subagent_type`, `run_in_background`, and any other parameter Codex does not have. Codex subagents already run in the background.
- Where pstack says to pick each subagent's reasoning level and fast or standard speed for the job, per the Subagents section of **poteto-mode**, adjust only `reasoning_effort`. Start from the role's value, move the effort the way poteto-mode says, then clamp it as described under Models. Codex has no per-spawn speed choice, so ignore the speed half and never add `-fast`. If the spawn rejects the adjusted effort, spawn with the role's value and say so.
- When this host only accepts model overrides with a partial or empty fork, use `fork_turns: "none"` for independent tasks and include their context explicitly. This controls history inheritance, not V1/V2 transport or encryption.
- `readonly: true` means the prompt must say the agent may read files and run commands but must not edit files, commit, or push.
- `environment: "cloud"` means a local subagent that works in its own git worktree and output directory.
- `subagent_type: "poteto-agent"` means a subagent whose message starts with "Read {{PSTACK_DIST}}/skills/poteto-mode/SKILL.md in full, including its Principles section, before any work." Then give the task.
- `subagent_type: "Comment Sicko"` means a read-only subagent whose message starts with "Read {{PSTACK_DIST}}/agents/comment-sicko.md and follow it as your instructions."
- `subagent_type: "comment-sicko"` means a read-only subagent whose message starts with "Read {{PSTACK_DIST}}/agents/comment-sicko.md and follow it as your instructions."
- A pstack step that tells you to spawn subagents is the skill instruction that authorizes spawning. A model chosen in the pstack settings file is the user's explicit model choice.
- Codex can stop a subagent from spawning its own subagents (`agents.max_depth`). When a spawn fails for that reason, do those roles yourself, one after another, and say so in the report.

Expand Down Expand Up @@ -70,12 +73,25 @@ Codex stores sessions at `~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl`, subagen
- `/goal` means Codex's `create_goal` when this session has it. Otherwise keep the objective and its exit condition in the plan file.
- `/loop` means a timed wait between checks: a shell `sleep` of at most 60 seconds per call, repeated. In the Codex desktop app, a thread heartbeat automation can wake the thread for longer intervals.

## Skill notes

Invoke every skill as `$name`. These skills need more than the mappings above:

- `ketchup`: the user's last message is the last one they typed in this session. `wait_agent` results, subagent messages, and notifications are not their messages. Give each screenshot or video the work produced as a Markdown image or link to its absolute local path, and say in the same line what it shows, since not every Codex client renders media inline. Write diagrams as fenced `mermaid` blocks. For charts, see `/visualize` under Tools pstack does not ship.
- `poteto-help`: the build rewrites its install, settings, and mode guidance for Codex (overlay patch `0002`). Its links to the README and guide pages open the unmodified upstream copies, which describe Cursor's install, Custom Modes, and settings. For this build, install with `tools/pstack_opencodex.py build` and `install`, invoke skills as `$name`, start each task with `$poteto-mode` because Codex has no Custom Modes, resume a task in a new session through the Session pickup playbook, keep model settings in `~/.codex/pstack-models.md`, and say that `make-bot-ui` is not installed.
- `create-formal-verification-skill`, `maintain-formal-verification-skill`, and `create-verification-skill`: write a generated project-local skill to the repository's `.agents/skills/<name>/SKILL.md`, with frontmatter whose `name` equals the folder name and a `description`. A session that started before the file existed may not list it, so open it by path or start a new session.
- `correct`: the agent instruction file is the repository's `AGENTS.md`. Keep the rule table there.
- `benchmark-checklist`, `principle-explain-the-number`, `in-your-own-words`, and `sharpen` need nothing beyond this file.

## Help and guide pages

`$poteto-help` links to `{{PSTACK_DIST}}/README.md` and `{{PSTACK_DIST}}/docs/guide/`. The build copies them unmodified from upstream, so they describe Cursor's install, Custom Modes, and settings. For this build, install with `tools/pstack_opencodex.py build` and `install`, and run skills as `$name`. Codex has no Custom Modes, so start each task with `$poteto-mode`; a new session does not remember the last one, so resume through the Session pickup playbook. Settings live in `~/.codex/pstack-models.md`, and `make-bot-ui` is not installed.

## Cursor features Codex does not have

- Cursor cloud agents and the Cursor dashboard. Codex subagents run on this machine and stop when Codex exits. Their state lives in `wait_agent` results, their worktrees, pushed branches, and the program's ledger files. Where pstack describes a Cursor restart, apply the same rule to a Codex restart: treat every subagent as gone and resume from those records. Where pstack offers a local root or a cloud root, follow the local root instructions.
- Cursor's built-in skills, such as its babysit skill. Codex has none of them, so follow the pstack playbook pstack names.
- Cursor automations, webhook routines, and Grok Bots. The `make-bot-ui` skill depends on them and is not installed.
- Graphite. Orchestrate's stack tools (`orch frontier`) run `gt` and read PR numbers through Graphite, which needs `gt auth` and `gt init` in the repository. Before starting Orchestrate, check `command -v gt` and check that `~/.config/graphite/user_config` contains an `authToken` key without printing its value, for example with `rg -q authToken ~/.config/graphite/user_config`. If `gt` is missing or not authenticated, tell the user before any work. The other playbooks use `gh` and never require `gt`.

## Tools pstack does not ship

Expand All @@ -85,3 +101,4 @@ Codex stores sessions at `~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl`, subagen
- `control-cli`: a tmux session or a PTY command for CLIs and TUIs.
- Bugbot and Cursor's agentic security review: apply their triage rules to whatever review bots the repository uses. If none comment, skip those steps.
- MCP discovery in the **why** skill: Cursor's `mcps/` directory means the MCP tools in your own tool list, named `mcp__<server>__<tool>`. `codex mcp list` shows the configured servers.
- `/visualize`: Cursor's chart tool. Draw a fenced `mermaid` chart instead, such as `xychart-beta` for numbers, or give the numbers in one sentence. Never invent a number.
12 changes: 6 additions & 6 deletions overlay/patches/0001-worktree-audit-linux-and-codex.patch
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
--- a/skills/poteto-mode/scripts/worktree-audit.sh
+++ b/skills/poteto-mode/scripts/worktree-audit.sh
@@ -22,11 +22,19 @@
gh pr list --author "@me" --state all --limit 1000 \
--json number,state,headRefName 2>/dev/null > "$prs" || echo "[]" > "$prs"
@@ -61,11 +61,19 @@
fi
[ -s "$prs" ] || echo "[]" > "$prs"

-# Transcripts dir: ~/.cursor/projects/<slugified-repo-path>/agent-transcripts.
+# Transcripts: Cursor keeps them per project under
Expand All @@ -18,10 +18,10 @@
+mtimes() { if stat -c %Y / >/dev/null 2>&1; then xargs stat -c '%Y %n'; else xargs stat -f '%m %N'; fi; }
+day() { date -d "@$1" '+%Y-%m-%d' 2>/dev/null || date -r "$1" '+%Y-%m-%d'; }
+
echo "# base: $base"
printf "SIZE\tAGE\tMERGED\tDIRTY\tREMOTE\tPR\tLAST_CHAT\tBUCKET\tWORKTREE\n"

git worktree list --porcelain | awk '/^worktree /{print $2}' | while read -r wt; do
@@ -63,12 +71,11 @@
@@ -103,12 +111,11 @@
# Most recent chat whose transcript operated in this worktree. Match path
# followed by "/" or a quote so glint-482 does not match glint-482-r37.
last="-"; last_ts=0
Expand All @@ -39,7 +39,7 @@
recent=$([ "$last_ts" -gt 0 ] 2>/dev/null && [ $(( (now - last_ts) / 86400 )) -le 4 ] && echo yes || echo no)

case "$dirty" in wip:*) bucket=hold-wip ;; *)
@@ -83,4 +90,4 @@
@@ -123,4 +130,4 @@
"$size" "$age" "$merged" "$dirty" "$remote" "$pr" "$last" "$bucket" "$wt"
done | sort -t$'\t' -k1,1 -rh

Expand Down
Loading
Loading