unbrowse 7.1.0 → 7.2.0-preview.0

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
@@ -74,7 +74,7 @@ If a wallet is configured, that wallet address becomes the contributor/payment t
74
74
 
75
75
  Recommended for new installs: set up Crossmint `lobster.cash` during bootstrap. `unbrowse setup` now encourages it, and when the tooling is already present it will try `npx @crossmint/lobster-cli setup` automatically. That wallet becomes the payout destination for contributed routes and the spending wallet for paid marketplace routes.
76
76
 
77
- Unbrowse supports wallet providers such as Crossmint `lobster.cash` for x402-gated routes. If you use `lobster.cash`, set `LOBSTER_WALLET_ADDRESS`. Other providers can use `AGENT_WALLET_ADDRESS` and optional `AGENT_WALLET_PROVIDER`.
77
+ Unbrowse supports wallet providers such as Crossmint `lobster.cash` for paid routes. If you use `lobster.cash`, set `LOBSTER_WALLET_ADDRESS`. Other providers can use `AGENT_WALLET_ADDRESS` and optional `AGENT_WALLET_PROVIDER`.
78
78
 
79
79
  For repeat npm use after a healthy publish:
80
80
 
package/SKILL.md CHANGED
@@ -24,7 +24,7 @@ All four resolve to the same runtime workflow underneath:
24
24
  - **execute** picks one endpoint from the shortlist and runs it — returns the real data.
25
25
  - **browse-session** opens a managed browser when the API is too dynamic to predict; local capture indexes route metadata.
26
26
 
27
- The two-tool flow (resolve + execute) is the agent UX north star: never one call, never three. The shortlist is structured so the calling LLM picks; execute is paid via x402 when the route is priced.
27
+ The two-tool flow (resolve + execute) is the agent UX north star: never one call, never three. The shortlist is structured so the calling LLM picks; execute is paid from the agent's wallet (or sponsored credit) when the route is priced.
28
28
 
29
29
  ## Quickstart
30
30
 
@@ -10,10 +10,13 @@ import { createRequire } from "node:module";
10
10
  import { join, dirname } from "node:path";
11
11
  import { fileURLToPath } from "node:url";
12
12
  import { spawn } from "node:child_process";
13
+ import { unbrowseBinaryName } from "../scripts/release-assets.mjs";
13
14
 
14
15
  const __dirname = dirname(fileURLToPath(import.meta.url));
15
16
  const packageRoot = join(__dirname, "..");
16
- const binaryPath = join(__dirname, "unbrowse");
17
+ // Windows ships `unbrowse.exe`; postinstall installs it under that name, so the
18
+ // wrapper must look for the same name (a plain `unbrowse` never exists on win).
19
+ const binaryPath = join(__dirname, unbrowseBinaryName(process.platform));
17
20
  const launcherPath = join(__dirname, "unbrowse.js");
18
21
  const require = createRequire(import.meta.url);
19
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unbrowse",
3
- "version": "7.1.0",
3
+ "version": "7.2.0-preview.0",
4
4
  "description": "Reverse-engineer any website into reusable API skills. Zero-dep single binary with embedded browser engine.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,6 +9,7 @@
9
9
  "files": [
10
10
  "bin",
11
11
  "vendor/kuri",
12
+ "vendor/utls-proxy",
12
13
  "scripts/release-assets.mjs",
13
14
  "scripts/postinstall.mjs",
14
15
  "scripts/postinstall-ping.mjs",
@@ -19,7 +20,7 @@
19
20
  ],
