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.
Files changed (2) hide show
  1. package/index.ts +55 -14
  2. 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: "user_prompt" | "pre_tool" | "post_tool" | "notification" | "stop" | "agent_turn_complete"
17
+ eventType: "pre_tool" | "post_tool" | "notification" | "stop"
19
18
  sessionId: string
20
- category: "approval_required" | "task_complete" | "tool_running" | "tool_finished" | "info" | "error"
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 sendEvent(token: string, event: AgentEvent): Promise<void> {
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
- console.error(`[moshi-hooks] API error: ${res.status}`)
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
- console.error(`[moshi-hooks] Failed to send event:`, err)
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) break
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 sendEvent(token, evt)
161
+ await sendAgentEvent(client, token, evt)
123
162
  }
124
163
  }
125
164
  } catch (err) {
126
- console.error(`[moshi-hooks] Event subscription error:`, err)
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 sendEvent(token, evt)
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 sendEvent(token, evt)
223
+ await sendAgentEvent(client, token, evt)
183
224
  },
184
225
 
185
- "permission.ask": async (input, output) => {
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 sendEvent(token, evt)
247
+ await sendAgentEvent(client, token, evt)
207
248
  },
208
249
  }
209
250
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moshi-opencode-hooks",
3
- "version": "1.0.1",
3
+ "version": "1.0.8",
4
4
  "description": "OpenCode plugin for Moshi live activity integration",
5
5
  "repository": {
6
6
  "type": "git",