moshi-opencode-hooks 1.0.1 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +55 -14
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -10,14 +10,13 @@ interface HookState {
|
|
|
10
10
|
model?: string
|
|
11
11
|
lastToolName?: string
|
|
12
12
|
lastStopTime?: number
|
|
13
|
-
sessionStartTime?: number
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
interface AgentEvent {
|
|
17
16
|
source: "opencode"
|
|
18
|
-
eventType: "
|
|
17
|
+
eventType: "pre_tool" | "post_tool" | "notification" | "stop"
|
|
19
18
|
sessionId: string
|
|
20
|
-
category: "approval_required" | "task_complete" | "tool_running" | "tool_finished"
|
|
19
|
+
category: "approval_required" | "task_complete" | "tool_running" | "tool_finished"
|
|
21
20
|
title: string
|
|
22
21
|
message: string
|
|
23
22
|
eventId: string
|
|
@@ -55,7 +54,27 @@ async function loadToken(): Promise<string | null> {
|
|
|
55
54
|
}
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
async function
|
|
57
|
+
async function logPluginEvent(
|
|
58
|
+
client: Parameters<Plugin>[0]["client"],
|
|
59
|
+
level: "warn" | "error",
|
|
60
|
+
message: string,
|
|
61
|
+
extra?: Record<string, unknown>,
|
|
62
|
+
): Promise<void> {
|
|
63
|
+
try {
|
|
64
|
+
await client.app.log({
|
|
65
|
+
body: {
|
|
66
|
+
service: "moshi-hooks",
|
|
67
|
+
level,
|
|
68
|
+
message,
|
|
69
|
+
extra,
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
} catch (err) {
|
|
73
|
+
console.error(`[moshi-hooks] ${message}`, err)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function sendEvent(token: string, event: AgentEvent): Promise<Response> {
|
|
59
78
|
const body = JSON.stringify(event)
|
|
60
79
|
const headers = {
|
|
61
80
|
"Content-Type": "application/json",
|
|
@@ -69,11 +88,32 @@ async function sendEvent(token: string, event: AgentEvent): Promise<void> {
|
|
|
69
88
|
body,
|
|
70
89
|
signal: AbortSignal.timeout(5000),
|
|
71
90
|
})
|
|
91
|
+
return res
|
|
92
|
+
} catch (err) {
|
|
93
|
+
throw err
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function sendAgentEvent(
|
|
98
|
+
client: Parameters<Plugin>[0]["client"],
|
|
99
|
+
token: string,
|
|
100
|
+
event: AgentEvent,
|
|
101
|
+
): Promise<void> {
|
|
102
|
+
try {
|
|
103
|
+
const res = await sendEvent(token, event)
|
|
72
104
|
if (!res.ok && res.status >= 500) {
|
|
73
|
-
|
|
105
|
+
await logPluginEvent(client, "error", "Moshi API returned server error", {
|
|
106
|
+
status: res.status,
|
|
107
|
+
eventType: event.eventType,
|
|
108
|
+
sessionId: event.sessionId,
|
|
109
|
+
})
|
|
74
110
|
}
|
|
75
111
|
} catch (err) {
|
|
76
|
-
|
|
112
|
+
await logPluginEvent(client, "error", "Failed to send Moshi event", {
|
|
113
|
+
error: err instanceof Error ? err.message : String(err),
|
|
114
|
+
eventType: event.eventType,
|
|
115
|
+
sessionId: event.sessionId,
|
|
116
|
+
})
|
|
77
117
|
}
|
|
78
118
|
}
|
|
79
119
|
|
|
@@ -87,7 +127,7 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
|
|
|
87
127
|
const events = await client.event.subscribe()
|
|
88
128
|
for await (const event of events.stream) {
|
|
89
129
|
const token = await loadToken()
|
|
90
|
-
if (!token)
|
|
130
|
+
if (!token) continue
|
|
91
131
|
|
|
92
132
|
const sessionId = (event as any).sessionId ?? "unknown"
|
|
93
133
|
const projectName = directory ? basename(directory) : undefined
|
|
@@ -95,7 +135,6 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
|
|
|
95
135
|
|
|
96
136
|
if (event.type === "session.created") {
|
|
97
137
|
await writeState(sessionId, {
|
|
98
|
-
sessionStartTime: Date.now() / 1000,
|
|
99
138
|
model: (event as any).properties?.model,
|
|
100
139
|
})
|
|
101
140
|
continue
|
|
@@ -119,11 +158,13 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
|
|
|
119
158
|
modelName: state.model,
|
|
120
159
|
toolName: state.lastToolName,
|
|
121
160
|
}
|
|
122
|
-
await
|
|
161
|
+
await sendAgentEvent(client, token, evt)
|
|
123
162
|
}
|
|
124
163
|
}
|
|
125
164
|
} catch (err) {
|
|
126
|
-
|
|
165
|
+
await logPluginEvent(client, "error", "Event subscription error", {
|
|
166
|
+
error: err instanceof Error ? err.message : String(err),
|
|
167
|
+
})
|
|
127
168
|
}
|
|
128
169
|
}
|
|
129
170
|
|
|
@@ -154,7 +195,7 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
|
|
|
154
195
|
modelName: state.model,
|
|
155
196
|
toolName: tool,
|
|
156
197
|
}
|
|
157
|
-
await
|
|
198
|
+
await sendAgentEvent(client, token, evt)
|
|
158
199
|
},
|
|
159
200
|
|
|
160
201
|
"tool.execute.after": async (input, output) => {
|
|
@@ -179,10 +220,10 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
|
|
|
179
220
|
modelName: state.model,
|
|
180
221
|
toolName: tool,
|
|
181
222
|
}
|
|
182
|
-
await
|
|
223
|
+
await sendAgentEvent(client, token, evt)
|
|
183
224
|
},
|
|
184
225
|
|
|
185
|
-
"permission.
|
|
226
|
+
"permission.asked": async (input: any, _output: any) => {
|
|
186
227
|
const token = await loadToken()
|
|
187
228
|
if (!token) return
|
|
188
229
|
|
|
@@ -203,7 +244,7 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
|
|
|
203
244
|
projectName,
|
|
204
245
|
modelName: state.model,
|
|
205
246
|
}
|
|
206
|
-
await
|
|
247
|
+
await sendAgentEvent(client, token, evt)
|
|
207
248
|
},
|
|
208
249
|
}
|
|
209
250
|
}
|