@owloops/browserbird 1.0.10 → 1.0.11

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
@@ -31,7 +31,11 @@ docker compose up -d
31
31
 
32
32
  Everything is included: agent CLI, Chromium browser, VNC, and Playwright MCP. Open `http://<host>:18800` to begin onboarding.
33
33
 
34
- The browser runs in **persistent** mode by default: logins and cookies are saved across sessions, one agent at a time. Set `BROWSER_MODE=isolated` in `.env` for parallel sessions with fresh contexts (requires container restart). `shm_size: 2g` is required for Chromium stability.
34
+ The browser runs in **persistent** mode by default: logins and cookies are saved across sessions, one agent at a time. Set `BROWSER_MODE=isolated` in `.env` for parallel sessions with fresh contexts (requires container restart).
35
+
36
+ ### Railway
37
+
38
+ [![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/browserbird)
35
39
 
36
40
  ### npm
37
41
 
package/dist/index.mjs CHANGED
@@ -122,8 +122,8 @@ function unknownSubcommand(subcommand, command, validCommands) {
122
122
  /** @fileoverview ASCII banner displayed on daemon startup and in help text. */
123
123
  const pkg = createRequire(import.meta.url)("../package.json");
124
124
  const buildInfo = [];
125
- buildInfo.push(`commit: ${"32c794e0d9ef0359a278ff184486621ac313e8ae".substring(0, 7)}`);
126
- buildInfo.push(`built: 2026-03-01T17:05:40+04:00`);
125
+ buildInfo.push(`commit: ${"319d6990795fcfce2a7df3f53b47d02c0b2af95e".substring(0, 7)}`);
126
+ buildInfo.push(`built: 2026-03-01T23:29:34+04:00`);
127
127
  const buildString = buildInfo.length > 0 ? ` (${buildInfo.join(", ")})` : "";
128
128
  const VERSION = `browserbird ${pkg.version}${buildString}`;
129
129
  const BIRD = [
@@ -292,6 +292,27 @@ function isTokenResolvable(value) {
292
292
  }
293
293
  return true;
294
294
  }
295
+ /**
296
+ * When the browser is enabled but no explicit mcpConfigPath is set, generates
297
+ * a Playwright MCP config file using novncHost as the SSE server hostname.
298
+ * Writes to `<configDir>/mcp.json` and mutates `config.browser.mcpConfigPath`.
299
+ */
300
+ function ensureMcpConfig(config, configDir) {
301
+ if (!config.browser.enabled) return;
302
+ if (config.browser.mcpConfigPath) {
303
+ if (existsSync(resolve(config.browser.mcpConfigPath))) return;
304
+ logger.warn(`mcp config not found at ${config.browser.mcpConfigPath}, regenerating`);
305
+ }
306
+ const mcpPath = resolve(configDir, "mcp.json");
307
+ const host = config.browser.novncHost || "localhost";
308
+ const mcpConfig = { mcpServers: { playwright: {
309
+ type: "sse",
310
+ url: `http://${host}:3000/sse`
311
+ } } };
312
+ writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n", "utf-8");
313
+ config.browser.mcpConfigPath = mcpPath;
314
+ logger.info(`generated mcp config at ${mcpPath} (host: ${host})`);
315
+ }
295
316
  /** Atomic write: writes to a .tmp file then renames over the target. */
296
317
  function saveConfig(configPath, data) {
297
318
  const tmp = configPath + ".tmp";
@@ -3793,11 +3814,13 @@ async function startDaemon(options) {
3793
3814
  process.stdout.write(BANNER + "\n\n");
3794
3815
  if (options.flags.verbose) logger.setLevel("debug");
3795
3816
  const configPath = resolve(options.flags.config ?? process.env["BROWSERBIRD_CONFIG"] ?? "browserbird.json");
3796
- const envPath = resolve(dirname(configPath), ".env");
3817
+ const configDir = dirname(configPath);
3818
+ const envPath = resolve(configDir, ".env");
3797
3819
  openDatabase(resolveDbPath(options.flags.db));
3798
3820
  startWorker(controller.signal);
3799
3821
  loadDotEnv(envPath);
3800
3822
  let currentConfig = loadConfig(configPath);
3823
+ ensureMcpConfig(currentConfig, configDir);
3801
3824
  let slackHandle = null;
3802
3825
  let setupMode = true;
3803
3826
  const getConfig = () => currentConfig;
@@ -3828,12 +3851,14 @@ async function startDaemon(options) {
3828
3851
  const onLaunch = async () => {
3829
3852
  loadDotEnv(envPath);
3830
3853
  const config = loadConfig(configPath);
3854
+ ensureMcpConfig(config, configDir);
3831
3855
  if (!config.slack.botToken || !config.slack.appToken) throw new Error("Slack tokens are required to launch");
3832
3856
  startFull(config);
3833
3857
  };
3834
3858
  const reloadConfig = () => {
3835
3859
  loadDotEnv(envPath);
3836
3860
  currentConfig = loadConfig(configPath);
3861
+ ensureMcpConfig(currentConfig, configDir);
3837
3862
  logger.info("config reloaded");
3838
3863
  };
3839
3864
  if (hasSlackTokens(configPath)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owloops/browserbird",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "Self-hosted AI agent for Slack with a real browser, a scheduler, and a web dashboard",
5
5
  "type": "module",
6
6
  "bin": {