remote-opencode 1.0.4 → 1.0.7
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 +18 -89
- package/dist/src/cli.js +2 -0
- package/dist/src/setup/wizard.js +68 -15
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -42,12 +42,6 @@ The bot runs on your development machine alongside OpenCode. When you send a com
|
|
|
42
42
|
- [Installation](#installation)
|
|
43
43
|
- [Quick Start](#quick-start)
|
|
44
44
|
- [Discord Bot Setup](#discord-bot-setup)
|
|
45
|
-
- [Step 1: Create Discord Application](#step-1-create-discord-application)
|
|
46
|
-
- [Step 2: Create Bot & Get Token](#step-2-create-bot--get-token)
|
|
47
|
-
- [Step 3: Enable Required Intents](#step-3-enable-required-intents)
|
|
48
|
-
- [Step 4: Configure Bot Permissions](#step-4-configure-bot-permissions)
|
|
49
|
-
- [Step 5: Get Your Server (Guild) ID](#step-5-get-your-server-guild-id)
|
|
50
|
-
- [Step 6: Invite Bot to Your Server](#step-6-invite-bot-to-your-server)
|
|
51
45
|
- [CLI Commands](#cli-commands)
|
|
52
46
|
- [Discord Slash Commands](#discord-slash-commands)
|
|
53
47
|
- [Usage Workflow](#usage-workflow)
|
|
@@ -104,95 +98,30 @@ That's it! Now use Discord slash commands to interact with OpenCode.
|
|
|
104
98
|
|
|
105
99
|
## Discord Bot Setup
|
|
106
100
|
|
|
107
|
-
|
|
101
|
+
The setup wizard (`remote-opencode setup`) guides you through the entire process interactively:
|
|
108
102
|
|
|
109
|
-
|
|
103
|
+
1. **Opens Discord Developer Portal** in your browser
|
|
104
|
+
2. **Walks you through** creating an application, enabling intents, and getting your bot token
|
|
105
|
+
3. **Generates the invite link** automatically and opens it in your browser
|
|
106
|
+
4. **Deploys slash commands** to your server
|
|
110
107
|
|
|
111
|
-
|
|
112
|
-
2. Click **"New Application"**
|
|
113
|
-
3. Enter a name (e.g., "Remote OpenCode")
|
|
114
|
-
4. Copy the **Application ID** — you'll need this later
|
|
108
|
+
Just run `remote-opencode setup` and follow the prompts — no manual URL copying needed!
|
|
115
109
|
|
|
116
|
-
<
|
|
110
|
+
<details>
|
|
111
|
+
<summary>📖 Manual setup reference (click to expand)</summary>
|
|
117
112
|
|
|
118
|
-
|
|
113
|
+
If you prefer manual setup or need to troubleshoot:
|
|
119
114
|
|
|
120
|
-
1.
|
|
121
|
-
2.
|
|
122
|
-
3. **
|
|
123
|
-
4.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
Still in the **"Bot"** section, scroll down to **"Privileged Gateway Intents"** and enable:
|
|
129
|
-
|
|
130
|
-
- ✅ **SERVER MEMBERS INTENT**
|
|
131
|
-
- ✅ **MESSAGE CONTENT INTENT**
|
|
132
|
-
|
|
133
|
-
Click **"Save Changes"**
|
|
134
|
-
|
|
135
|
-
<img width="1500" alt="image" src="https://github.com/user-attachments/assets/d20406ff-26ad-4204-9771-b157c340846a" />
|
|
136
|
-
|
|
137
|
-
### Step 4: Configure Bot Permissions
|
|
138
|
-
|
|
139
|
-
The bot needs specific permissions to function properly. You can configure permissions in two ways:
|
|
140
|
-
|
|
141
|
-
#### Option A: Using OAuth2 URL Generator (Recommended)
|
|
142
|
-
|
|
143
|
-
1. Navigate to the **"OAuth2"** section in the sidebar
|
|
144
|
-
2. Click on **"URL Generator"**
|
|
145
|
-
3. In **"Scopes"**, select:
|
|
146
|
-
- ✅ `bot`
|
|
147
|
-
- ✅ `applications.commands`
|
|
148
|
-
4. In **"Bot Permissions"**, select only these essential permissions:
|
|
149
|
-
|
|
150
|
-
**General Permissions:**
|
|
151
|
-
- ✅ **View Channels** — Required to access channels
|
|
152
|
-
|
|
153
|
-
**Text Permissions:**
|
|
154
|
-
- ✅ **Send Messages** — Send responses to channels
|
|
155
|
-
- ✅ **Create Public Threads** — Create threads for each `/opencode` session
|
|
156
|
-
- ✅ **Send Messages in Threads** — Reply within threads
|
|
157
|
-
- ✅ **Embed Links** — Send formatted embed messages
|
|
158
|
-
- ✅ **Read Message History** — Access context for conversations
|
|
159
|
-
- ✅ **Add Reactions** — Add buttons (uses emoji reactions internally)
|
|
160
|
-
- ✅ **Use Slash Commands** — Register and use slash commands
|
|
161
|
-
|
|
162
|
-
5. Copy the generated URL at the bottom — this is your bot invite link!
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
#### Option B: Manual Permission Calculation
|
|
166
|
-
|
|
167
|
-
If you're building the URL manually, use this permission value:
|
|
168
|
-
|
|
169
|
-
```
|
|
170
|
-
https://discord.com/api/oauth2/authorize?client_id=YOUR_CLIENT_ID&permissions=311385214016&integration_type=0&scope=bot+applications.commands
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
**Important:** The URL must include `applications.commands` scope for slash commands to work!
|
|
174
|
-
|
|
175
|
-
### Step 5: Get Your Server (Guild) ID
|
|
176
|
-
|
|
177
|
-
1. Open Discord and go to **User Settings → Advanced**
|
|
178
|
-
2. Enable **"Developer Mode"**
|
|
179
|
-
3. Right-click on your server name in the sidebar
|
|
180
|
-
4. Click **"Copy Server ID"**
|
|
181
|
-
|
|
182
|
-
<img width="184" height="530" alt="스크린샷 2026-02-03 오전 2 34 31" src="https://github.com/user-attachments/assets/8ecc2a28-05e5-494f-834f-95d9d0e4e730" />
|
|
183
|
-
|
|
184
|
-
### Step 6: Invite Bot to Your Server
|
|
185
|
-
|
|
186
|
-
Use the URL generated in Step 4 (OAuth2 URL Generator), or construct it manually:
|
|
187
|
-
|
|
188
|
-
```
|
|
189
|
-
https://discord.com/api/oauth2/authorize?client_id=YOUR_CLIENT_ID&permissions=218900185540&scope=bot%20applications.commands
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
1. Replace `YOUR_CLIENT_ID` with your Application ID
|
|
193
|
-
2. Open the URL in your browser
|
|
194
|
-
3. Select your server and authorize
|
|
115
|
+
1. **Create Application**: Go to [Discord Developer Portal](https://discord.com/developers/applications), create a new application
|
|
116
|
+
2. **Enable Intents**: In "Bot" section, enable SERVER MEMBERS INTENT and MESSAGE CONTENT INTENT
|
|
117
|
+
3. **Get Bot Token**: In "Bot" section, reset/view token and copy it
|
|
118
|
+
4. **Get Guild ID**: Enable Developer Mode in Discord settings, right-click your server → Copy Server ID
|
|
119
|
+
5. **Invite Bot**: Use this URL format:
|
|
120
|
+
```
|
|
121
|
+
https://discord.com/api/oauth2/authorize?client_id=YOUR_CLIENT_ID&permissions=2147534848&scope=bot+applications.commands
|
|
122
|
+
```
|
|
195
123
|
|
|
124
|
+
</details>
|
|
196
125
|
|
|
197
126
|
---
|
|
198
127
|
|
package/dist/src/cli.js
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import pc from 'picocolors';
|
|
4
4
|
import { createRequire } from 'module';
|
|
5
|
+
import updateNotifier from 'update-notifier';
|
|
5
6
|
import { runSetupWizard } from './setup/wizard.js';
|
|
6
7
|
import { deployCommands } from './setup/deploy.js';
|
|
7
8
|
import { startBot } from './bot.js';
|
|
8
9
|
import { hasBotConfig, getConfigDir } from './services/configStore.js';
|
|
9
10
|
const require = createRequire(import.meta.url);
|
|
10
11
|
const pkg = require('../../package.json');
|
|
12
|
+
updateNotifier({ pkg }).notify({ isGlobal: true });
|
|
11
13
|
const program = new Command();
|
|
12
14
|
program
|
|
13
15
|
.name('remote-opencode')
|
package/dist/src/setup/wizard.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as p from '@clack/prompts';
|
|
2
2
|
import pc from 'picocolors';
|
|
3
|
+
import open from 'open';
|
|
3
4
|
import { setBotConfig, getBotConfig, hasBotConfig } from '../services/configStore.js';
|
|
4
5
|
import { deployCommands } from './deploy.js';
|
|
5
6
|
const DISCORD_DEV_URL = 'https://discord.com/developers/applications';
|
|
7
|
+
const BOT_PERMISSIONS = '2147534848';
|
|
8
|
+
const BOT_SCOPES = 'bot applications.commands';
|
|
6
9
|
function validateApplicationId(value) {
|
|
7
10
|
if (!value)
|
|
8
11
|
return 'Application ID is required';
|
|
@@ -24,6 +27,21 @@ function validateGuildId(value) {
|
|
|
24
27
|
return 'Invalid format (should be 17-20 digits)';
|
|
25
28
|
return undefined;
|
|
26
29
|
}
|
|
30
|
+
function generateInviteUrl(clientId) {
|
|
31
|
+
const url = new URL('https://discord.com/api/oauth2/authorize');
|
|
32
|
+
url.searchParams.set('client_id', clientId);
|
|
33
|
+
url.searchParams.set('permissions', BOT_PERMISSIONS);
|
|
34
|
+
url.searchParams.set('scope', BOT_SCOPES);
|
|
35
|
+
return url.toString();
|
|
36
|
+
}
|
|
37
|
+
async function openUrl(url) {
|
|
38
|
+
try {
|
|
39
|
+
await open(url);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Silently fail - URL is displayed to user anyway
|
|
43
|
+
}
|
|
44
|
+
}
|
|
27
45
|
export async function runSetupWizard() {
|
|
28
46
|
console.clear();
|
|
29
47
|
p.intro(pc.bgCyan(pc.black(' remote-opencode setup ')));
|
|
@@ -38,10 +56,21 @@ export async function runSetupWizard() {
|
|
|
38
56
|
return;
|
|
39
57
|
}
|
|
40
58
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
`
|
|
44
|
-
`
|
|
59
|
+
// Step 1: Open Discord Developer Portal
|
|
60
|
+
p.note(`We'll open the Discord Developer Portal in your browser.\n\n` +
|
|
61
|
+
`1. Click ${pc.bold('"New Application"')}\n` +
|
|
62
|
+
`2. Give your application a name (e.g., "Remote OpenCode")\n` +
|
|
63
|
+
`3. Copy the ${pc.bold('Application ID')} from "General Information"`, 'Step 1: Create Discord Application');
|
|
64
|
+
const openPortal = await p.text({
|
|
65
|
+
message: `Press ${pc.cyan('Enter')} to open Discord Developer Portal...`,
|
|
66
|
+
placeholder: 'Press Enter',
|
|
67
|
+
defaultValue: '',
|
|
68
|
+
});
|
|
69
|
+
if (p.isCancel(openPortal)) {
|
|
70
|
+
p.cancel('Setup cancelled.');
|
|
71
|
+
process.exit(0);
|
|
72
|
+
}
|
|
73
|
+
await openUrl(DISCORD_DEV_URL);
|
|
45
74
|
const clientId = await p.text({
|
|
46
75
|
message: 'Enter your Discord Application ID:',
|
|
47
76
|
placeholder: 'e.g., 1234567890123456789',
|
|
@@ -51,19 +80,27 @@ export async function runSetupWizard() {
|
|
|
51
80
|
p.cancel('Setup cancelled.');
|
|
52
81
|
process.exit(0);
|
|
53
82
|
}
|
|
54
|
-
|
|
83
|
+
// Step 2: Enable Intents (guidance only)
|
|
84
|
+
p.note(`In the Discord Developer Portal:\n\n` +
|
|
85
|
+
`1. Go to the ${pc.bold('"Bot"')} section in the left sidebar\n` +
|
|
55
86
|
`2. Scroll down to ${pc.bold('"Privileged Gateway Intents"')}\n` +
|
|
56
87
|
`3. Enable these intents:\n` +
|
|
57
|
-
`
|
|
58
|
-
`
|
|
59
|
-
`4. Click "Save Changes"`, 'Step 2: Enable Required Intents');
|
|
60
|
-
await p.confirm({
|
|
88
|
+
` ${pc.green('*')} SERVER MEMBERS INTENT\n` +
|
|
89
|
+
` ${pc.green('*')} MESSAGE CONTENT INTENT\n` +
|
|
90
|
+
`4. Click ${pc.bold('"Save Changes"')}`, 'Step 2: Enable Required Intents');
|
|
91
|
+
const intentsConfirm = await p.confirm({
|
|
61
92
|
message: 'Have you enabled the required intents?',
|
|
62
93
|
initialValue: true,
|
|
63
94
|
});
|
|
64
|
-
p.
|
|
95
|
+
if (p.isCancel(intentsConfirm)) {
|
|
96
|
+
p.cancel('Setup cancelled.');
|
|
97
|
+
process.exit(0);
|
|
98
|
+
}
|
|
99
|
+
// Step 3: Get Bot Token (guidance only)
|
|
100
|
+
p.note(`Still in the Discord Developer Portal:\n\n` +
|
|
101
|
+
`1. In the ${pc.bold('"Bot"')} section\n` +
|
|
65
102
|
`2. Click ${pc.bold('"Reset Token"')} (or "View Token" if available)\n` +
|
|
66
|
-
`3. Copy the token (it's only shown once!)`, 'Step 3: Get Bot Token');
|
|
103
|
+
`3. Copy the token ${pc.dim('(it\'s only shown once!)')}`, 'Step 3: Get Bot Token');
|
|
67
104
|
const discordToken = await p.password({
|
|
68
105
|
message: 'Enter your Discord Bot Token:',
|
|
69
106
|
validate: validateToken,
|
|
@@ -72,7 +109,8 @@ export async function runSetupWizard() {
|
|
|
72
109
|
p.cancel('Setup cancelled.');
|
|
73
110
|
process.exit(0);
|
|
74
111
|
}
|
|
75
|
-
|
|
112
|
+
// Step 4: Get Guild ID (guidance only)
|
|
113
|
+
p.note(`1. Open Discord and go to ${pc.bold('User Settings > Advanced')}\n` +
|
|
76
114
|
`2. Enable ${pc.bold('"Developer Mode"')}\n` +
|
|
77
115
|
`3. Right-click on your server name\n` +
|
|
78
116
|
`4. Click ${pc.bold('"Copy Server ID"')}`, 'Step 4: Get Guild (Server) ID');
|
|
@@ -85,6 +123,7 @@ export async function runSetupWizard() {
|
|
|
85
123
|
p.cancel('Setup cancelled.');
|
|
86
124
|
process.exit(0);
|
|
87
125
|
}
|
|
126
|
+
// Save configuration
|
|
88
127
|
const s = p.spinner();
|
|
89
128
|
s.start('Saving configuration...');
|
|
90
129
|
setBotConfig({
|
|
@@ -93,9 +132,22 @@ export async function runSetupWizard() {
|
|
|
93
132
|
guildId: guildId,
|
|
94
133
|
});
|
|
95
134
|
s.stop('Configuration saved!');
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
135
|
+
// Step 5: Invite Bot to Server
|
|
136
|
+
const inviteUrl = generateInviteUrl(clientId);
|
|
137
|
+
p.note(`We'll open the bot invite page in your browser.\n\n` +
|
|
138
|
+
`1. Select your server\n` +
|
|
139
|
+
`2. Click ${pc.bold('"Authorize"')}\n\n` +
|
|
140
|
+
`${pc.dim('URL: ' + inviteUrl)}`, 'Step 5: Invite Bot to Server');
|
|
141
|
+
const openInvite = await p.text({
|
|
142
|
+
message: `Press ${pc.cyan('Enter')} to open the invite page...`,
|
|
143
|
+
placeholder: 'Press Enter',
|
|
144
|
+
defaultValue: '',
|
|
145
|
+
});
|
|
146
|
+
if (p.isCancel(openInvite)) {
|
|
147
|
+
p.cancel('Setup cancelled.');
|
|
148
|
+
process.exit(0);
|
|
149
|
+
}
|
|
150
|
+
await openUrl(inviteUrl);
|
|
99
151
|
const invited = await p.confirm({
|
|
100
152
|
message: 'Have you invited the bot to your server?',
|
|
101
153
|
initialValue: true,
|
|
@@ -104,6 +156,7 @@ export async function runSetupWizard() {
|
|
|
104
156
|
p.cancel('Setup cancelled.');
|
|
105
157
|
process.exit(0);
|
|
106
158
|
}
|
|
159
|
+
// Step 6: Deploy Commands
|
|
107
160
|
const shouldDeploy = await p.confirm({
|
|
108
161
|
message: 'Deploy slash commands now?',
|
|
109
162
|
initialValue: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remote-opencode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Discord bot for remote OpenCode CLI access",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -41,10 +41,13 @@
|
|
|
41
41
|
"discord.js": "^14.25.1",
|
|
42
42
|
"eventsource": "^4.1.0",
|
|
43
43
|
"node-pty": "^1.1.0",
|
|
44
|
-
"
|
|
44
|
+
"open": "^10.1.0",
|
|
45
|
+
"picocolors": "^1.1.1",
|
|
46
|
+
"update-notifier": "^7.3.1"
|
|
45
47
|
},
|
|
46
48
|
"devDependencies": {
|
|
47
49
|
"@types/node": "^25.1.0",
|
|
50
|
+
"@types/update-notifier": "^6.0.8",
|
|
48
51
|
"ts-node": "^10.9.2",
|
|
49
52
|
"typescript": "^5.9.3",
|
|
50
53
|
"vitest": "^4.0.18"
|