@snowyroad/braid 0.79.3 → 0.79.5

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
@@ -71,6 +71,8 @@ For developing the bridge itself, see `DEVELOPMENT.md` in the repository.
71
71
  the exit-code contract, headless provider login, and troubleshooting; and
72
72
  [docs/VPS-RECIPE.md](docs/VPS-RECIPE.md) for an always-on agent on a rented box.
73
73
 
74
+ > **Run in Docker:** an official multi-arch image is published to Docker Hub (`snowyroad/braid`) and GHCR (`ghcr.io/snowy-road/braid`). See [docs/DOCKER.md](docs/DOCKER.md).
75
+
74
76
  ## Options for join/start
75
77
 
76
78
  Every knob below can be set with a flag (for the current invocation), an env var
@@ -374,7 +374,7 @@ var InviteExpiredError = class extends Error {
374
374
  }
375
375
  };
376
376
  async function redeemInvite(relayHttpUrl, code) {
377
- const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-U5DXUIMM.js");
377
+ const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-JUDUFIOQ.js");
378
378
  const r = await boundedJsonFetch2(`${relayHttpUrl.replace(/\/$/, "")}/invites/redeem`, {
379
379
  method: "POST",
380
380
  headers: { "content-type": "application/json" },
@@ -463,7 +463,7 @@ function validateReplacementToken(newToken, currentToken, nowMs = Date.now()) {
463
463
  return { ok: true };
464
464
  }
465
465
  async function mintAccessToken(relayHttpUrl, agentKey, fetchFn = fetch, dpopProof) {
466
- const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-U5DXUIMM.js");
466
+ const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-JUDUFIOQ.js");
467
467
  const r = await boundedJsonFetch2(`${relayHttpUrl.replace(/\/$/, "")}/agents/token`, {
468
468
  method: "POST",
469
469
  headers: {
@@ -971,14 +971,13 @@ function sanitizeForTty(s) {
971
971
  return s.replace(ANSI_RE, "").replace(CTRL_RE, "");
972
972
  }
973
973
  var ESC = String.fromCharCode(27);
974
- function restoreTerminal() {
975
- const out = process.stdout;
974
+ function restoreTerminal(out = process.stdout, stdin = process.stdin) {
976
975
  if (!out.isTTY) return;
977
976
  out.write(
978
- `${ESC}[?1l${ESC}>${ESC}[?25h${ESC}[?1049l${ESC}[?2004l${ESC}[?1000l${ESC}[?1002l${ESC}[?1003l${ESC}[?1006l`
977
+ `${ESC}[?1l${ESC}>${ESC}[?25h${ESC}[?1049l${ESC}[?2004l${ESC}[>4;0m${ESC}[?1000l${ESC}[?1002l${ESC}[?1003l${ESC}[?1006l`
979
978
  );
980
979
  try {
981
- if (process.stdin.isTTY) process.stdin.setRawMode(false);
980
+ if (stdin.isTTY) stdin.setRawMode?.(false);
982
981
  } catch {
983
982
  }
984
983
  }
@@ -2235,11 +2234,23 @@ function redactConfig(cfg) {
2235
2234
  }
2236
2235
  return { ...cfg, token: "<redacted>", model };
2237
2236
  }
2237
+ function buildVersion() {
2238
+ try {
2239
+ const pkg = JSON.parse(readFileSync2(new URL("../package.json", import.meta.url), "utf8"));
2240
+ return String(pkg.version ?? "");
2241
+ } catch {
2242
+ return "";
2243
+ }
2244
+ }
2238
2245
  function startingLines(cfg) {
2239
2246
  const row = (label, value) => `${label.padEnd(8)} : ${value}`;
2240
2247
  const anthropicCredential = cfg.agentMode !== "acp" || cfg.agent === "claude-code";
2241
2248
  const catchUpHours = cfg.catchUpTtlMs % 36e5 === 0 ? `${cfg.catchUpTtlMs / 36e5}h` : `${Math.round(cfg.catchUpTtlMs / 6e4)}min`;
2242
2249
  return [
2250
+ // The running braid version — the fastest way to confirm which build a live bridge
2251
+ // is (BL-229). Sourced from the runtimeVersion threaded onto config; an honest
2252
+ // placeholder shows when it could not be read, never a blank row.
2253
+ row("version", cfg.runtimeVersion ? sanitizeForTty(cfg.runtimeVersion) : "(unknown)"),
2243
2254
  row("agent", sanitizeForTty(cfg.agentName)),
2244
2255
  row("relay", sanitizeForTty(cfg.relayWsUrl)),
2245
2256
  row("provider", cfg.agentMode === "acp" ? cfg.agent : "bundled SDK (generic mode)"),
@@ -2492,5 +2503,6 @@ export {
2492
2503
  validateRelayWsUrl,
2493
2504
  wsToHttp,
2494
2505
  resolveConfig,
2506
+ buildVersion,
2495
2507
  startingLines
2496
2508
  };
package/dist/cli.js CHANGED
@@ -26,6 +26,7 @@ import {
26
26
  acquireAgentLock,
27
27
  assertKeystorePerms,
28
28
  boundedJsonFetch,
29
+ buildVersion,
29
30
  classifyFatal,
30
31
  cleanContent,
31
32
  configDir,
@@ -66,7 +67,7 @@ import {
66
67
  validateReplacementToken,
67
68
  verifyCardSignature,
68
69
  wsToHttp
69
- } from "./chunk-SKUYOAV5.js";
70
+ } from "./chunk-M5WUSDQN.js";
70
71
 
71
72
  // src/health.ts
72
73
  var CEILING_STRIKES_TO_DEAD = 3;
@@ -7705,6 +7706,7 @@ async function runHandoff(opts) {
7705
7706
  });
7706
7707
  });
7707
7708
  } finally {
7709
+ restoreTerminal();
7708
7710
  await session.handoffResume();
7709
7711
  out.write(`
7710
7712
  [handoff] resumed driving ${label}
@@ -7762,7 +7764,7 @@ async function runHandoffCommand(opts) {
7762
7764
  const socket = connectFn(sockPath);
7763
7765
  const lc = lineClient(socket);
7764
7766
  try {
7765
- return opts.recover ? await runRecover(lc, { write, promptFn, token, name: safeName }) : await runTakeover(lc, { write, promptFn, token, name: safeName, env, spawnFn, channel: opts.channel });
7767
+ return opts.recover ? await runRecover(lc, { write, promptFn, token, name: safeName }) : await runTakeover(lc, { write, promptFn, token, name: safeName, env, spawnFn, channel: opts.channel, stdin, stdout });
7766
7768
  } catch (err) {
7767
7769
  write(`[handoff] control socket error: ${sanitizeForTty(String(err?.message ?? err))}
7768
7770
  `);
@@ -7775,7 +7777,7 @@ async function runHandoffCommand(opts) {
7775
7777
  }
7776
7778
  }
7777
7779
  async function runTakeover(lc, ctx) {
7778
- const { write, promptFn, token, name, env, spawnFn, channel } = ctx;
7780
+ const { write, promptFn, token, name, env, spawnFn, channel, stdin, stdout } = ctx;
7779
7781
  lc.send({ verb: "handoff", ...token ? { token } : {} });
7780
7782
  const first = await lc.next();
7781
7783
  if (typeof first["error"] === "string") return reportError(write, first["error"], name);
@@ -7830,6 +7832,7 @@ async function runTakeover(lc, ctx) {
7830
7832
  settle({ error: e });
7831
7833
  }
7832
7834
  });
7835
+ restoreTerminal(stdout, stdin);
7833
7836
  await sendDone();
7834
7837
  if (outcome.error) {
7835
7838
  write(`[handoff] failed to open the session: ${sanitizeForTty(String(outcome.error.message ?? outcome.error))}
@@ -9489,12 +9492,7 @@ async function main() {
9489
9492
  process.exit(1);
9490
9493
  }
9491
9494
  if (invocation.kind === "version") {
9492
- try {
9493
- const pkg = JSON.parse(readFileSync9(new URL("../package.json", import.meta.url), "utf8"));
9494
- console.log(String(pkg.version ?? "unknown"));
9495
- } catch {
9496
- console.log("unknown");
9497
- }
9495
+ console.log(buildVersion() || "unknown");
9498
9496
  return;
9499
9497
  }
9500
9498
  if (invocation.kind === "list") {
@@ -9569,11 +9567,7 @@ async function main() {
9569
9567
  homeDir: process.env.HOME ?? homedir7()
9570
9568
  });
9571
9569
  }
9572
- try {
9573
- const pkg = JSON.parse(readFileSync9(new URL("../package.json", import.meta.url), "utf8"));
9574
- cfg.runtimeVersion = String(pkg.version ?? "");
9575
- } catch {
9576
- }
9570
+ cfg.runtimeVersion = buildVersion();
9577
9571
  {
9578
9572
  const dir = configDir(process.env);
9579
9573
  let file = "";
@@ -4,7 +4,7 @@ import {
4
4
  boundedJsonFetch,
5
5
  resetHttpMetricsForTest,
6
6
  snapshotHttpMetrics
7
- } from "./chunk-SKUYOAV5.js";
7
+ } from "./chunk-M5WUSDQN.js";
8
8
  export {
9
9
  assertHttpEndpoint,
10
10
  boundedJsonFetch,
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@snowyroad/braid",
3
- "version": "0.79.3",
3
+ "version": "0.79.5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@snowyroad/braid",
9
- "version": "0.79.3",
9
+ "version": "0.79.5",
10
10
  "license": "SEE LICENSE IN LICENSE.md",
11
11
  "dependencies": {
12
12
  "@agentclientprotocol/sdk": "0.25.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snowyroad/braid",
3
- "version": "0.79.3",
3
+ "version": "0.79.5",
4
4
  "description": "Braid: connect your own coding agent (Claude Code, Codex, Gemini, Grok) to a Braid channel and collaborate with other agents and humans.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "SnowyRoad",