@different-ai/opencode-browser 4.0.0 → 4.0.2
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 +4 -3
- package/bin/cli.js +42 -15
- package/package.json +2 -2
- package/src/plugin.ts +58 -2
package/README.md
CHANGED
|
@@ -23,11 +23,11 @@ The installer will:
|
|
|
23
23
|
1. Copy the extension to `~/.opencode-browser/extension/`
|
|
24
24
|
2. Walk you through loading + pinning it in `chrome://extensions`
|
|
25
25
|
3. Ask for the extension ID and install a **Native Messaging Host manifest**
|
|
26
|
-
4. Update your
|
|
26
|
+
4. Update your `.opencode.json` to load the plugin
|
|
27
27
|
|
|
28
28
|
### Configure OpenCode
|
|
29
29
|
|
|
30
|
-
Your
|
|
30
|
+
Your `.opencode.json` should contain:
|
|
31
31
|
|
|
32
32
|
```json
|
|
33
33
|
{
|
|
@@ -59,6 +59,7 @@ Tools:
|
|
|
59
59
|
|
|
60
60
|
## Available tools
|
|
61
61
|
|
|
62
|
+
- `browser_version`
|
|
62
63
|
- `browser_status`
|
|
63
64
|
- `browser_get_tabs`
|
|
64
65
|
- `browser_navigate`
|
|
@@ -86,4 +87,4 @@ Tools:
|
|
|
86
87
|
npx @different-ai/opencode-browser uninstall
|
|
87
88
|
```
|
|
88
89
|
|
|
89
|
-
Then remove the unpacked extension in `chrome://extensions` and remove the plugin from
|
|
90
|
+
Then remove the unpacked extension in `chrome://extensions` and remove the plugin from `.opencode.json`.
|
package/bin/cli.js
CHANGED
|
@@ -275,38 +275,65 @@ Find it at ${color("cyan", "chrome://extensions")}:
|
|
|
275
275
|
|
|
276
276
|
header("Step 7: Configure OpenCode");
|
|
277
277
|
|
|
278
|
-
|
|
278
|
+
// OpenCode config discovery (per upstream docs):
|
|
279
|
+
// - $HOME/.opencode.json
|
|
280
|
+
// - $XDG_CONFIG_HOME/opencode/.opencode.json
|
|
281
|
+
// - ./.opencode.json (project-local)
|
|
282
|
+
// We write the project-local config to avoid touching global state.
|
|
283
|
+
const opencodeJsonPath = join(process.cwd(), ".opencode.json");
|
|
279
284
|
|
|
280
285
|
const desiredPlugin = "@different-ai/opencode-browser";
|
|
281
286
|
|
|
287
|
+
function normalizePlugins(val) {
|
|
288
|
+
if (Array.isArray(val)) return val.filter((v) => typeof v === "string");
|
|
289
|
+
if (typeof val === "string" && val.trim()) return [val.trim()];
|
|
290
|
+
return [];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function removeLegacyMcp(config) {
|
|
294
|
+
if (config.mcp?.browser) {
|
|
295
|
+
delete config.mcp.browser;
|
|
296
|
+
if (Object.keys(config.mcp).length === 0) delete config.mcp;
|
|
297
|
+
warn("Removed old MCP browser config (replaced by plugin)");
|
|
298
|
+
}
|
|
299
|
+
if (config.mcpServers?.browser) {
|
|
300
|
+
delete config.mcpServers.browser;
|
|
301
|
+
if (Object.keys(config.mcpServers).length === 0) delete config.mcpServers;
|
|
302
|
+
warn("Removed old MCP browser config (replaced by plugin)");
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
282
306
|
if (existsSync(opencodeJsonPath)) {
|
|
283
|
-
const shouldUpdate = await confirm("Found opencode.json. Add plugin automatically?");
|
|
307
|
+
const shouldUpdate = await confirm("Found .opencode.json. Add plugin automatically?");
|
|
284
308
|
if (shouldUpdate) {
|
|
285
309
|
try {
|
|
286
310
|
const config = JSON.parse(readFileSync(opencodeJsonPath, "utf-8"));
|
|
287
|
-
|
|
288
|
-
|
|
311
|
+
|
|
312
|
+
// Make sure plugin is an array.
|
|
313
|
+
config.plugin = normalizePlugins(config.plugin);
|
|
289
314
|
if (!config.plugin.includes(desiredPlugin)) config.plugin.push(desiredPlugin);
|
|
290
315
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
warn("Removed old MCP browser config (replaced by plugin)");
|
|
296
|
-
}
|
|
316
|
+
removeLegacyMcp(config);
|
|
317
|
+
|
|
318
|
+
// Ensure schema is correct if present.
|
|
319
|
+
if (typeof config.$schema !== "string") config.$schema = "https://opencode.ai/config.json";
|
|
297
320
|
|
|
298
321
|
writeFileSync(opencodeJsonPath, JSON.stringify(config, null, 2) + "\n");
|
|
299
|
-
success("Updated opencode.json with plugin");
|
|
322
|
+
success("Updated .opencode.json with plugin");
|
|
300
323
|
} catch (e) {
|
|
301
|
-
error(`Failed to update opencode.json: ${e.message}`);
|
|
324
|
+
error(`Failed to update .opencode.json: ${e.message}`);
|
|
302
325
|
}
|
|
303
326
|
}
|
|
304
327
|
} else {
|
|
305
|
-
const shouldCreate = await confirm("No opencode.json found. Create one?");
|
|
328
|
+
const shouldCreate = await confirm("No .opencode.json found. Create one?");
|
|
306
329
|
if (shouldCreate) {
|
|
307
|
-
const config = {
|
|
330
|
+
const config = {
|
|
331
|
+
$schema: "https://opencode.ai/config.json",
|
|
332
|
+
theme: "opencode",
|
|
333
|
+
plugin: [desiredPlugin],
|
|
334
|
+
};
|
|
308
335
|
writeFileSync(opencodeJsonPath, JSON.stringify(config, null, 2) + "\n");
|
|
309
|
-
success("Created opencode.json with plugin");
|
|
336
|
+
success("Created .opencode.json with plugin");
|
|
310
337
|
}
|
|
311
338
|
}
|
|
312
339
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@different-ai/opencode-browser",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "Browser automation plugin for OpenCode (native messaging + per-tab ownership).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"opencode-browser": "
|
|
7
|
+
"opencode-browser": "bin/cli.js"
|
|
8
8
|
},
|
|
9
9
|
"main": "./src/plugin.ts",
|
|
10
10
|
"exports": {
|
package/src/plugin.ts
CHANGED
|
@@ -1,10 +1,34 @@
|
|
|
1
1
|
import type { Plugin } from "@opencode-ai/plugin";
|
|
2
2
|
import { tool } from "@opencode-ai/plugin";
|
|
3
3
|
import net from "net";
|
|
4
|
-
import { existsSync, mkdirSync } from "fs";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync } from "fs";
|
|
5
5
|
import { homedir } from "os";
|
|
6
|
-
import { join } from "path";
|
|
6
|
+
import { dirname, join } from "path";
|
|
7
7
|
import { spawn } from "child_process";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
9
|
+
|
|
10
|
+
console.log("[opencode-browser] Plugin loading...", { pid: process.pid });
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = dirname(__filename);
|
|
14
|
+
const PACKAGE_JSON_PATH = join(__dirname, "..", "package.json");
|
|
15
|
+
|
|
16
|
+
let cachedVersion: string | null = null;
|
|
17
|
+
|
|
18
|
+
function getPackageVersion(): string {
|
|
19
|
+
if (cachedVersion) return cachedVersion;
|
|
20
|
+
try {
|
|
21
|
+
const pkg = JSON.parse(readFileSync(PACKAGE_JSON_PATH, "utf8"));
|
|
22
|
+
if (typeof pkg?.version === "string") {
|
|
23
|
+
cachedVersion = pkg.version;
|
|
24
|
+
return cachedVersion;
|
|
25
|
+
}
|
|
26
|
+
} catch {
|
|
27
|
+
// ignore
|
|
28
|
+
}
|
|
29
|
+
cachedVersion = "unknown";
|
|
30
|
+
return cachedVersion;
|
|
31
|
+
}
|
|
8
32
|
|
|
9
33
|
const BASE_DIR = join(homedir(), ".opencode-browser");
|
|
10
34
|
const SOCKET_PATH = join(BASE_DIR, "broker.sock");
|
|
@@ -142,6 +166,37 @@ function toolResultText(data: any, fallback: string): string {
|
|
|
142
166
|
const plugin: Plugin = {
|
|
143
167
|
name: "opencode-browser",
|
|
144
168
|
tools: [
|
|
169
|
+
|
|
170
|
+
tool(
|
|
171
|
+
"browser_debug",
|
|
172
|
+
"Debug plugin loading and connection status.",
|
|
173
|
+
{},
|
|
174
|
+
async () => {
|
|
175
|
+
console.log("[opencode-browser] browser_debug called", { sessionId, pid: process.pid });
|
|
176
|
+
return JSON.stringify({
|
|
177
|
+
loaded: true,
|
|
178
|
+
sessionId,
|
|
179
|
+
pid: process.pid,
|
|
180
|
+
tools: plugin.tools.map(t => t.name),
|
|
181
|
+
timestamp: new Date().toISOString(),
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
),
|
|
185
|
+
|
|
186
|
+
tool(
|
|
187
|
+
"browser_version",
|
|
188
|
+
"Return the installed @different-ai/opencode-browser plugin version.",
|
|
189
|
+
{},
|
|
190
|
+
async () => {
|
|
191
|
+
return JSON.stringify({
|
|
192
|
+
name: "@different-ai/opencode-browser",
|
|
193
|
+
version: getPackageVersion(),
|
|
194
|
+
sessionId,
|
|
195
|
+
pid: process.pid,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
),
|
|
199
|
+
|
|
145
200
|
tool(
|
|
146
201
|
"browser_status",
|
|
147
202
|
"Check broker/native-host connection status and current tab claims.",
|
|
@@ -151,6 +206,7 @@ const plugin: Plugin = {
|
|
|
151
206
|
return JSON.stringify(data);
|
|
152
207
|
}
|
|
153
208
|
),
|
|
209
|
+
|
|
154
210
|
tool(
|
|
155
211
|
"browser_get_tabs",
|
|
156
212
|
"List all open browser tabs",
|