@snowyroad/braid 0.84.1 → 0.86.0

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.
@@ -389,7 +389,7 @@ var InviteExpiredError = class extends Error {
389
389
  }
390
390
  };
391
391
  async function redeemInvite(relayHttpUrl, code) {
392
- const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-SXNTO4ON.js");
392
+ const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-LZV3OAR2.js");
393
393
  const r = await boundedJsonFetch2(`${relayHttpUrl.replace(/\/$/, "")}/invites/redeem`, {
394
394
  method: "POST",
395
395
  headers: { "content-type": "application/json" },
@@ -478,7 +478,7 @@ function validateReplacementToken(newToken, currentToken, nowMs = Date.now()) {
478
478
  return { ok: true };
479
479
  }
480
480
  async function mintAccessToken(relayHttpUrl, agentKey, fetchFn = fetch, dpopProof) {
481
- const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-SXNTO4ON.js");
481
+ const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-LZV3OAR2.js");
482
482
  const r = await boundedJsonFetch2(`${relayHttpUrl.replace(/\/$/, "")}/agents/token`, {
483
483
  method: "POST",
484
484
  headers: {
@@ -3120,6 +3120,27 @@ var RelayClient = class {
3120
3120
  // single-shot: onReady has fired (relay accepted the agent)
3121
3121
  reconnectAnnounced = false;
3122
3122
  // per-connection: "reconnected" printed for this connection
3123
+ connEventCb = null;
3124
+ /** Subscribe the connection-status sink (single subscriber, like onReady). When set,
3125
+ * the seven legacy per-event console lines are suppressed: the sink owns presentation
3126
+ * (connStatus.ts aggregates episodes + applies verbosity). When absent, behavior is
3127
+ * byte-identical to before (plain per-event lines). */
3128
+ onConnEvent(cb) {
3129
+ this.connEventCb = cb;
3130
+ }
3131
+ reportConn(e, legacy) {
3132
+ if (this.connEventCb) this.connEventCb(e);
3133
+ else legacy?.();
3134
+ }
3135
+ /** Current token's JWT exp (epoch seconds), for status display. Non-JWT/garbage -> undefined. */
3136
+ tokenExpSeconds() {
3137
+ try {
3138
+ const exp = decodeJwt(this.cfg.token).exp;
3139
+ return typeof exp === "number" ? exp : void 0;
3140
+ } catch {
3141
+ return void 0;
3142
+ }
3143
+ }
3123
3144
  catchUpCbs = [];
3124
3145
  caughtUp = /* @__PURE__ */ new Set();
3125
3146
  // channels caught up this connection
@@ -3298,9 +3319,9 @@ var RelayClient = class {
3298
3319
  sock.terminate();
3299
3320
  } catch {
3300
3321
  }
3301
- console.log(
3322
+ this.reportConn({ kind: "connectTimeout", timeoutSecs: CONNECT_TIMEOUT_MS / 1e3 }, () => console.log(
3302
3323
  `[braid] connect attempt timed out after ${CONNECT_TIMEOUT_MS / 1e3}s (socket accepted but the relay never completed the handshake); retrying`
3303
- );
3324
+ ));
3304
3325
  const delay2 = this.backoffDelay();
3305
3326
  this.reconnectAttempts++;
3306
3327
  this.reconnectTimer = setTimeout(() => {
@@ -3337,12 +3358,13 @@ var RelayClient = class {
3337
3358
  if (this.confirmed) {
3338
3359
  if (!this.reconnectAnnounced) {
3339
3360
  this.reconnectAnnounced = true;
3340
- console.log("[braid] reconnected");
3361
+ this.reportConn({ kind: "reconnected", tokenExp: this.tokenExpSeconds() }, () => console.log("[braid] reconnected"));
3341
3362
  this.connectedCb?.();
3342
3363
  }
3343
3364
  return;
3344
3365
  }
3345
3366
  this.confirmed = true;
3367
+ this.reportConn({ kind: "connected", tokenExp: this.tokenExpSeconds() });
3346
3368
  this.readyCb?.();
3347
3369
  this.connectedCb?.();
3348
3370
  }
@@ -3491,9 +3513,12 @@ var RelayClient = class {
3491
3513
  onClose(code, reason) {
3492
3514
  this.clearTimers();
3493
3515
  if (this.stopped) return;
3494
- console.log(`[braid] disconnected (close ${code})${reason ? `: ${sanitizeForTty(reason)}` : ""}`);
3516
+ this.reportConn(
3517
+ { kind: "disconnected", code, reason: reason ? sanitizeForTty(reason) : "" },
3518
+ () => console.log(`[braid] disconnected (close ${code})${reason ? `: ${sanitizeForTty(reason)}` : ""}`)
3519
+ );
3495
3520
  if (code === 4001 && this.cfg.mintToken) {
3496
- console.log("[braid] access token rejected; re-minting from agent key");
3521
+ this.reportConn({ kind: "remintStarted" }, () => console.log("[braid] access token rejected; re-minting from agent key"));
3497
3522
  this.attemptRemint(code);
3498
3523
  return;
3499
3524
  }
@@ -3654,7 +3679,7 @@ var RelayClient = class {
3654
3679
  return;
3655
3680
  }
3656
3681
  this.cfg.token = token;
3657
- console.log("[braid] token proactively re-minted before expiry");
3682
+ this.reportConn({ kind: "tokenReminted", tokenExp: this.tokenExpSeconds() }, () => console.log("[braid] token proactively re-minted before expiry"));
3658
3683
  this.scheduleTokenRefresh();
3659
3684
  }
3660
3685
  stop() {
@@ -3699,7 +3724,7 @@ var RelayClient = class {
3699
3724
  }
3700
3725
  this.cfg.token = msg.token;
3701
3726
  this.scheduleTokenRefresh();
3702
- console.log("[braid] token refreshed");
3727
+ this.reportConn({ kind: "tokenRefreshed", tokenExp: this.tokenExpSeconds() }, () => console.log("[braid] token refreshed"));
3703
3728
  break;
3704
3729
  }
3705
3730
  case "removed": {
package/dist/cli.js CHANGED
@@ -70,7 +70,7 @@ import {
70
70
  toolStatusLine,
71
71
  validateRelayWsUrl,
72
72
  wsToHttp
73
- } from "./chunk-PQGSJM2V.js";
73
+ } from "./chunk-XENNQYCX.js";
74
74
  import {
75
75
  externalSourceLabel,
76
76
  externalUntrustedPreamble,
@@ -2902,7 +2902,9 @@ Options for join/start (each also has an env twin; flag > env > file > default):
2902
2902
  --allow-read <path> widen sandbox read access (repeatable)
2903
2903
  --allow-domain <host> widen sandbox network egress (repeatable)
2904
2904
  --no-socket do not open the local control socket (on by default)
2905
- --verbose print the full posture detail during the guided first-run
2905
+ --verbose print every connection lifecycle event (token refreshes, each
2906
+ disconnect) instead of the default per-episode summaries; also
2907
+ prints the full posture detail during the guided first-run
2906
2908
  setup (an interactive first start walks provider/permission
2907
2909
  prompts and offers to keep the agent running in the
2908
2910
  background; details any time via: braid status <name>)
@@ -5502,6 +5504,225 @@ function installTee(outWriter, errWriter) {
5502
5504
 
5503
5505
  // src/cli.ts
5504
5506
  import { homedir as homedir6 } from "os";
5507
+
5508
+ // src/connStatus.ts
5509
+ var ESCALATE_FIRST_MS = 6e4;
5510
+ var ESCALATE_REPEAT_MS = 3e5;
5511
+ function fmtDur(ms) {
5512
+ const s = Math.max(0, Math.floor(ms / 1e3));
5513
+ if (s < 60) return `${s}s`;
5514
+ const m = Math.floor(s / 60);
5515
+ if (m < 60) return `${m}m${String(s % 60).padStart(2, "0")}s`;
5516
+ return `${Math.floor(m / 60)}h${String(m % 60).padStart(2, "0")}m`;
5517
+ }
5518
+ function fmtClock(epochMs) {
5519
+ const d = new Date(epochMs);
5520
+ return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
5521
+ }
5522
+ function plural(n, one, many) {
5523
+ return `${n} ${n === 1 ? one : many}`;
5524
+ }
5525
+ function createConnStatus(opts) {
5526
+ const now = opts.now ?? Date.now;
5527
+ const startedAt = now();
5528
+ let state = "starting";
5529
+ let connectedSince = null;
5530
+ let offlineSince = null;
5531
+ let attempts = 0;
5532
+ let reconnects = 0;
5533
+ let lastReconnectAt = null;
5534
+ let tokenExp = null;
5535
+ let lastCloseCode = null;
5536
+ let nextEscalateAt = null;
5537
+ function noteDrop() {
5538
+ if (state !== "offline") {
5539
+ offlineSince = now();
5540
+ attempts = 0;
5541
+ nextEscalateAt = offlineSince + ESCALATE_FIRST_MS;
5542
+ }
5543
+ state = "offline";
5544
+ connectedSince = null;
5545
+ attempts++;
5546
+ }
5547
+ function closeEpisode(t) {
5548
+ if (offlineSince === null || attempts === 0) return null;
5549
+ const down = fmtDur(t - offlineSince);
5550
+ const suffix = attempts > 1 ? `${down}, ${plural(attempts, "attempt", "attempts")}` : down;
5551
+ offlineSince = null;
5552
+ nextEscalateAt = null;
5553
+ return suffix;
5554
+ }
5555
+ function adoptExp(exp) {
5556
+ if (exp !== void 0) tokenExp = exp;
5557
+ }
5558
+ function handle(e) {
5559
+ switch (e.kind) {
5560
+ case "connected": {
5561
+ const t = now();
5562
+ const hadRetries = offlineSince !== null && attempts > 0;
5563
+ const n = attempts;
5564
+ const since = offlineSince;
5565
+ const ep = closeEpisode(t);
5566
+ state = "connected";
5567
+ connectedSince = t;
5568
+ adoptExp(e.tokenExp);
5569
+ if (hadRetries && ep !== null && since !== null) {
5570
+ opts.log(`[braid] connected (after ${plural(n, "attempt", "attempts")}, ${fmtDur(t - since)})`);
5571
+ }
5572
+ break;
5573
+ }
5574
+ case "reconnected": {
5575
+ const t = now();
5576
+ const ep = closeEpisode(t);
5577
+ state = "connected";
5578
+ connectedSince = t;
5579
+ reconnects++;
5580
+ lastReconnectAt = t;
5581
+ adoptExp(e.tokenExp);
5582
+ opts.log(`[braid] reconnected${ep !== null ? ` (offline ${ep})` : ""}`);
5583
+ break;
5584
+ }
5585
+ case "disconnected":
5586
+ lastCloseCode = e.code;
5587
+ noteDrop();
5588
+ if (opts.verbose) {
5589
+ opts.log(`[braid] disconnected (close ${e.code})${e.reason ? `: ${e.reason}` : ""}`);
5590
+ }
5591
+ break;
5592
+ case "connectTimeout":
5593
+ noteDrop();
5594
+ if (opts.verbose) {
5595
+ opts.log(
5596
+ `[braid] connect attempt timed out after ${e.timeoutSecs}s (socket accepted but the relay never completed the handshake); retrying`
5597
+ );
5598
+ }
5599
+ break;
5600
+ case "remintStarted":
5601
+ if (opts.verbose) opts.log("[braid] access token rejected; re-minting from agent key");
5602
+ break;
5603
+ case "tokenRefreshed":
5604
+ adoptExp(e.tokenExp);
5605
+ if (opts.verbose) opts.log("[braid] token refreshed");
5606
+ break;
5607
+ case "tokenReminted":
5608
+ adoptExp(e.tokenExp);
5609
+ if (opts.verbose) opts.log("[braid] token proactively re-minted before expiry");
5610
+ break;
5611
+ }
5612
+ }
5613
+ function tick() {
5614
+ if (state !== "offline" || offlineSince === null || nextEscalateAt === null) return;
5615
+ const t = now();
5616
+ if (t >= nextEscalateAt) {
5617
+ opts.warn(
5618
+ `[braid] still reconnecting: offline ${fmtDur(t - offlineSince)} (${plural(attempts, "attempt", "attempts")})`
5619
+ );
5620
+ nextEscalateAt = t + ESCALATE_REPEAT_MS;
5621
+ }
5622
+ }
5623
+ function snapshot() {
5624
+ return { state, startedAt, connectedSince, offlineSince, attempts, reconnects, lastReconnectAt, tokenExp, lastCloseCode };
5625
+ }
5626
+ return { handle, tick, snapshot };
5627
+ }
5628
+
5629
+ // src/statusLine.ts
5630
+ var ESC = String.fromCharCode(27);
5631
+ var CLEAR = `\r${ESC}[2K`;
5632
+ var RAW_QUIESCE_MS = 2e3;
5633
+ function createStickyLine(out, now = Date.now) {
5634
+ const enabled = out.isTTY === true;
5635
+ let last = "";
5636
+ let painted = false;
5637
+ let paused = false;
5638
+ let stopped = false;
5639
+ let lastRawWriteAt = -Infinity;
5640
+ const width = () => typeof out.columns === "number" && out.columns > 0 ? out.columns : 80;
5641
+ const active = () => enabled && !stopped && !paused;
5642
+ return {
5643
+ enabled,
5644
+ render(line) {
5645
+ if (!active()) return;
5646
+ last = line.slice(0, Math.max(0, width() - 1));
5647
+ out.write(`${CLEAR}${last}`);
5648
+ painted = true;
5649
+ },
5650
+ repaint() {
5651
+ if (!active() || last === "") return;
5652
+ out.write(`${CLEAR}${last}`);
5653
+ painted = true;
5654
+ },
5655
+ clearIfPainted() {
5656
+ if (!enabled || stopped || !painted) return;
5657
+ out.write(CLEAR);
5658
+ painted = false;
5659
+ },
5660
+ noteRawWrite() {
5661
+ this.clearIfPainted();
5662
+ lastRawWriteAt = now();
5663
+ },
5664
+ quiesced() {
5665
+ return now() - lastRawWriteAt >= RAW_QUIESCE_MS;
5666
+ },
5667
+ pause() {
5668
+ if (!enabled || stopped || paused) return;
5669
+ this.clearIfPainted();
5670
+ paused = true;
5671
+ },
5672
+ resume() {
5673
+ paused = false;
5674
+ },
5675
+ stop() {
5676
+ if (enabled && !stopped) this.clearIfPainted();
5677
+ stopped = true;
5678
+ }
5679
+ };
5680
+ }
5681
+ function installConsoleBridge(sticky) {
5682
+ const orig = { log: console.log, warn: console.warn, error: console.error };
5683
+ const wrap = (fn) => (...a) => {
5684
+ sticky.clearIfPainted();
5685
+ fn(...a);
5686
+ sticky.repaint();
5687
+ };
5688
+ console.log = wrap(orig.log.bind(console));
5689
+ console.warn = wrap(orig.warn.bind(console));
5690
+ console.error = wrap(orig.error.bind(console));
5691
+ return () => {
5692
+ console.log = orig.log;
5693
+ console.warn = orig.warn;
5694
+ console.error = orig.error;
5695
+ };
5696
+ }
5697
+ function stickyWriteThrough(sticky, real) {
5698
+ return {
5699
+ isTTY: real.isTTY,
5700
+ write(s) {
5701
+ sticky.noteRawWrite();
5702
+ real.write(s);
5703
+ }
5704
+ };
5705
+ }
5706
+ function formatStatusLine(s, agentName, now) {
5707
+ const name = sanitizeForTty(agentName) || "agent";
5708
+ if (s.state === "connected" && s.connectedSince !== null) {
5709
+ const parts = [`\u25CF braid \xB7 ${name}`, "connected", `up ${fmtDur(now - s.startedAt)}`];
5710
+ if (s.reconnects > 0 && s.lastReconnectAt !== null) {
5711
+ parts.push(`${s.reconnects} ${s.reconnects === 1 ? "reconnect" : "reconnects"} (last ${fmtClock(s.lastReconnectAt)})`);
5712
+ }
5713
+ if (s.tokenExp !== null) {
5714
+ const left = s.tokenExp * 1e3 - now;
5715
+ parts.push(left > 0 ? `token expires in ${fmtDur(left)}` : "token renewing");
5716
+ }
5717
+ return parts.join(" \xB7 ");
5718
+ }
5719
+ if (s.state === "offline" && s.offlineSince !== null) {
5720
+ return `\u25CC braid \xB7 ${name} \xB7 reconnecting: offline ${fmtDur(now - s.offlineSince)} (attempt ${s.attempts})`;
5721
+ }
5722
+ return `\u25CC braid \xB7 ${name} \xB7 connecting\u2026`;
5723
+ }
5724
+
5725
+ // src/cli.ts
5505
5726
  function printList() {
5506
5727
  console.log(formatAgentList(listAgents(configDir(process.env))));
5507
5728
  }
@@ -6039,6 +6260,22 @@ async function main() {
6039
6260
  await initScopeRuntime(cfg, cfg.agent);
6040
6261
  console.log(banner("braid", "SCOPE", resolveScope(cfg, cfg.agent, process.env).describe()));
6041
6262
  }
6263
+ const runVerbose = invocation.argv.includes("--verbose");
6264
+ const sticky = createStickyLine(process.stdout);
6265
+ const connStatus = createConnStatus({
6266
+ verbose: runVerbose,
6267
+ log: (l) => console.log(l),
6268
+ warn: (l) => console.warn(l)
6269
+ });
6270
+ const restoreConsole = sticky.enabled ? installConsoleBridge(sticky) : null;
6271
+ const statusTimer = setInterval(() => {
6272
+ connStatus.tick();
6273
+ if (sticky.enabled && sticky.quiesced()) {
6274
+ sticky.render(formatStatusLine(connStatus.snapshot(), cfg.agentName ?? "", Date.now()));
6275
+ }
6276
+ }, 1e3);
6277
+ statusTimer.unref?.();
6278
+ process.on("exit", () => sticky.stop());
6042
6279
  console.log("[braid] connecting to the relay...");
6043
6280
  const keysLive = attachEligible(process.stdin, process.stdout, process.env);
6044
6281
  const serviceEligible = process.env.BRAID_SERVICE !== "1" && !!cfg.agentName;
@@ -6090,6 +6327,7 @@ async function main() {
6090
6327
  telemetry,
6091
6328
  onRelayCreated: (relay) => {
6092
6329
  relayRef.current = relay;
6330
+ relay.onConnEvent((e) => connStatus.handle(e));
6093
6331
  }
6094
6332
  });
6095
6333
  if (cfg.runtimeVersion) {
@@ -6099,6 +6337,9 @@ async function main() {
6099
6337
  installGracefulShutdown(bridge, {
6100
6338
  agentName: cfg.agentName,
6101
6339
  beforeDrain: () => {
6340
+ clearInterval(statusTimer);
6341
+ restoreConsole?.();
6342
+ sticky.stop();
6102
6343
  attach?.stop();
6103
6344
  void bridge.controlSocketClose?.();
6104
6345
  resetScope();
@@ -6114,7 +6355,7 @@ async function main() {
6114
6355
  listChannels: () => [...bridge.sessions.keys()],
6115
6356
  channelName: (channelId) => bridge.channelNames.get(channelId),
6116
6357
  stdin: process.stdin,
6117
- stdout: process.stdout,
6358
+ stdout: stickyWriteThrough(sticky, process.stdout),
6118
6359
  onInterrupt: () => {
6119
6360
  try {
6120
6361
  process.kill(process.pid, "SIGINT");
@@ -6125,21 +6366,26 @@ async function main() {
6125
6366
  // Pause the headless driver for this channel, open the real `claude --resume <id>` on the
6126
6367
  // owner's terminal (same conversation), and resume driving when they quit it.
6127
6368
  handoff: async (channelId, out) => {
6128
- const session = bridge.sessions.get(channelId);
6129
- if (!session) {
6130
- out.write("\n[handoff] that session is no longer active\n");
6131
- return;
6132
- }
6133
- if (!handoffGate.tryAcquire(channelId, "terminal")) {
6134
- const g = handoffGate.snapshot();
6135
- out.write(g.state === "orphaned" ? `
6136
- [handoff] a previous handoff was orphaned - run: braid handoff ${cfg.agentName ?? ""} --recover`.trimEnd() + "\n" : "\n[handoff] another handoff is already in progress\n");
6137
- return;
6138
- }
6369
+ sticky.pause();
6139
6370
  try {
6140
- await runHandoff({ channelId, provider: cfg.agent, session, cwd: handoffCwdFor(cfg, channelId), out, channelLabel: channelLabel(channelId), scope: cfg.scope });
6371
+ const session = bridge.sessions.get(channelId);
6372
+ if (!session) {
6373
+ out.write("\n[handoff] that session is no longer active\n");
6374
+ return;
6375
+ }
6376
+ if (!handoffGate.tryAcquire(channelId, "terminal")) {
6377
+ const g = handoffGate.snapshot();
6378
+ out.write(g.state === "orphaned" ? `
6379
+ [handoff] a previous handoff was orphaned - run: braid handoff ${cfg.agentName ?? ""} --recover`.trimEnd() + "\n" : "\n[handoff] another handoff is already in progress\n");
6380
+ return;
6381
+ }
6382
+ try {
6383
+ await runHandoff({ channelId, provider: cfg.agent, session, cwd: handoffCwdFor(cfg, channelId), out, channelLabel: channelLabel(channelId), scope: cfg.scope });
6384
+ } finally {
6385
+ handoffGate.release();
6386
+ }
6141
6387
  } finally {
6142
- handoffGate.release();
6388
+ sticky.resume();
6143
6389
  }
6144
6390
  }
6145
6391
  });
@@ -4,7 +4,7 @@ import {
4
4
  boundedJsonFetch,
5
5
  resetHttpMetricsForTest,
6
6
  snapshotHttpMetrics
7
- } from "./chunk-PQGSJM2V.js";
7
+ } from "./chunk-XENNQYCX.js";
8
8
  import "./chunk-BDOF72CL.js";
9
9
  export {
10
10
  assertHttpEndpoint,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snowyroad/braid",
3
- "version": "0.84.1",
3
+ "version": "0.86.0",
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",
@@ -51,7 +51,7 @@
51
51
  "@anthropic-ai/sandbox-runtime": "0.0.63",
52
52
  "@anthropic-ai/sdk": "0.104.1",
53
53
  "@modelcontextprotocol/sdk": "1.29.0",
54
- "@snowyroad/braid-tui": "0.0.22",
54
+ "@snowyroad/braid-tui": "0.0.25",
55
55
  "canonicalize": "^3.0.0",
56
56
  "jose": "^6.2.3",
57
57
  "ws": "8.21.0",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@snowyroad/braid",
3
- "version": "0.84.1",
3
+ "version": "0.86.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@snowyroad/braid",
9
- "version": "0.84.1",
9
+ "version": "0.86.0",
10
10
  "license": "SEE LICENSE IN LICENSE.md",
11
11
  "dependencies": {
12
12
  "@agentclientprotocol/sdk": "0.25.1",
@@ -14,7 +14,7 @@
14
14
  "@anthropic-ai/sandbox-runtime": "0.0.63",
15
15
  "@anthropic-ai/sdk": "0.104.1",
16
16
  "@modelcontextprotocol/sdk": "1.29.0",
17
- "@snowyroad/braid-tui": "0.0.22",
17
+ "@snowyroad/braid-tui": "0.0.25",
18
18
  "canonicalize": "^3.0.0",
19
19
  "jose": "^6.2.3",
20
20
  "ws": "8.21.0",
@@ -1183,9 +1183,9 @@
1183
1183
  ]
1184
1184
  },
1185
1185
  "node_modules/@snowyroad/braid-tui": {
1186
- "version": "0.0.22",
1187
- "resolved": "https://registry.npmjs.org/@snowyroad/braid-tui/-/braid-tui-0.0.22.tgz",
1188
- "integrity": "sha512-Sgsn8Dl8v6qLwZjRnlPUKJEXM6nOLFu0B/d2bOAJycSu1AI35LyzWjrOoui6TIwDB7KKBYVkbdOKqfwUtHFbyA==",
1186
+ "version": "0.0.25",
1187
+ "resolved": "https://registry.npmjs.org/@snowyroad/braid-tui/-/braid-tui-0.0.25.tgz",
1188
+ "integrity": "sha512-HXtqJ0FBPAOTdR5bZ9zFb3Rcew+1ZlDU44AeOz/PxrDW5a1D+TAdrfVSby32mUk9Z5dVUgWZ2wrnGdbyIX725g==",
1189
1189
  "license": "SEE LICENSE IN LICENSE.md",
1190
1190
  "dependencies": {
1191
1191
  "ink": "^5.2.0",
@@ -2505,9 +2505,9 @@
2505
2505
  "license": "ISC"
2506
2506
  },
2507
2507
  "node_modules/jose": {
2508
- "version": "6.2.3",
2509
- "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz",
2510
- "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==",
2508
+ "version": "6.2.4",
2509
+ "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.4.tgz",
2510
+ "integrity": "sha512-N8acGzVsQy6M/fjFcxtysNc4Q379TcM5dM/qKkNtsHFji88yANnXTr7BLeP75iPnFwBfQzM/jg2BZ9+HZrHCZA==",
2511
2511
  "license": "MIT",
2512
2512
  "funding": {
2513
2513
  "url": "https://github.com/sponsors/panva"
@@ -2908,9 +2908,9 @@
2908
2908
  }
2909
2909
  },
2910
2910
  "node_modules/postcss": {
2911
- "version": "8.5.20",
2912
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.20.tgz",
2913
- "integrity": "sha512-lW616l85ucIQL+FocMmL7pQFPqBmwejrCMg+iPxyImlrANNJG9NHq/RkyCZopDhd8C3LA03PHRJDjkbGu8vvug==",
2911
+ "version": "8.5.22",
2912
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.22.tgz",
2913
+ "integrity": "sha512-KBDEIpLrvpv16pp3K0Fw+UCoZfopFjjgeB+0tA/aaThfEE74kKDLrgg603YvOWJyg3+WYtyq3xYsQWsIyZlPqQ==",
2914
2914
  "dev": true,
2915
2915
  "funding": [
2916
2916
  {