Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
aff6cc5
feat: support Claude Code and Codex with upstream sync
yxhta Oct 3, 2026
a37612f
fix: bundle runtime adaptation for skills CLI installs
yxhta Oct 3, 2026
252f978
refactor(pstack): preserve upstream source and generate portable package
yxhta Oct 3, 2026
8491d3a
feat: add native pstack routing and effort support
yxhta Oct 3, 2026
cbc4793
docs: migrate legacy pstack skill update paths
yxhta Oct 3, 2026
8a911ae
Improve portable pstack upstream parity
yxhta Oct 4, 2026
17e35db
test: isolate worktree fixtures from runner system filters
yxhta Oct 4, 2026
c2c6c6e
merge: retain pinned upstream ancestry for source validation
yxhta Oct 4, 2026
e761c3c
Merge pull request #3 from yxhta/improve/upstream-parity
yxhta Oct 4, 2026
5f83e92
feat(thermos): support Claude Code and Codex (#4)
yxhta Oct 5, 2026
384e721
feat(pstack): add opt-in Claude Mods bug-fix gates
yxhta Oct 6, 2026
e7e0221
fix(pstack): align review diffs with raw snapshots
yxhta Oct 6, 2026
721810a
chore(pstack): sync 0.15.15 and fix maintenance gates
yxhta Oct 7, 2026
2b3794a
Merge pull request #6 from yxhta/maintenance/upstream-oct7
yxhta Oct 7, 2026
37b65a8
chore(pstack): refresh Mods against current main
yxhta Oct 7, 2026
2ad948e
fix(pstack-mods): isolate stale tool guard failures
yxhta Oct 7, 2026
40433ea
Merge pull request #5 from yxhta/feat/claude-mods-bugfix-gates
yxhta Oct 7, 2026
a99b428
chore(pstack): sync upstream marketplace additions
yxhta Oct 8, 2026
f755e1f
Merge pull request #7 from yxhta/maintenance/upstream-oct8
yxhta Oct 8, 2026
f5474b4
chore: sync pstack 0.15.21 and preserve portable invocation gates
yxhta Oct 13, 2026
2595adf
Merge pull request #9 from yxhta/maintenance/pstack-20261013
yxhta Oct 13, 2026
03fe759
Merge remote-tracking branch 'upstream/main' into sync/pstack-upstrea…
yxhta Oct 15, 2026
9b10e1c
chore: sync pstack upstream e5136d8 and adapt per-job effort for Claude
yxhta Oct 15, 2026
a57e1f0
Merge pull request #11 from yxhta/sync/pstack-upstream-e5136d8
yxhta Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
38 changes: 38 additions & 0 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "yxhta-pstack",
"interface": {
"displayName": "pstack"
},
"plugins": [
{
"name": "pstack",
"source": {
"source": "local",
"path": "./portable/pstack"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL",
"products": [
"CODEX"
]
},
"category": "Developer Tools"
},
{
"name": "thermos",
"source": {
"source": "local",
"path": "./portable/thermos"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL",
"products": [
"CODEX"
]
},
"category": "Developer Tools"
}
]
}
22 changes: 16 additions & 6 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
{
"name": "cursor-plugins",
"name": "yxhta-pstack",
"description": "Upstream pstack and Thermos adapted for Claude Code and Codex.",
"owner": {
"name": "Cursor",
"email": "plugins@cursor.com"
"name": "yxhta"
},
"plugins": [
{
"name": "origin-apps",
"source": "./origin-apps",
"description": "Skills for building on the Cursor Origin API. Fetch the live spec first, then follow the Origin rules for credentials, scopes, webhooks, paging, and errors. Includes a skill that plans the port of an existing GitHub App."
"name": "pstack",
"source": "./portable/pstack",
"description": "Upstream pstack workflows adapted for Claude Code and Codex."
},
{
"name": "thermos",
"source": "./portable/thermos",
"description": "Independent correctness and code-quality branch reviews."

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thermos listing descriptions do not match

Medium Severity · Bugbot Rules

Plugin listing description must match verbatim across Claude listing surfaces. The marketplace Thermos entry says Independent correctness and code-quality branch reviews. while .claude-plugin/plugin.json (template and generated package) says Thermos correctness and code-quality reviews for Claude Code and Codex. That split listing copy leaves marketplace and install UI out of sync.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by learned rule: Plugin listing copy must match plugin.json and marketplace.json

Reviewed by Cursor Bugbot for commit a57e1f0. Configure here.

},
{
"name": "pstack-mods",
"source": "./portable/pstack-mods",
"description": "Opt-in Claude Mods bug-fix evidence gates. Validated against Claude Code 2.1.289."

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mods listing descriptions do not match

Medium Severity · Bugbot Rules

Plugin listing description must match verbatim across Claude listing surfaces. The marketplace pstack-mods entry says Opt-in Claude Mods bug-fix evidence gates. Validated against Claude Code 2.1.289. while .claude-plugin/plugin.json says Opt-in, snapshot-bound bug-fix evidence gates for Claude Code. Marketplace and installed plugin listings therefore disagree.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by learned rule: Plugin listing copy must match plugin.json and marketplace.json

Reviewed by Cursor Bugbot for commit a57e1f0. Configure here.

}
]
}
6 changes: 6 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pstack/** -whitespace
README.md -whitespace
portable/pstack/** -whitespace linguist-generated=true
thermos/** -whitespace
portable/thermos/** -whitespace linguist-generated=true
portable/pstack-mods/** -whitespace linguist-generated=true
38 changes: 38 additions & 0 deletions .github/workflows/sync-pstack-upstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Sync pstack upstream

on:
workflow_dispatch:
schedule:
- cron: '23 2 * * *'

permissions:
contents: write
pull-requests: write

concurrency:
group: pstack-upstream-sync
cancel-in-progress: false

jobs:
sync:
if: github.repository == 'yxhta/pstack'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
token: ${{ secrets.UPSTREAM_SYNC_TOKEN || github.token }}
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: python -m pip install PyYAML==6.0.3
- name: Configure commit identity
run: |
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
- name: Merge, validate, and open a sync PR
env:
GH_TOKEN: ${{ secrets.UPSTREAM_SYNC_TOKEN || github.token }}
GH_REPO: ${{ github.repository }}
run: bash tools/portable/sync-upstream.sh
79 changes: 79 additions & 0 deletions .github/workflows/validate-pstack-portable.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Validate portable pstack, Thermos, and Mods

on:
push:
paths:
- 'pstack/**'
- 'thermos/**'
- 'cursor-team-kit/skills/deslop/**'
- 'cursor-team-kit/LICENSE'
- 'portable/**'
- 'README.md'
- 'README_PORTABLE.md'
- 'docs/thermos-*.md'
- 'docs/pstack-mods*.md'
- '.gitattributes'
- 'tools/portable/**'
- '.claude-plugin/**'
- '.agents/plugins/**'
- '.github/workflows/*pstack*.yml'
pull_request:
paths:
- 'pstack/**'
- 'thermos/**'
- 'cursor-team-kit/skills/deslop/**'
- 'cursor-team-kit/LICENSE'
- 'portable/**'
- 'README.md'
- 'README_PORTABLE.md'
- 'docs/thermos-*.md'
- 'docs/pstack-mods*.md'
- '.gitattributes'
- 'tools/portable/**'
- '.claude-plugin/**'
- '.agents/plugins/**'
- '.github/workflows/*pstack*.yml'

permissions:
contents: read

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '20'
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: python -m pip install PyYAML==6.0.3
- run: python3 tools/portable/validate.py
- run: python3 -m unittest discover -s tools/portable -p 'test_*.py'
- name: Validate Mods with pinned native Claude Code
env:
DISABLE_AUTOUPDATER: '1'
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1'
run: |
curl -fsSL https://claude.ai/install.sh -o "$RUNNER_TEMP/install-claude.sh"
bash "$RUNNER_TEMP/install-claude.sh" 2.1.289
export PATH="$HOME/.local/bin:$PATH"
test "$(claude --version)" = '2.1.289 (Claude Code)'
bash tools/portable/check-mods.sh
- run: bash -n tools/portable/sync-upstream.sh
- run: sh -n portable/pstack/hooks/session-start.sh
- name: Install the skills for both agents in an isolated project
run: |
mkdir -p "$RUNNER_TEMP/pstack-skills-smoke"
cd "$RUNNER_TEMP/pstack-skills-smoke"
npx --yes skills add "$GITHUB_WORKSPACE/portable/pstack" --skill '*' --agent claude-code codex --copy --yes
python3 "$GITHUB_WORKSPACE/tools/portable/check-install.py" "$RUNNER_TEMP/pstack-skills-smoke"
- name: Install Thermos for both agents in an isolated project
run: |
mkdir -p "$RUNNER_TEMP/thermos-skills-smoke"
cd "$RUNNER_TEMP/thermos-skills-smoke"
npx --yes skills add "$GITHUB_WORKSPACE/portable/thermos" --skill '*' --agent claude-code codex --copy --yes
python3 "$GITHUB_WORKSPACE/tools/portable/check-install.py" "$RUNNER_TEMP/thermos-skills-smoke" --package thermos
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ build/

# Logs
*.log

# Runtime-generated Claude Mods declarations
/portable/pstack-mods/.claude-plugin/types/
/tools/portable/mods-assets/.claude-plugin/types/
107 changes: 107 additions & 0 deletions README_PORTABLE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# pstack for Claude Code and Codex

This is a fork of [cursor/plugins](https://github.com/cursor/plugins), maintained for the pstack and Thermos skills. Upstream's playbooks and principles are shared by both runtimes. The original [pstack README](pstack/README.md) remains the Cursor guide; the instructions here apply to this fork.

For Thermos installation and review commands, see [Thermos for Claude Code and Codex](docs/thermos-portable.md).

For an optional Claude-only bug-fix evidence pipeline, see [pstack Mods](docs/pstack-mods.md). It runs only after explicit opt-in and leaves the existing portable workflows unchanged.

## Install

### Skills CLI (Claude Code and Codex)

```sh
npx skills add yxhta/pstack/portable/pstack --skill '*' --agent claude-code codex
```

This installs the shared skill bundle for both agents in the current project. Add `--global` for a personal installation. Install all pstack skills together: the entry points share the runtime adaptation and other resources under poteto-mode. The bundle includes the adaptation and agent reference prompts, but it does not register plugin agent types or plugin namespaces. Use `/poteto-mode` on Claude Code and `$poteto-mode` on Codex; the adaptation describes the general-purpose agent fallback.

```sh
npx skills update
```

Upstream synchronization updates this fork through PRs. After merging a sync PR, update the installed skills separately with the command above.

If this fork was installed before the portable package split, reinstall it once from the explicit portable path. Old lock entries point to `pstack/skills/`, which now contains untouched Cursor source. Updating those entries can install Cursor instructions or fail to match normalized names such as `poteto-mode` and `make-bot-ui`.

For an existing global installation:

```sh
npx skills add yxhta/pstack/portable/pstack --skill '*' --agent claude-code codex --global --yes
```

Include any other agents that already use this bundle. For a project installation, omit `--global`. Reinstallation refreshes the skill contents and records `portable/pstack/skills/<name>/SKILL.md` as the update path. Subsequent `npx skills update` calls use that path.

### Native plugins

Claude Code:

```text
/plugin marketplace add yxhta/pstack
/plugin install pstack@yxhta-pstack
```

Codex CLI:

```sh
codex plugin marketplace add yxhta/pstack
codex plugin add pstack@yxhta-pstack
```

Start with `/pstack:poteto-mode` on Claude Code. On Codex, select the installed `pstack:poteto-mode` skill or ask to use poteto-mode. Run setup-pstack to configure roles. Missing roles inherit the session model; multi-model diversity needs models that your runtime actually exposes. Native plugins supply startup context when their hook is enabled and trusted.

For a skills-only installation, clone this repository and keep it in place, then link each directory under `portable/pstack/skills/` into your runtime's user skill directory. Install all skill directories together so the shared runtime adaptation and other relative references stay reachable. Existing skill names such as `swarm` and `architect` may collide: inspect existing installations before replacing them.

Read [runtime adaptation](tools/portable/assets/skills/poteto-mode/references/runtime-adaptation.md) for the tool mappings, paths, and limitations. Cursor-only `make-bot-ui`, Benny automations, cloud workers, and transcript parsers are not ported. Deslop is bundled at the same upstream pin. Other optional cursor-team-kit dependencies are not included. Installation and structural validation do not establish that every workflow runs correctly; check a real task in each runtime.

## Runtime parity and limits

The adapter preserves upstream review roles, participant counts, fresh-agent policy, and completion gates. The shared bundle intentionally removes `disable-model-invocation` from workflow skills so poteto-mode can route to them. The poteto-help and ketchup entry points retain upstream's explicit-only invocation, including matching Codex policies. This changes discovery and invocation availability; it does not grant permission for side effects. Capacity limits queue participants in waves. If the host cannot provide an independent reviewer or isolated context, that gate remains unverified. A self-review or a missing transcript does not count as passing evidence.

Portable Comment Sicko is read-only. Its parent applies accepted, scoped comment deletions and checks the resulting diff before completing no-comments. A findings-only report does not complete the edit workflow.

For worktree discovery, use `python3 <skills-root>/poteto-mode/scripts/portable-worktree-audit.py --repo <repo> --base <verified-ref>`. The script returns local Git evidence as JSON without fetching, reading chats, or deleting anything. Every worktree's usage remains unknown until independently checked. Clean or merged worktrees are not automatically safe to remove.

For portable multi-phase plans, run `node <skills-root>/poteto-mode/scripts/check-portable-plan.mjs <plan.md>`. Add the runtime contract described in the adaptation under the program's Arm the program section. The companion preserves upstream structural gates and reports actual runtime assertions separately as unverified or blocked.

The [parity report](docs/parity-report.md) separates source preservation, executable checks, and host-dependent behavior. Read the runtime adaptation before using bundled scripts. Their presence does not establish installed dependencies, scheduler persistence, or authorization for external actions.

## Upstream updates

The **Sync pstack upstream** GitHub Actions workflow checks daily and can be run manually. It merges upstream main into a dedicated branch, records the upstream SHA, regenerates the portable package, validates it, and opens a draft PR. It never merges into main automatically. The complete repository history is retained because this is a GitHub fork. The PR body separates raw pstack paths from other changed paths, which include generated output, fork tooling, and other upstream plugins.

Enable GitHub Actions in this fork and allow Actions to create pull requests under **Settings → Actions → General**. Scheduled workflows may be disabled by GitHub after prolonged inactivity; run or re-enable the workflow when needed. If Actions is not allowed to create PRs, supply a suitably scoped repository secret `UPSTREAM_SYNC_TOKEN`; do not commit credentials. A PR opened with the default GITHUB_TOKEN does not trigger other PR workflows, so the sync job runs validation itself.

The sync script requires a clean dedicated checkout at the latest `origin` default branch. Only one sync PR is kept open. If an open sync PR blocks a newer upstream revision, the job fails and names both the branch and pending SHA. Review and merge or close that PR before retrying. An already-current fork succeeds even if an old sync PR remains open. A merge conflict or validation failure fails the workflow with logs instead of overwriting the local adaptation. Retries use an unused branch suffix when a closed PR or interrupted run left a branch behind; they never force-push that branch. Resolve the conflicting upstream change on a branch and run the checks below. New upstream skills receive the same adaptation automatically.

```sh
python3 tools/portable/prepare.py
python3 tools/portable/validate.py
python3 -m unittest discover -s tools/portable -p 'test_*.py'
git diff --check
claude plugin validate ./portable/pstack
```

The raw `pstack/` tree and root `README.md` match `tools/portable/upstream.json` byte for byte, including executable modes. Do not edit these source paths. The generator copies the complete upstream package to `portable/pstack/`, adds runtime mappings, and normalizes skill names there. It copies agents, licenses, scripts, and references. It rejects input symlinks and overlay collisions instead of overwriting unfamiliar upstream files.

Edit fork-owned inputs under `tools/portable/assets/` and rerun `python3 tools/portable/prepare.py`. Never edit `portable/pstack/` by hand. The generated package is committed intentionally so every installation works without a build. `python3 tools/portable/prepare.py --check` detects missing, stale, modified, or mode-changed output. Root marketplaces point to this single package. Source files remain unpatched when upstream changes a skill header.

Native plugin versions include the upstream pin and a digest of the package contents and executable modes. Adapter-only changes receive a new version without a manual bump. Template version fields are excluded from the digest.

Git whitespace checks apply to fork-owned inputs. `.gitattributes` exempts the upstream source paths and generated package so upstream whitespace remains intact. Source integrity and generation checks cover those paths.

Use `$sync-pstack-upstream` on Codex or `/sync-pstack-upstream` on Claude Code to review and integrate upstream changes from a source checkout. A native Claude plugin exposes `/pstack:sync-pstack-upstream`. The skill reads the recorded pin and full upstream diff, reviews changed runtime assumptions, regenerates, verifies, and prepares a PR. It does not merge automatically. Consumer installation updates still use `npx skills update`.

Mechanical merge conflicts in raw `pstack/` are avoided by keeping it pristine. Conflicts in root marketplaces or fork-owned automation can still occur. Semantic changes to upstream workflows still require review and actual execution on the affected runtime. Automated sync PRs report this review gap rather than claiming complete runtime compatibility.

## Native runtime support

Native plugin installation includes a read-only SessionStart hook. Claude Code discovers `hooks/hooks.json`; Codex uses the explicitly registered `hooks/codex-hooks.json`. Claude also receives fresh native poteto-agent and read-only comment-sicko wrappers with low, medium, high, xhigh and max effort variants. Each variant inherits the model. Support for the requested effort still depends on the chosen model.

The runtime adaptation has separate Claude and Codex dispatch contracts. They consume confirmed session models, preserve the upstream role labels and panel counts, and disclose unsupported model or effort choices. Native wrapper Markdown links use the host-substituted `${CLAUDE_PLUGIN_ROOT}` so required reading resolves from the installed plugin root. Skills-only installations use general-purpose agents with the required reading in their brief. They do not register hooks or native agents.

The startup hook reads only the `session hook` directive in the runtime model sheet. Add `session hook: off` to `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/pstack-models.md` or `${CODEX_HOME:-$HOME/.codex}/pstack-models.md` to disable it. Missing sheets leave startup context enabled. Unreadable sheets or conflicting directives suppress context and print a warning. No setting is written automatically.

Codex hooks require review and trust through `/hooks`. Installing or enabling the plugin does not grant that trust. Changed hook definitions require another review. SessionStart supplies parent context only; delegated agents still receive explicit reading instructions.

Deslop is generated directly from `cursor-team-kit/skills/deslop/SKILL.md` at the recorded upstream pin. Both the standalone skill and the poteto-mode reference use the same source. `DESLOP_SOURCE.md` and `LICENSE-CURSOR-TEAM-KIT` carry its provenance and MIT license in the native package and inside both skill folders, so skills-only copies retain them. All upstream pstack skill bodies and playbooks remain unchanged.
Loading