Skip to content

Commit e7c2738

Browse files
committed
Open store page during setup
1 parent 2e8cbb1 commit e7c2738

17 files changed

Lines changed: 120 additions & 25 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ brew upgrade open-browser-use
4646

4747
### Set Up Chrome
4848

49-
Register the native host for the extension, then install the matching Chrome
50-
extension.
49+
Register the native host for the extension. The setup command also opens the
50+
Chrome Web Store page so you can install or enable the matching Chrome
51+
extension, then restart Chrome if needed.
5152

5253
```bash
5354
open-browser-use setup

README.zh-CN.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ brew upgrade open-browser-use
3838
```
3939

4040
### 配置 Chrome
41-
注册绑定到该插件的 native host,然后安装对应的浏览器插件
41+
注册绑定到该插件的 native host。setup 也会打开 Chrome Web Store 页面,你需要在
42+
页面里安装或启用对应的浏览器插件,必要时再重启 Chrome。
4243

4344
```bash
4445
open-browser-use setup

apps/chrome-extension/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"manifest_version": 3,
33
"name": "Open Browser Use",
44
"description": "Open Browser Use Chrome automation extension.",
5-
"version": "0.1.34",
5+
"version": "0.1.35",
66
"icons": {
77
"16": "icons/icon-16.png",
88
"32": "icons/icon-32.png",

cmd/open-browser-use/main.go

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ import (
2626
"github.com/spf13/cobra"
2727
)
2828

29-
const version = "0.1.34"
29+
const version = "0.1.35"
3030
const defaultChromeExtensionID = "bgjoihaepiejlfjinojjfgokghnodnhd"
3131
const defaultCLISessionID = "obu-cli"
3232
const defaultMCPSessionID = "obu-mcp"
3333
const chromeWebStoreUpdateURL = "https://clients2.google.com/service/update2/crx"
34+
const chromeWebStoreExtensionURL = "https://chromewebstore.google.com/detail/open-browser-use/" + defaultChromeExtensionID + "?utm_source=open-computer-use"
3435
const betaExtensionPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnBLT95WWVnHYH0pOBRH/eP+BWtlKVmLE/RHkERUTI2+PGDSQrbWVabmTw4CZ3yhjko04dijSX2Az8cnp65xh23Dh5mP5TCtiP9LexRFJokd8EsyeFdtKamMYr0hF1ZUc1/8ZpLnetAU65ZMB9VzHQBqpJWeUwuIvecgfRtGklDgJMjnvcq5J6pttZrzWrI/2B0BNufwsTQfEt7qLtDFPHXmUdtZfQbc2EfYFvkXLDAXicYviiocedrsAGIKUxpyQegobhUFL+tNLOuXKBpZlLFQn3xgm5CyGZwN6bueiV/S7reigVTKAMQ8BX0eacT22e8r0UzjsjkugeHOIonIvtQIDAQAB"
3536

3637
func main() {
@@ -125,6 +126,7 @@ func newSetupCommand() *cobra.Command {
125126
extensionID := defaultChromeExtensionID
126127
var binaryPath string
127128
var externalExtensionOutput string
129+
var noOpen bool
128130
cmd := &cobra.Command{
129131
Use: "setup",
130132
Short: "Register Chrome integration for Open Browser Use",
@@ -134,13 +136,21 @@ func newSetupCommand() *cobra.Command {
134136
if err != nil {
135137
return err
136138
}
139+
if !noOpen {
140+
if err := openChromeWebStorePage(); err != nil {
141+
result.StoreOpenError = err.Error()
142+
} else {
143+
result.OpenedStore = true
144+
}
145+
}
137146
status := detectBrowserExtension(host.DefaultSocketDir, 700*time.Millisecond)
138147
return renderStoreSetupResult(cmd.OutOrStdout(), result, status)
139148
},
140149
}
141150
cmd.Flags().StringVar(&extensionID, "extension-id", defaultChromeExtensionID, "Chrome extension id for allowed_origins")
142151
cmd.Flags().StringVar(&binaryPath, "path", "", "native host binary target for the stable host link")
143152
cmd.Flags().StringVar(&externalExtensionOutput, "external-extension-output", "", "Chrome external extension JSON output path")
153+
cmd.Flags().BoolVar(&noOpen, "no-open", false, "register Chrome integration without opening the Chrome Web Store page")
144154
cmd.AddCommand(newSetupBetaCommand())
145155
return cmd
146156
}
@@ -298,6 +308,9 @@ func installNativeManifest(extensionID string, binaryPath string, outputPath str
298308
type setupResult struct {
299309
NativeManifestPath string
300310
ExternalExtensionPath string
311+
StoreURL string
312+
OpenedStore bool
313+
StoreOpenError string
301314
}
302315

303316
type manualSetupResult struct {
@@ -333,6 +346,7 @@ func setupChrome(extensionID string, binaryPath string, externalExtensionOutput
333346
return setupResult{
334347
NativeManifestPath: manifestPath,
335348
ExternalExtensionPath: extensionPath,
349+
StoreURL: chromeWebStoreExtensionURL,
336350
}, nil
337351
}
338352

@@ -369,7 +383,14 @@ func renderStoreSetupResult(writer io.Writer, result setupResult, status browser
369383
fmt.Fprintln(writer, "✅ Open Browser Use setup")
370384
fmt.Fprintf(writer, "1. ✅ Registered native host\n %s\n", result.NativeManifestPath)
371385
fmt.Fprintf(writer, "2. ✅ Requested Chrome extension install\n Extension id: %s\n Chrome install file: %s\n", defaultChromeExtensionID, result.ExternalExtensionPath)
372-
fmt.Fprintf(writer, "3. 🧩 Browser extension\n %s\n", status.summaryForSetup("Not installed yet. Chrome still needs to install or enable it."))
386+
if result.OpenedStore {
387+
fmt.Fprintf(writer, "3. ✅ Opened Chrome Web Store\n %s\n", result.StoreURL)
388+
} else if result.StoreOpenError != "" {
389+
fmt.Fprintf(writer, "3. ⚠️ Chrome Web Store page was not opened\n %s\n Error: %s\n", result.StoreURL, result.StoreOpenError)
390+
} else {
391+
fmt.Fprintf(writer, "3. Open Chrome Web Store\n %s\n", result.StoreURL)
392+
}
393+
fmt.Fprintf(writer, "4. 🧩 Browser extension\n %s\n", status.summaryForSetup("Not installed yet. Install or enable it from the Chrome Web Store page."))
373394
fmt.Fprintln(writer)
374395
if status.isReady() {
375396
fmt.Fprintln(writer, "All set. The browser extension is installed, connected, and on the expected version.")
@@ -380,8 +401,8 @@ func renderStoreSetupResult(writer io.Writer, result setupResult, status browser
380401
return nil
381402
}
382403
fmt.Fprintln(writer, "Next:")
383-
fmt.Fprintln(writer, " 1. Restart Chrome if it is already open.")
384-
fmt.Fprintln(writer, " 2. Approve or enable the Open Browser Use extension if Chrome asks.")
404+
fmt.Fprintln(writer, " 1. Install or enable Open Browser Use from the Chrome Web Store page.")
405+
fmt.Fprintln(writer, " 2. Restart Chrome if Chrome asks or the extension does not appear immediately.")
385406
fmt.Fprintln(writer, " 3. Verify the connection: open-browser-use info")
386407
return nil
387408
}
@@ -2303,6 +2324,24 @@ func openChromeExtensionsPage() error {
23032324
return cmd.Process.Release()
23042325
}
23052326

2327+
func openChromeWebStorePage() error {
2328+
var cmd *exec.Cmd
2329+
switch runtime.GOOS {
2330+
case "darwin":
2331+
cmd = exec.Command("open", "-a", "Google Chrome", chromeWebStoreExtensionURL)
2332+
case "linux":
2333+
cmd = exec.Command("xdg-open", chromeWebStoreExtensionURL)
2334+
case "windows":
2335+
cmd = exec.Command("rundll32", "url.dll,FileProtocolHandler", chromeWebStoreExtensionURL)
2336+
default:
2337+
return fmt.Errorf("opening Chrome Web Store is not implemented for %s", runtime.GOOS)
2338+
}
2339+
if err := cmd.Start(); err != nil {
2340+
return err
2341+
}
2342+
return cmd.Process.Release()
2343+
}
2344+
23062345
func numberAsInt(value any) (int, bool) {
23072346
switch typed := value.(type) {
23082347
case int:

cmd/open-browser-use/main_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ func TestCobraSetupWritesNativeAndExternalManifests(t *testing.T) {
222222
cmd := newRootCommand()
223223
var output bytes.Buffer
224224
cmd.SetOut(&output)
225-
cmd.SetArgs([]string{"setup", "--path", targetPath, "--external-extension-output", externalPath})
225+
cmd.SetArgs([]string{"setup", "--path", targetPath, "--external-extension-output", externalPath, "--no-open"})
226226
if err := cmd.Execute(); err != nil {
227227
t.Fatal(err)
228228
}
@@ -235,6 +235,9 @@ func TestCobraSetupWritesNativeAndExternalManifests(t *testing.T) {
235235
if !strings.Contains(output.String(), "Browser extension") {
236236
t.Fatalf("expected setup output to mention browser extension status, got %q", output.String())
237237
}
238+
if !strings.Contains(output.String(), chromeWebStoreExtensionURL) {
239+
t.Fatalf("expected setup output to mention Chrome Web Store URL, got %q", output.String())
240+
}
238241
if _, err := os.Stat(filepath.Join(home, "Library/Application Support/Google/Chrome/NativeMessagingHosts", host.NativeHostName+".json")); runtime.GOOS == "darwin" && err != nil {
239242
t.Fatal(err)
240243
}

docs/ARCHITECTURE.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,10 @@ dot;hyphen 版本 `com.ifuryst.open-computer-use.extension` 会被
9696
写入 Chrome 默认位置,或通过 `--output` 写到指定路径。默认 extension id
9797
是 Chrome Web Store 版 `bgjoihaepiejlfjinojjfgokghnodnhd`
9898
- `open-browser-use setup`:显式安装流程,先调用 native host manifest
99-
注册,再写入 Chrome External Extensions JSON,让 Chrome 从 Web Store
100-
安装正式扩展。macOS/Windows 仍需要用户在 Chrome 中确认启用扩展;Linux
101-
的 External Extensions 写入默认使用 Chrome 官方系统路径,可能需要更高权限。
99+
注册,再写入 Chrome External Extensions JSON,并打开 Chrome Web Store
100+
正式扩展页,引导用户手动安装或启用扩展。macOS/Windows 仍可能需要用户在
101+
Chrome 中确认启用扩展并重启;Linux 的 External Extensions 写入默认使用
102+
Chrome 官方系统路径,可能需要更高权限。
102103
- `open-browser-use setup beta`:Chrome Web Store 临时不可用时的备用路径,
103104
注册 native host 后从 GitHub Releases 下载最新
104105
`open-browser-use-chrome-extension-*.zip`。CLI 会在本地 unpacked 目录和待拖入

docs/CHROME_WEB_STORE_LISTING.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,9 @@ short in the Dashboard if character limits apply.
115115

116116
The Chrome Web Store package contains only the MV3 extension. Users must install
117117
the native host separately through npm or Homebrew. After installing the CLI,
118-
users run setup to register the native host and the Chrome Web Store extension
119-
install hint for extension `bgjoihaepiejlfjinojjfgokghnodnhd`.
118+
users run setup to register the native host, write the Chrome Web Store
119+
extension install hint for extension `bgjoihaepiejlfjinojjfgokghnodnhd`, and
120+
open the store page so the user can install or enable the extension.
120121

121122
Recommended setup command:
122123

docs/CHROME_WEB_STORE_RELEASE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ Chrome extension 不能自己安装 native messaging host manifest。正式扩
1717
open-browser-use setup
1818
```
1919

