@@ -77,8 +77,6 @@ export const WarpPlugin: Plugin = async ({ client, directory }) => {
7777 case "session.idle" : {
7878 const sessionId = event . properties . sessionID
7979
80- // Fetch the conversation to extract last query and response
81- // (port of on-stop.sh transcript parsing)
8280 let query = ""
8381 let response = ""
8482
@@ -133,6 +131,52 @@ export const WarpPlugin: Plugin = async ({ client, directory }) => {
133131 return
134132 }
135133
134+ case "message.part.updated" : {
135+ const part = ( event . properties as { part : unknown } ) . part as {
136+ type : string
137+ tool ?: string
138+ state ?: { status : string }
139+ callID ?: string
140+ }
141+ if ( part ?. type !== "tool" || ! part ?. state ) return
142+
143+ const sessionId = ( event . properties as { sessionID ?: string } ) . sessionID || ""
144+
145+ if ( part . tool === "question" && part . state . status === "running" ) {
146+ const body = buildPayload ( "question_asked" , sessionId , cwd , {
147+ tool_name : part . tool ,
148+ } )
149+ warpNotify ( NOTIFICATION_TITLE , body )
150+ return
151+ }
152+
153+ if ( part . state . status === "completed" ) {
154+ const body = buildPayload ( "tool_complete" , sessionId , cwd , {
155+ tool_name : part . tool || "unknown" ,
156+ } )
157+ warpNotify ( NOTIFICATION_TITLE , body )
158+ return
159+ }
160+ return
161+ }
162+
163+ case "message.updated" : {
164+ const info = ( event . properties as { info : { role ?: string ; parts ?: unknown [ ] ; id ?: string } } ) . info
165+ if ( info ?. role !== "user" ) return
166+
167+ const sessionId = ( event . properties as { sessionID ?: string } ) . sessionID || ""
168+ const queryText = extractTextFromParts (
169+ info . parts as unknown as Parameters < typeof extractTextFromParts > [ 0 ] ,
170+ )
171+ if ( ! queryText ) return
172+
173+ const body = buildPayload ( "prompt_submit" , sessionId , cwd , {
174+ query : truncate ( queryText , 200 ) ,
175+ } )
176+ warpNotify ( NOTIFICATION_TITLE , body )
177+ return
178+ }
179+
136180 default : {
137181 // permission.asked is listed in the opencode docs but has no SDK type.
138182 // Handle it with the same logic as permission.updated.
@@ -142,44 +186,5 @@ export const WarpPlugin: Plugin = async ({ client, directory }) => {
142186 }
143187 }
144188 } ,
145-
146- // Fires once per new user message β used to send the prompt_submit hook.
147- // (We avoid the generic message.updated event because OpenCode fires it
148- // multiple times per message, and a late duplicate can clobber the
149- // completion notification.)
150- "chat.message" : async ( input , output ) => {
151- const cwd = directory || ""
152- const queryText = extractTextFromParts ( output . parts )
153- if ( ! queryText ) return
154-
155- const body = buildPayload ( "prompt_submit" , input . sessionID , cwd , {
156- query : truncate ( queryText , 200 ) ,
157- } )
158- warpNotify ( NOTIFICATION_TITLE , body )
159- } ,
160-
161- // Fires before a tool executes β used to detect the built-in
162- // "question" tool so Warp can notify the user that input is needed.
163- "tool.execute.before" : async ( input ) => {
164- if ( input . tool !== "question" ) return
165-
166- const cwd = directory || ""
167- const body = buildPayload ( "question_asked" , input . sessionID , cwd , {
168- tool_name : input . tool ,
169- } )
170- warpNotify ( NOTIFICATION_TITLE , body )
171- } ,
172-
173- // Tool completion β fires after every tool call
174- "tool.execute.after" : async ( input ) => {
175- const toolName = input . tool
176- const sessionId = input . sessionID
177- const cwd = directory || ""
178-
179- const body = buildPayload ( "tool_complete" , sessionId , cwd , {
180- tool_name : toolName ,
181- } )
182- warpNotify ( NOTIFICATION_TITLE , body )
183- } ,
184189 }
185- }
190+ }
0 commit comments