aboutsummaryrefslogtreecommitdiff
path: root/src/integration/assets/opencode/herdr-agent-state.js
diff options
context:
space:
mode:
authorMark Jaquith <mark@jaquith.me>2026-09-05 17:08:19 -0400
committerGitHub <noreply@github.com>2026-09-06 00:08:19 +0300
commitec05328a4413e38ebdcb84365938345e9cf47431 (patch)
tree3f280531f2c81d00d2204ca7e7fb0d3b161072a6 /src/integration/assets/opencode/herdr-agent-state.js
parent6f57f2f62c5d2591647262caf15bc3c962b9c9f8 (diff)
fix: prevent OpenCode child prompts from leaving status blocked (#3669)
Child permission and question reports omitted the session ID, clearing Herdr’s root session identity and preventing later lifecycle reports from clearing the blocked state. Track child-to-parent relationships and report prompt transitions with their root session ID, including for nested children. This preserves identity and lets existing ownership checks reject unrelated sessions. Add regression coverage for prompt routing and lifecycle transitions, and bump the OpenCode integration version to 11.
Diffstat (limited to 'src/integration/assets/opencode/herdr-agent-state.js')
-rw-r--r--src/integration/assets/opencode/herdr-agent-state.js14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/integration/assets/opencode/herdr-agent-state.js b/src/integration/assets/opencode/herdr-agent-state.js
index 2840c221..45032335 100644
--- a/src/integration/assets/opencode/herdr-agent-state.js
+++ b/src/integration/assets/opencode/herdr-agent-state.js
@@ -2,7 +2,7 @@
// managed by herdr; reinstalling or updating the integration overwrites this file.
// add custom hooks/plugins beside this file instead of editing it.
// HERDR_INTEGRATION_ID=opencode
-// HERDR_INTEGRATION_VERSION=10
+// HERDR_INTEGRATION_VERSION=11
import net from "node:net";
@@ -13,8 +13,8 @@ let requestChain = Promise.resolve();
let reportedRootSessionID;
// Track child sessions so their events cannot replace the pane's root session.
-// Their user prompts still project state without attaching the child session id.
-const childSessions = new Set();
+// User prompts carry the root id to preserve its identity and cross-talk guard.
+const childSessions = new Map();
const CHILD_EVENT_STATES = new Map([
["permission.asked", "blocked"],
["question.asked", "blocked"],
@@ -141,12 +141,16 @@ export const HerdrAgentStatePlugin = async () => {
const info = properties.info;
if (info?.id && info.parentID) {
- childSessions.add(info.id);
+ childSessions.set(info.id, info.parentID);
}
if (sessionID && childSessions.has(sessionID)) {
const state = CHILD_EVENT_STATES.get(type);
if (state) {
- await reportState(state);
+ let rootSessionID = sessionID;
+ while (childSessions.has(rootSessionID)) {
+ rootSessionID = childSessions.get(rootSessionID);
+ }
+ await reportState(state, rootSessionID);
}
return;
}