@bankr/cli 0.3.37 → 0.3.43

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/dist/cli.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { readFileSync } from "node:fs";
3
2
  import { Command } from "commander";
4
3
  import { input } from "@inquirer/prompts";
5
4
  import { balancesCommand } from "./commands/balances.js";
@@ -9,7 +8,7 @@ import { swapCommand } from "./commands/swap.js";
9
8
  import { skillsCommand } from "./commands/capabilities.js";
10
9
  import { cancelCommand } from "./commands/cancel.js";
11
10
  import { configGetCommand, configSetCommand } from "./commands/config.js";
12
- import { setConfigPath } from "./lib/config.js";
11
+ import { CLI_VERSION, setConfigPath } from "./lib/config.js";
13
12
  import { getErrorMessage } from "./lib/errors.js";
14
13
  import { passthroughArgs } from "./lib/passthrough.js";
15
14
  import { claudeCommand, creditsCommand, creditsAddCommand, creditsAutoCommand, modelsCommand, opencodeCommand, setupClaudeCodeCommand, setupCursorCommand, setupOpenclawCommand, setupOpenCodeCommand, } from "./commands/llm.js";
@@ -18,7 +17,7 @@ import { launchCommand } from "./commands/launch.js";
18
17
  import { launchQuotesCommand } from "./commands/launchQuotes.js";
19
18
  import { loginCommand } from "./commands/login.js";
20
19
  import { logoutCommand } from "./commands/logout.js";
21
- import { promptCommand } from "./commands/prompt.js";
20
+ import { MAX_MODE_MODEL_EXAMPLE, promptCommand } from "./commands/prompt.js";
22
21
  import { signCommand } from "./commands/sign.js";
23
22
  import { soundsDisableCommand, soundsEnableCommand, soundsInstallCommand, soundsListCommand, soundsMuteCommand, soundsSearchCommand, soundsStatusCommand, soundsTestCommand, soundsUnmuteCommand, soundsUseCommand, soundsVolumeCommand, } from "./commands/sounds.js";
24
23
  import { statusCommand } from "./commands/status.js";
@@ -28,12 +27,11 @@ import { whoamiCommand } from "./commands/whoami.js";
28
27
  import { tokensSearchCommand, tokensInfoCommand } from "./commands/tokens.js";
29
28
  import { x402InitCommand, x402AddCommand, x402ConfigureCommand, x402DeployCommand, x402ListCommand, x402PauseResumeCommand, x402DeleteCommand, x402RevenueCommand, x402EnvSetCommand, x402EnvListCommand, x402EnvUnsetCommand, x402SearchCommand, x402SchemaCommand, x402CallCommand, } from "./commands/x402.js";
30
29
  import { webhooksInitCommand, webhooksAddCommand, webhooksDeployCommand, webhooksListCommand, webhooksPauseResumeCommand, webhooksDeleteCommand, webhooksLogsCommand, webhooksEnvSetCommand, webhooksEnvListCommand, webhooksEnvUnsetCommand, } from "./commands/webhooks.js";
31
- import { profileViewCommand, profileCreateCommand, profileUpdateCommand, profileDeleteCommand, profileAddUpdateCommand, } from "./commands/profile.js";
30
+ import { projectViewCommand, projectCreateCommand, projectUpdateCommand, projectDeleteCommand, projectAddUpdateCommand, } from "./commands/project.js";
32
31
  import { filesListCommand, filesUploadCommand, filesDownloadCommand, filesMkdirCommand, filesRmCommand, filesStorageCommand, filesCatCommand, filesEditCommand, filesWriteCommand, filesSearchCommand, filesMvCommand, filesRenameCommand, filesInfoCommand, } from "./commands/files.js";
33
32
  import { clubStatusCommand, clubSignupCommand, clubCancelCommand, } from "./commands/club.js";
34
33
  import * as output from "./lib/output.js";
35
34
  import { checkForUpdate } from "./lib/updateCheck.js";
