opencode-discord 1.5.0 → 1.6.1
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/README.md +38 -0
- package/index.ts +32 -32
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# opencode-discord
|
|
2
|
+
|
|
3
|
+
Discord Rich Presence plugin for [OpenCode](https://opencode.ai). Shows your AI coding activity in Discord.
|
|
4
|
+
|
|
5
|
+
> **Note:** This project is not built by the OpenCode team and is not affiliated with them in any way.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Add to your `opencode.json`:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"plugin": ["opencode-discord"]
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Make sure Discord desktop is running. Your status will show contextual info like:
|
|
18
|
+
|
|
19
|
+
- **Waiting for response...** — AI is generating
|
|
20
|
+
- **Editing main.ts** — editing a file
|
|
21
|
+
- **Running terminal commands** — using bash
|
|
22
|
+
- **Reading config.json** — reading files
|
|
23
|
+
- **No active session** — idle
|
|
24
|
+
|
|
25
|
+
## Rich Presence Assets
|
|
26
|
+
|
|
27
|
+
Upload these assets to your [Discord Application](https://discord.com/developers/applications) under Rich Presence > Art Assets:
|
|
28
|
+
|
|
29
|
+
| Name | Description |
|
|
30
|
+
|------|-------------|
|
|
31
|
+
| `opencode` | Large image (main logo) |
|
|
32
|
+
| `thinking` | Small image (AI generating) |
|
|
33
|
+
| `active` | Small image (session active) |
|
|
34
|
+
| `idle` | Small image (idle) |
|
|
35
|
+
|
|
36
|
+
## License
|
|
37
|
+
|
|
38
|
+
MIT
|
package/index.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { Plugin } from "@opencode-ai/plugin"
|
|
2
2
|
import { Client } from "@xhayper/discord-rpc"
|
|
3
3
|
|
|
4
|
-
const CLIENT_ID = process.env.DISCORD_CLIENT_ID ?? "
|
|
4
|
+
const CLIENT_ID = process.env.DISCORD_CLIENT_ID ?? "1486144419940929676"
|
|
5
5
|
|
|
6
6
|
type Activity = "idle" | "thinking" | "editing" | "running" | "reading"
|
|
7
7
|
|
|
8
|
-
export const DiscordStatus: Plugin = async ({ project }) => {
|
|
9
|
-
const
|
|
8
|
+
export const DiscordStatus: Plugin = async ({ client: sdk, project }) => {
|
|
9
|
+
const rpc = new Client({ clientId: CLIENT_ID })
|
|
10
10
|
let connected = false
|
|
11
11
|
let sessionActive = false
|
|
12
12
|
let currentProject = project?.name ?? "Unknown Project"
|
|
@@ -14,9 +14,19 @@ export const DiscordStatus: Plugin = async ({ project }) => {
|
|
|
14
14
|
let lastEditedFile: string | undefined
|
|
15
15
|
let activity: Activity = "idle"
|
|
16
16
|
let sessionCount = 0
|
|
17
|
-
let lastTool: string | undefined
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
async function log(level: string, message: string, extra?: Record<string, unknown>) {
|
|
19
|
+
try {
|
|
20
|
+
await sdk.app.log({
|
|
21
|
+
service: "opencode-discord",
|
|
22
|
+
level,
|
|
23
|
+
message,
|
|
24
|
+
extra,
|
|
25
|
+
})
|
|
26
|
+
} catch {}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
await log("info", "Plugin initializing", { clientId: CLIENT_ID, project: currentProject })
|
|
20
30
|
|
|
21
31
|
async function updatePresence() {
|
|
22
32
|
if (!connected) return
|
|
@@ -37,17 +47,13 @@ export const DiscordStatus: Plugin = async ({ project }) => {
|
|
|
37
47
|
details = "Waiting for response..."
|
|
38
48
|
break
|
|
39
49
|
case "editing":
|
|
40
|
-
details = lastEditedFile
|
|
41
|
-
? `Editing ${lastEditedFile}`
|
|
42
|
-
: `Editing files`
|
|
50
|
+
details = lastEditedFile ? `Editing ${lastEditedFile}` : "Editing files"
|
|
43
51
|
break
|
|
44
52
|
case "running":
|
|
45
53
|
details = "Running terminal commands"
|
|
46
54
|
break
|
|
47
55
|
case "reading":
|
|
48
|
-
details = lastEditedFile
|
|
49
|
-
? `Reading ${lastEditedFile}`
|
|
50
|
-
: "Reading files"
|
|
56
|
+
details = lastEditedFile ? `Reading ${lastEditedFile}` : "Reading files"
|
|
51
57
|
break
|
|
52
58
|
default:
|
|
53
59
|
details = "Session active"
|
|
@@ -59,7 +65,7 @@ export const DiscordStatus: Plugin = async ({ project }) => {
|
|
|
59
65
|
}
|
|
60
66
|
|
|
61
67
|
try {
|
|
62
|
-
await
|
|
68
|
+
await rpc.user?.setActivity({
|
|
63
69
|
details,
|
|
64
70
|
state,
|
|
65
71
|
startTimestamp,
|
|
@@ -67,39 +73,36 @@ export const DiscordStatus: Plugin = async ({ project }) => {
|
|
|
67
73
|
largeImageText: `OpenCode · ${sessionCount} session${sessionCount !== 1 ? "s" : ""}`,
|
|
68
74
|
smallImageKey,
|
|
69
75
|
smallImageText,
|
|
70
|
-
buttons: [
|
|
71
|
-
{ label: "OpenCode", url: "https://opencode.ai" },
|
|
72
|
-
],
|
|
73
76
|
})
|
|
74
|
-
|
|
77
|
+
await log("debug", "Presence updated", { details, state })
|
|
75
78
|
} catch (e) {
|
|
76
|
-
|
|
79
|
+
await log("error", "Failed to set presence", { error: String(e) })
|
|
77
80
|
}
|
|
78
81
|
}
|
|
79
82
|
|
|
80
|
-
|
|
83
|
+
rpc.on("ready", async () => {
|
|
81
84
|
connected = true
|
|
82
85
|
startTimestamp = Date.now()
|
|
83
|
-
|
|
84
|
-
updatePresence()
|
|
86
|
+
await log("info", "Discord RPC connected")
|
|
87
|
+
await updatePresence()
|
|
85
88
|
})
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
rpc.on("error", async (err: any) => {
|
|
91
|
+
await log("error", "Discord RPC error", { error: String(err) })
|
|
89
92
|
})
|
|
90
93
|
|
|
91
|
-
|
|
94
|
+
rpc.on("disconnected", async () => {
|
|
92
95
|
connected = false
|
|
93
|
-
|
|
96
|
+
await log("warn", "Discord RPC disconnected")
|
|
94
97
|
})
|
|
95
98
|
|
|
96
99
|
try {
|
|
97
|
-
|
|
98
|
-
await
|
|
99
|
-
|
|
100
|
+
await log("info", "Logging in to Discord RPC...")
|
|
101
|
+
await rpc.login()
|
|
102
|
+
await log("info", "Discord RPC login successful")
|
|
100
103
|
} catch (e) {
|
|
101
104
|
connected = false
|
|
102
|
-
|
|
105
|
+
await log("error", "Discord RPC login failed", { error: String(e) })
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
return {
|
|
@@ -136,8 +139,7 @@ export const DiscordStatus: Plugin = async ({ project }) => {
|
|
|
136
139
|
case "file.edited":
|
|
137
140
|
activity = "editing"
|
|
138
141
|
lastEditedFile =
|
|
139
|
-
(event as any).file?.split("/").pop() ??
|
|
140
|
-
(event as any).file
|
|
142
|
+
(event as any).file?.split("/").pop() ?? (event as any).file
|
|
141
143
|
break
|
|
142
144
|
}
|
|
143
145
|
|
|
@@ -145,8 +147,6 @@ export const DiscordStatus: Plugin = async ({ project }) => {
|
|
|
145
147
|
},
|
|
146
148
|
|
|
147
149
|
"tool.execute.before": async (input) => {
|
|
148
|
-
lastTool = input.tool
|
|
149
|
-
|
|
150
150
|
if (input.tool === "bash") {
|
|
151
151
|
activity = "running"
|
|
152
152
|
} else if (input.tool === "edit" || input.tool === "write") {
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-discord",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
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",
|
|
7
7
|
"files": [
|
|
8
|
-
"index.ts"
|
|
8
|
+
"index.ts",
|
|
9
|
+
"README.md"
|
|
9
10
|
],
|
|
10
11
|
"keywords": [
|
|
11
12
|
"opencode",
|