Skip to content

Run pstack from OpenCode (third parent harness) #3

Description

@thisguymartin

Follow-up to #1 and #2. This is the last piece from pstack-flex-legacy I haven't brought over: commit 92b5ef4.

The problem

After #1, the lanes pstack spins up can run on DeepSeek or MiniMax. But the session you're typing into still has to be Claude Code or Codex. So "zero-subscription mode" still needs a Claude or OpenAI subscription for the main session.

OpenCode lets you point the main session at pretty much any provider. If pstack can run inside OpenCode, nothing in the stack needs a Claude or OpenAI plan.

Example

Say my OpenCode session is set to a DeepSeek model, and I've exported DEEPSEEK_API_KEY and MINIMAX_API_KEY. /setup-pstack writes ~/.config/opencode/pstack-models.md with something like:

interrogate reviewers: deepseek:deepseek-flash@high, minimax:MiniMax-M3@high, inherit-parent
why investigators: inherit-parent

Then I run /interrogate on a diff:

flowchart TD
    A["/interrogate in OpenCode<br/>(session on DeepSeek)"] --> B["read pstack-models.md<br/>(via opencode.json instructions)"]
    B --> C1["deepseek:deepseek-flash@high"]
    B --> C2["minimax:MiniMax-M3@high"]
    B --> C3["inherit-parent"]
    C1 --> R1["setsid nohup pstack-runner --parent opencode --provider deepseek &"]
    C2 --> R2["setsid nohup pstack-runner --parent opencode --provider minimax &"]
    R1 --> G1["claude binary → api.deepseek.com/anthropic"]
    R2 --> G2["claude binary → api.minimax.io/anthropic"]
    C3 --> T["OpenCode task tool<br/>(same model as the session)"]
    G1 --> P["poll receipt files"]
    G2 --> P
    T --> S["session merges the three reviews"]
    P --> S
Loading

What that gets you:

  • Three reviewers from two labs, and you only pay DeepSeek and MiniMax API rates.
  • The inherit-parent reviewer runs on whatever model OpenCode is using, so switching models in OpenCode switches that lane too.
  • Swap the session to a local model and only the two gateway lanes cost anything.
  • claude:*, codex:*, and grok:* lanes still work if you have those logins. They go through the runner like the gateway lanes do.

What changes

  • runner/types.ts, runner/cli.ts: accept --parent opencode.
  • runner/run.ts: drop OPENCODE, OPENCODE_PID, and AGENT from child environments, so a lane doesn't think it's running inside OpenCode.
  • New poteto-mode/references/opencode-tools.md: which OpenCode tool to use when a skill names a Claude tool (Agent → task, AskUserQuestion → question, and so on), how to install the skills, and how the model sheet gets loaded.
  • poteto-mode/SKILL.md: mention OpenCode and link that file.
  • references/provider-dispatch.md: an OpenCode routing row, plus the detached launch pattern.
  • setup-pstack/SKILL.md: write the sheet to ~/.config/opencode/pstack-models.md and register it in opencode.json.

Why it isn't in #1 or #2

  • AGENTS.md says the skill tree is shared by "Claude Code and Codex". This PR has to change that line, and we should agree we want to.
  • Once OpenCode is a supported parent, any change to shared skills needs a live OpenCode test before merge, not just Claude Code and Codex.
  • OpenCode's bash tool has no background mode and gives up after about two minutes. So lanes start with setsid nohup ... &, completion means "the receipt file showed up", and cancel means kill -TERM <pid>. That works, but it depends on how OpenCode behaves today. Re-check it against the current release before porting.
  • OpenCode's task tool can't choose a model per call, so any lane pinned to a specific model goes through the runner. Nothing runs natively except inherit-parent and auto.

Done when

  • PR stacked on feat(setup): flex dispatch matrix, assignment-first setup, and lane docs #2, with AGENTS.md updated
  • Bun tests, typecheck, static invariants, and plugin validation pass
  • Live test in a real OpenCode session:
    • skills show up and /poteto-mode runs
    • one detached lane completes and its receipt is read
    • kill -TERM gives a cancelled receipt
    • an inherit-parent lane runs through task
    • a rerun of /setup-pstack doesn't change the files
  • Claude Code and Codex re-checked, nothing broke

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions