Skip to content

Commit 8469420

Browse files
aqeelatharryalbert
andauthored
fix: suppress stop notifications for subagent sessions (#22)
* fix: suppress stop notifications for subagent sessions Fetch the session on session.idle to check for parentID. If the session is a child (subagent) session, return early without sending a stop notification. Falls through on fetch failure so notifications are never silently dropped. Bump version to 0.1.7. * fix: suppress all notifications for subagent sessions * bump package-lock.json --------- Co-authored-by: harryalbert <harryalbert364@gmail.com>
1 parent b392a9f commit 8469420

3 files changed

Lines changed: 47 additions & 18 deletions

File tree

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@warp-dot-dev/opencode-warp",
3-
"version": "0.1.6",
3+
"version": "0.1.7",
44
"description": "Warp terminal integration for OpenCode — native notifications and more",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

src/index.ts

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ import { truncate, extractTextFromParts } from "./utils"
99
// NOTE: do not `export` this constant — opencode's legacy plugin loader
1010
// treats every named export as a plugin function and throws if any export
1111
// is not a function ("Plugin export is not a function").
12-
const PLUGIN_VERSION = "0.1.6"
12+
const PLUGIN_VERSION = "0.1.7"
1313
const NOTIFICATION_TITLE = "warp://cli-agent"
1414

15-
function sendPermissionNotification(perm: Permission, cwd: string): void {
16-
const sessionId = perm.sessionID
15+
function buildPermissionPayload(perm: Permission, cwd: string) {
1716
const toolName = perm.type || "unknown"
1817
const metadata = perm.metadata || {}
1918

@@ -34,12 +33,11 @@ function sendPermissionNotification(perm: Permission, cwd: string): void {
3433
summary += `: ${truncate(toolPreview, 120)}`
3534
}
3635

37-
const body = buildPayload("permission_request", sessionId, cwd, {
36+
return buildPayload("permission_request", perm.sessionID, cwd, {
3837
summary,
3938
tool_name: toolName,
4039
tool_input: metadata,
4140
})
42-
warpNotify(NOTIFICATION_TITLE, body)
4341
}
4442

4543
export const WarpPlugin: Plugin = async ({ client, directory }) => {
@@ -73,17 +71,41 @@ export const WarpPlugin: Plugin = async ({ client, directory }) => {
7371
console.error("[opencode-warp] failed to emit init log:", err)
7472
})
7573

74+
const subagentCache = new Map<string, boolean>()
75+
76+
async function isSubagentSession(sessionId?: string): Promise<boolean> {
77+
if (!sessionId) return false
78+
if (subagentCache.has(sessionId)) return subagentCache.get(sessionId)!
79+
try {
80+
const session = await client.session.get({
81+
path: { id: sessionId },
82+
})
83+
const result = !!session.data?.parentID
84+
subagentCache.set(sessionId, result)
85+
return result
86+
} catch {
87+
// If we can't fetch the session, fall through and notify anyway
88+
return false
89+
}
90+
}
91+
92+
async function maybeWarpNotify(sessionId: string | undefined, body: string): Promise<void> {
93+
if (await isSubagentSession(sessionId)) return
94+
warpNotify(NOTIFICATION_TITLE, body)
95+
}
96+
7697
return {
7798
event: async ({ event }: { event: Event }) => {
7899
const cwd = directory || ""
79100

80101
switch (event.type) {
81102
case "session.created": {
82-
const sessionId = event.properties.info.id
83-
const body = buildPayload("session_start", sessionId, cwd, {
103+
const info = event.properties.info
104+
if (info.parentID) return
105+
const body = buildPayload("session_start", info.id, cwd, {
84106
plugin_version: PLUGIN_VERSION,
85107
})
86-
warpNotify(NOTIFICATION_TITLE, body)
108+
await maybeWarpNotify(info.id, body)
87109
return
88110
}
89111

@@ -129,28 +151,34 @@ export const WarpPlugin: Plugin = async ({ client, directory }) => {
129151
response: truncate(response, 200),
130152
transcript_path: "",
131153
})
132-
warpNotify(NOTIFICATION_TITLE, body)
154+
await maybeWarpNotify(sessionId, body)
133155
return
134156
}
135157

136158
case "permission.updated": {
137-
sendPermissionNotification(event.properties, cwd)
159+
await maybeWarpNotify(
160+
event.properties.sessionID,
161+
buildPermissionPayload(event.properties, cwd),
162+
)
138163
return
139164
}
140165

141166
case "permission.replied": {
142167
const { sessionID, response } = event.properties
143168
if (response === "reject") return
144169
const body = buildPayload("permission_replied", sessionID, cwd)
145-
warpNotify(NOTIFICATION_TITLE, body)
170+
await maybeWarpNotify(sessionID, body)
146171
return
147172
}
148173

149174
default: {
150175
// permission.asked is listed in the opencode docs but has no SDK type.
151176
// Handle it with the same logic as permission.updated.
152177
if ((event as any).type === "permission.asked") {
153-
sendPermissionNotification((event as any).properties, cwd)
178+
await maybeWarpNotify(
179+
(event as any).properties?.sessionID,
180+
buildPermissionPayload((event as any).properties, cwd),
181+
)
154182
}
155183
}
156184
}
@@ -162,13 +190,14 @@ export const WarpPlugin: Plugin = async ({ client, directory }) => {
162190
// completion notification.)
163191
"chat.message": async (input, output) => {
164192
const cwd = directory || ""
193+
165194
const queryText = extractTextFromParts(output.parts)
166195
if (!queryText) return
167196

168197
const body = buildPayload("prompt_submit", input.sessionID, cwd, {
169198
query: truncate(queryText, 200),
170199
})
171-
warpNotify(NOTIFICATION_TITLE, body)
200+
await maybeWarpNotify(input.sessionID, body)
172201
},
173202

174203
// Fires before a tool executes — used to detect the built-in
@@ -180,7 +209,7 @@ export const WarpPlugin: Plugin = async ({ client, directory }) => {
180209
const body = buildPayload("question_asked", input.sessionID, cwd, {
181210
tool_name: input.tool,
182211
})
183-
warpNotify(NOTIFICATION_TITLE, body)
212+
await maybeWarpNotify(input.sessionID, body)
184213
},
185214

186215
// Tool completion — fires after every tool call
@@ -192,7 +221,7 @@ export const WarpPlugin: Plugin = async ({ client, directory }) => {
192221
const body = buildPayload("tool_complete", sessionId, cwd, {
193222
tool_name: toolName,
194223
})
195-
warpNotify(NOTIFICATION_TITLE, body)
224+
await maybeWarpNotify(sessionId, body)
196225
},
197226
}
198227
}

0 commit comments

Comments
 (0)