crawlio-browser 1.4.1 → 1.4.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.
|
Binary file
|
package/dist/mcp-server/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
WS_PORT,
|
|
8
8
|
WS_RECONNECT_GRACE,
|
|
9
9
|
WS_STALE_THRESHOLD
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-XNQ5PU33.js";
|
|
11
11
|
|
|
12
12
|
// src/mcp-server/index.ts
|
|
13
13
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
@@ -488,6 +488,7 @@ var WebSocketBridge = class {
|
|
|
488
488
|
import("child_process").then(({ execFile: execFile2 }) => {
|
|
489
489
|
execFile2("open", ["-a", "Crawlio"], () => {
|
|
490
490
|
});
|
|
491
|
+
}).catch(() => {
|
|
491
492
|
});
|
|
492
493
|
return;
|
|
493
494
|
}
|
|
@@ -4023,9 +4024,10 @@ function createCodeModeTools(bridge2, crawlio2) {
|
|
|
4023
4024
|
}
|
|
4024
4025
|
|
|
4025
4026
|
// src/mcp-server/index.ts
|
|
4027
|
+
process.title = "Crawlio Agent";
|
|
4026
4028
|
var initMode = process.argv.includes("init") || process.argv.includes("--setup") || process.argv.includes("setup");
|
|
4027
4029
|
if (initMode) {
|
|
4028
|
-
const { runInit } = await import("./init-
|
|
4030
|
+
const { runInit } = await import("./init-X7LA5PSD.js");
|
|
4029
4031
|
await runInit(process.argv.slice(2));
|
|
4030
4032
|
process.exit(0);
|
|
4031
4033
|
}
|
|
@@ -4125,6 +4127,11 @@ async function main() {
|
|
|
4125
4127
|
const mcpServer = createMcpServer();
|
|
4126
4128
|
await mcpServer.connect(transport);
|
|
4127
4129
|
console.error("[MCP] Crawlio Browser MCP server running (stdio)");
|
|
4130
|
+
process.stdin.on("end", async () => {
|
|
4131
|
+
console.error("[MCP] stdin closed \u2014 client disconnected, shutting down");
|
|
4132
|
+
await bridge.stop();
|
|
4133
|
+
process.exit(0);
|
|
4134
|
+
});
|
|
4128
4135
|
}
|
|
4129
4136
|
}
|
|
4130
4137
|
var ALLOWED_ORIGINS = [
|
|
@@ -4217,13 +4224,19 @@ main().catch((e) => {
|
|
|
4217
4224
|
console.error("[MCP] Fatal:", e);
|
|
4218
4225
|
process.exit(1);
|
|
4219
4226
|
});
|
|
4227
|
+
process.stdout.on("error", (err) => {
|
|
4228
|
+
if (err.code === "EPIPE") return;
|
|
4229
|
+
console.error("[MCP] stdout error:", err.message);
|
|
4230
|
+
});
|
|
4231
|
+
process.stderr.on("error", () => {
|
|
4232
|
+
});
|
|
4220
4233
|
process.on("uncaughtException", (err) => {
|
|
4234
|
+
if (err.code === "EPIPE") return;
|
|
4221
4235
|
console.error("[MCP] CRASH \u2014 uncaughtException:", err.stack ?? err.message);
|
|
4222
4236
|
process.exit(1);
|
|
4223
4237
|
});
|
|
4224
4238
|
process.on("unhandledRejection", (reason) => {
|
|
4225
|
-
console.error("[MCP]
|
|
4226
|
-
process.exit(1);
|
|
4239
|
+
console.error("[MCP] unhandledRejection (non-fatal):", reason instanceof Error ? reason.message : reason);
|
|
4227
4240
|
});
|
|
4228
4241
|
for (const sig of ["SIGTERM", "SIGINT"]) {
|
|
4229
4242
|
process.on(sig, async () => {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PKG_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XNQ5PU33.js";
|
|
4
4
|
|
|
5
5
|
// src/mcp-server/init.ts
|
|
6
6
|
import { execFileSync, spawn } from "child_process";
|
|
7
|
-
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, copyFileSync } from "fs";
|
|
7
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, copyFileSync, chmodSync } from "fs";
|
|
8
8
|
import { join, resolve, dirname, sep, basename } from "path";
|
|
9
9
|
import { homedir, platform } from "os";
|
|
10
10
|
import { createServer as createNetServer } from "net";
|
|
@@ -75,6 +75,15 @@ function buildAddMcpArgs(options) {
|
|
|
75
75
|
return args;
|
|
76
76
|
}
|
|
77
77
|
function buildStdioEntry(options) {
|
|
78
|
+
if (platform() === "darwin") {
|
|
79
|
+
const serverPath = getServerEntryPath();
|
|
80
|
+
const wrapperPath = createAppWrapper(serverPath);
|
|
81
|
+
if (wrapperPath) {
|
|
82
|
+
const args2 = [];
|
|
83
|
+
if (options?.full) args2.push("--full");
|
|
84
|
+
return { command: wrapperPath, args: args2 };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
78
87
|
const args = ["-y", `crawlio-browser@${PKG_VERSION}`];
|
|
79
88
|
if (options?.full) args.push("--full");
|
|
80
89
|
return { command: "npx", args };
|
|
@@ -188,6 +197,64 @@ function resolveNodePath() {
|
|
|
188
197
|
}
|
|
189
198
|
return process.execPath;
|
|
190
199
|
}
|
|
200
|
+
function createAppWrapper(serverEntryPath) {
|
|
201
|
+
if (platform() !== "darwin") return null;
|
|
202
|
+
const crawlioDir = join(HOME, ".crawlio");
|
|
203
|
+
const appDir = join(crawlioDir, "Crawlio Agent.app");
|
|
204
|
+
const contentsDir = join(appDir, "Contents");
|
|
205
|
+
const macosDir = join(contentsDir, "MacOS");
|
|
206
|
+
const resourcesDir = join(contentsDir, "Resources");
|
|
207
|
+
const wrapperBin = join(macosDir, "crawlio-agent");
|
|
208
|
+
try {
|
|
209
|
+
mkdirSync(macosDir, { recursive: true });
|
|
210
|
+
mkdirSync(resourcesDir, { recursive: true });
|
|
211
|
+
} catch {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
215
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
216
|
+
<plist version="1.0">
|
|
217
|
+
<dict>
|
|
218
|
+
<key>CFBundleName</key>
|
|
219
|
+
<string>Crawlio Agent</string>
|
|
220
|
+
<key>CFBundleIdentifier</key>
|
|
221
|
+
<string>com.crawlio.agent</string>
|
|
222
|
+
<key>CFBundleExecutable</key>
|
|
223
|
+
<string>crawlio-agent</string>
|
|
224
|
+
<key>CFBundleIconFile</key>
|
|
225
|
+
<string>AppIcon</string>
|
|
226
|
+
<key>CFBundlePackageType</key>
|
|
227
|
+
<string>APPL</string>
|
|
228
|
+
<key>LSBackgroundOnly</key>
|
|
229
|
+
<true/>
|
|
230
|
+
</dict>
|
|
231
|
+
</plist>`;
|
|
232
|
+
try {
|
|
233
|
+
writeFileSync(join(contentsDir, "Info.plist"), plist);
|
|
234
|
+
} catch {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
238
|
+
const iconSrc = resolve(moduleDir, "..", "..", "assets", "AppIcon.icns");
|
|
239
|
+
const iconDest = join(resourcesDir, "AppIcon.icns");
|
|
240
|
+
if (existsSync(iconSrc)) {
|
|
241
|
+
try {
|
|
242
|
+
copyFileSync(iconSrc, iconDest);
|
|
243
|
+
} catch {
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const nodePath = resolveNodePath();
|
|
247
|
+
const script = `#!/bin/bash
|
|
248
|
+
exec "${nodePath}" "${serverEntryPath}" "$@"
|
|
249
|
+
`;
|
|
250
|
+
try {
|
|
251
|
+
writeFileSync(wrapperBin, script);
|
|
252
|
+
chmodSync(wrapperBin, 493);
|
|
253
|
+
} catch {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
return wrapperBin;
|
|
257
|
+
}
|
|
191
258
|
function isPortFree(port) {
|
|
192
259
|
return new Promise((resolve2) => {
|
|
193
260
|
const srv = createNetServer();
|
|
@@ -205,7 +272,7 @@ function generatePlist(nodePath, serverPath) {
|
|
|
205
272
|
<plist version="1.0">
|
|
206
273
|
<dict>
|
|
207
274
|
<key>Label</key>
|
|
208
|
-
<string>com.crawlio.
|
|
275
|
+
<string>com.crawlio.agent</string>
|
|
209
276
|
<key>ProgramArguments</key>
|
|
210
277
|
<array>
|
|
211
278
|
<string>${nodePath}</string>
|
|
@@ -242,7 +309,7 @@ async function ensurePortalRunning(dryRun) {
|
|
|
242
309
|
console.log(` ${dim("~")} Node path: ${nodePath}`);
|
|
243
310
|
console.log(` ${dim("~")} Server entry: ${serverPath}`);
|
|
244
311
|
if (platform() === "darwin") {
|
|
245
|
-
const plistPath = join(HOME, "Library/LaunchAgents/com.crawlio.
|
|
312
|
+
const plistPath = join(HOME, "Library/LaunchAgents/com.crawlio.agent.plist");
|
|
246
313
|
console.log(` ${dim("~")} Would write plist to: ${plistPath}`);
|
|
247
314
|
console.log(` ${dim("~")} Would run: launchctl load ${plistPath}`);
|
|
248
315
|
} else {
|
|
@@ -252,7 +319,7 @@ async function ensurePortalRunning(dryRun) {
|
|
|
252
319
|
}
|
|
253
320
|
if (platform() === "darwin") {
|
|
254
321
|
const plistDir = join(HOME, "Library/LaunchAgents");
|
|
255
|
-
const plistPath = join(plistDir, "com.crawlio.
|
|
322
|
+
const plistPath = join(plistDir, "com.crawlio.agent.plist");
|
|
256
323
|
const logDir = join(HOME, "Library/Logs/Crawlio");
|
|
257
324
|
mkdirSync(logDir, { recursive: true });
|
|
258
325
|
mkdirSync(plistDir, { recursive: true });
|
|
@@ -762,6 +829,7 @@ export {
|
|
|
762
829
|
buildCloudflareEntry,
|
|
763
830
|
buildPortalEntry,
|
|
764
831
|
buildStdioEntry,
|
|
832
|
+
createAppWrapper,
|
|
765
833
|
extractSkillName,
|
|
766
834
|
findConflictingConfigs,
|
|
767
835
|
findMcpConfig,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crawlio-browser",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "MCP server with 96 CDP-backed tools for browser automation — screenshots, DOM, network capture, framework detection, cookies, storage, session recording, performance metrics via Chrome",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/mcp-server/index.js",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"bin/crawlio-browser.js",
|
|
12
12
|
"dist/mcp-server/",
|
|
13
13
|
"skills/",
|
|
14
|
+
"assets/",
|
|
14
15
|
".claude-plugin/",
|
|
15
16
|
"README.md"
|
|
16
17
|
],
|