20
21
  "scripts": {
21
22
  "postinstall": "node scripts/postinstall.mjs",
22
- "prepack": "node scripts/prepare-pack.mjs && node scripts/assert-kuri-vendor.mjs",
23
+ "prepack": "node scripts/prepare-pack.mjs && node scripts/assert-kuri-vendor.mjs && node scripts/assert-utls-vendor.mjs",
23
24
  "prepublishOnly": "node scripts/assert-release-flow.mjs && node scripts/verify-release-assets.mjs",
24
25
  "start": "bun src/index.ts",
25
26
  "dev": "bun --watch src/index.ts"
@@ -15,7 +15,7 @@ import { execFileSync } from "node:child_process";
15
15
  import { tmpdir, homedir } from "node:os";
16
16
  import http from "node:http";
17
17
  import https from "node:https";
18
- import { SUPPORTED_TARGETS, buildBinaryArchiveName, buildReleaseAssetUrl, getReleaseAssetConfig } from "./release-assets.mjs";
18
+ import { SUPPORTED_TARGETS, buildBinaryArchiveName, buildReleaseAssetUrl, getReleaseAssetConfig, unbrowseBinaryName } from "./release-assets.mjs";
19
19
 
20
20
  // --- Persist landing attribution from env to disk ---
21
21
  // The UNBROWSE_LANDING_TOKEN env var is set when the user copies the install
@@ -42,7 +42,11 @@ try {
42
42
  const __dirname = dirname(fileURLToPath(import.meta.url));
43
43
  const packageRoot = join(__dirname, "..");
44
44
  const binDir = join(packageRoot, "bin");
45
- const binaryPath = join(binDir, "unbrowse");
45
+ // On Windows the compiled binary is `unbrowse.exe`; everywhere else it's
46
+ // `unbrowse`. The wrapper (bin/unbrowse-wrapper.mjs) resolves the same name,
47
+ // so both sides must agree — the decision lives in release-assets.mjs.
48
+ const installedBinaryName = unbrowseBinaryName(process.platform);
49
+ const binaryPath = join(binDir, installedBinaryName);
46
50
  const localBinaryPath = process.env.UNBROWSE_INSTALL_BINARY_PATH;
47
51
  const wrapperPath = join(binDir, "unbrowse-wrapper.mjs");
48
52
  const launcherPath = join(binDir, "unbrowse.js");
@@ -148,9 +152,14 @@ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
148
152
  await download(url, archivePath);
149
153
  mkdirSync(extractDir, { recursive: true });
150
154
  execFileSync("tar", ["-xzf", archivePath, "-C", extractDir]);
151
- const extractedBinary = join(extractDir, "unbrowse");
152
- if (!existsSync(extractedBinary)) {
153
- throw new Error(`Archive ${assetName} did not contain ./unbrowse`);
155
+ // The win-x64 tarball packs `unbrowse.exe` at the archive root; darwin/linux
156
+ // pack `unbrowse`. Prefer the target-appropriate member, but accept either
157
+ // layout so an unexpectedly-named asset still installs.
158
+ const memberName = unbrowseBinaryName(target);
159
+ const memberCandidates = [join(extractDir, memberName), join(extractDir, "unbrowse"), join(extractDir, "unbrowse.exe")];
160
+ const extractedBinary = memberCandidates.find((p) => existsSync(p));
161
+ if (!extractedBinary) {
162
+ throw new Error(`Archive ${assetName} did not contain ${memberName}`);
154
163
  }
155
164
  mkdirSync(binDir, { recursive: true });
156
165
  copyFileSync(extractedBinary, binaryPath);
@@ -38,3 +38,21 @@ export function buildBinaryArchiveName(version, target) {
38
38
  export function buildReleaseAssetUrl(baseUrl, tag, assetName) {
39
39
  return `${baseUrl.replace(/\/+$/, "")}/${tag}/${assetName}`;
40
40
  }
41
+
42
+ // --- Windows-aware binary naming -------------------------------------------
43
+ // The compiled unbrowse binary is `unbrowse` on darwin/linux but `unbrowse.exe`
44
+ // on Windows: bun emits `.exe` for `--target=bun-windows-x64`, the release
45
+ // tarball packs it at the archive root as `unbrowse.exe`, and Windows refuses
46
+ // to exec a file without the extension. Both the postinstall (which extracts
47
+ // the tarball member and installs it into bin/) and the wrapper (which execs
48
+ // bin/unbrowse[.exe]) must agree on the name, so the decision lives here.
49
+ //
50
+ // Accepts either a Node `process.platform` value (`win32`) or a release target
51
+ // id (`win-x64`) — anything that starts with `win` is treated as Windows.
52
+ export function isWindowsPlatform(platformOrTarget) {
53
+ return typeof platformOrTarget === "string" && platformOrTarget.startsWith("win");
54
+ }
55
+
56
+ export function unbrowseBinaryName(platformOrTarget) {
57
+ return isWindowsPlatform(platformOrTarget) ? "unbrowse.exe" : "unbrowse";
58
+ }
Binary file
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "repo_url": "https://github.com/justrach/kuri.git",
3
3
  "branch": "adding-extensions",
4
- "source_sha": "f2487712bae677fa4aa7ed3ce773355711f2e56e",
5
- "built_at": "2026-05-27T07:15:46.062Z",
4
+ "source_sha": "8938f89f3d0c032bd19c59db0de4eadca18a1800",
5
+ "built_at": "2026-05-31T07:22:18.500Z",
6
6
  "binaries": {
7
7
  "darwin-arm64": {
8
8
  "zig_target": "aarch64-macos",
@@ -21,8 +21,33 @@
21
21
  },
22
22
  "linux-x64": {
23
23
  "zig_target": "x86_64-linux",
24
- "source": "placeholder",
25
- "sha256": "66e35d14361feb683b80dc7e01902a454945ce6829dbb31ed99c1751abc9ced8"
24
+ "sha256": "fa91a78820effff9db8465fa66567ac7fe22f42ea89522ef7b6f482e6678ad0d"
25
+ },
26
+ "win-x64": {
27
+ "zig_target": "x86_64-windows-gnu",
28
+ "sha256": "0919906d9b1512166dd6af207782949cd1ace6babec1817f94e4efdf3beb26db"
29
+ }
30
+ },
31
+ "ffi": {
32
+ "darwin-arm64": {
33
+ "zig_target": "aarch64-macos",
34
+ "lib": "libkuri_ffi.dylib",
35
+ "sha256": "ec87c92ed59368e674266ce47aa42c9c6496313953e2747d01b28e116f5a21f4"
36
+ },
37
+ "darwin-x64": {
38
+ "zig_target": "x86_64-macos",
39
+ "lib": "libkuri_ffi.dylib",
40
+ "sha256": "905e7e6bb67fb9791e4a3585e1802042a65d7fcb2d5d064651f2cfc48e97cb0d"
41
+ },
42
+ "linux-arm64": {
43
+ "zig_target": "aarch64-linux",
44
+ "lib": "libkuri_ffi.so",
45
+ "sha256": "9dbdf3b4e4588ee30295715a74afb3c1e01059cf5a3c451f6ab21d63036caa44"
46
+ },
47
+ "linux-x64": {
48
+ "zig_target": "x86_64-linux",
49
+ "lib": "libkuri_ffi.so",
50
+ "sha256": "7685b4b81338f5ade4d72839b85f341ca32f4711964d3becfc9970785240cdb2"
26
51
  }
27
52
  }
28
53
  }
Binary file