Skip to content
Open
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
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

This port applies the Cursor → Claude Code substitutions in skill bodies. Earlier drafts left them flagged; this revision resolves them. A later pass added a Codex build that shares the same skills; see [Codex port](#codex-port) below.

## Unreleased

**Claude poteto-agent preload.** The Claude Code agent definition preloads `pstack:poteto-mode` through its `skills` frontmatter. Claude subagents start with isolated context, so the upstream prompt alone exposed the skill name but not its body. The shared skill tree and the Codex path are unchanged. The static invariants preserve the binding, and the behavioral check proves that the packaged agent can read a named principle without invoking `Skill` or reading a file.

## 1.3.0 syncs to Cursor pstack 0.14.7

Open Pstack now tracks Cursor pstack 0.14.7 at `efa2a531985e0a8084d36ff3cf87233be8a9f34b`.
Expand Down
1 change: 1 addition & 0 deletions NOTICE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Summary of structural changes:
- `plugins/pstack/skills/babysit/` is independently authored as the Claude Code analog of Cursor's `/babysit` built-in. It has no upstream pstack equivalent; its workflow is informed by Cursor's public `/babysit` behavior. No code or prose was copied from any source.
- `plugins/pstack/skills/poteto-mode/scripts/` is vendored from upstream (`watch-pr`, `orch`, `bootstrap.ts`, `worktree-audit.sh`, `package.json`, `bun.lock`) with these port edits: `worktree-audit.sh` reads `~/.claude/projects/` instead of Cursor's transcript directory and warns when `jq` or `rg` is missing (their absence silently blanks the columns the prune decision reads), the private workspace package is named `@open-pstack/poteto-mode-tools`, `bootstrap.ts` rejects Node before it reads Bun-only APIs, and `package.json` includes the port-authored tests in `bun run test`. `check-plan.mjs` is the Cursor 0.14.3 checker adapted for the shared Claude Code and Codex skeleton. `bootstrap.test.ts` and `check-plan.test.ts` are authored for this port.
- `plugins/pstack/agents/comment-sicko.md` is upstream's `Comment Sicko` agent, renamed to `comment-sicko` so the name works as a Claude Code `subagent_type`. The body is verbatim.
- `plugins/pstack/agents/poteto-agent.md` keeps the upstream prompt and adds Claude Code `skills` frontmatter so the isolated subagent preloads `pstack:poteto-mode`.
- Claude-native Fable and Opus lanes are port-authored agent definitions. They select the rolling family alias plus requested effort for every selectable Claude-native pair in the provider-dispatch model matrix.
- A Codex build shares the same `skills/` tree. It adds `plugins/pstack/.codex-plugin/plugin.json`, a root `.agents/plugins/marketplace.json`, and `plugins/pstack/skills/poteto-mode/references/codex-tools.md` (the Claude-to-Codex tool, model, and built-in map), plus a one-line Platform note in the skills that name a Claude primitive. The skill content itself is unchanged. See [CHANGES.md](CHANGES.md#codex-port).

Expand Down
2 changes: 1 addition & 1 deletion docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ The table uses the short upstream names. Claude Code exposes each native skill w

## Subagents

`poteto-agent` ships unchanged. Spawn from a parent with `subagent_type: "poteto-agent"`.
`poteto-agent` keeps the upstream prompt and adds Claude Code `skills` frontmatter. The field preloads `pstack:poteto-mode` because Claude subagents do not inherit the parent's loaded skills. Spawn the agent from a parent with `subagent_type: "poteto-agent"`.

`comment-sicko` is the read-only comment reviewer the `no-comments` skill spawns. Upstream names it `Comment Sicko`; the port renames it to `comment-sicko` so the name is a valid `subagent_type`. Invoke it through `/no-comments`, not directly.

Expand Down
2 changes: 2 additions & 0 deletions plugins/pstack/agents/poteto-agent.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
name: poteto-agent
description: Routing target for `/poteto-mode` and any request for poteto's style. Resume an existing `poteto-agent` for the conversation rather than spawning a sibling. Reads the `poteto-mode` skill's `SKILL.md` in full before any work, including its inline Principles index. Substituting `general-purpose` skips that read and drifts.
skills:
- pstack:poteto-mode
---

# Poteto subagent
Expand Down
30 changes: 30 additions & 0 deletions tests/skill-collision-repro.sh
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,24 @@ else
fi

plugin="$repo/plugins/pstack"

poteto_agent="$plugin/agents/poteto-agent.md"
poteto_agent_front="$(sed -n '2,/^---$/p' "$poteto_agent")"
poteto_preload_bad=""
if [ "$(printf '%s\n' "$poteto_agent_front" | grep -cx 'skills:' || true)" != "1" ]; then
poteto_preload_bad="${poteto_agent} must declare one skills list"$'\n'
fi
if [ "$(printf '%s\n' "$poteto_agent_front" | grep -cx ' - pstack:poteto-mode' || true)" != "1" ]; then
poteto_preload_bad="${poteto_preload_bad}${poteto_agent} must preload pstack:poteto-mode"$'\n'
fi
if [ -n "$poteto_preload_bad" ]; then
note "FAIL: Claude poteto-agent does not preload poteto-mode:"
note "$poteto_preload_bad"
fail=1
else
note "ok: Claude poteto-agent preloads poteto-mode"
fi

canon="$plugin/skills/poteto-mode/references/bugbot-triage.md"
skill="$plugin/skills/babysit/SKILL.md"
playbook="$plugin/skills/poteto-mode/playbooks/babysit.md"
Expand Down Expand Up @@ -437,4 +455,16 @@ invoke='Call the Skill tool with skill "testplug:foo" exactly once and follow wh
check "model-initiated Skill-tool invocation" "SKILL-RAN" "$(run "$invoke")"
check "user /testplug:foo invocation" "SKILL-RAN" "$(run '/testplug:foo')"

preloaded_agent_output="$(
claude -p \
'Use the Agent tool once with subagent_type pstack:poteto-agent. Give it this task verbatim: "Without invoking Skill or reading files, reply with the first Core principle named in the preloaded poteto-mode skill." Return only the child response.' \
--plugin-dir "$plugin" \
--model fable \
--effort max \
--max-turns 5 \
--tools Agent \
< /dev/null 2>&1
)"
check "poteto-agent preloaded skill" "Laziness Protocol" "$preloaded_agent_output"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Preload Check Is Indirect

This regression only checks the child’s final text for Laziness Protocol. Asking the model not to invoke Skill or read files does not verify that restriction, especially because the agent description itself tells the child to read the poteto-mode skill. If the child obtains the phrase through that alternate path, the test passes without proving that frontmatter preloading worked. Consider asserting the child’s tool activity or making the expected value unavailable without the preload.

Knowledge Base Used: Testing and CI quality gates

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Codex Fix in Cursor


exit "$fail"