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
@@ -1,7 +1,7 @@
1
1
  // src/shared/constants.ts
2
2
  import { homedir } from "os";
3
3
  import { join } from "path";
4
- var PKG_VERSION = "1.4.1";
4
+ var PKG_VERSION = "1.4.3";
5
5
  var WS_PORT = 9333;
6
6
  var WS_HOST = "127.0.0.1";
7
7
  var CRAWLIO_PORT_FILE = join(
@@ -7,7 +7,7 @@ import {
7
7
  WS_PORT,
8
8
  WS_RECONNECT_GRACE,
9
9
  WS_STALE_THRESHOLD
10
- } from "./chunk-DUJTVASE.js";
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-EJMNI6KH.js");
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] CRASH \u2014 unhandledRejection:", reason instanceof Error ? reason.stack ?? reason.message : reason);
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-DUJTVASE.js";
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.browser</string>
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.browser.plist");
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.browser.plist");
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.1",
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
  ],