@snowyroad/braid 0.73.0 → 0.74.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.
@@ -372,7 +372,7 @@ var InviteExpiredError = class extends Error {
372
372
  }
373
373
  };
374
374
  async function redeemInvite(relayHttpUrl, code) {
375
- const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-Y62OCD7R.js");
375
+ const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-EP5W2BCL.js");
376
376
  const r = await boundedJsonFetch2(`${relayHttpUrl.replace(/\/$/, "")}/invites/redeem`, {
377
377
  method: "POST",
378
378
  headers: { "content-type": "application/json" },
@@ -461,7 +461,7 @@ function validateReplacementToken(newToken, currentToken, nowMs = Date.now()) {
461
461
  return { ok: true };
462
462
  }
463
463
  async function mintAccessToken(relayHttpUrl, agentKey, fetchFn = fetch, dpopProof) {
464
- const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-Y62OCD7R.js");
464
+ const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-EP5W2BCL.js");
465
465
  const r = await boundedJsonFetch2(`${relayHttpUrl.replace(/\/$/, "")}/agents/token`, {
466
466
  method: "POST",
467
467
  headers: {
@@ -2106,6 +2106,7 @@ async function boundedJsonFetch(url, opts) {
2106
2106
  }
2107
2107
 
2108
2108
  export {
2109
+ ACP_AGENT_IDS,
2109
2110
  parseRunFlags,
2110
2111
  resolveKnobs,
2111
2112
  newBeyondFile,
package/dist/cli.js CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  utext
16
16
  } from "./chunk-LGYVCFGB.js";
17
17
  import {
18
+ ACP_AGENT_IDS,
18
19
  EXIT_CRASH,
19
20
  EXIT_NEEDS_HUMAN,
20
21
  EXIT_OK,
@@ -62,7 +63,7 @@ import {
62
63
  validateReplacementToken,
63
64
  verifyCardSignature,
64
65
  wsToHttp
65
- } from "./chunk-7BBB4CRN.js";
66
+ } from "./chunk-IARPNMQJ.js";
66
67
 
67
68
  // src/health.ts
68
69
  var CEILING_STRIKES_TO_DEAD = 3;
@@ -6788,10 +6789,11 @@ var USAGE = `Usage: braid <command>
6788
6789
 
6789
6790
  Commands:
6790
6791
  join <code> Join a relay with an invite code (saves the credential)
6791
- enroll --invite-stdin [--json]
6792
+ enroll --invite-stdin [--json] [--provider <id>] [--model <name>]
6792
6793
  One-shot enrollment: reads the invite from stdin (never as an
6793
6794
  argument), redeems it, saves and verifies the credential, then
6794
- exits without starting a session (--json for machine output)
6795
+ exits without starting a session (--json for machine output;
6796
+ --provider/--model persist to the saved agent, same as join)
6795
6797
  start [name] Start the bridge from a saved credential
6796
6798
  (env-driven config like BRAID_INVITE / BRAID_TOKEN is honored)
6797
6799
  list List saved agents and their tool access
@@ -6934,7 +6936,11 @@ function parseCliArgs(argv) {
6934
6936
  if (first === "enroll") {
6935
6937
  let inviteStdin = false;
6936
6938
  let json = false;
6937
- for (const a of argv.slice(1)) {
6939
+ let provider;
6940
+ let model;
6941
+ const rest = argv.slice(1);
6942
+ for (let i = 0; i < rest.length; i++) {
6943
+ const a = rest[i];
6938
6944
  if (a === "--invite-stdin") {
6939
6945
  inviteStdin = true;
6940
6946
  continue;
@@ -6943,6 +6949,22 @@ function parseCliArgs(argv) {
6943
6949
  json = true;
6944
6950
  continue;
6945
6951
  }
6952
+ if (a === "--provider" || a === "--model") {
6953
+ const v = rest[i + 1]?.trim();
6954
+ if (v === void 0 || v === "" || v.startsWith("--")) {
6955
+ return { kind: "usage", error: `Missing value for ${a}` };
6956
+ }
6957
+ i++;
6958
+ if (a === "--provider") {
6959
+ if (!ACP_AGENT_IDS.includes(v)) {
6960
+ return { kind: "usage", error: `Invalid --provider: ${v}. Expected one of: ${ACP_AGENT_IDS.join(", ")}` };
6961
+ }
6962
+ provider = v;
6963
+ } else {
6964
+ model = v;
6965
+ }
6966
+ continue;
6967
+ }
6946
6968
  if (a.startsWith("-")) return { kind: "usage", error: `Unknown flag for enroll: ${a}` };
6947
6969
  return {
6948
6970
  kind: "usage",
@@ -6955,7 +6977,7 @@ function parseCliArgs(argv) {
6955
6977
  error: "enroll requires --invite-stdin (the invite is read from stdin, never from arguments)."
6956
6978
  };
6957
6979
  }
6958
- return { kind: "enroll", json };
6980
+ return { kind: "enroll", json, ...provider ? { provider } : {}, ...model ? { model } : {} };
6959
6981
  }
6960
6982
  if (first === "join" || first === "start") {
6961
6983
  const parsed = parseRunFlags(argv);
@@ -7038,12 +7060,18 @@ async function runEnroll(opts, io, env) {
7038
7060
  const relayHttpUrl = wsToHttp(inv.relayUrl);
7039
7061
  const bundle = await redeemInvite(relayHttpUrl, inv.code);
7040
7062
  const dir = configDir(env);
7063
+ const existing = listAgents(dir).find(
7064
+ (e) => e.agent.agentName === bundle.agentName && e.agent.relayUrl === inv.relayUrl
7065
+ );
7041
7066
  const stored = {
7067
+ ...existing?.agent ?? {},
7042
7068
  relayUrl: inv.relayUrl,
7043
7069
  agentId: bundle.agentId,
7044
7070
  agentName: bundle.agentName,
7045
7071
  agentUuid: bundle.agentUuid,
7046
- agentKey: bundle.agentKey
7072
+ agentKey: bundle.agentKey,
7073
+ ...opts.provider ? { provider: opts.provider } : {},
7074
+ ...opts.model ? { model: opts.model } : {}
7047
7075
  };
7048
7076
  const file = persistOrNeedsHuman(dir, stored);
7049
7077
  assertKeystorePerms(dir, file);
@@ -7057,12 +7085,17 @@ async function runEnroll(opts, io, env) {
7057
7085
  agentName: bundle.agentName,
7058
7086
  agentUuid: bundle.agentUuid,
7059
7087
  relayUrl: inv.relayUrl,
7060
- keystoreFile: file
7088
+ keystoreFile: file,
7089
+ // provider/model appear ONLY when persisted on the stored agent.
7090
+ ...stored.provider ? { provider: stored.provider } : {},
7091
+ ...stored.model ? { model: stored.model } : {}
7061
7092
  }));
7062
7093
  } else {
7063
7094
  outLine(`[braid] enrolled: ${name}`);
7064
7095
  outLine(`[braid] relay: ${inv.relayUrl}`);
7065
7096
  outLine(`[braid] credential saved to ${file} (verified: token mint ok)`);
7097
+ if (opts.provider) outLine(`[braid] provider persisted: ${opts.provider}`);
7098
+ if (opts.model) outLine(`[braid] model persisted: ${sanitizeForTty(opts.model)}`);
7066
7099
  outLine(`[braid] start it with: npx @snowyroad/braid start ${cmdName}`);
7067
7100
  }
7068
7101
  return EXIT_OK;
@@ -8939,7 +8972,7 @@ async function main() {
8939
8972
  if (invocation.kind === "enroll") {
8940
8973
  process.exit(
8941
8974
  await runEnroll(
8942
- { json: invocation.json },
8975
+ { json: invocation.json, provider: invocation.provider, model: invocation.model },
8943
8976
  { stdin: process.stdin, stdout: process.stdout, stderr: process.stderr },
8944
8977
  process.env
8945
8978
  )
@@ -4,7 +4,7 @@ import {
4
4
  boundedJsonFetch,
5
5
  resetHttpMetricsForTest,
6
6
  snapshotHttpMetrics
7
- } from "./chunk-7BBB4CRN.js";
7
+ } from "./chunk-IARPNMQJ.js";
8
8
  export {
9
9
  assertHttpEndpoint,
10
10
  boundedJsonFetch,
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@snowyroad/braid",
3
- "version": "0.73.0",
3
+ "version": "0.74.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@snowyroad/braid",
9
- "version": "0.73.0",
9
+ "version": "0.74.0",
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.73.0",
3
+ "version": "0.74.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",