@snowyroad/braid 0.96.4 → 0.96.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.
|
@@ -205,9 +205,9 @@ function newBeyondFile(list) {
|
|
|
205
205
|
flag: list.flag.filter((x) => !file.has(x))
|
|
206
206
|
};
|
|
207
207
|
}
|
|
208
|
-
function seg(n, singular,
|
|
208
|
+
function seg(n, singular, plural2) {
|
|
209
209
|
if (n === 0) return null;
|
|
210
|
-
return `+${n} ${n === 1 ? singular :
|
|
210
|
+
return `+${n} ${n === 1 ? singular : plural2}`;
|
|
211
211
|
}
|
|
212
212
|
function computePostureWarnings(flags, env, stored) {
|
|
213
213
|
if (stored === void 0) return [];
|
|
@@ -400,7 +400,7 @@ var InviteExpiredError = class extends Error {
|
|
|
400
400
|
}
|
|
401
401
|
};
|
|
402
402
|
async function redeemInvite(relayHttpUrl, code) {
|
|
403
|
-
const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-
|
|
403
|
+
const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-DZ3ZHOHX.js");
|
|
404
404
|
const r = await boundedJsonFetch2(`${relayHttpUrl.replace(/\/$/, "")}/invites/redeem`, {
|
|
405
405
|
method: "POST",
|
|
406
406
|
headers: { "content-type": "application/json" },
|
|
@@ -492,7 +492,7 @@ function validateReplacementToken(newToken, currentToken, nowMs = Date.now()) {
|
|
|
492
492
|
return { ok: true };
|
|
493
493
|
}
|
|
494
494
|
async function mintAccessToken(relayHttpUrl, agentKey, fetchFn = fetch, dpopProof) {
|
|
495
|
-
const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-
|
|
495
|
+
const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-DZ3ZHOHX.js");
|
|
496
496
|
const r = await boundedJsonFetch2(`${relayHttpUrl.replace(/\/$/, "")}/agents/token`, {
|
|
497
497
|
method: "POST",
|
|
498
498
|
headers: {
|
|
@@ -1770,6 +1770,44 @@ function dropVendorNotifications(input) {
|
|
|
1770
1770
|
});
|
|
1771
1771
|
}
|
|
1772
1772
|
|
|
1773
|
+
// src/acp/stderrNoise.ts
|
|
1774
|
+
var TEARDOWN_HEAD = /cancellation failed during teardown/;
|
|
1775
|
+
var CONTINUATION = /^(\s+at\s|\s*[{}]\s*$|\s+(telemetryMessage|errorClass|exitCode)\s*:)/;
|
|
1776
|
+
function createTeardownNoiseFilter(isStopping) {
|
|
1777
|
+
let pending = "";
|
|
1778
|
+
let dropping = false;
|
|
1779
|
+
function line(l) {
|
|
1780
|
+
if (dropping) {
|
|
1781
|
+
if (CONTINUATION.test(l)) return "";
|
|
1782
|
+
dropping = false;
|
|
1783
|
+
}
|
|
1784
|
+
if (isStopping() && TEARDOWN_HEAD.test(l)) {
|
|
1785
|
+
dropping = true;
|
|
1786
|
+
return "";
|
|
1787
|
+
}
|
|
1788
|
+
return l + "\n";
|
|
1789
|
+
}
|
|
1790
|
+
return {
|
|
1791
|
+
push(chunk) {
|
|
1792
|
+
pending += chunk;
|
|
1793
|
+
let out = "";
|
|
1794
|
+
let nl;
|
|
1795
|
+
while ((nl = pending.indexOf("\n")) !== -1) {
|
|
1796
|
+
out += line(pending.slice(0, nl));
|
|
1797
|
+
pending = pending.slice(nl + 1);
|
|
1798
|
+
}
|
|
1799
|
+
return out;
|
|
1800
|
+
},
|
|
1801
|
+
flush() {
|
|
1802
|
+
const rest = pending;
|
|
1803
|
+
pending = "";
|
|
1804
|
+
if (!rest) return "";
|
|
1805
|
+
if (dropping && CONTINUATION.test(rest)) return "";
|
|
1806
|
+
return rest;
|
|
1807
|
+
}
|
|
1808
|
+
};
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1773
1811
|
// src/acp/client.ts
|
|
1774
1812
|
import { randomUUID } from "crypto";
|
|
1775
1813
|
|
|
@@ -2106,7 +2144,17 @@ var AcpClient = class {
|
|
|
2106
2144
|
detached: true
|
|
2107
2145
|
});
|
|
2108
2146
|
this.child = child;
|
|
2109
|
-
|
|
2147
|
+
const noise = createTeardownNoiseFilter(() => this.stopping);
|
|
2148
|
+
pipeSanitizedToTty(child.stderr, {
|
|
2149
|
+
write: (s) => {
|
|
2150
|
+
const kept = noise.push(s);
|
|
2151
|
+
if (kept) process.stderr.write(kept);
|
|
2152
|
+
}
|
|
2153
|
+
});
|
|
2154
|
+
child.on("close", () => {
|
|
2155
|
+
const rest = noise.flush();
|
|
2156
|
+
if (rest) process.stderr.write(rest);
|
|
2157
|
+
});
|
|
2110
2158
|
child.on("error", (err) => {
|
|
2111
2159
|
this.failPending(new Error(`ACP agent subprocess error: ${err.message}`));
|
|
2112
2160
|
});
|
|
@@ -3437,6 +3485,137 @@ function classifyCatchUp(messages, agentName, nowMs, opts) {
|
|
|
3437
3485
|
return { context: inWindow, mentions: capped };
|
|
3438
3486
|
}
|
|
3439
3487
|
|
|
3488
|
+
// src/connStatus.ts
|
|
3489
|
+
var ESCALATE_FIRST_MS = 6e4;
|
|
3490
|
+
var ESCALATE_REPEAT_MS = 3e5;
|
|
3491
|
+
var CLOSE_TRY_AGAIN_LATER = 1013;
|
|
3492
|
+
function fmtDur(ms) {
|
|
3493
|
+
const s = Math.max(0, Math.floor(ms / 1e3));
|
|
3494
|
+
if (s < 60) return `${s}s`;
|
|
3495
|
+
const m = Math.floor(s / 60);
|
|
3496
|
+
if (m < 60) return `${m}m${String(s % 60).padStart(2, "0")}s`;
|
|
3497
|
+
return `${Math.floor(m / 60)}h${String(m % 60).padStart(2, "0")}m`;
|
|
3498
|
+
}
|
|
3499
|
+
function fmtClock(epochMs) {
|
|
3500
|
+
const d = new Date(epochMs);
|
|
3501
|
+
return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
3502
|
+
}
|
|
3503
|
+
function plural(n, one, many) {
|
|
3504
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
3505
|
+
}
|
|
3506
|
+
function createConnStatus(opts) {
|
|
3507
|
+
const now = opts.now ?? Date.now;
|
|
3508
|
+
const startedAt = now();
|
|
3509
|
+
let state = "starting";
|
|
3510
|
+
let connectedSince = null;
|
|
3511
|
+
let offlineSince = null;
|
|
3512
|
+
let attempts = 0;
|
|
3513
|
+
let reconnects = 0;
|
|
3514
|
+
let lastReconnectAt = null;
|
|
3515
|
+
let tokenExp = null;
|
|
3516
|
+
let lastCloseCode = null;
|
|
3517
|
+
let nextEscalateAt = null;
|
|
3518
|
+
let tryAgainLaterSaid = false;
|
|
3519
|
+
function noteDrop() {
|
|
3520
|
+
if (state !== "offline") {
|
|
3521
|
+
offlineSince = now();
|
|
3522
|
+
attempts = 0;
|
|
3523
|
+
nextEscalateAt = offlineSince + ESCALATE_FIRST_MS;
|
|
3524
|
+
}
|
|
3525
|
+
state = "offline";
|
|
3526
|
+
connectedSince = null;
|
|
3527
|
+
attempts++;
|
|
3528
|
+
}
|
|
3529
|
+
function closeEpisode(t) {
|
|
3530
|
+
if (offlineSince === null || attempts === 0) return null;
|
|
3531
|
+
const down = fmtDur(t - offlineSince);
|
|
3532
|
+
const suffix = attempts > 1 ? `${down}, ${plural(attempts, "attempt", "attempts")}` : down;
|
|
3533
|
+
offlineSince = null;
|
|
3534
|
+
nextEscalateAt = null;
|
|
3535
|
+
tryAgainLaterSaid = false;
|
|
3536
|
+
return suffix;
|
|
3537
|
+
}
|
|
3538
|
+
function adoptExp(exp) {
|
|
3539
|
+
if (exp !== void 0) tokenExp = exp;
|
|
3540
|
+
}
|
|
3541
|
+
function handle(e) {
|
|
3542
|
+
switch (e.kind) {
|
|
3543
|
+
case "connected": {
|
|
3544
|
+
const t = now();
|
|
3545
|
+
const hadRetries = offlineSince !== null && attempts > 0;
|
|
3546
|
+
const n = attempts;
|
|
3547
|
+
const since = offlineSince;
|
|
3548
|
+
const ep = closeEpisode(t);
|
|
3549
|
+
state = "connected";
|
|
3550
|
+
connectedSince = t;
|
|
3551
|
+
adoptExp(e.tokenExp);
|
|
3552
|
+
if (hadRetries && ep !== null && since !== null) {
|
|
3553
|
+
opts.log(`[braid] connected (after ${plural(n, "attempt", "attempts")}, ${fmtDur(t - since)})`);
|
|
3554
|
+
}
|
|
3555
|
+
break;
|
|
3556
|
+
}
|
|
3557
|
+
case "reconnected": {
|
|
3558
|
+
const t = now();
|
|
3559
|
+
const ep = closeEpisode(t);
|
|
3560
|
+
state = "connected";
|
|
3561
|
+
connectedSince = t;
|
|
3562
|
+
reconnects++;
|
|
3563
|
+
lastReconnectAt = t;
|
|
3564
|
+
adoptExp(e.tokenExp);
|
|
3565
|
+
opts.log(`[braid] reconnected${ep !== null ? ` (offline ${ep})` : ""}`);
|
|
3566
|
+
break;
|
|
3567
|
+
}
|
|
3568
|
+
case "disconnected":
|
|
3569
|
+
lastCloseCode = e.code;
|
|
3570
|
+
noteDrop();
|
|
3571
|
+
if (e.code === CLOSE_TRY_AGAIN_LATER) {
|
|
3572
|
+
if (!tryAgainLaterSaid) {
|
|
3573
|
+
tryAgainLaterSaid = true;
|
|
3574
|
+
opts.warn(
|
|
3575
|
+
`[braid] relay asked us to try again later${e.reason ? ` (${e.reason})` : ""}; reconnecting automatically`
|
|
3576
|
+
);
|
|
3577
|
+
}
|
|
3578
|
+
} else if (opts.verbose) {
|
|
3579
|
+
opts.log(`[braid] disconnected (close ${e.code})${e.reason ? `: ${e.reason}` : ""}`);
|
|
3580
|
+
}
|
|
3581
|
+
break;
|
|
3582
|
+
case "connectTimeout":
|
|
3583
|
+
noteDrop();
|
|
3584
|
+
if (opts.verbose) {
|
|
3585
|
+
opts.log(
|
|
3586
|
+
`[braid] connect attempt timed out after ${e.timeoutSecs}s (socket accepted but the relay never completed the handshake); retrying`
|
|
3587
|
+
);
|
|
3588
|
+
}
|
|
3589
|
+
break;
|
|
3590
|
+
case "remintStarted":
|
|
3591
|
+
if (opts.verbose) opts.log("[braid] access token rejected; re-minting from agent key");
|
|
3592
|
+
break;
|
|
3593
|
+
case "tokenRefreshed":
|
|
3594
|
+
adoptExp(e.tokenExp);
|
|
3595
|
+
if (opts.verbose) opts.log("[braid] token refreshed");
|
|
3596
|
+
break;
|
|
3597
|
+
case "tokenReminted":
|
|
3598
|
+
adoptExp(e.tokenExp);
|
|
3599
|
+
if (opts.verbose) opts.log("[braid] token proactively re-minted before expiry");
|
|
3600
|
+
break;
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3603
|
+
function tick() {
|
|
3604
|
+
if (state !== "offline" || offlineSince === null || nextEscalateAt === null) return;
|
|
3605
|
+
const t = now();
|
|
3606
|
+
if (t >= nextEscalateAt) {
|
|
3607
|
+
opts.warn(
|
|
3608
|
+
`[braid] still reconnecting: offline ${fmtDur(t - offlineSince)} (${plural(attempts, "attempt", "attempts")})`
|
|
3609
|
+
);
|
|
3610
|
+
nextEscalateAt = t + ESCALATE_REPEAT_MS;
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3613
|
+
function snapshot() {
|
|
3614
|
+
return { state, startedAt, connectedSince, offlineSince, attempts, reconnects, lastReconnectAt, tokenExp, lastCloseCode };
|
|
3615
|
+
}
|
|
3616
|
+
return { handle, tick, snapshot };
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3440
3619
|
// src/cardIdentity.ts
|
|
3441
3620
|
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
3442
3621
|
|
|
@@ -4160,7 +4339,7 @@ var RelayClient = class {
|
|
|
4160
4339
|
this.fatalCb?.(code, reason);
|
|
4161
4340
|
return;
|
|
4162
4341
|
}
|
|
4163
|
-
if (!this.helloReceived) {
|
|
4342
|
+
if (!this.helloReceived && code !== CLOSE_TRY_AGAIN_LATER) {
|
|
4164
4343
|
this.preHelloFailures++;
|
|
4165
4344
|
if (this.preHelloFailures >= PRE_HELLO_HINT_AFTER && !this.handshakeHintShown) {
|
|
4166
4345
|
this.handshakeHintShown = true;
|
|
@@ -7715,6 +7894,9 @@ export {
|
|
|
7715
7894
|
isAddressed,
|
|
7716
7895
|
isAddressedByReply,
|
|
7717
7896
|
classifyCatchUp,
|
|
7897
|
+
fmtDur,
|
|
7898
|
+
fmtClock,
|
|
7899
|
+
createConnStatus,
|
|
7718
7900
|
WS_MAX_PAYLOAD_BYTES,
|
|
7719
7901
|
RelayClient,
|
|
7720
7902
|
SourceBroker,
|
package/dist/cli.js
CHANGED
|
@@ -29,12 +29,15 @@ import {
|
|
|
29
29
|
classifyFatal,
|
|
30
30
|
configDir,
|
|
31
31
|
createAdapter,
|
|
32
|
+
createConnStatus,
|
|
32
33
|
createEphemeralLisaAdapter,
|
|
33
34
|
createWorkspaceNoticeGate,
|
|
34
35
|
decodeInvite,
|
|
35
36
|
describeClaudeBinary,
|
|
36
37
|
distinctWorkspaceNames,
|
|
37
38
|
effectiveAnthropicCredential,
|
|
39
|
+
fmtClock,
|
|
40
|
+
fmtDur,
|
|
38
41
|
handoffCwdFor,
|
|
39
42
|
hasSubscriptionLogin,
|
|
40
43
|
initScopeRuntime,
|
|
@@ -78,7 +81,7 @@ import {
|
|
|
78
81
|
updateAgentWorkspace,
|
|
79
82
|
validateRelayWsUrl,
|
|
80
83
|
wsToHttp
|
|
81
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-DIUVFB7Z.js";
|
|
82
85
|
import {
|
|
83
86
|
clampUntrusted,
|
|
84
87
|
externalSourceLabel,
|
|
@@ -5714,127 +5717,6 @@ function installTee(outWriter, errWriter) {
|
|
|
5714
5717
|
// src/cli.ts
|
|
5715
5718
|
import { homedir as homedir6 } from "os";
|
|
5716
5719
|
|
|
5717
|
-
// src/connStatus.ts
|
|
5718
|
-
var ESCALATE_FIRST_MS = 6e4;
|
|
5719
|
-
var ESCALATE_REPEAT_MS = 3e5;
|
|
5720
|
-
function fmtDur(ms) {
|
|
5721
|
-
const s = Math.max(0, Math.floor(ms / 1e3));
|
|
5722
|
-
if (s < 60) return `${s}s`;
|
|
5723
|
-
const m = Math.floor(s / 60);
|
|
5724
|
-
if (m < 60) return `${m}m${String(s % 60).padStart(2, "0")}s`;
|
|
5725
|
-
return `${Math.floor(m / 60)}h${String(m % 60).padStart(2, "0")}m`;
|
|
5726
|
-
}
|
|
5727
|
-
function fmtClock(epochMs) {
|
|
5728
|
-
const d = new Date(epochMs);
|
|
5729
|
-
return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
5730
|
-
}
|
|
5731
|
-
function plural(n, one, many) {
|
|
5732
|
-
return `${n} ${n === 1 ? one : many}`;
|
|
5733
|
-
}
|
|
5734
|
-
function createConnStatus(opts) {
|
|
5735
|
-
const now = opts.now ?? Date.now;
|
|
5736
|
-
const startedAt = now();
|
|
5737
|
-
let state = "starting";
|
|
5738
|
-
let connectedSince = null;
|
|
5739
|
-
let offlineSince = null;
|
|
5740
|
-
let attempts = 0;
|
|
5741
|
-
let reconnects = 0;
|
|
5742
|
-
let lastReconnectAt = null;
|
|
5743
|
-
let tokenExp = null;
|
|
5744
|
-
let lastCloseCode = null;
|
|
5745
|
-
let nextEscalateAt = null;
|
|
5746
|
-
function noteDrop() {
|
|
5747
|
-
if (state !== "offline") {
|
|
5748
|
-
offlineSince = now();
|
|
5749
|
-
attempts = 0;
|
|
5750
|
-
nextEscalateAt = offlineSince + ESCALATE_FIRST_MS;
|
|
5751
|
-
}
|
|
5752
|
-
state = "offline";
|
|
5753
|
-
connectedSince = null;
|
|
5754
|
-
attempts++;
|
|
5755
|
-
}
|
|
5756
|
-
function closeEpisode(t) {
|
|
5757
|
-
if (offlineSince === null || attempts === 0) return null;
|
|
5758
|
-
const down = fmtDur(t - offlineSince);
|
|
5759
|
-
const suffix = attempts > 1 ? `${down}, ${plural(attempts, "attempt", "attempts")}` : down;
|
|
5760
|
-
offlineSince = null;
|
|
5761
|
-
nextEscalateAt = null;
|
|
5762
|
-
return suffix;
|
|
5763
|
-
}
|
|
5764
|
-
function adoptExp(exp) {
|
|
5765
|
-
if (exp !== void 0) tokenExp = exp;
|
|
5766
|
-
}
|
|
5767
|
-
function handle(e) {
|
|
5768
|
-
switch (e.kind) {
|
|
5769
|
-
case "connected": {
|
|
5770
|
-
const t = now();
|
|
5771
|
-
const hadRetries = offlineSince !== null && attempts > 0;
|
|
5772
|
-
const n = attempts;
|
|
5773
|
-
const since = offlineSince;
|
|
5774
|
-
const ep = closeEpisode(t);
|
|
5775
|
-
state = "connected";
|
|
5776
|
-
connectedSince = t;
|
|
5777
|
-
adoptExp(e.tokenExp);
|
|
5778
|
-
if (hadRetries && ep !== null && since !== null) {
|
|
5779
|
-
opts.log(`[braid] connected (after ${plural(n, "attempt", "attempts")}, ${fmtDur(t - since)})`);
|
|
5780
|
-
}
|
|
5781
|
-
break;
|
|
5782
|
-
}
|
|
5783
|
-
case "reconnected": {
|
|
5784
|
-
const t = now();
|
|
5785
|
-
const ep = closeEpisode(t);
|
|
5786
|
-
state = "connected";
|
|
5787
|
-
connectedSince = t;
|
|
5788
|
-
reconnects++;
|
|
5789
|
-
lastReconnectAt = t;
|
|
5790
|
-
adoptExp(e.tokenExp);
|
|
5791
|
-
opts.log(`[braid] reconnected${ep !== null ? ` (offline ${ep})` : ""}`);
|
|
5792
|
-
break;
|
|
5793
|
-
}
|
|
5794
|
-
case "disconnected":
|
|
5795
|
-
lastCloseCode = e.code;
|
|
5796
|
-
noteDrop();
|
|
5797
|
-
if (opts.verbose) {
|
|
5798
|
-
opts.log(`[braid] disconnected (close ${e.code})${e.reason ? `: ${e.reason}` : ""}`);
|
|
5799
|
-
}
|
|
5800
|
-
break;
|
|
5801
|
-
case "connectTimeout":
|
|
5802
|
-
noteDrop();
|
|
5803
|
-
if (opts.verbose) {
|
|
5804
|
-
opts.log(
|
|
5805
|
-
`[braid] connect attempt timed out after ${e.timeoutSecs}s (socket accepted but the relay never completed the handshake); retrying`
|
|
5806
|
-
);
|
|
5807
|
-
}
|
|
5808
|
-
break;
|
|
5809
|
-
case "remintStarted":
|
|
5810
|
-
if (opts.verbose) opts.log("[braid] access token rejected; re-minting from agent key");
|
|
5811
|
-
break;
|
|
5812
|
-
case "tokenRefreshed":
|
|
5813
|
-
adoptExp(e.tokenExp);
|
|
5814
|
-
if (opts.verbose) opts.log("[braid] token refreshed");
|
|
5815
|
-
break;
|
|
5816
|
-
case "tokenReminted":
|
|
5817
|
-
adoptExp(e.tokenExp);
|
|
5818
|
-
if (opts.verbose) opts.log("[braid] token proactively re-minted before expiry");
|
|
5819
|
-
break;
|
|
5820
|
-
}
|
|
5821
|
-
}
|
|
5822
|
-
function tick() {
|
|
5823
|
-
if (state !== "offline" || offlineSince === null || nextEscalateAt === null) return;
|
|
5824
|
-
const t = now();
|
|
5825
|
-
if (t >= nextEscalateAt) {
|
|
5826
|
-
opts.warn(
|
|
5827
|
-
`[braid] still reconnecting: offline ${fmtDur(t - offlineSince)} (${plural(attempts, "attempt", "attempts")})`
|
|
5828
|
-
);
|
|
5829
|
-
nextEscalateAt = t + ESCALATE_REPEAT_MS;
|
|
5830
|
-
}
|
|
5831
|
-
}
|
|
5832
|
-
function snapshot() {
|
|
5833
|
-
return { state, startedAt, connectedSince, offlineSince, attempts, reconnects, lastReconnectAt, tokenExp, lastCloseCode };
|
|
5834
|
-
}
|
|
5835
|
-
return { handle, tick, snapshot };
|
|
5836
|
-
}
|
|
5837
|
-
|
|
5838
5720
|
// src/statusLine.ts
|
|
5839
5721
|
var ESC = String.fromCharCode(27);
|
|
5840
5722
|
var CLEAR = `\r${ESC}[2K`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snowyroad/braid",
|
|
3
|
-
"version": "0.96.
|
|
3
|
+
"version": "0.96.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",
|
package/service-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snowyroad/braid",
|
|
3
|
-
"version": "0.96.
|
|
3
|
+
"version": "0.96.5",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@snowyroad/braid",
|
|
9
|
-
"version": "0.96.
|
|
9
|
+
"version": "0.96.5",
|
|
10
10
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@agentclientprotocol/sdk": "0.25.1",
|