20-
`setup` 会调用 native host manifest 注册,并写入 Chrome External Extensions
21-
JSON, Chrome 从 Chrome Web Store 安装正式扩展;用户仍可能需要重启 Chrome
22-
并确认启用扩展。需要只修复 native host 时,仍可运行:
20+
`setup` 会调用 native host manifest 注册,写入 Chrome External Extensions
21+
JSON,并打开 Chrome Web Store 正式扩展页。用户需要在商店页手动安装或启用扩展;
22+
Chrome 仍可能要求用户重启并确认启用扩展。需要只修复 native host 时,仍可运行:
2323

2424
```bash
2525
open-browser-use install-manifest
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
## [2026-05-11 19:31] | Task: guided store setup
2+
3+
### 🤖 Execution Context
4+
5+
- **Agent ID**: `Codex`
6+
- **Base Model**: `GPT-5`
7+
- **Runtime**: `Codex CLI`
8+
9+
### 📥 User Query
10+
11+
> 希望 `setup` 时打开 Open Browser Use 的 Chrome Web Store 页面,让用户自己安装和重启。
12+
13+
### 🛠 Changes Overview
14+
15+
**Scope:** CLI setup flow, install docs, release notes.
16+
17+
**Key Actions:**
18+
19+
- **[CLI]**: `open-browser-use setup` now opens the public Chrome Web Store listing after registering the native host and writing the External Extensions hint.
20+
- **[Automation Escape Hatch]**: Added `setup --no-open` for tests, CI, and headless environments that should only write setup files.
21+
- **[Release]**: Bumped Open Browser Use runtime/package versions from `0.1.34` to `0.1.35`.
22+
- **[Docs]**: Updated README, npm package README, Chrome Web Store release/listing docs, bundled skill installation reference, and feature release notes.
23+
24+
### 🧠 Design Intent (Why)
25+
26+
Chrome's external extension hint can be delayed until Chrome restart and does not give the user a visible place to act. Opening the store listing makes the remaining human step explicit while keeping native host registration repeatable from the CLI.
27+
28+
### 📁 Files Modified
29+
30+
- `cmd/open-browser-use/main.go`
31+
- `cmd/open-browser-use/main_test.go`
32+
- `apps/chrome-extension/manifest.json`
33+
- `packages/open-browser-use-cli/package.json`
34+
- `packages/open-browser-use-js/package.json`
35+
- `packages/open-browser-use-python/pyproject.toml`
36+
- `packages/browser-use-protocol/package.json`
37+
- `packages/browser-client-rewrite/package.json`
38+
- `README.md`
39+
- `README.zh-CN.md`
40+
- `packages/open-browser-use-cli/README.md`
41+
- `docs/ARCHITECTURE.md`
42+
- `docs/CHROME_WEB_STORE_RELEASE.md`
43+
- `docs/CHROME_WEB_STORE_LISTING.md`
44+
- `docs/releases/feature-release-notes.md`
45+
- `skills/open-browser-use/references/installation.md`

docs/releases/feature-release-notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
| 日期 | 功能域 | 用户价值 | 变更摘要 |
66
| --- | --- | --- | --- |
7+
| 2026-05-11 | Guided Store Setup | `open-browser-use setup` 会直接打开 Open Browser Use 的 Chrome Web Store 页面,用户可以在明确的页面里安装或启用扩展并按需重启。 | 发布 `0.1.35` patch 版本,setup 仍会注册 native host 和写入 External Extensions hint,同时新增 `--no-open` 供 CI、测试或无桌面环境只写配置。 |
78
| 2026-05-11 | Chrome Extension Popup | 高分辨率屏幕上 popup 顶部 LOGO 更清晰,不再因为用 32px 位图放大显示而出现明显锯齿。 | 发布 `0.1.34` patch 版本,popup 头部改用 128px icon 作为源图并保持 32 CSS px 显示尺寸;同步 runtime、SDK、extension 版本号和发布制品。 |
89
| 2026-05-11 | Chrome Extension Logo | Chrome Web Store 和浏览器工具栏会显示新版 Open Browser Use 标识,减少旧视觉资产和当前品牌方向不一致的问题。 | 发布 `0.1.33` patch 版本,替换 Chrome extension 的 16/32/48/128 PNG icons 和 1024px source logo,并沿用现有 tag release 与 Chrome Web Store 自动提交链路。 |
910
| 2026-05-11 | Chrome Web Store Release Drill | 维护者可以用 `v0.1.32` 验证 tag release 到 Chrome Web Store 自动提交审核的完整链路。 | 发布 `0.1.32` patch 版本,用新配置的 `CWS_SERVICE_ACCOUNT_JSON`、publisher/extension secrets 和 `CWS_AUTO_PUBLISH=true` 触发真实 CWS 上传与提交流程。 |

0 commit comments

Comments
 (0)