@bankr/cli 0.3.23 → 0.3.32

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
@@ -73,6 +73,12 @@ bankr agent -c "compare them"
73
73
 
74
74
  # Continue a specific thread
75
75
  bankr agent --thread thr_ABC123 "tell me more"
76
+
77
+ # Max Mode: pick the model. Only the two newest releases of each line, and
78
+ # only frontier / flagship / balanced lines, are accepted (the same set the
79
+ # web picker shows); anything else is rejected and the error lists every
80
+ # valid id.
81
+ bankr agent --model claude-opus-5 "audit this contract"
76
82
  ```
77
83
 
78
84
  ### Token Launch
package/dist/cli.js CHANGED
@@ -46,14 +46,12 @@ async function readPromptInput() {
46
46
  }
47
47
  const text = Buffer.concat(chunks).toString().trim();
48
48
  if (!text) {
49
- output.error("No input received from stdin");
50
- process.exit(1);
49
+ output.fatal("No input received from stdin");
51
50
  }
52
51
  return text;
53
52
  }
54
53
  if (output.isNonInteractive()) {
55
- output.error('No prompt provided. Pass it as an argument: bankr agent "your prompt"');
56
- process.exit(1);
54
+ output.fatal('No prompt provided. Pass it as an argument: bankr agent "your prompt"');
57
55
  }
58
56
  // Interactive input — shell expansion does not apply here
59
57
  const text = await input({
@@ -306,8 +304,7 @@ const agentCmd = program
306
304
  const joined = text.join(" ").trim();
307
305
  if (!joined) {
308
306
  if (output.isNonInteractive()) {
309
- output.error('No prompt provided. Pass it as an argument: bankr agent "your prompt"');
310
- process.exit(1);
307
+ output.fatal('No prompt provided. Pass it as an argument: bankr agent "your prompt"');
311
308
  }
312
309
  agentCmd.help();
313
310
  return;
@@ -342,12 +339,12 @@ agentCmd
342
339
  program.commandsGroup("Tokens");
343
340
  program
344
341
  .command("launch")
345
- .description("Launch a token on Base or Robinhood Chain (interactive wizard)")
342
+ .description("Launch a token on Base, Robinhood Chain or Arbitrum (interactive wizard)")
346
343
  .optionsGroup("Token")
347
344
  .option("--name <name>", "Token name")
348
345
  .option("--symbol <symbol>", "Token symbol (default: auto-generated from name)")
349
346
  .option("--image <url>", "Token image URL")
350
- .option("--chain <chain>", "Chain to launch on: base, robinhood (default: base)")
347
+ .option("--chain <chain>", "Chain to launch on: base, robinhood, arbitrum (default: base)")
351
348
  .option("--no-vesting", "Turn off the default 15% creator vesting (sell 100% of supply into the pool)")
352
349
  .optionsGroup("Links")
353
350
  .option("--tweet <url>", "Associated tweet URL")
@@ -1051,8 +1048,7 @@ program
1051
1048
  .action(async (text, opts) => {
1052
1049
  if (text.length === 0) {
1053
1050
  if (output.isNonInteractive()) {
1054
- output.error('No prompt provided. Pass it as an argument: bankr "your prompt"');
1055
- process.exit(1);
1051
+ output.fatal('No prompt provided. Pass it as an argument: bankr "your prompt"');
1056
1052
  }
1057
1053
  program.help();
1058
1054
  return;
@@ -1069,8 +1065,7 @@ async function main() {
1069
1065
  console.log();
1070
1066
  process.exit(0);
1071
1067
  }
1072
- output.error(getErrorMessage(err));
1073
- process.exit(1);
1068
+ output.fatal(getErrorMessage(err));
1074
1069
  }
1075
1070
  await checkForUpdate(pkg.version);
1076
1071
  }
@@ -43,8 +43,7 @@ export async function balancesCommand(opts) {
43
43
  if (chains) {
44
44
  const invalid = chains.filter((c) => !VALID_CHAINS.has(c));
45
45
  if (invalid.length > 0) {
46
- output.error(`Invalid chain${invalid.length > 1 ? "s" : ""}: ${invalid.join(", ")}. Valid chains: ${[...VALID_CHAINS].join(", ")}`);
47
- process.exit(1);
46
+ output.fatal(`Invalid chain${invalid.length > 1 ? "s" : ""}: ${invalid.join(", ")}. Valid chains: ${[...VALID_CHAINS].join(", ")}`);
48
47
  }
49
48
  }
50
49
  const spin = output.spinner("Fetching balances...");
@@ -1,7 +1,6 @@
1
1
  import { cancelJob } from "../lib/api.js";
2
2
  import { requireApiKey } from "../lib/config.js";
3
3
  import * as output from "../lib/output.js";
4
- import { getErrorMessage } from "../lib/errors.js";
5
4
  export async function cancelCommand(jobId) {
6
5
  requireApiKey();
7
6
  const spin = output.spinner("Cancelling job...");
@@ -18,9 +17,7 @@ export async function cancelCommand(jobId) {
18
17
  }
19
18
  }
20
19
  catch (err) {
21
- spin.fail("Failed to cancel job");
22
- output.error(getErrorMessage(err));
23
- process.exit(1);
20
+ output.failWith(spin, "Failed to cancel job", err);
24
21
  }
25
22
  }
26
23
  //# sourceMappingURL=cancel.js.map
@@ -1,14 +1,8 @@
1
1
  import { confirm } from "@inquirer/prompts";
2
- import { CLI_USER_AGENT, getApiUrl, requireApiKey } from "../lib/config.js";
2
+ import { getApiUrl } from "../lib/config.js";
3
+ import { authHeaders } from "../lib/api.js";
3
4
  import * as output from "../lib/output.js";
4
5
  import { getErrorMessage } from "../lib/errors.js";
5
- function authHeaders() {
6
- return {
7
- "X-API-Key": requireApiKey(),
8
- "Content-Type": "application/json",
9
- "User-Agent": CLI_USER_AGENT,
10
- };
11
- }
12
6
  // Common Base tokens accepted as `--token` shortcuts. Lowercase to bypass
13
7
  // viem's strict EIP-55 checksum on the API's isAddress() check; the route
14
8
  // resolves to lowercase server-side anyway. Inlined here (not imported
@@ -79,8 +73,7 @@ export async function clubStatusCommand() {
79
73
  }
80
74
  catch (err) {
81
75
  spinner.stop();
82
- output.error(getErrorMessage(err));
83
- process.exit(1);
76
+ output.fatal(getErrorMessage(err));
84
77
  }
85
78
  }
86
79
  // ── Sign up ─────────────────────────────────────────────────────────────
@@ -95,8 +88,7 @@ export async function clubSignupCommand(opts) {
95
88
  if (opts.token) {
96
89
  const resolved = resolvePaymentToken(opts.token);
97
90
  if (!resolved) {
98
- output.error(`Unknown token "${opts.token}". Use one of USDC, BNKR, ETH, or pass a 0x-prefixed Base address.`);
99
- process.exit(1);
91
+ output.fatal(`Unknown token "${opts.token}". Use one of USDC, BNKR, ETH, or pass a 0x-prefixed Base address.`);
100
92
  }
101
93
  tokenAddress = resolved;
102
94
  }
@@ -143,8 +135,7 @@ export async function clubSignupCommand(opts) {
143
135
  output.dim("Run `bankr club` to see your status.");
144
136
  }
145
137
  catch (err) {
146
- output.error(getErrorMessage(err));
147
- process.exit(1);
138
+ output.fatal(getErrorMessage(err));
148
139
  }
149
140
  }
150
141
  // ── Cancel ──────────────────────────────────────────────────────────────
@@ -187,8 +178,7 @@ export async function clubCancelCommand(opts) {
187
178
  output.dim("You'll keep Bankr Club access until the end of the current billing period.");
188
179
  }
189
180
  catch (err) {
190
- output.error(getErrorMessage(err));
191
- process.exit(1);
181
+ output.fatal(getErrorMessage(err));
192
182
  }
193
183
  }
194
184
  //# sourceMappingURL=club.js.map
@@ -12,8 +12,7 @@ function isValidKey(key) {
12
12
  }
13
13
  function requireValidKey(key) {
14
14
  if (!isValidKey(key)) {
15
- output.error(`Unknown config key "${key}". Valid keys: ${ALLOWED_KEYS.join(", ")}`);
16
- process.exit(1);
15
+ output.fatal(`Unknown config key "${key}". Valid keys: ${ALLOWED_KEYS.join(", ")}`);
17
16
  }
18
17
  }
19
18
  function displayValue(key, value) {
@@ -215,8 +215,13 @@ function renderDashboard(data) {
215
215
  }
216
216
  console.log(`${DIM(` Wallet: ${data.address}`)}`);
217
217
  // Tokens can span launch chains ("chain" absent on pre-multichain rows).
218
+ const launchChainLabel = {
219
+ base: "Base",
220
+ robinhood: "Robinhood",
221
+ arbitrum: "Arbitrum",
222
+ };
218
223
  const chainNames = [
219
- ...new Set(data.tokens.map((t) => (t.chain ?? "base") === "robinhood" ? "Robinhood" : "Base")),
224
+ ...new Set(data.tokens.map((t) => launchChainLabel[t.chain ?? "base"] ?? "Base")),
220
225
  ].join(" + ") || "Base";
221
226
  console.log(`${DIM(` Chain: ${chainNames} \u00b7 Tokens: ${data.tokens.length} \u00b7 Period: ${data.days} days`)}`);
222
227
  if (data.tokens.length === 0) {
@@ -329,8 +334,7 @@ export async function feesCommand(address, opts) {
329
334
  if (opts.days) {
330
335
  days = parseInt(opts.days, 10);
331
336
  if (isNaN(days) || days < MIN_DAYS || days > MAX_DAYS) {
332
- output.error(`Days must be between ${MIN_DAYS} and ${MAX_DAYS}`);
333
- process.exit(1);
337
+ output.fatal(`Days must be between ${MIN_DAYS} and ${MAX_DAYS}`);
334
338
  }
335
339
  }
336
340
  // --token flag: look up fees by token address (no wallet needed)
@@ -349,8 +353,7 @@ export async function feesCommand(address, opts) {
349
353
  catch (err) {
350
354
  spin.fail("Failed to fetch token fee data");
351
355
  emitCESP("task.error");
352
- output.error(getErrorMessage(err));
353
- process.exit(1);
356
+ output.fatal(getErrorMessage(err));
354
357
  }
355
358
  return;
356
359
  }
@@ -370,9 +373,7 @@ export async function feesCommand(address, opts) {
370
373
  spin.succeed(`Wallet: ${walletAddress}`);
371
374
  }
372
375
  catch (err) {
373
- spin.fail("Failed to fetch wallet info");
374
- output.error(getErrorMessage(err));
375
- process.exit(1);
376
+ output.failWith(spin, "Failed to fetch wallet info", err);
376
377
  }
377
378
  }
378
379
  // Fetch data
@@ -390,8 +391,7 @@ export async function feesCommand(address, opts) {
390
391
  catch (err) {
391
392
  spin.fail("Failed to fetch fee data");
392
393
  emitCESP("task.error");
393
- output.error(getErrorMessage(err));
394
- process.exit(1);
394
+ output.fatal(getErrorMessage(err));
395
395
  }
396
396
  }
397
397
  export async function feesClaimCommand(tokenAddress, opts) {
@@ -451,8 +451,7 @@ export async function feesClaimCommand(tokenAddress, opts) {
451
451
  catch (err) {
452
452
  spin.fail("Claim submission failed");
453
453
  emitCESP("task.error");
454
- output.error(getErrorMessage(err));
455
- process.exit(1);
454
+ output.fatal(getErrorMessage(err));
456
455
  }
457
456
  }
458
457
  // ---------------------------------------------------------------------------
@@ -465,8 +464,7 @@ export async function feesClaimWalletCommand(address, opts) {
465
464
  address = undefined;
466
465
  }
467
466
  if (output.isNonInteractive() && !opts.all) {
468
- output.error("Use --all to select all tokens in non-interactive mode, or run interactively to choose");
469
- process.exit(1);
467
+ output.fatal("Use --all to select all tokens in non-interactive mode, or run interactively to choose");
470
468
  }
471
469
  // Load .env from cwd if present (no dependency needed)
472
470
  try {
@@ -504,13 +502,11 @@ export async function feesClaimWalletCommand(address, opts) {
504
502
  privateKey = process.env.BANKR_PRIVATE_KEY.trim();
505
503
  }
506
504
  else if (!address) {
507
- output.error("Address required when no private key is available. Provide an address argument or set BANKR_PRIVATE_KEY in .env");
508
- process.exit(1);
505
+ output.fatal("Address required when no private key is available. Provide an address argument or set BANKR_PRIVATE_KEY in .env");
509
506
  }
510
507
  else {
511
508
  if (output.isNonInteractive()) {
512
- output.error("Private key required in non-interactive mode. Use --private-key or set BANKR_PRIVATE_KEY");
513
- process.exit(1);
509
+ output.fatal("Private key required in non-interactive mode. Use --private-key or set BANKR_PRIVATE_KEY");
514
510
  }
515
511
  privateKey = await password({
516
512
  message: "Enter private key for this wallet (0x...):",
@@ -529,8 +525,7 @@ export async function feesClaimWalletCommand(address, opts) {
529
525
  account = privateKeyToAccount(privateKey);
530
526
  }
531
527
  catch {
532
- output.error("Invalid private key format");
533
- process.exit(1);
528
+ output.fatal("Invalid private key format");
534
529
  }
535
530
  // Step 3: Resolve address — derive from key if not provided, verify match if provided
536
531
  if (!address) {
@@ -539,12 +534,10 @@ export async function feesClaimWalletCommand(address, opts) {
539
534
  }
540
535
  else {
541
536
  if (!isAddress(address)) {
542
- output.error("Invalid EVM address");
543
- process.exit(1);
537
+ output.fatal("Invalid EVM address");
544
538
  }
545
539
  if (account.address.toLowerCase() !== address.toLowerCase()) {
546
- output.error(`Private key does not match address ${address}. Derived: ${account.address}`);
547
- process.exit(1);
540
+ output.fatal(`Private key does not match address ${address}. Derived: ${account.address}`);
548
541
  }
549
542
  }
550
543
  console.log();
@@ -566,9 +559,7 @@ export async function feesClaimWalletCommand(address, opts) {
566
559
  allTokens = result.tokens;
567
560
  }
568
561
  catch (err) {
569
- fetchSpin.fail("Failed to fetch fee data");
570
- output.error(getErrorMessage(err));
571
- process.exit(1);
562
+ output.failWith(fetchSpin, "Failed to fetch fee data", err);
572
563
  }
573
564
  // Step 5: Filter to tokens with claimable fees (API already filters, but
574
565
  // double-check for any rounding edge cases)
@@ -675,8 +666,7 @@ export async function feesClaimWalletCommand(address, opts) {
675
666
  output.warn(`${baseChainTokens.length - buildableTokens.length} token(s) missing initializer data — skipped`);
676
667
  }
677
668
  if (buildableTokens.length === 0) {
678
- output.error("No transactions could be built");
679
- process.exit(1);
669
+ output.fatal("No transactions could be built");
680
670
  }
681
671
  // Encode calldata locally (instant, no RPC)
682
672
  const txData = buildableTokens.map((t) => ({
@@ -1,6 +1,7 @@
1
1
  import { readFileSync, statSync, writeFileSync } from "node:fs";
2
2
  import { basename } from "node:path";
3
3
  import { CLI_USER_AGENT, getApiUrl, requireApiKey } from "../lib/config.js";
4
+ import { authHeaders } from "../lib/api.js";
4
5
  import * as output from "../lib/output.js";
5
6
  import { getErrorMessage } from "../lib/errors.js";
6
7
  async function readStdin() {
@@ -12,13 +13,6 @@ async function readStdin() {
12
13
  chunks.push(chunk);
13
14
  return Buffer.concat(chunks).toString("utf-8");
14
15
  }
15
- function authHeaders() {
16
- return {
17
- "X-API-Key": requireApiKey(),
18
- "Content-Type": "application/json",
19
- "User-Agent": CLI_USER_AGENT,
20
- };
21
- }
22
16
  // ── List files ──────────────────────────────────────────────────────────
23
17
  export async function filesListCommand(opts) {
24
18
  const spinner = output.spinner("Fetching files...");
@@ -55,8 +49,7 @@ export async function filesListCommand(opts) {
55
49
  }
56
50
  catch (err) {
57
51
  spinner.stop();
58
- output.error(getErrorMessage(err));
59
- process.exit(1);
52
+ output.fatal(getErrorMessage(err));
60
53
  }
61
54
  }
62
55
  // ── Upload file ─────────────────────────────────────────────────────────
@@ -103,8 +96,7 @@ export async function filesUploadCommand(filePath, opts) {
103
96
  }
104
97
  catch (err) {
105
98
  spinner.stop();
106
- output.error(getErrorMessage(err));
107
- process.exit(1);
99
+ output.fatal(getErrorMessage(err));
108
100
  }
109
101
  }
110
102
  // ── Download file ───────────────────────────────────────────────────────
@@ -125,8 +117,7 @@ export async function filesDownloadCommand(fileId) {
125
117
  }
126
118
  catch (err) {
127
119
  spinner.stop();
128
- output.error(getErrorMessage(err));
129
- process.exit(1);
120
+ output.fatal(getErrorMessage(err));
130
121
  }
131
122
  }
132
123
  // ── Create folder ───────────────────────────────────────────────────────
@@ -150,8 +141,7 @@ export async function filesMkdirCommand(name, opts) {
150
141
  }
151
142
  catch (err) {
152
143
  spinner.stop();
153
- output.error(getErrorMessage(err));
154
- process.exit(1);
144
+ output.fatal(getErrorMessage(err));
155
145
  }
156
146
  }
157
147
  // ── Delete file ─────────────────────────────────────────────────────────
@@ -171,8 +161,7 @@ export async function filesRmCommand(fileId) {
171
161
  }
172
162
  catch (err) {
173
163
  spinner.stop();
174
- output.error(getErrorMessage(err));
175
- process.exit(1);
164
+ output.fatal(getErrorMessage(err));
176
165
  }
177
166
  }
178
167
  // ── Storage usage ───────────────────────────────────────────────────────
@@ -203,8 +192,7 @@ export async function filesStorageCommand() {
203
192
  }
204
193
  catch (err) {
205
194
  spinner.stop();
206
- output.error(getErrorMessage(err));
207
- process.exit(1);
195
+ output.fatal(getErrorMessage(err));
208
196
  }
209
197
  }
210
198
  // ── Read file contents ──────────────────────────────────────────────────
@@ -240,8 +228,7 @@ export async function filesCatCommand(fileId, opts) {
240
228
  }
241
229
  catch (err) {
242
230
  spinner.stop();
243
- output.error(getErrorMessage(err));
244
- process.exit(1);
231
+ output.fatal(getErrorMessage(err));
245
232
  }
246
233
  }
247
234
  // ── Edit file (find/replace or overwrite) ───────────────────────────────
@@ -249,16 +236,13 @@ export async function filesEditCommand(fileId, opts) {
249
236
  const hasReplace = opts.find !== undefined || opts.replace !== undefined;
250
237
  const hasOverwrite = opts.content !== undefined || opts.from !== undefined;
251
238
  if (!hasReplace && !hasOverwrite) {
252
- output.error("Specify either --find/--replace for find-and-replace, or --content/--from for full overwrite.");
253
- process.exit(1);
239
+ output.fatal("Specify either --find/--replace for find-and-replace, or --content/--from for full overwrite.");
254
240
  }
255
241
  if (hasReplace && hasOverwrite) {
256
- output.error("Cannot combine --find/--replace with --content/--from.");
257
- process.exit(1);
242
+ output.fatal("Cannot combine --find/--replace with --content/--from.");
258
243
  }
259
244
  if (hasReplace && (opts.find === undefined || opts.replace === undefined)) {
260
- output.error("Find-and-replace requires both --find and --replace.");
261
- process.exit(1);
245
+ output.fatal("Find-and-replace requires both --find and --replace.");
262
246
  }
263
247
  const spinner = output.spinner("Editing file...");
264
248
  try {
@@ -316,8 +300,7 @@ export async function filesEditCommand(fileId, opts) {
316
300
  }
317
301
  catch (err) {
318
302
  spinner.stop();
319
- output.error(getErrorMessage(err));
320
- process.exit(1);
303
+ output.fatal(getErrorMessage(err));
321
304
  }
322
305
  }
323
306
  // ── Write/replace file content from stdin or local file ─────────────────
@@ -342,8 +325,7 @@ export async function filesWriteCommand(fileId, opts) {
342
325
  }
343
326
  catch (err) {
344
327
  spinner.stop();
345
- output.error(getErrorMessage(err));
346
- process.exit(1);
328
+ output.fatal(getErrorMessage(err));
347
329
  }
348
330
  }
349
331
  // ── Search files ────────────────────────────────────────────────────────
@@ -381,8 +363,7 @@ export async function filesSearchCommand(query, opts) {
381
363
  }
382
364
  catch (err) {
383
365
  spinner.stop();
384
- output.error(getErrorMessage(err));
385
- process.exit(1);
366
+ output.fatal(getErrorMessage(err));
386
367
  }
387
368
  }
388
369
  // ── Move file to a different folder ─────────────────────────────────────
@@ -404,8 +385,7 @@ export async function filesMvCommand(fileId, folder) {
404
385
  }
405
386
  catch (err) {
406
387
  spinner.stop();
407
- output.error(getErrorMessage(err));
408
- process.exit(1);
388
+ output.fatal(getErrorMessage(err));
409
389
  }
410
390
  }
411
391
  // ── Rename file ─────────────────────────────────────────────────────────
@@ -427,8 +407,7 @@ export async function filesRenameCommand(fileId, name) {
427
407
  }
428
408
  catch (err) {
429
409
  spinner.stop();
430
- output.error(getErrorMessage(err));
431
- process.exit(1);
410
+ output.fatal(getErrorMessage(err));
432
411
  }
433
412
  }
434
413
  // ── File info ───────────────────────────────────────────────────────────
@@ -456,8 +435,7 @@ export async function filesInfoCommand(fileId) {
456
435
  }
457
436
  catch (err) {
458
437
  spinner.stop();
459
- output.error(getErrorMessage(err));
460
- process.exit(1);
438
+ output.fatal(getErrorMessage(err));
461
439
  }
462
440
  }
463
441
  // ── Helpers ─────────────────────────────────────────────────────────────
@@ -5,9 +5,14 @@ import { requireApiKey } from "../lib/config.js";
5
5
  import * as output from "../lib/output.js";
6
6
  import { getErrorMessage } from "../lib/errors.js";
7
7
  const VALID_FEE_TYPES = ["x", "farcaster", "ens", "wallet"];
8
- const VALID_CHAINS = ["base", "robinhood"];
8
+ const VALID_CHAINS = ["base", "robinhood", "arbitrum"];
9
+ const CHAIN_LABELS = {
10
+ base: "Base",
11
+ robinhood: "Robinhood Chain",
12
+ arbitrum: "Arbitrum",
13
+ };
9
14
  function chainLabel(chain) {
10
- return chain === "robinhood" ? "Robinhood Chain" : "Base";
15
+ return CHAIN_LABELS[chain];
11
16
  }
12
17
  function parseChain(value) {
13
18
  if (!value)
@@ -17,8 +22,7 @@ function parseChain(value) {
17
22
  return lower;
18
23
  // Launching is irreversible and chain-selecting — a mistyped chain must be
19
24
  // a hard usage error, never a silent fallback to Base.
20
- output.error(`Unknown chain "${value}". Valid chains: ${VALID_CHAINS.join(", ")}.`);
21
- process.exit(1);
25
+ output.fatal(`Unknown chain "${value}". Valid chains: ${VALID_CHAINS.join(", ")}.`);
22
26
  }
23
27
  function parseFeeType(value) {
24
28
  if (!value)
@@ -48,8 +52,7 @@ async function promptOrSkip(message) {
48
52
  }
49
53
  async function collectInteractive(options) {
50
54
  if (output.isNonInteractive() && !options.name) {
51
- output.error("--name is required in non-interactive mode");
52
- process.exit(1);
55
+ output.fatal("--name is required in non-interactive mode");
53
56
  }
54
57
  const tokenName = options.name ??
55
58
  (await input({
@@ -67,10 +70,10 @@ async function collectInteractive(options) {
67
70
  if (!chain && !output.isNonInteractive()) {
68
71
  chain = await select({
69
72
  message: "Which chain do you want to launch on?",
70
- choices: [
71
- { name: "Base", value: "base" },
72
- { name: "Robinhood Chain", value: "robinhood" },
73
- ],
73
+ choices: VALID_CHAINS.map((value) => ({
74
+ name: chainLabel(value),
75
+ value,
76
+ })),
74
77
  default: "base",
75
78
  theme: output.bankrTheme,
76
79
  });
@@ -142,8 +145,7 @@ export async function launchCommand(options) {
142
145
  // Collect token details
143
146
  const state = await collectInteractive(options);
144
147
  if (!state.tokenName) {
145
- output.error("Token name is required.");
146
- process.exit(1);
148
+ output.fatal("Token name is required.");
147
149
  }
148
150
  // Display summary
149
151
  console.log();
@@ -229,8 +231,7 @@ export async function launchCommand(options) {
229
231
  catch (err) {
230
232
  spin.fail("Token launch failed");
231
233
  emitCESP("task.error");
232
- output.error(getErrorMessage(err));
233
- process.exit(1);
234
+ output.fatal(getErrorMessage(err));
234
235
  }
235
236
  }
236
237
  //# sourceMappingURL=launch.js.map
@@ -23,6 +23,14 @@ export declare function setupOpenCodeCommand(opts: {
23
23
  }): Promise<void>;
24
24
  export declare function setupCursorCommand(): Promise<void>;
25
25
  export declare function setupClaudeCodeCommand(): Promise<void>;
26
+ /**
27
+ * Rewrite gateway-canonical Claude IDs (dotted, e.g. `claude-opus-4.8`) to
28
+ * the wire format Claude Code expects (dashed, e.g. `claude-opus-4-8`).
29
+ * Otherwise Claude Code silently falls back to its default model — the
30
+ * `--model` flag appears honored but the real request is a different
31
+ * model. Any suffix (e.g. `[1m]` context tier) is preserved.
32
+ */
33
+ export declare function toAnthropicModelId(model: string): string;
26
34
  export declare function claudeCommand(args: string[]): Promise<void>;
27
35
  export declare function opencodeCommand(args: string[]): Promise<void>;
28
36
  //# sourceMappingURL=llm.d.ts.map