From 60c040057e3949ae93ee88d495df09b4b848d22d Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Sat, 18 Jul 2026 23:54:03 +0300 Subject: fix: serialize opencode lifecycle reports refs #1519 --- src/integration/assets/opencode/herdr-agent-state.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/integration/assets/opencode/herdr-agent-state.js') diff --git a/src/integration/assets/opencode/herdr-agent-state.js b/src/integration/assets/opencode/herdr-agent-state.js index 9a14b3c8..4d59f9ec 100644 --- a/src/integration/assets/opencode/herdr-agent-state.js +++ b/src/integration/assets/opencode/herdr-agent-state.js @@ -2,13 +2,15 @@ // 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=8 +// HERDR_INTEGRATION_VERSION=9 import net from "node:net"; const SOURCE = "herdr:opencode"; const AGENT = "opencode"; let reportSeq = Date.now() * 1000; +let requestChain = Promise.resolve(); +let reportedRootSessionID; // Subagent (task tool) sessions carry a parentID; the main agent session does // not. Their lifecycle events would otherwise clobber the pane's real state, so @@ -47,6 +49,12 @@ function stateFromSessionStatus(status) { } function request(method, params) { + const pending = requestChain.then(() => requestOnce(method, params)); + requestChain = pending.catch(() => {}); + return pending; +} + +function requestOnce(method, params) { const paneId = process.env.HERDR_PANE_ID; const socketPath = process.env.HERDR_SOCKET_PATH; @@ -101,6 +109,7 @@ function reportSession(sessionID, sessionStartSource) { function reportState(state, sessionID) { const params = { state }; if (sessionID) { + reportedRootSessionID = sessionID; params.agent_session_id = sessionID; } return request("pane.report_agent", params); @@ -160,7 +169,9 @@ export const HerdrAgentStatePlugin = async () => { await reportSession(sessionID, "new"); break; case "session.updated": - await reportSession(sessionID); + if (sessionID && sessionID !== reportedRootSessionID) { + await reportSession(sessionID); + } break; case "session.status": { const state = stateFromSessionStatus(properties.status); -- cgit v1.2.3