moshi-opencode-hooks 1.0.13 → 1.0.14

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 (3) hide show
  1. package/README.md +2 -16
  2. package/index.ts +18 -6
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  OpenCode plugin that sends real-time events to the [Moshi](https://getmoshi.app) iOS app for live activity integration.
4
4
 
5
- ![Live Activity](https://img.shields.io/badge/Live%20Activity-Moshi-blue)
6
-
7
5
  ## Motivation
8
6
 
9
7
  [Moshi](https://getmoshi.app) is an iOS SSH app that provides live activity widgets on the lock screen and Dynamic Island. While it already supports Cloud Code, this plugin brings the same live activity experience to [OpenCode](https://opencode.ai) users.
@@ -36,27 +34,15 @@ Add to `~/.config/opencode/opencode.json`:
36
34
  }
37
35
  ```
38
36
 
39
- ## Events
40
-
41
- The plugin sends these events to Moshi:
42
-
43
- | OpenCode Event | Moshi Display |
44
- |----------------|--------------|
45
- | `session.created` | Session started |
46
- | `tool.execute.before` | Running tool (Bash, Edit, Write, Read, Glob, Grep, Task) |
47
- | `tool.execute.after` | Tool finished |
48
- | `permission.ask` | Permission required |
49
- | `session.idle` | Task complete |
50
-
51
37
  ## Requirements
52
38
 
53
39
  - [OpenCode](https://opencode.ai)
54
- - [Moshi iOS app](https://getmoshi.app) with Cloud Code subscription
40
+ - [Moshi iOS app](https://getmoshi.app) with Pro subscription
55
41
 
56
42
  ## Moshi Token
57
43
 
58
44
  Get your token from the Moshi iOS app:
59
- 1. Open Moshi → Settings → Coding Agents
45
+ 1. Open Moshi → Settings → Agent Hooks
60
46
  2. Copy the hook token
61
47
 
62
48
  ## Uninstall
package/index.ts CHANGED
@@ -4,12 +4,13 @@ import type { Plugin } from "@opencode-ai/plugin"
4
4
 
5
5
  const TOKEN_PATH = `${homedir()}/.config/moshi/token`
6
6
  const API_URL = "https://api.getmoshi.app/api/v1/agent-events"
7
- const INTERESTING_TOOLS = new Set(["bash", "edit", "write", "read", "glob", "grep", "task", "question", "apply_patch"])
7
+ const INTERESTING_TOOLS = new Set(["bash", "edit", "write", "read", "glob", "grep", "task", "question", "apply_patch", "webfetch", "websearch"])
8
8
 
9
9
  interface HookState {
10
10
  model?: string
11
11
  lastToolName?: string
12
12
  lastStopTime?: number
13
+ isSubagent?: boolean
13
14
  }
14
15
 
15
16
  interface AgentEvent {
@@ -121,6 +122,11 @@ function formatToolName(toolName: string): string {
121
122
  return toolName.charAt(0).toUpperCase() + toolName.slice(1)
122
123
  }
123
124
 
125
+ function formatModelName(model: string | undefined): string | undefined {
126
+ if (!model) return undefined
127
+ return model.replace(/^claude-/, "")
128
+ }
129
+
124
130
  export const MoshiHooks: Plugin = async ({ client, directory }) => {
125
131
  const setupEventSubscription = async () => {
126
132
  try {
@@ -134,13 +140,17 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
134
140
  const state = await readState(sessionId)
135
141
 
136
142
  if (event.type === "session.created") {
143
+ const isSubagent = await isSubagentSession(sessionId)
137
144
  await writeState(sessionId, {
138
145
  model: (event as any).properties?.model,
146
+ isSubagent,
139
147
  })
140
148
  continue
141
149
  }
142
150
 
143
151
  if (event.type === "session.idle") {
152
+ if (state.isSubagent) continue
153
+
144
154
  const now = Date.now() / 1000
145
155
  if (state.lastStopTime && now - state.lastStopTime < 5) continue
146
156
 
@@ -155,7 +165,7 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
155
165
  message: "",
156
166
  eventId: crypto.randomUUID(),
157
167
  projectName,
158
- modelName: state.model,
168
+ modelName: formatModelName(state.model),
159
169
  toolName: state.lastToolName,
160
170
  }
161
171
  await sendAgentEvent(client, token, evt)
@@ -208,7 +218,7 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
208
218
  message: lines.join("\n---\n").slice(0, 512),
209
219
  eventId: crypto.randomUUID(),
210
220
  projectName,
211
- modelName: state.model,
221
+ modelName: formatModelName(state.model),
212
222
  toolName: tool,
213
223
  }
214
224
  await sendAgentEvent(client, token, evt)
@@ -224,7 +234,7 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
224
234
  message: "",
225
235
  eventId: crypto.randomUUID(),
226
236
  projectName,
227
- modelName: state.model,
237
+ modelName: formatModelName(state.model),
228
238
  toolName: tool,
229
239
  }
230
240
  await sendAgentEvent(client, token, evt)
@@ -252,7 +262,7 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
252
262
  message: "",
253
263
  eventId: crypto.randomUUID(),
254
264
  projectName,
255
- modelName: state.model,
265
+ modelName: formatModelName(state.model),
256
266
  toolName: tool,
257
267
  }
258
268
  await sendAgentEvent(client, token, evt)
@@ -264,6 +274,8 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
264
274
 
265
275
  const sessionID = (input as any).sessionID ?? "unknown"
266
276
  const state = await readState(sessionID)
277
+ if (state.isSubagent) return
278
+
267
279
  const projectName = directory ? basename(directory) : undefined
268
280
 
269
281
  const prompt = (input as any).prompt ?? ""
@@ -277,7 +289,7 @@ export const MoshiHooks: Plugin = async ({ client, directory }) => {
277
289
  message: prompt.slice(0, 256),
278
290
  eventId: crypto.randomUUID(),
279
291
  projectName,
280
- modelName: state.model,
292
+ modelName: formatModelName(state.model),
281
293
  }
282
294
  await sendAgentEvent(client, token, evt)
283
295
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moshi-opencode-hooks",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "OpenCode plugin for Moshi live activity integration",
5
5
  "repository": {
6
6
  "type": "git",