@different-ai/opencode-browser
Advanced tools
| --- | ||
| name: github-release | ||
| description: Create a GitHub release after pnpm publish with clear feature updates. | ||
| --- | ||
| Use this skill after running `pnpm publish`. | ||
| 1. Read the current version from `package.json` and set the tag name to `v<version>`. | ||
| 2. Summarize changes from git commits since the last tag, or if no tags exist, from the current conversation and latest commits. | ||
| 3. Draft release notes with a "## Features" section using those changes, and confirm with the user. | ||
| 4. Create the GitHub release with `gh release create v<version> --title "v<version>" --notes "<notes>"`. | ||
| 5. Confirm the release appears on GitHub and share the URL. |
+20
-19
@@ -209,6 +209,9 @@ #!/usr/bin/env node | ||
| async function resolveActiveTab(sessionId) { | ||
| const res = await callExtension("get_active_tab", {}, sessionId); | ||
| async function ensureSessionTab(sessionId) { | ||
| if (!sessionId) throw new Error("Missing sessionId for tab creation"); | ||
| const res = await callExtension("open_tab", { active: false }, sessionId); | ||
| const tabId = res && typeof res.tabId === "number" ? res.tabId : undefined; | ||
| if (!tabId) throw new Error("Could not determine active tab"); | ||
| if (!tabId) throw new Error("Failed to create a new tab for this session"); | ||
| touchClaim(tabId, sessionId); | ||
| setDefaultTab(sessionId, tabId); | ||
| return tabId; | ||
@@ -226,9 +229,3 @@ } | ||
| if (tool === "open_tab" && toolArgs.active !== false) { | ||
| const activeTabId = await resolveActiveTab(sessionId); | ||
| const claimCheck = checkClaim(activeTabId, sessionId); | ||
| if (!claimCheck.ok) { | ||
| toolArgs.active = false; | ||
| } | ||
| } | ||
| const isCloseTool = tool === "close_tab"; | ||
@@ -241,10 +238,6 @@ if (wantsTab(tool)) { | ||
| tabId = defaultTabId; | ||
| } else if (!isCloseTool) { | ||
| tabId = await ensureSessionTab(sessionId); | ||
| } else { | ||
| const activeTabId = await resolveActiveTab(sessionId); | ||
| const claimCheck = checkClaim(activeTabId, sessionId); | ||
| if (!claimCheck.ok) { | ||
| throw new Error(`${claimCheck.error}. No default tab for session; open a new tab or claim one.`); | ||
| } | ||
| tabId = activeTabId; | ||
| setDefaultTab(sessionId, tabId); | ||
| throw new Error("No tab owned by this session. Open a new tab first."); | ||
| } | ||
@@ -262,4 +255,12 @@ } | ||
| if (typeof usedTabId === "number") { | ||
| touchClaim(usedTabId, sessionId); | ||
| setDefaultTab(sessionId, usedTabId); | ||
| if (isCloseTool) { | ||
| if (claims.has(usedTabId)) { | ||
| releaseClaim(usedTabId); | ||
| } else { | ||
| clearDefaultTab(sessionId, usedTabId); | ||
| } | ||
| } else { | ||
| touchClaim(usedTabId, sessionId); | ||
| setDefaultTab(sessionId, usedTabId); | ||
| } | ||
| } | ||
@@ -266,0 +267,0 @@ |
@@ -104,2 +104,3 @@ const NATIVE_HOST_NAME = "com.opencode.browser_automation" | ||
| open_tab: toolOpenTab, | ||
| close_tab: toolCloseTab, | ||
| navigate: toolNavigate, | ||
@@ -713,2 +714,8 @@ click: toolClick, | ||
| async function toolCloseTab({ tabId }) { | ||
| if (!Number.isFinite(tabId)) throw new Error("tabId is required") | ||
| await chrome.tabs.remove(tabId) | ||
| return { tabId, content: { tabId, closed: true } } | ||
| } | ||
| async function toolNavigate({ url, tabId }) { | ||
@@ -715,0 +722,0 @@ if (!url) throw new Error("URL is required") |
+9
-11
| { | ||
| "name": "@different-ai/opencode-browser", | ||
| "version": "4.5.0", | ||
| "version": "4.5.1", | ||
| "description": "Browser automation plugin for OpenCode (native messaging + per-tab ownership).", | ||
@@ -21,11 +21,2 @@ "type": "module", | ||
| ], | ||
| "scripts": { | ||
| "build": "bun build src/plugin.ts --target=node --outfile=dist/plugin.js", | ||
| "prepublishOnly": "bun run build", | ||
| "publish": "node -e \"const argv=(() => { try { return JSON.parse(process.env.npm_config_argv || '{}').original || []; } catch { return []; } })(); if (argv.length === 1 && argv[0] === 'publish') process.exit(0); require('child_process').execSync('npm publish --access public', { stdio: 'inherit' });\"", | ||
| "install": "node bin/cli.js install", | ||
| "uninstall": "node bin/cli.js uninstall", | ||
| "status": "node bin/cli.js status", | ||
| "tool-test": "bun bin/tool-test.ts" | ||
| }, | ||
| "keywords": [ | ||
@@ -58,3 +49,10 @@ "opencode", | ||
| "bun-types": "*" | ||
| }, | ||
| "scripts": { | ||
| "build": "bun build src/plugin.ts --target=node --outfile=dist/plugin.js", | ||
| "install": "node bin/cli.js install", | ||
| "uninstall": "node bin/cli.js uninstall", | ||
| "status": "node bin/cli.js status", | ||
| "tool-test": "bun bin/tool-test.ts" | ||
| } | ||
| } | ||
| } |
+9
-7
@@ -114,7 +114,7 @@ # OpenCode Browser | ||
| - First time a session touches a tab, the broker **auto-claims** it for that session. | ||
| - Each session tracks a default tab; tools without `tabId` route to it. | ||
| - `browser_open_tab` always works; if another session owns the active tab, the new tab opens in the background. | ||
| - Each session owns its own tabs; tabs are never shared between sessions. | ||
| - If a session has no tab yet, the broker auto-creates a background tab on first tool use. | ||
| - `browser_open_tab` always creates and claims a new tab for the session. | ||
| - Claims expire after inactivity (`OPENCODE_BROWSER_CLAIM_TTL_MS`, default 5 minutes). | ||
| - Use `browser_status` or `browser_list_claims` to inspect claims if needed. | ||
| - Use `browser_status` or `browser_list_claims` for debugging. | ||
@@ -130,2 +130,3 @@ ## Available tools | ||
| - `browser_open_tab` | ||
| - `browser_close_tab` | ||
| - `browser_navigate` | ||
@@ -154,3 +155,3 @@ - `browser_query` (modes: `text`, `value`, `list`, `exists`, `page_text`; optional `timeoutMs`/`pollMs`) | ||
| - [ ] Add tab management tools (`browser_set_active_tab`, `browser_close_tab`) | ||
| - [ ] Add tab management tools (`browser_set_active_tab`) | ||
| - [ ] Add navigation helpers (`browser_back`, `browser_forward`, `browser_reload`) | ||
@@ -168,4 +169,5 @@ - [ ] Add keyboard input tool (`browser_key`) | ||
| **Tab ownership errors** | ||
| - Use `browser_status` or `browser_list_claims` to see current claims | ||
| - Use `browser_release_tab` or close the other OpenCode session to release ownership | ||
| - Errors usually mean you passed a `tabId` owned by another session | ||
| - Use `browser_open_tab` to create a tab for your session (or omit `tabId` to use your default) | ||
| - Use `browser_status` or `browser_list_claims` for debugging | ||
@@ -172,0 +174,0 @@ ## Uninstall |
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 19 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 19 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
538595
0.23%15
7.14%15667
0.16%177
1.14%