opencode-discord 1.6.1 → 1.7.0

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 +37 -26
  2. package/package.json +5 -1
package/index.ts CHANGED
@@ -4,26 +4,36 @@ import { Client } from "@xhayper/discord-rpc"
4
4
  const CLIENT_ID = process.env.DISCORD_CLIENT_ID ?? "1486144419940929676"
5
5
 
6
6
  type Activity = "idle" | "thinking" | "editing" | "running" | "reading"
7
+ type LogLevel = "debug" | "info" | "error" | "warn"
7
8
 
8
- export const DiscordStatus: Plugin = async ({ client: sdk, project }) => {
9
+ function basename(filePath?: string): string | undefined {
10
+ if (!filePath) return undefined
11
+ const normalized = filePath.replace(/\\/g, "/")
12
+ const name = normalized.split("/").pop()
13
+ return name || undefined
14
+ }
15
+
16
+ export const DiscordStatus: Plugin = async ({ client: sdk, directory }) => {
9
17
  const rpc = new Client({ clientId: CLIENT_ID })
10
18
  let connected = false
11
19
  let sessionActive = false
12
- let currentProject = project?.name ?? "Unknown Project"
20
+ const currentProject = basename(directory) ?? "Unknown Project"
13
21
  let startTimestamp = Date.now()
14
22
  let lastEditedFile: string | undefined
15
23
  let activity: Activity = "idle"
16
24
  let sessionCount = 0
17
25
 
18
- async function log(level: string, message: string, extra?: Record<string, unknown>) {
26
+ async function log(level: LogLevel, message: string, extra?: Record<string, unknown>) {
19
27
  try {
20
28
  await sdk.app.log({
21
- service: "opencode-discord",
22
- level,
23
- message,
24
- extra,
29
+ body: {
30
+ service: "discord-status",
31
+ level,
32
+ message,
33
+ extra,
34
+ },
25
35
  })
26
- } catch {}
36
+ } catch { }
27
37
  }
28
38
 
29
39
  await log("info", "Plugin initializing", { clientId: CLIENT_ID, project: currentProject })
@@ -107,56 +117,54 @@ export const DiscordStatus: Plugin = async ({ client: sdk, project }) => {
107
117
 
108
118
  return {
109
119
  event: async ({ event }) => {
110
- switch (event.type) {
120
+ const eventType = event.type as string
121
+
122
+ switch (eventType) {
111
123
  case "session.created":
112
124
  sessionActive = true
113
- sessionCount++
125
+ sessionCount += 1
114
126
  startTimestamp = Date.now()
115
127
  lastEditedFile = undefined
116
128
  activity = "thinking"
117
129
  break
118
-
119
130
  case "session.idle":
120
131
  sessionActive = true
121
132
  activity = "idle"
122
133
  break
123
-
124
134
  case "session.error":
125
135
  sessionActive = false
126
136
  activity = "idle"
127
137
  break
128
-
129
138
  case "session.deleted":
130
139
  sessionActive = false
131
140
  lastEditedFile = undefined
132
141
  activity = "idle"
133
142
  break
134
-
135
143
  case "session.compacted":
136
144
  activity = "thinking"
137
145
  break
138
-
139
- case "file.edited":
146
+ case "file.edited": {
140
147
  activity = "editing"
141
- lastEditedFile =
142
- (event as any).file?.split("/").pop() ?? (event as any).file
148
+ const editedFile = (event as { properties?: { file?: string } }).properties?.file
149
+ lastEditedFile = basename(editedFile) ?? lastEditedFile
143
150
  break
151
+ }
144
152
  }
145
153
 
146
154
  await updatePresence()
147
155
  },
148
156
 
149
- "tool.execute.before": async (input) => {
157
+ "tool.execute.before": async (input, output) => {
158
+ const args = output.args as { filePath?: string } | undefined
159
+
150
160
  if (input.tool === "bash") {
151
161
  activity = "running"
152
162
  } else if (input.tool === "edit" || input.tool === "write") {
153
163
  activity = "editing"
154
- const path = input.args?.filePath as string | undefined
155
- if (path) lastEditedFile = path.split("/").pop() ?? path
164
+ lastEditedFile = basename(args?.filePath) ?? lastEditedFile
156
165
  } else if (input.tool === "read") {
157
166
  activity = "reading"
158
- const path = input.args?.filePath as string | undefined
159
- if (path) lastEditedFile = path.split("/").pop() ?? path
167
+ lastEditedFile = basename(args?.filePath) ?? lastEditedFile
160
168
  }
161
169
 
162
170
  await updatePresence()
@@ -165,10 +173,13 @@ export const DiscordStatus: Plugin = async ({ client: sdk, project }) => {
165
173
  "tool.execute.after": async (input) => {
166
174
  if (input.tool === "edit" || input.tool === "write") {
167
175
  activity = "editing"
168
- const path = input.args?.filePath as string | undefined
169
- if (path) lastEditedFile = path.split("/").pop() ?? path
176
+ const filePath = input.args?.filePath as string | undefined
177
+ lastEditedFile = basename(filePath) ?? lastEditedFile
178
+ } else if (input.tool === "bash") {
179
+ activity = sessionActive ? "thinking" : "idle"
170
180
  }
181
+
171
182
  await updatePresence()
172
183
  },
173
184
  }
174
- }
185
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-discord",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "Discord Rich Presence plugin for OpenCode — shows your AI coding activity in Discord",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -26,6 +26,10 @@
26
26
  },
27
27
  "homepage": "https://github.com/TheUntraceable/opencode-discord-status#readme",
28
28
  "dependencies": {
29
+ "@opencode-ai/plugin": "^1.3.3",
29
30
  "@xhayper/discord-rpc": "^1.3.1"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^25.5.0"
30
34
  }
31
35
  }