0
Fork 0
mirror of https://github.com/obra/superpowers.git synced 2026-09-25 22:09:05 +00:00

OpenCode: bootstrap injection can reset custom agent to build (possible noReply interaction) #226

Closed
opened 2026-01-03 16:02:21 +00:00 by PhilippPolterauer · 11 comments
PhilippPolterauer commented 2026-01-03 16:02:21 +00:00 (Migrated from github.com)

OpenCode + Superpowers: custom agent resets to build on first prompt (hypothesis + suggested fix)

Summary

After installing the Superpowers plugin (git clone method), OpenCode sometimes appears to ignore a manually selected custom agent and silently revert the session to the default build agent on the first prompt of a new session.

This document is written as a working hypothesis + proposal for discussion, not a definitive upstream diagnosis.

Symptom

  • Selecting a non-default/custom agent works initially.
  • When sending the first prompt in a new session, OpenCode switches to build.
  • After switching agents again, the selection often “sticks”.

Suspected trigger (hypothesis)

Superpowers injects bootstrap instructions early in the session lifecycle using a programmatic prompt insertion:

  • client.session.prompt({ noReply: true, ... }) during session.created

There is active upstream discussion that noReply: true prompts can interact with OpenCode’s agent/model selection logic (see anomalyco/opencode#4475). Based on that, it seems plausible that the synthetic bootstrap injection:

  • is processed under (or defaults to) build, and/or
  • causes the session’s current agent/mode to be inferred as build, clobbering a user’s selection for the next turn.

(Again: this is a plausible explanation based on observed behavior and upstream chatter, not a confirmed root cause.)

Suggested mitigation (proposal)

Instead of inserting a synthetic noReply message into the chat transcript at session start, consider injecting the Superpowers instructions via OpenCode’s system prompt transform hook (supported in newer OpenCode versions):

  • experimental.chat.system.transform

Rationale:

  • Avoids modifying the chat history.
  • Avoids relying on noReply message insertion for persistence.
  • May avoid the agent-loop edge-case where the session snaps back to build.

Sketch of the approach

hooks: {
  'experimental.chat.system.transform': async ({ system }) => {
    const bootstrap = getBootstrapContent(false)
    if (!bootstrap) return { system }
    return { system: system + "\n\n" + bootstrap }
  }
}

Local experiment

In a local patch of .opencode/plugin/superpowers.js, disabling the session.created bootstrap prompt injection and using experimental.chat.system.transform instead appears to prevent the agent switch in my environment.

This likely indicates the bug is tied to the message-insertion approach rather than the Superpowers content itself.

References

# OpenCode + Superpowers: custom agent resets to `build` on first prompt (hypothesis + suggested fix) ## Summary After installing the Superpowers plugin (git clone method), OpenCode sometimes appears to **ignore a manually selected custom agent** and silently revert the session to the default `build` agent on the **first prompt** of a new session. This document is written as a **working hypothesis + proposal for discussion**, not a definitive upstream diagnosis. ## Symptom - Selecting a non-default/custom agent works initially. - When sending the first prompt in a new session, OpenCode switches to `build`. - After switching agents again, the selection often “sticks”. ## Suspected trigger (hypothesis) Superpowers injects bootstrap instructions early in the session lifecycle using a programmatic prompt insertion: - `client.session.prompt({ noReply: true, ... })` during `session.created` There is active upstream discussion that `noReply: true` prompts can interact with OpenCode’s agent/model selection logic (see anomalyco/opencode#4475). Based on that, it seems plausible that the synthetic bootstrap injection: - is processed under (or defaults to) `build`, and/or - causes the session’s current agent/mode to be inferred as `build`, clobbering a user’s selection for the next turn. (Again: this is a *plausible explanation* based on observed behavior and upstream chatter, not a confirmed root cause.) ## Suggested mitigation (proposal) Instead of inserting a synthetic `noReply` message into the chat transcript at session start, consider injecting the Superpowers instructions via OpenCode’s **system prompt transform hook** (supported in newer OpenCode versions): - `experimental.chat.system.transform` Rationale: - Avoids modifying the chat history. - Avoids relying on `noReply` message insertion for persistence. - May avoid the agent-loop edge-case where the session snaps back to `build`. ### Sketch of the approach ```js hooks: { 'experimental.chat.system.transform': async ({ system }) => { const bootstrap = getBootstrapContent(false) if (!bootstrap) return { system } return { system: system + "\n\n" + bootstrap } } } ``` ## Local experiment In a local patch of `.opencode/plugin/superpowers.js`, disabling the `session.created` bootstrap prompt injection and using `experimental.chat.system.transform` instead appears to prevent the agent switch in my environment. This likely indicates the bug is tied to the message-insertion approach rather than the Superpowers content itself. ## References - OpenCode upstream discussion: https://github.com/anomalyco/opencode/issues/4475
Nindaleth commented 2026-01-07 11:15:42 +00:00 (Migrated from github.com)

In #187 there's an alternative angle of approach

In #187 there's an alternative angle of approach
Nindaleth commented 2026-01-07 11:15:42 +00:00 (Migrated from github.com)

In #187 there's an alternative angle of approach

In #187 there's an alternative angle of approach
PhilippPolterauer commented 2026-01-07 18:36:28 +00:00 (Migrated from github.com)

am i missing something, i do not see how this solves the super power prompt injection? or would we just not add a system level prompt that instruct each agent that he has super powers, without the need for discovering and loading skills ?

am i missing something, i do not see how this solves the super power prompt injection? or would we just not add a system level prompt that instruct each agent that he has super powers, without the need for discovering and loading skills ?
PhilippPolterauer commented 2026-01-07 18:36:28 +00:00 (Migrated from github.com)

am i missing something, i do not see how this solves the super power prompt injection? or would we just not add a system level prompt that instruct each agent that he has super powers, without the need for discovering and loading skills ?

am i missing something, i do not see how this solves the super power prompt injection? or would we just not add a system level prompt that instruct each agent that he has super powers, without the need for discovering and loading skills ?
Nindaleth commented 2026-01-07 19:18:13 +00:00 (Migrated from github.com)

My understanding of superpowers is that this is a set of skills and commands and the OpenCode plugin teaches OpenCode to use the skills (with additional skills usage reinforcement by the system prompt).

If OpenCode supports skills and commands out of the box, I would think that (after necessary changes) OpenCode part of superpowers could turn into a set of files without much else needed, is that right?

My understanding of superpowers is that this is a set of skills and commands and the OpenCode plugin teaches OpenCode to use the skills (with additional skills usage reinforcement by the system prompt). If OpenCode supports skills and commands out of the box, I would think that (after necessary changes) OpenCode part of superpowers could turn into a set of files without much else needed, is that right?
Nindaleth commented 2026-01-07 19:18:13 +00:00 (Migrated from github.com)

My understanding of superpowers is that this is a set of skills and commands and the OpenCode plugin teaches OpenCode to use the skills (with additional skills usage reinforcement by the system prompt).

If OpenCode supports skills and commands out of the box, I would think that (after necessary changes) OpenCode part of superpowers could turn into a set of files without much else needed, is that right?

My understanding of superpowers is that this is a set of skills and commands and the OpenCode plugin teaches OpenCode to use the skills (with additional skills usage reinforcement by the system prompt). If OpenCode supports skills and commands out of the box, I would think that (after necessary changes) OpenCode part of superpowers could turn into a set of files without much else needed, is that right?
PhilippPolterauer commented 2026-01-07 21:36:17 +00:00 (Migrated from github.com)

Yes, this is correct although it is important that skills are not always loaded, so if we want to make sure that superpowers are available one could inject the short description of each skill.

Skills are loaded via the find_skill tool so not always reliable

I think we could also make the plugin announce the skills, without the need for physical files, at least for commands that is possible

Yes, this is correct although it is important that skills are not always loaded, so if we want to make sure that superpowers are available one could inject the short description of each skill. Skills are loaded via the find_skill tool so not always reliable I think we could also make the plugin announce the skills, without the need for physical files, at least for commands that is possible
PhilippPolterauer commented 2026-01-07 21:36:17 +00:00 (Migrated from github.com)

Yes, this is correct although it is important that skills are not always loaded, so if we want to make sure that superpowers are available one could inject the short description of each skill.

Skills are loaded via the find_skill tool so not always reliable

I think we could also make the plugin announce the skills, without the need for physical files, at least for commands that is possible

Yes, this is correct although it is important that skills are not always loaded, so if we want to make sure that superpowers are available one could inject the short description of each skill. Skills are loaded via the find_skill tool so not always reliable I think we could also make the plugin announce the skills, without the need for physical files, at least for commands that is possible
Nindaleth commented 2026-01-09 21:12:19 +00:00 (Migrated from github.com)

OK, I've had a better look through the repo - I didn't realize that the Claude path of the plugin also injects the "You have superpowers." text. You're right then that while the other issue will make the OpenCode path cleaner and adhering to the standard, your fix will 100% continue to have merit for OpenCode path.

OK, I've had a better look through the repo - I didn't realize that the Claude path of the plugin also injects the "You have superpowers." text. You're right then that while the other issue will make the OpenCode path cleaner and adhering to the standard, your fix will 100% continue to have merit for OpenCode path.
Nindaleth commented 2026-01-09 21:12:19 +00:00 (Migrated from github.com)

OK, I've had a better look through the repo - I didn't realize that the Claude path of the plugin also injects the "You have superpowers." text. You're right then that while the other issue will make the OpenCode path cleaner and adhering to the standard, your fix will 100% continue to have merit for OpenCode path.

OK, I've had a better look through the repo - I didn't realize that the Claude path of the plugin also injects the "You have superpowers." text. You're right then that while the other issue will make the OpenCode path cleaner and adhering to the standard, your fix will 100% continue to have merit for OpenCode path.
obra commented 2026-01-22 20:39:16 +00:00 (Migrated from github.com)

Fixed in PR #330.

The fix uses experimental.chat.system.transform hook instead of session.prompt({ noReply: true }), which avoids the agent reset side effect.

Fixed in PR #330. The fix uses `experimental.chat.system.transform` hook instead of `session.prompt({ noReply: true })`, which avoids the agent reset side effect.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
skills/obra-superpowers#226
No description provided.