@bondsmith/bondsmithd 0.1.1 → 0.1.2

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.
Files changed (3) hide show
  1. package/README.md +6 -5
  2. package/dist/index.js +55 -14
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -37,7 +37,7 @@ Environment variables (all optional):
37
37
  ```
38
38
  PORT=4577 # defaults to 4577
39
39
  ALLOWED_ORIGINS=https://app.bondsmith.dev
40
- BONDSMITH_RELAY_URL=wss://relay.bondsmith.dev # defaults to a local-only address; set this for a real install
40
+ BONDSMITH_RELAY_URL=ws://127.0.0.1:8787 # defaults to production; set this when developing bondsmithd against a local apps/relay
41
41
  ```
42
42
 
43
43
  `BONDSMITH_DEV_TUNNEL_TOKEN` also exists but only applies to the legacy direct-connection path
@@ -54,10 +54,11 @@ BONDSMITH_RELAY_URL=wss://relay.bondsmith.dev # defaults to a local-only address
54
54
 
55
55
  ## Production connectivity (current status)
56
56
 
57
- `bondsmithd` connects outbound to the Bondsmith relay by default (`BONDSMITH_RELAY_ENABLED=true`),
58
- which is what a production account actually uses — no dev-tunnel token involved. Point
59
- `BONDSMITH_RELAY_URL` at `wss://relay.bondsmith.dev` for a real install (see "Environment
60
- variables" above); it defaults to a local-only address for monorepo development.
57
+ `bondsmithd` connects outbound to the Bondsmith relay by default (`BONDSMITH_RELAY_ENABLED=true`,
58
+ `BONDSMITH_RELAY_URL=wss://relay.bondsmith.dev`), which is what a production account actually
59
+ uses — no dev-tunnel token involved, no config needed for a real install. Override
60
+ `BONDSMITH_RELAY_URL` to a local apps/relay instance (see "Environment variables" above) only when
61
+ developing bondsmithd itself.
61
62
 
62
63
  The dev-tunnel-token requirement only applies to the legacy direct-connection path
63
64
  (`BONDSMITH_RELAY_ENABLED=false`), which still 404s the token-handoff route in production by
package/dist/index.js CHANGED
@@ -508,18 +508,19 @@ var environmentSchema = z8.object({
508
508
  // install needs to touch.
509
509
  BONDSMITH_BIND_HOST: z8.string().min(1).default("127.0.0.1"),
510
510
  // BD-450/BD-483/BD-484: connect outbound to the Bondsmith relay instead of
511
- // (or alongside) listening inbound. ON by default — local dev is meant to
512
- // mirror production's actual topology (browser -> relay -> daemon), not
513
- // diverge from it, so plain `pnpm --filter @bondsmith/bondsmithd dev`
514
- // connects outbound to a locally-running apps/relay (its own `pnpm dev`
515
- // on the default port below) exactly like a real deployment would.
516
- // BONDSMITH_RELAY_URL defaults to that same local apps/relay instance for
517
- // the same reason. The existing inbound listener is completely
518
- // unaffected either way — it keeps running regardless, so direct-
519
- // connection debugging (bypassing the relay entirely) is still possible
520
- // by setting BONDSMITH_RELAY_ENABLED=false explicitly.
511
+ // (or alongside) listening inbound. ON by default. The existing inbound
512
+ // listener is completely unaffected either way — it keeps running
513
+ // regardless, so direct-connection debugging (bypassing the relay
514
+ // entirely) is still possible by setting BONDSMITH_RELAY_ENABLED=false
515
+ // explicitly.
521
516
  BONDSMITH_RELAY_ENABLED: z8.string().default("true").transform((value) => value === "true" || value === "1"),
522
- BONDSMITH_RELAY_URL: z8.string().url().default("ws://127.0.0.1:8787")
517
+ // Defaults to production, mirroring BONDSMITH_API_URL above, so a real
518
+ // install works with zero config — a bare `bondsmithd` used to silently
519
+ // connect outbound to loopback (nothing listening there) with no error,
520
+ // looking healthy while never reaching relay at all. Override to a local
521
+ // apps/relay instance (its own `pnpm dev` default port) when developing
522
+ // bondsmithd itself against a local relay.
523
+ BONDSMITH_RELAY_URL: z8.string().url().default("wss://relay.bondsmith.dev")
523
524
  });
524
525
  function getDaemonConfig(env = process.env) {
525
526
  const parsed = environmentSchema.parse(env);
@@ -763,6 +764,27 @@ var TmuxNoServerRunningError = class extends Error {
763
764
  this.name = "TmuxNoServerRunningError";
764
765
  }
765
766
  };
767
+ var TmuxNotFoundError = class extends Error {
768
+ constructor() {
769
+ super(
770
+ [
771
+ "bondsmithd requires tmux, and it was not found on PATH.",
772
+ "",
773
+ "Install it:",
774
+ " macOS (Homebrew): brew install tmux",
775
+ " Debian/Ubuntu: sudo apt-get install tmux",
776
+ " Fedora/RHEL: sudo dnf install tmux",
777
+ " Arch: sudo pacman -S tmux",
778
+ "",
779
+ "If tmux is already installed, start bondsmithd from a normal interactive shell \u2014",
780
+ "not a LaunchAgent, Docker container, or other minimal-PATH context. Those often",
781
+ "don't inherit the PATH tmux was installed into (e.g. Homebrew's /opt/homebrew/bin",
782
+ "on Apple Silicon)."
783
+ ].join("\n")
784
+ );
785
+ this.name = "TmuxNotFoundError";
786
+ }
787
+ };
766
788
  var SENSITIVE_ENV_KEYS = ["ANTHROPIC_API_KEY", "BONDSMITH_DEV_TUNNEL_TOKEN"];
767
789
  function filterSpawnEnv(env) {
768
790
  const filtered = { ...env };
@@ -770,8 +792,13 @@ function filterSpawnEnv(env) {
770
792
  return filtered;
771
793
  }
772
794
  async function runTmux(args, options) {
773
- const { stdout } = await execFile("tmux", args, { ...options, encoding: "utf8" });
774
- return stdout;
795
+ try {
796
+ const { stdout } = await execFile("tmux", args, { ...options, encoding: "utf8" });
797
+ return stdout;
798
+ } catch (error2) {
799
+ if (error2?.code === "ENOENT") throw new TmuxNotFoundError();
800
+ throw error2;
801
+ }
775
802
  }
776
803
  async function sendKeysLiteral(tmuxSessionName, text) {
777
804
  await runTmux(["send-keys", "-t", tmuxSessionName, "-l", text]);
@@ -2346,7 +2373,12 @@ var PtyAttachmentManager = class {
2346
2373
  cwd: process.env.HOME,
2347
2374
  env: filterSpawnEnv(process.env)
2348
2375
  });
2349
- } catch {
2376
+ } catch (error2) {
2377
+ if (error2?.code === "ENOENT") {
2378
+ console.error(`
2379
+ ${new TmuxNotFoundError().message}
2380
+ `);
2381
+ }
2350
2382
  return false;
2351
2383
  }
2352
2384
  handle = { process: ptyProcess, refCount: 0, dataListeners: /* @__PURE__ */ new Set() };
@@ -2505,6 +2537,12 @@ async function discoverSessions() {
2505
2537
  return Promise.all(sessions.map((session) => enrichSessionWithGitMetadata(session)));
2506
2538
  } catch (error2) {
2507
2539
  if (error2 instanceof TmuxNoServerRunningError) return [];
2540
+ if (error2 instanceof TmuxNotFoundError) {
2541
+ console.error(`
2542
+ ${error2.message}
2543
+ `);
2544
+ process.exit(1);
2545
+ }
2508
2546
  throw error2;
2509
2547
  }
2510
2548
  }
@@ -2568,6 +2606,9 @@ var SessionManager = class {
2568
2606
  const output = await listTmuxSessions("#{session_name}");
2569
2607
  liveSessionNames = new Set(output.split("\n").filter((name) => name.length > 0));
2570
2608
  } catch (error2) {
2609
+ if (error2 instanceof TmuxNotFoundError) console.error(`
2610
+ ${error2.message}
2611
+ `);
2571
2612
  if (!(error2 instanceof TmuxNoServerRunningError)) return;
2572
2613
  }
2573
2614
  await Promise.all(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bondsmith/bondsmithd",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "private": false,
5
5
  "description": "Local daemon for Bondsmith agent sessions — runs on the user's own machine, pairs with a Bondsmith account, and exposes tmux-backed terminal sessions to the Bondsmith web app over a signed WebSocket protocol.",
6
6
  "homepage": "https://bondsmith.dev",