bookmark-bridge 2.0.0 → 2.0.3

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 CHANGED
@@ -121,14 +121,20 @@ extension's storage. `BOOKMARK_BRIDGE_PORT` changes the port.
121
121
  The v2 server is available on the npm `native` channel. The standard
122
122
  `bookmark-bridge` command still installs the legacy server.
123
123
 
124
- 1. In your MCP client, change the command arguments from `-y bookmark-bridge`
124
+ 1. Open `chrome://extensions` and check the Bridgey extension version. Native
125
+ Messaging requires **2.0.0 or later**. If you have an older version, keep
126
+ using the legacy MCP command or [load the unpacked extension](#unpacked-development-extension)
127
+ before changing your MCP configuration.
128
+ 2. In your MCP client, change the command arguments from `-y bookmark-bridge`
125
129
  to `-y bookmark-bridge@native`, then restart its MCP connection. With Claude
126
130
  Code, the command for a new entry is
127
131
  `claude mcp add bookmark-bridge -- npx -y bookmark-bridge@native`.
128
- 2. Open Bridgey's popup and choose **Native Messaging**. Approve Chrome's
132
+ 3. Open Bridgey's popup and choose **Native Messaging**. Approve Chrome's
129
133
  permission prompt. If setup fails, the extension stays in Legacy mode.
130
- 3. Run `bridge_status` from your MCP client to confirm the connection.
134
+ Restore the legacy MCP command to reconnect.
135
+ 4. Run `bridge_status` from your MCP client to confirm the connection.
131
136
 
137
+ The Native npm package contains the prebuilt servers and their checksums.
132
138
  The first server startup installs the native host in a user data directory
133
139
  outside the npm cache and registers it with Chrome. Chrome launches that host
134
140
  when the extension connects. The host and the MCP process communicate over an
@@ -139,14 +145,19 @@ Bridgey serves one Native Messaging browser profile at a time. Each profile's
139
145
  v2 snapshots live under `native-v2/<profileId>` inside the existing history
140
146
  state directory. Legacy snapshots remain available in Legacy mode.
141
147
 
142
- To switch back, choose **Legacy (WebSocket)** in the popup, restore the MCP
143
- command arguments to `-y bookmark-bridge`, and restart its MCP connection.
148
+ To switch back, choose **Legacy (WebSocket)** if the popup shows a mode
149
+ selector, restore the MCP command arguments to `-y bookmark-bridge`, and
150
+ restart its MCP connection.
144
151
  Restarting Chrome or reconnecting the popup refreshes the browser connection.
145
152
  Restart the MCP connection after updating the server to refresh its tool list.
146
153
 
147
- For an unpacked development extension, build the v2 binary and run
148
- `bookmark-bridge register-native <extension-id>` with that binary before
149
- selecting Native Messaging. It remembers the ID alongside the published one.
154
+ ### Unpacked development extension
155
+
156
+ At `chrome://extensions`, enable Developer mode and load the `extension/`
157
+ directory from this repository at `v2.0.0` or later. Copy the unpacked
158
+ extension's ID and run `npx -y bookmark-bridge@native register-native <extension-id>`
159
+ before selecting Native Messaging. The host remembers this ID alongside the
160
+ published one.
150
161
  On macOS and Linux, set `BOOKMARK_BRIDGE_CHROME_USER_DATA_DIR` to the absolute
151
162
  user data directory when registering for a Chrome test profile outside the
152
163
  default location.
@@ -1,13 +1,11 @@
1
1
  #!/usr/bin/env node
2
- // Fetches the prebuilt server for this platform on first run, then hands over to
3
- // it. An MCP client launches this over stdio, so nothing may be written to
2
+ // Verifies and unpacks the bundled server, then hands over to it.
3
+ // An MCP client launches this over stdio, so nothing may be written to
4
4
  // stdout that is not protocol: progress goes to stderr.
5
5
  import {spawn} from 'node:child_process';
6
6
  import {createHash} from 'node:crypto';
7
- import {createWriteStream} from 'node:fs';
8
7
  import {chmod, mkdir, mkdtemp, readFile, rename, rm, stat} from 'node:fs/promises';
9
8
  import {dirname, join} from 'node:path';
10
- import {pipeline} from 'node:stream/promises';
11
9
  import {fileURLToPath} from 'node:url';
12
10
 
13
11
  const here = dirname(fileURLToPath(import.meta.url));
@@ -35,7 +33,7 @@ if (!target) {
35
33
  die(`no prebuilt server for ${key}. Build from source: https://github.com/${REPO}`);
36
34
  }
37
35
 
38
- // Cached per version, so upgrading the package fetches a matching server rather
36
+ // Cached per version, so upgrading the package unpacks a matching server rather
39
37
  // than silently reusing an old one.
40
38
  const cacheDir = join(here, '..', '.bin', pkg.version);
41
39
  const binary = join(cacheDir, `bookmark-bridge${EXE}`);
@@ -44,38 +42,20 @@ async function exists(path) {
44
42
  try { await stat(path); return true; } catch { return false; }
45
43
  }
46
44
 
47
- async function fetchOrDie(url, what) {
48
- const res = await fetch(url, {redirect: 'follow'});
49
- if (!res.ok) die(`could not download ${what} (HTTP ${res.status})\n ${url}`);
50
- return res;
51
- }
52
-
53
45
  async function install() {
54
- const tag = `v${pkg.version}`;
46
+ const assets = join(here, '..', 'release-assets');
55
47
  const name = `bookmark-bridge-${target}.tar.gz`;
56
- const base = `https://github.com/${REPO}/releases/download/${tag}`;
57
-
58
- process.stderr.write(`bookmark-bridge: fetching ${tag} for ${key}\n`);
59
- const sums = (await (await fetchOrDie(`${base}/SHA256SUMS`, 'checksums')).text());
60
- const line = sums.split('\n').find((l) => l.trim().endsWith(name));
61
- if (!line) die(`no checksum published for ${name} in ${tag}`);
62
- const expected = line.trim().split(/\s+/)[0];
48
+ const sums = await readFile(join(assets, 'SHA256SUMS'), 'utf8');
49
+ const expected = sums.split('\n').map(line => line.trim().split(/\s+/))
50
+ .find(([, file]) => file === name)?.[0];
51
+ if (!expected) throw new Error(`no checksum bundled for ${name}`);
52
+ const archive = join(assets, name);
53
+ const actual = createHash('sha256').update(await readFile(archive)).digest('hex');
54
+ if (actual !== expected) throw new Error(`checksum mismatch for ${name}`);
63
55
 
64
56
  await mkdir(dirname(cacheDir), {recursive: true});
65
57
  const staging = await mkdtemp(join(dirname(cacheDir), '.install-'));
66
- const archive = join(staging, name);
67
58
  try {
68
- await pipeline(
69
- (await fetchOrDie(`${base}/${name}`, 'the server')).body,
70
- createWriteStream(archive),
71
- );
72
-
73
- // Never run a binary that does not match what the release published.
74
- const actual = createHash('sha256').update(await readFile(archive)).digest('hex');
75
- if (actual !== expected) {
76
- die(`checksum mismatch for ${name}\n expected ${expected}\n got ${actual}`);
77
- }
78
-
79
59
  await new Promise((resolve, reject) => {
80
60
  const tar = spawn('tar', ['-xzf', archive, '-C', staging], {stdio: 'inherit'});
81
61
  tar.on('error', reject);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bookmark-bridge",
3
- "version": "2.0.0",
3
+ "version": "2.0.3",
4
4
  "description": "Chrome bookmarks as MCP tools, with every change recorded in git so it can be rolled back",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -13,10 +13,11 @@
13
13
  },
14
14
  "files": [
15
15
  "bin/",
16
+ "release-assets/",
16
17
  "README.md"
17
18
  ],
18
19
  "scripts": {
19
- "prepublishOnly": "node -e \"if (process.env.npm_config_tag !== 'native') { console.error('Publish this version with npm publish --tag native.'); process.exit(1); }\""
20
+ "prepublishOnly": "node -e \"if (process.env.npm_config_tag !== 'native' || !require('fs').existsSync('release-assets/SHA256SUMS')) { console.error('Publish the bundled release with npm publish --tag native.'); process.exit(1); }\""
20
21
  },
21
22
  "publishConfig": {
22
23
  "tag": "native"
@@ -0,0 +1,5 @@
1
+ a55375e6a1e8fd9cfb4aaa595a594ae62d8e4c5047dccda59c9631a3a7a5b1fc bookmark-bridge-aarch64-apple-darwin.tar.gz
2
+ ee37b2bf74d9670bef55b0464ce880272d63b76cafe16f501be4cd53fedb7b55 bookmark-bridge-aarch64-unknown-linux-gnu.tar.gz
3
+ 944b198396dc0becdfe926e83f5f71130329eb2241e337b416bccf7b5be1251e bookmark-bridge-x86_64-apple-darwin.tar.gz
4
+ 2df2e9704ba897d96f0b8466d1e20256ef3d30afe2a61103ec69339f6d6420a6 bookmark-bridge-x86_64-pc-windows-msvc.tar.gz
5
+ 4fdd3d39d3560fad4749dbd9208698a39b3c8b6d232f4a9f2c91ab53175b6116 bookmark-bridge-x86_64-unknown-linux-gnu.tar.gz