36
- const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
37
35
  /**
38
36
  * Read prompt text from stdin (piped) or interactively.
39
37
  * Bypasses shell expansion so dollar signs and special characters are preserved.
@@ -81,7 +79,7 @@ function colorizeHelp(text) {
81
79
  program
82
80
  .name("bankr")
83
81
  .description("Bankr AI agent CLI\n\n Docs: https://docs.bankr.bot\n Skills: https://docs.bankr.bot/skills/overview")
84
- .version(pkg.version, "-v, --version", "Show CLI version")
82
+ .version(CLI_VERSION, "-v, --version", "Show CLI version")
85
83
  .helpOption("-h, --help", "Display help")
86
84
  .helpCommand(false)
87
85
  .option("--config <path>", "Path to config file (default: ~/.bankr/config.json)")
@@ -123,8 +121,8 @@ loginCmd
123
121
  .command("email [address]")
124
122
  .description("Sign in with email (sends verification code)")
125
123
  .option("--code <otp>", "OTP code (step 2 of headless login)")
126
- .option("--accept-terms", "Accept Terms of Service (skips prompt)")
127
- .option("--key-name <name>", "API key name (default: CLI)")
124
+ .option("--accept-terms", "Accept Terms of Service (skips prompt; implied by headless login)")
125
+ .option("--key-name <name>", "API key name (default: CLI-<date>-<time>)")
128
126
  .optionsGroup("API Permissions")
129
127
  .option("--read-only", "Restrict the API key to read operations")
130
128
  .option("--read-write", "Allow transactions (the default for new keys)")
@@ -302,10 +300,10 @@ walletSubmitCmd
302
300
  program.commandsGroup("Agent");
303
301
  const agentCmd = program
304
302
  .command("agent [text...]")
305
- .description("AI agent commands (prompt, status, cancel, profile, skills)")
303
+ .description("AI agent commands (prompt, status, cancel, skills)")
306
304
  .option("--thread <id>", "Continue a specific conversation thread")
307
305
  .option("-c, --continue", "Continue the most recent thread")
308
- .option("-m, --model <model>", "Use Max Mode with a specific model (e.g. claude-opus-4.6)")
306
+ .option("-m, --model <model>", `Use Max Mode with a specific model (e.g. ${MAX_MODE_MODEL_EXAMPLE})`)
309
307
  .action(async (text, opts, cmd) => {
310
308
  opts.model ?? (opts.model = cmd.parent?.opts()?.model);
311
309
  const joined = text.join(" ").trim();
@@ -323,7 +321,7 @@ agentCmd
323
321
  .description("Send a prompt to the Bankr AI agent")
324
322
  .option("--thread <id>", "Continue a specific conversation thread")
325
323
  .option("-c, --continue", "Continue the most recent thread")
326
- .option("-m, --model <model>", "Use Max Mode with a specific model (e.g. claude-opus-4.6)")
324
+ .option("-m, --model <model>", `Use Max Mode with a specific model (e.g. ${MAX_MODE_MODEL_EXAMPLE})`)
327
325
  .action(async (text, opts, cmd) => {
328
326
  // Commander hoists --model to the parent when both define it;
329
327
  // fall back to parent/grandparent opts so `bankr agent prompt --model` works.
@@ -334,6 +332,7 @@ agentCmd
334
332
  agentCmd
335
333
  .command("status <jobId>")
336
334
  .description("Check the status of a job")
335
+ .option("-w, --wait", "Follow the job until it finishes, printing progress as it arrives")
337
336
  .action(statusCommand);
338
337
  agentCmd
339
338
  .command("cancel <jobId>")
@@ -410,76 +409,6 @@ feesCmd
410
409
  .option("--all", "Claim all tokens without selection prompt")
411
410
  .option("-y, --yes", "Skip confirmation prompt")
412
411
  .action(feesClaimWalletCommand);
413
- // Profile under agent namespace
414
- const profileCmd = agentCmd
415
- .command("profile")
416
- .description("Manage your agent profile page")
417
- .option("--json", "Output raw JSON")
418
- .action(async (opts) => {
419
- await profileViewCommand({ json: opts.json });
420
- });
421
- profileCmd
422
- .command("create")
423
- .description("Create a new agent profile")
424
- .option("--name <name>", "Project name")
425
- .option("--description <text>", "Project description")
426
- .option("--token <address>", "Token contract address")
427
- .option("--image <url>", "Profile image URL")
428
- .option("--website <url>", "Project website URL")
429
- .option("--json", "Output raw JSON")
430
- .action(async (opts) => {
431
- await profileCreateCommand({
432
- name: opts.name,
433
- description: opts.description,
434
- token: opts.token,
435
- image: opts.image,
436
- website: opts.website,
437
- json: opts.json,
438
- });
439
- });
440
- profileCmd
441
- .command("update")
442
- .description("Update your agent profile")
443
- .option("--slug <slug>", "Project slug (required if multiple profiles)")
444
- .option("--name <name>", "Project name")
445
- .option("--description <text>", "Project description")
446
- .option("--token <address>", "Token contract address")
447
- .option("--image <url>", "Profile image URL")
448
- .option("--website <url>", "Project website URL")
449
- .option("--json", "Output raw JSON")
450
- .action(async (opts) => {
451
- await profileUpdateCommand({
452
- slug: opts.slug,
453
- name: opts.name,
454
- description: opts.description,
455
- token: opts.token,
456
- image: opts.image,
457
- website: opts.website,
458
- json: opts.json,
459
- });
460
- });
461
- profileCmd
462
- .command("delete")
463
- .description("Delete your agent profile")
464
- .option("--slug <slug>", "Project slug (required if multiple profiles)")
465
- .action(async (opts) => {
466
- await profileDeleteCommand({ slug: opts.slug });
467
- });
468
- profileCmd
469
- .command("add-update")
470
- .description("Add a project update to your profile")
471
- .option("--slug <slug>", "Project slug (required if multiple profiles)")
472
- .option("--title <title>", "Update title")
473
- .option("--content <text>", "Update content")
474
- .option("--json", "Output raw JSON")
475
- .action(async (opts) => {
476
- await profileAddUpdateCommand({
477
- slug: opts.slug,
478
- title: opts.title,
479
- content: opts.content,
480
- json: opts.json,
481
- });
482
- });
483
412
  program.commandsGroup("LLM");
484
413
  const llmCmd = program
485
414
  .command("llm")
@@ -639,76 +568,89 @@ program
639
568
  deprecatedCmd("cancel", "agent cancel");
640
569
  await cancelCommand(jobId);
641
570
  });
642
- const profileAliasCmd = program
643
- .command("profile", { hidden: true })
644
- .description("Deprecated: use `bankr agent profile` instead")
645
- .option("--json", "Output raw JSON")
646
- .action(async (opts) => {
647
- deprecatedCmd("profile", "agent profile");
648
- await profileViewCommand({ json: opts.json });
649
- });
650
- profileAliasCmd
651
- .command("create")
652
- .option("--name <name>", "Project name")
653
- .option("--description <text>", "Project description")
654
- .option("--token <address>", "Token contract address")
655
- .option("--image <url>", "Profile image URL")
656
- .option("--website <url>", "Project website URL")
657
- .option("--json", "Output raw JSON")
658
- .action(async (opts) => {
659
- deprecatedCmd("profile create", "agent profile create");
660
- await profileCreateCommand({
661
- name: opts.name,
662
- description: opts.description,
663
- token: opts.token,
664
- image: opts.image,
665
- website: opts.website,
666
- json: opts.json,
571
+ /**
572
+ * Registers the deprecated `profile` tree on `parent`. It runs the project
573
+ * commands; `oldPrefix` is the command path the warning tells users to drop.
574
+ */
575
+ function registerProfileAlias(parent, oldPrefix) {
576
+ const aliasCmd = parent
577
+ .command("profile", { hidden: true })
578
+ .description("Deprecated: use `bankr project` instead")
579
+ .option("--json", "Output raw JSON")
580
+ .action(async (opts) => {
581
+ deprecatedCmd(oldPrefix, "project");
582
+ await projectViewCommand({ json: opts.json });
667
583
  });
668
- });
669
- profileAliasCmd
670
- .command("update")
671
- .option("--slug <slug>", "Project slug")
672
- .option("--name <name>", "Project name")
673
- .option("--description <text>", "Project description")
674
- .option("--token <address>", "Token contract address")
675
- .option("--image <url>", "Profile image URL")
676
- .option("--website <url>", "Project website URL")
677
- .option("--json", "Output raw JSON")
678
- .action(async (opts) => {
679
- deprecatedCmd("profile update", "agent profile update");
680
- await profileUpdateCommand({
681
- slug: opts.slug,
682
- name: opts.name,
683
- description: opts.description,
684
- token: opts.token,
685
- image: opts.image,
686
- website: opts.website,
687
- json: opts.json,
584
+ aliasCmd
585
+ .command("create")
586
+ .description("Deprecated: use `bankr project create`")
587
+ .option("--name <name>", "Project name")
588
+ .option("--description <text>", "Project description")
589
+ .option("--token <address>", "Token contract address")
590
+ .option("--image <url>", "Project image URL")
591
+ .option("--website <url>", "Project website URL")
592
+ .option("--json", "Output raw JSON")
593
+ .action(async (opts) => {
594
+ deprecatedCmd(`${oldPrefix} create`, "project create");
595
+ await projectCreateCommand({
596
+ name: opts.name,
597
+ description: opts.description,
598
+ token: opts.token,
599
+ image: opts.image,
600
+ website: opts.website,
601
+ json: opts.json,
602
+ });
688
603
  });
689
- });
690
- profileAliasCmd
691
- .command("delete")
692
- .option("--slug <slug>", "Project slug")
693
- .action(async (opts) => {
694
- deprecatedCmd("profile delete", "agent profile delete");
695
- await profileDeleteCommand({ slug: opts.slug });
696
- });
697
- profileAliasCmd
698
- .command("add-update")
699
- .option("--slug <slug>", "Project slug")
700
- .option("--title <title>", "Update title")
701
- .option("--content <text>", "Update content")
702
- .option("--json", "Output raw JSON")
703
- .action(async (opts) => {
704
- deprecatedCmd("profile add-update", "agent profile add-update");
705
- await profileAddUpdateCommand({
706
- slug: opts.slug,
707
- title: opts.title,
708
- content: opts.content,
709
- json: opts.json,
604
+ aliasCmd
605
+ .command("update")
606
+ .description("Deprecated: use `bankr project update`")
607
+ .option("--slug <slug>", "Project slug")
608
+ .option("--name <name>", "Project name")
609
+ .option("--description <text>", "Project description")
610
+ .option("--token <address>", "Token contract address")
611
+ .option("--image <url>", "Project image URL")
612
+ .option("--website <url>", "Project website URL")
613
+ .option("--json", "Output raw JSON")
614
+ .action(async (opts) => {
615
+ deprecatedCmd(`${oldPrefix} update`, "project update");
616
+ await projectUpdateCommand({
617
+ slug: opts.slug,
618
+ name: opts.name,
619
+ description: opts.description,
620
+ token: opts.token,
621
+ image: opts.image,
622
+ website: opts.website,
623
+ json: opts.json,
624
+ });
710
625
  });
711
- });
626
+ aliasCmd
627
+ .command("delete")
628
+ .description("Deprecated: use `bankr project delete`")
629
+ .option("--slug <slug>", "Project slug")
630
+ .action(async (opts) => {
631
+ deprecatedCmd(`${oldPrefix} delete`, "project delete");
632
+ await projectDeleteCommand({ slug: opts.slug });
633
+ });
634
+ aliasCmd
635
+ .command("add-update")
636
+ .description("Deprecated: use `bankr project add-update`")
637
+ .option("--slug <slug>", "Project slug")
638
+ .option("--title <title>", "Update title")
639
+ .option("--content <text>", "Update content")
640
+ .option("--json", "Output raw JSON")
641
+ .action(async (opts) => {
642
+ deprecatedCmd(`${oldPrefix} add-update`, "project add-update");
643
+ await projectAddUpdateCommand({
644
+ slug: opts.slug,
645
+ title: opts.title,
646
+ content: opts.content,
647
+ json: opts.json,
648
+ });
649
+ });
650
+ }
651
+ // `bankr agent profile` (now `bankr project`) and the older top-level `bankr profile`.
652
+ registerProfileAlias(agentCmd, "agent profile");
653
+ registerProfileAlias(program, "profile");
712
654
  program
713
655
  .command("sign", { hidden: true })
714
656
  .description("Deprecated: use `bankr wallet sign` instead")
@@ -863,6 +805,76 @@ clubCmd
863
805
  .description("Cancel your Bankr Club subscription")
864
806
  .option("-y, --yes", "Skip confirmation prompt")
865
807
  .action(clubCancelCommand);
808
+ // ── Project Pages ─────────────────────────────────────────────
809
+ const projectCmd = program
810
+ .command("project")
811
+ .description("Manage your project page")
812
+ .option("--json", "Output raw JSON")
813
+ .action(async (opts) => {
814
+ await projectViewCommand({ json: opts.json });
815
+ });
816
+ projectCmd
817
+ .command("create")
818
+ .description("Create a new project")
819
+ .option("--name <name>", "Project name")
820
+ .option("--description <text>", "Project description")
821
+ .option("--token <address>", "Token contract address")
822
+ .option("--image <url>", "Project image URL")
823
+ .option("--website <url>", "Project website URL")
824
+ .option("--json", "Output raw JSON")
825
+ .action(async (opts) => {
826
+ await projectCreateCommand({
827
+ name: opts.name,
828
+ description: opts.description,
829
+ token: opts.token,
830
+ image: opts.image,
831
+ website: opts.website,
832
+ json: opts.json,
833
+ });
834
+ });
835
+ projectCmd
836
+ .command("update")
837
+ .description("Update your project")
838
+ .option("--slug <slug>", "Project slug (required if multiple projects)")
839
+ .option("--name <name>", "Project name")
840
+ .option("--description <text>", "Project description")
841
+ .option("--token <address>", "Token contract address")
842
+ .option("--image <url>", "Project image URL")
843
+ .option("--website <url>", "Project website URL")
844
+ .option("--json", "Output raw JSON")
845
+ .action(async (opts) => {
846
+ await projectUpdateCommand({
847
+ slug: opts.slug,
848
+ name: opts.name,
849
+ description: opts.description,
850
+ token: opts.token,
851
+ image: opts.image,
852
+ website: opts.website,
853
+ json: opts.json,
854
+ });
855
+ });
856
+ projectCmd
857
+ .command("delete")
858
+ .description("Delete your project")
859
+ .option("--slug <slug>", "Project slug (required if multiple projects)")
860
+ .action(async (opts) => {
861
+ await projectDeleteCommand({ slug: opts.slug });
862
+ });
863
+ projectCmd
864
+ .command("add-update")
865
+ .description("Add a project update to your project page")
866
+ .option("--slug <slug>", "Project slug (required if multiple projects)")
867
+ .option("--title <title>", "Update title")
868
+ .option("--content <text>", "Update content")
869
+ .option("--json", "Output raw JSON")
870
+ .action(async (opts) => {
871
+ await projectAddUpdateCommand({
872
+ slug: opts.slug,
873
+ title: opts.title,
874
+ content: opts.content,
875
+ json: opts.json,
876
+ });
877
+ });
866
878
  // ── x402 Endpoint Hosting ─────────────────────────────────────────────
867
879
  program.commandsGroup("Protocol");
868
880
  const x402Cmd = program
@@ -1061,7 +1073,7 @@ program
1061
1073
  .arguments("[text...]")
1062
1074
  .option("--thread <id>", "Continue a specific conversation thread")
1063
1075
  .option("-c, --continue", "Continue the most recent thread")
1064
- .option("-m, --model <model>", "Use Max Mode with a specific model (e.g. claude-opus-4.6)")
1076
+ .option("-m, --model <model>", `Use Max Mode with a specific model (e.g. ${MAX_MODE_MODEL_EXAMPLE})`)
1065
1077
  .action(async (text, opts) => {
1066
1078
  if (text.length === 0) {
1067
1079
  if (output.isNonInteractive()) {
@@ -1084,7 +1096,7 @@ async function main() {
1084
1096
  }
1085
1097
  output.fatal(getErrorMessage(err));
1086
1098
  }
1087
- await checkForUpdate(pkg.version);
1099
+ await checkForUpdate(CLI_VERSION);
1088
1100
  }
1089
1101
  main();
1090
1102
  //# sourceMappingURL=cli.js.map
@@ -3,6 +3,7 @@ import { confirm, password, checkbox } from "@inquirer/prompts";
3
3
  import { isAddress } from "viem";
4
4
  import { getCreatorFees, getBeneficiaryFeesStreaming, getTokenCreatorFees, getUserInfo, claimTokenLaunchFees, } from "../lib/api.js";
5
5
  import { emitCESP } from "../lib/cesp/engine.js";
6
+ import { CHAIN_LABELS } from "../lib/chains.js";
6
7
  import { requireApiKey } from "../lib/config.js";
7
8
  import { txExplorer } from "../lib/explorer.js";
8
9
  import * as output from "../lib/output.js";
@@ -129,7 +130,7 @@ function drawChart(dailyData) {
129
130
  const xAxisPadding = " ".repeat(14);
130
131
  if (dailyData.length > 0) {
131
132
  const first = dailyData[0].date.slice(5);
132
- const last = dailyData[dailyData.length - 1].date.slice(5);
133
+ const last = dailyData.at(-1).date.slice(5);
133
134
  const mid = dailyData[Math.floor(dailyData.length / 2)].date.slice(5);
134
135
  const gap1 = Math.floor(CHART_WIDTH / 2) - first.length;
135
136
  const gap2 = CHART_WIDTH - Math.floor(CHART_WIDTH / 2) - mid.length;
@@ -653,12 +654,21 @@ export async function feesClaimWalletCommand(address, opts) {
653
654
  ],
654
655
  },
655
656
  ];
656
- // Robinhood-chain launches can't be claimed here: this flow signs and
657
- // broadcasts on Base only, and a Base tx to a robinhood initializer is a
658
- // gas-burning no-op. Skip them loudly.
659
- const baseChainTokens = selectedTokens.filter((t) => (t.chain ?? "base") === "base");
660
- if (baseChainTokens.length < selectedTokens.length) {
661
- output.warn(`${selectedTokens.length - baseChainTokens.length} Robinhood Chain token(s) skipped — CLI claiming supports Base only for now. Claim at https://bankr.bot/launches instead.`);
657
+ // Launches on other chains can't be claimed here: this flow signs and
658
+ // broadcasts on Base only, and a Base tx to another chain's initializer is a
659
+ // gas-burning no-op. Skip them loudly, linking each token page's claim flow.
660
+ const chainOf = (t) => t.chain ?? "base";
661
+ const baseChainTokens = selectedTokens.filter((t) => chainOf(t) === "base");
662
+ const skippedTokens = selectedTokens.filter((t) => chainOf(t) !== "base");
663
+ if (skippedTokens.length > 0) {
664
+ const names = [...new Set(skippedTokens.map(chainOf))].map((chain) => CHAIN_LABELS[chain] ?? chain);
665
+ const skippedChains = names.length > 1
666
+ ? `${names.slice(0, -1).join(", ")} and ${names[names.length - 1]}`
667
+ : names[0];
668
+ output.warn(`${skippedTokens.length} ${skippedChains} token(s) skipped — CLI claiming supports Base only for now. Claim them on each token's page instead:`);
669
+ for (const t of skippedTokens) {
670
+ output.dim(` ${t.symbol}: https://bankr.bot/terminal/trade?out=${t.tokenAddress}&chain=${chainOf(t)}`);
671
+ }
662
672
  }
663
673
  // Filter to tokens with initializer (required for local tx building)
664
674
  const buildableTokens = baseChainTokens.filter((t) => t.initializer);
@@ -38,6 +38,15 @@ const GATEWAY_MODELS = [
38
38
  input: IMAGE_INPUT,
39
39
  cost: { input: 10.0, output: 50.0, cacheRead: 1.0, cacheWrite: 12.5 },
40
40
  },
41
+ {
42
+ id: "claude-opus-5.5",
43
+ name: "Claude Opus 5.5",
44
+ owned_by: "anthropic",
45
+ contextWindow: 1000000,
46
+ maxTokens: 128000,
47
+ input: IMAGE_INPUT,
48
+ cost: { input: 4.0, output: 20.0, cacheRead: 0.2, cacheWrite: 5.0 },
49
+ },
41
50
  {
42
51
  id: "claude-opus-5",
43
52
  name: "Claude Opus 5",
@@ -83,6 +92,15 @@ const GATEWAY_MODELS = [
83
92
  input: IMAGE_INPUT,
84
93
  cost: { input: 5.0, output: 25.0, cacheRead: 0.5, cacheWrite: 6.25 },
85
94
  },
95
+ {
96
+ id: "claude-sonnet-5.5",
97
+ name: "Claude Sonnet 5.5",
98
+ owned_by: "anthropic",
99
+ contextWindow: 1000000,
100
+ maxTokens: 128000,
101
+ input: IMAGE_INPUT,
102
+ cost: { input: 2.0, output: 10.0, cacheRead: 0.2, cacheWrite: 2.5 },
103
+ },
86
104
  {
87
105
  id: "claude-sonnet-5",
88
106
  name: "Claude Sonnet 5",
@@ -182,6 +200,12 @@ const GATEWAY_MODELS = [
182
200
  maxTokens: 65536,
183
201
  input: IMAGE_INPUT,
184
202
  cost: { input: 1.25, output: 10.0, cacheRead: 0.125, cacheWrite: 0.375 },
203
+ // Google retires the 2.5 line on 2026-10-20 (published on every Vertex
204
+ // endpoint). Without this the offline catalog advertises it as active.
205
+ deprecation: {
206
+ replaced_by: "gemini-3.1-pro",
207
+ removed_at: "2026-10-20T00:00:00.000Z",
208
+ },
185
209
  },
186
210
  {
187
211
  id: "gemini-2.5-flash",
@@ -191,6 +215,10 @@ const GATEWAY_MODELS = [
191
215
  maxTokens: 65535,
192
216
  input: IMAGE_INPUT,
193
217
  cost: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0.0833 },
218
+ deprecation: {
219
+ replaced_by: "gemini-3.8-flash",
220
+ removed_at: "2026-10-20T00:00:00.000Z",
221
+ },
194
222
  },
195
223
  // Gemma
196
224
  {
@@ -243,6 +271,24 @@ const GATEWAY_MODELS = [
243
271
  input: IMAGE_INPUT,
244
272
  cost: { input: 10.0, output: 50.0, cacheRead: 1.0, cacheWrite: 12.5 },
245
273
  },
274
+ {
275
+ id: "gpt-6-sol",
276
+ name: "GPT 6 Sol",
277
+ owned_by: "openai",
278
+ contextWindow: 1050000,
279
+ maxTokens: 128000,
280
+ input: IMAGE_INPUT,
281
+ cost: { input: 2.0, output: 10.0, cacheRead: 0.2, cacheWrite: 2.5 },
282
+ },
283
+ {
284
+ id: "gpt-6-luna",
285
+ name: "GPT 6 Luna",
286
+ owned_by: "openai",
287
+ contextWindow: 1050000,
288
+ maxTokens: 128000,
289
+ input: IMAGE_INPUT,
290
+ cost: { input: 0.1, output: 0.5, cacheRead: 0.01, cacheWrite: 0.125 },
291
+ },
246
292
  {
247
293
  id: "gpt-5.6-sol",
248
294
  name: "GPT 5.6 Sol",
@@ -355,6 +401,15 @@ const GATEWAY_MODELS = [
355
401
  cost: { input: 0.05, output: 0.4, cacheRead: 0.005, cacheWrite: 0 },
356
402
  },
357
403
  // Other providers
404
+ {
405
+ id: "grok-4.7",
406
+ name: "Grok 4.7",
407
+ owned_by: "x-ai",
408
+ contextWindow: 500000,
409
+ maxTokens: 500000,
410
+ input: IMAGE_INPUT,
411
+ cost: { input: 2.0, output: 6.0, cacheRead: 0.5, cacheWrite: 0 },
412
+ },
358
413
  {
359
414
  id: "grok-4.6",
360
415
  name: "Grok 4.6",
@@ -604,6 +659,15 @@ const GATEWAY_MODELS = [
604
659
  input: TEXT_INPUT,
605
660
  cost: { input: 0.6, output: 2.4, cacheRead: 0.06, cacheWrite: 0 },
606
661
  },
662
+ {
663
+ id: "glm-5.3-flashx",
664
+ name: "GLM-5.3 FlashX",
665
+ owned_by: "z-ai",
666
+ contextWindow: 1048576,
667
+ maxTokens: 131072,
668
+ input: IMAGE_INPUT,
669
+ cost: { input: 0.37, output: 1.25, cacheRead: 0.075, cacheWrite: 0 },
670
+ },
607
671
  {
608
672
  id: "glm-5.3-flash",
609
673
  name: "GLM-5.3 Flash",
@@ -1,3 +1,51 @@
1
+ /**
2
+ * Thrown when a login-gated call answers with the MFA step-up envelope. A
3
+ * passkey ceremony can't run in a terminal, so the email flow can't recover;
4
+ * the caller turns this into the browser-key guidance instead of the server's
5
+ * fallback text.
6
+ */
7
+ export declare class MfaStepUpError extends Error {
8
+ readonly context: string;
9
+ constructor(context: string);
10
+ }
11
+ /** Keyed on `code`, never on message text, so a server wording change can't
12
+ * silently turn this back into the opaque failure. */
13
+ export declare function mfaStepUpErrorFrom(body: unknown): MfaStepUpError | null;
14
+ /** Any 5xx: a gateway page (ALB/CloudFront 502/503/504) the API never saw, or
15
+ * an API catch-all such as a DB blip. Idempotent callers retry it; the API's
16
+ * own message, when it sent one, is kept for the final report. */
17
+ export declare class TransientHttpError extends Error {
18
+ readonly status: number;
19
+ constructor(status: number, apiMessage?: string);
20
+ }
21
+ /** True for a request the API never answered: undici's `fetch failed`, a
22
+ * socket-level code, or a gateway error page. An API refusal is not one. */
23
+ export declare function isTransientNetworkError(err: unknown, depth?: number): boolean;
24
+ /**
25
+ * Retry a login step on network blips only. The OTP is already spent by the
26
+ * time the wallet step runs, so a dropped connection here used to cost the
27
+ * user a fresh code; three quick attempts ride out the transient case.
28
+ */
29
+ export declare function withNetworkRetry<T>(run: () => Promise<T>, opts?: {
30
+ attempts?: number;
31
+ baseDelayMs?: number;
32
+ sleep?: (ms: number) => Promise<void>;
33
+ }): Promise<T>;
34
+ /** Key names are unique per user, so the default carries the time to the
35
+ * second: a scripted re-login seconds after a dropped mint response (which
36
+ * already created the key) must not collide with the earlier default. */
37
+ export declare function defaultCliKeyName(now?: Date): string;
38
+ /** Headless login (`--code` / `--ni`) accepts the Terms of Service as part of
39
+ * logging in, so the one-time code isn't burned on a missing flag. Interactive
40
+ * login returns undefined to defer to the prompt. */
41
+ export declare function resolveTermsAcceptance(opts: {
42
+ headless: boolean;
43
+ acceptTerms?: boolean;
44
+ }): boolean | undefined;
45
+ /** The web app that fronts an API URL: `BANKR_WEB_URL` when set (local dev,
46
+ * staging), bankr.bot for the official API, else the API host with its
47
+ * `api.`/`api-` prefix dropped. */
48
+ export declare function deriveWebOrigin(apiUrl: string): string;
1
49
  /**
2
50
  * Both Privy credentials minted by the OTP exchange. The identity token alone
3
51
  * authenticates, but only the ACCESS token carries the session `sid` claim —
@@ -24,6 +72,33 @@ export declare function resolveKeyPermissionOverrides(opts: {
24
72
  readOnly?: boolean;
25
73
  agentApiEnabled?: boolean;
26
74
  };
75
+ /**
76
+ * Parse a login-gated response. The body is read as text first so a gateway
77
+ * HTML error page becomes a `TransientHttpError` instead of a `SyntaxError`
78
+ * from `res.json()`. Every 5xx is transient (callers that opted into the
79
+ * retry replay it; others just report it); a 4xx keeps the API's message.
80
+ */
81
+ export declare function readGatedResponse<T>(res: Response, label: string): Promise<T>;
82
+ declare const CHALLENGE_STATUSES: readonly ["pending", "verified", "expired", "abandoned", "failed"];
83
+ export type ChallengeStatus = (typeof CHALLENGE_STATUSES)[number];
84
+ /**
85
+ * One poll's outcome from its HTTP status. Only a definitive refusal ends the
86
+ * wait: the gate (401, an API without this route yet), another wallet's token
87
+ * (403) or a gone challenge (404). Anything else — 429, 5xx, a dropped
88
+ * connection — is a blip, so the wait keeps polling as if still pending.
89
+ */
90
+ export declare function pollOutcome(httpStatus: number, body: unknown): ChallengeStatus;
91
+ /**
92
+ * Poll until the challenge leaves `pending` or the deadline passes: once at
93
+ * once, then every 2s for the first 30s, then every 5s. Pure over its
94
+ * collaborators so the loop is unit-testable without a network.
95
+ */
96
+ export declare function waitForChallengeApproval(deps: {
97
+ poll: () => Promise<ChallengeStatus>;
98
+ sleep: (ms: number) => Promise<void>;
99
+ deadlineMs: number;
100
+ now?: () => number;
101
+ }): Promise<ChallengeStatus>;
27
102
  export declare function loginCommand(opts: {
28
103
  apiUrl?: string;
29
104
  apiKey?: string;