gearbox-code 0.1.16 → 0.1.19

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.
Files changed (2) hide show
  1. package/dist/cli.mjs +384 -193
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -106134,7 +106134,7 @@ var init_catalog = __esm(() => {
106134
106134
  { id: "deepseek", label: "DeepSeek", group: "native", exec: "in-loop", authKind: "api-key", envVars: ["DEEPSEEK_API_KEY"], baseUrl: "https://api.deepseek.com/v1", signupUrl: "https://platform.deepseek.com/api_keys", defaultModels: ["deepseek-v4-pro", "deepseek-v4-flash"] },
106135
106135
  { id: "xai", label: "xAI (Grok)", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["XAI_API_KEY"], keyPrefix: ["xai-"], baseUrl: "https://api.x.ai/v1", signupUrl: "https://console.x.ai", defaultModels: ["grok-4.3", "grok-4.1-fast"] },
106136
106136
  { id: "mistral", label: "Mistral", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["MISTRAL_API_KEY"], baseUrl: "https://api.mistral.ai/v1", signupUrl: "https://console.mistral.ai/api-keys", defaultModels: ["mistral-large-latest", "codestral-latest"] },
106137
- { id: "groq", label: "Groq", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["GROQ_API_KEY"], keyPrefix: ["gsk_"], baseUrl: "https://api.groq.com/openai/v1", signupUrl: "https://console.groq.com/keys", defaultModels: ["llama-3.3-70b-versatile", "moonshotai/kimi-k2-instruct"] },
106137
+ { id: "groq", label: "Groq", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["GROQ_API_KEY"], keyPrefix: ["gsk_"], baseUrl: "https://api.groq.com/openai/v1", signupUrl: "https://console.groq.com/keys", defaultModels: ["llama-3.3-70b-versatile", "qwen-qwq-32b", "gemma2-9b-it"] },
106138
106138
  { id: "together", label: "Together AI", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["TOGETHER_API_KEY"], baseUrl: "https://api.together.xyz/v1", signupUrl: "https://api.together.ai/settings/api-keys", defaultModels: ["deepseek-ai/DeepSeek-V3", "Qwen/Qwen2.5-Coder-32B-Instruct"] },
106139
106139
  { id: "fireworks", label: "Fireworks", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["FIREWORKS_API_KEY"], keyPrefix: ["fw_"], baseUrl: "https://api.fireworks.ai/inference/v1", signupUrl: "https://fireworks.ai/account/api-keys", defaultModels: ["accounts/fireworks/models/deepseek-v3"] },
106140
106140
  { id: "deepinfra", label: "DeepInfra", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["DEEPINFRA_API_KEY"], baseUrl: "https://api.deepinfra.com/v1/openai", signupUrl: "https://deepinfra.com/dash/api_keys" },
@@ -106153,9 +106153,9 @@ var init_catalog = __esm(() => {
106153
106153
  { id: "portkey", label: "Portkey", group: "gateway", exec: "in-loop", authKind: "openai-compat", envVars: ["PORTKEY_API_KEY"], baseUrl: "https://api.portkey.ai/v1", signupUrl: "https://app.portkey.ai", notes: "Config-driven routing via x-portkey-* headers." },
106154
106154
  { id: "litellm", label: "LiteLLM proxy", group: "gateway", exec: "in-loop", authKind: "openai-compat", envVars: ["LITELLM_API_KEY"], signupUrl: "https://docs.litellm.ai/docs/simple_proxy", notes: "Self-hosted; set baseUrl to your proxy." },
106155
106155
  { id: "azure-foundry", label: "Azure AI Foundry", group: "gateway", exec: "in-loop", authKind: "openai-compat", envVars: ["AZURE_AI_FOUNDRY_API_KEY", "AZURE_AI_INFERENCE_API_KEY"], signupUrl: "https://ai.azure.com", defaultModels: ["gpt-5.5", "gpt-5.5-mini", "gpt-4.1", "o4-mini"], notes: "OpenAI-compatible Foundry endpoint. Use baseUrl ending in /openai/v1." },
106156
- { id: "bedrock", label: "Amazon Bedrock", group: "cloud", exec: "in-loop", authKind: "aws", envVars: ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_REGION", "AWS_PROFILE"], keyPrefix: ["AKIA", "ASIA"], signupUrl: "https://console.aws.amazon.com/bedrock", defaultModels: ["anthropic.claude-sonnet-4-20250514-v1:0"], notes: "Needs @ai-sdk/amazon-bedrock (P2)." },
106157
- { id: "vertex", label: "Google Vertex AI", group: "cloud", exec: "in-loop", authKind: "vertex", envVars: ["GOOGLE_VERTEX_PROJECT", "GOOGLE_VERTEX_LOCATION", "GOOGLE_APPLICATION_CREDENTIALS"], signupUrl: "https://console.cloud.google.com/vertex-ai", defaultModels: ["gemini-3.1-pro-preview"], notes: "ADC or a service-account JSON." },
106158
- { id: "azure", label: "Azure OpenAI", group: "cloud", exec: "in-loop", authKind: "azure", envVars: ["AZURE_API_KEY", "AZURE_RESOURCE_NAME"], signupUrl: "https://oai.azure.com", notes: "Needs @ai-sdk/azure (P2); resourceName + deployment." },
106156
+ { id: "bedrock", label: "Amazon Bedrock", group: "cloud", exec: "in-loop", authKind: "aws", envVars: ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_REGION", "AWS_PROFILE"], keyPrefix: ["AKIA", "ASIA"], signupUrl: "https://console.aws.amazon.com/bedrock", defaultModels: ["anthropic.claude-sonnet-4-20250514-v1:0", "anthropic.claude-haiku-4-5-20251001-v1:0", "anthropic.claude-opus-4-20250514-v1:0", "amazon.nova-pro-v1:0", "amazon.nova-lite-v1:0", "amazon.nova-micro-v1:0", "meta.llama4-maverick-17b-instruct-v1:0", "meta.llama4-scout-17b-instruct-v1:0"], notes: "AWS IAM credentials or ~/.aws profile. Enable models in the Bedrock console first." },
106157
+ { id: "vertex", label: "Google Vertex AI", group: "cloud", exec: "in-loop", authKind: "vertex", envVars: ["GOOGLE_VERTEX_PROJECT", "GOOGLE_VERTEX_LOCATION", "GOOGLE_APPLICATION_CREDENTIALS"], signupUrl: "https://console.cloud.google.com/vertex-ai", defaultModels: ["gemini-3.1-pro-preview", "gemini-3.5-flash", "gemini-3.1-flash-lite"], notes: "ADC (gcloud auth application-default login) or a service-account JSON." },
106158
+ { id: "azure", label: "Azure OpenAI", group: "cloud", exec: "in-loop", authKind: "azure", envVars: ["AZURE_API_KEY", "AZURE_RESOURCE_NAME"], signupUrl: "https://oai.azure.com", defaultModels: ["gpt-5.5", "gpt-5.5-mini", "gpt-4.1"], notes: "resourceName (e.g. my-resource) + API key. Model IDs are your deployment names." },
106159
106159
  { id: "ollama", label: "Ollama (local)", group: "local", exec: "in-loop", authKind: "openai-compat", envVars: [], baseUrl: "http://localhost:11434/v1", signupUrl: "https://ollama.com", defaultModels: ["qwen2.5-coder:7b", "llama3.3"], notes: "No key; runs on your machine." },
106160
106160
  { id: "lmstudio", label: "LM Studio (local)", group: "local", exec: "in-loop", authKind: "openai-compat", envVars: [], baseUrl: "http://localhost:1234/v1", signupUrl: "https://lmstudio.ai" },
106161
106161
  { id: "vllm", label: "vLLM (local/self-host)", group: "local", exec: "in-loop", authKind: "openai-compat", envVars: [], baseUrl: "http://localhost:8000/v1", signupUrl: "https://docs.vllm.ai" },
@@ -106322,8 +106322,19 @@ var init_providers = __esm(() => {
106322
106322
  { id: "gpt-5.5-pro", provider: "openai", sdkId: "gpt-5.5-pro", label: "gpt-5.5-pro", contextWindow: 400000, cost: { inUSDPerMtok: 15, outUSDPerMtok: 120 }, reasoning: true, efforts: ["none", "minimal", "low", "medium", "high", "xhigh"] },
106323
106323
  { id: "gemini-3.1-pro-preview", provider: "google", sdkId: "gemini-3.1-pro-preview", label: "gemini-3.1-pro", contextWindow: 1e6, cost: { inUSDPerMtok: 2, outUSDPerMtok: 12 }, reasoning: true, efforts: ["minimal", "low", "medium", "high"] },
106324
106324
  { id: "gemini-3.5-flash", provider: "google", sdkId: "gemini-3.5-flash", label: "gemini-3.5-flash", contextWindow: 1e6, cost: { inUSDPerMtok: 0.3, outUSDPerMtok: 2.5 }, reasoning: true, efforts: ["minimal", "low", "medium", "high"] },
106325
- { id: "deepseek-v4-pro", provider: "deepseek", sdkId: "deepseek-v4-pro", label: "deepseek-v4-pro", contextWindow: 128000, cost: { inUSDPerMtok: 0.4, outUSDPerMtok: 1.75 }, reasoning: true },
106326
- { id: "deepseek-v4-flash", provider: "deepseek", sdkId: "deepseek-v4-flash", label: "deepseek-v4-flash", contextWindow: 128000, cost: { inUSDPerMtok: 0.27, outUSDPerMtok: 1.1 } }
106325
+ { id: "deepseek-v4-pro", provider: "deepseek", sdkId: "deepseek-v4-pro", label: "deepseek-v4-pro", contextWindow: 128000, cost: { inUSDPerMtok: 0.4, outUSDPerMtok: 1.75 } },
106326
+ { id: "deepseek-v4-flash", provider: "deepseek", sdkId: "deepseek-v4-flash", label: "deepseek-v4-flash", contextWindow: 128000, cost: { inUSDPerMtok: 0.27, outUSDPerMtok: 1.1 } },
106327
+ { id: "bedrock/anthropic.claude-sonnet-4-20250514-v1:0", provider: "bedrock", sdkId: "anthropic.claude-sonnet-4-20250514-v1:0", label: "bedrock/sonnet-4", contextWindow: 200000, cost: { inUSDPerMtok: 3.3, outUSDPerMtok: 16.5 }, reasoning: true, efforts: ["low", "medium", "high", "max"] },
106328
+ { id: "bedrock/anthropic.claude-haiku-4-5-20251001-v1:0", provider: "bedrock", sdkId: "anthropic.claude-haiku-4-5-20251001-v1:0", label: "bedrock/haiku-4.5", contextWindow: 200000, cost: { inUSDPerMtok: 1.1, outUSDPerMtok: 5.5 }, reasoning: true, efforts: ["low", "medium", "high", "max"] },
106329
+ { id: "bedrock/anthropic.claude-opus-4-20250514-v1:0", provider: "bedrock", sdkId: "anthropic.claude-opus-4-20250514-v1:0", label: "bedrock/opus-4", contextWindow: 200000, cost: { inUSDPerMtok: 5.5, outUSDPerMtok: 27.5 }, reasoning: true, efforts: ["low", "medium", "high", "max"] },
106330
+ { id: "bedrock/amazon.nova-pro-v1:0", provider: "bedrock", sdkId: "amazon.nova-pro-v1:0", label: "bedrock/nova-pro", contextWindow: 300000, cost: { inUSDPerMtok: 0.8, outUSDPerMtok: 3.2 } },
106331
+ { id: "bedrock/amazon.nova-lite-v1:0", provider: "bedrock", sdkId: "amazon.nova-lite-v1:0", label: "bedrock/nova-lite", contextWindow: 300000, cost: { inUSDPerMtok: 0.06, outUSDPerMtok: 0.24 } },
106332
+ { id: "bedrock/amazon.nova-micro-v1:0", provider: "bedrock", sdkId: "amazon.nova-micro-v1:0", label: "bedrock/nova-micro", contextWindow: 128000, cost: { inUSDPerMtok: 0.035, outUSDPerMtok: 0.14 } },
106333
+ { id: "bedrock/meta.llama4-maverick-17b-instruct-v1:0", provider: "bedrock", sdkId: "meta.llama4-maverick-17b-instruct-v1:0", label: "bedrock/llama-4-mav", contextWindow: 128000, cost: { inUSDPerMtok: 0.24, outUSDPerMtok: 0.97 } },
106334
+ { id: "bedrock/meta.llama4-scout-17b-instruct-v1:0", provider: "bedrock", sdkId: "meta.llama4-scout-17b-instruct-v1:0", label: "bedrock/llama-4-scout", contextWindow: 128000, cost: { inUSDPerMtok: 0.17, outUSDPerMtok: 0.66 } },
106335
+ { id: "vertex/gemini-3.1-pro-preview", provider: "vertex", sdkId: "gemini-3.1-pro-preview", label: "vertex/gemini-3.1-pro", contextWindow: 1e6, cost: { inUSDPerMtok: 2, outUSDPerMtok: 12 }, reasoning: true, efforts: ["minimal", "low", "medium", "high"] },
106336
+ { id: "vertex/gemini-3.5-flash", provider: "vertex", sdkId: "gemini-3.5-flash", label: "vertex/gemini-3.5-flash", contextWindow: 1e6, cost: { inUSDPerMtok: 0.3, outUSDPerMtok: 2.5 }, reasoning: true, efforts: ["minimal", "low", "medium", "high"] },
106337
+ { id: "vertex/gemini-3.1-flash-lite", provider: "vertex", sdkId: "gemini-3.1-flash-lite", label: "vertex/gemini-3.1-flash-lite", contextWindow: 1e6, cost: { inUSDPerMtok: 0.1, outUSDPerMtok: 0.4 } }
106327
106338
  ];
106328
106339
  MODELS = [...CURATED, ...generatedModels()];
106329
106340
  ENV_KEY = {
@@ -106371,12 +106382,13 @@ var init_permission = __esm(() => {
106371
106382
  function profileFor(id) {
106372
106383
  return BY_ID2.get(id);
106373
106384
  }
106374
- var CLAUDE_TOK, TIKTOKEN, GEMINI_TOK, DEEPSEEK_TOK, PROFILES, BY_ID2;
106385
+ var CLAUDE_TOK, TIKTOKEN, GEMINI_TOK, DEEPSEEK_TOK, LLAMA_TOK, PROFILES, BY_ID2;
106375
106386
  var init_profiles = __esm(() => {
106376
106387
  CLAUDE_TOK = { family: "claude", calibration: 1.35, calibrationSrc: "measured" };
106377
106388
  TIKTOKEN = { family: "tiktoken-o200k", calibration: 1, calibrationSrc: "measured" };
106378
106389
  GEMINI_TOK = { family: "gemini", calibration: 1.1, calibrationSrc: "seeded" };
106379
106390
  DEEPSEEK_TOK = { family: "deepseek", calibration: 1.05, calibrationSrc: "seeded" };
106391
+ LLAMA_TOK = { family: "llama", calibration: 1.1, calibrationSrc: "seeded" };
106380
106392
  PROFILES = [
106381
106393
  {
106382
106394
  id: "claude-opus-4-8",
@@ -106468,12 +106480,171 @@ var init_profiles = __esm(() => {
106468
106480
  strengths: ["far cheaper than frontier", "strong coding for the price", "reasoning"],
106469
106481
  weaknesses: ["smaller context", "slower hosted latency"],
106470
106482
  asOf: "2026-06"
106483
+ },
106484
+ {
106485
+ id: "bedrock/anthropic.claude-sonnet-4-20250514-v1:0",
106486
+ provider: "bedrock",
106487
+ contextWindow: 200000,
106488
+ maxOutput: 64000,
106489
+ tokenizer: CLAUDE_TOK,
106490
+ cost: { inUSDPerMtok: 3.3, outUSDPerMtok: 16.5, src: "seeded" },
106491
+ latency: { ttftMs: 1900, tps: 90, src: "seeded" },
106492
+ quality: { sweBenchVerified: 0.77, intelligenceIndex: 50, src: "seeded" },
106493
+ strengths: ["agentic coding", "tool use", "instruction-following", "AWS-native deployment", "extended thinking"],
106494
+ weaknesses: ["10% pricier than Anthropic direct", "Bedrock model enablement required"],
106495
+ asOf: "2026-06"
106496
+ },
106497
+ {
106498
+ id: "bedrock/anthropic.claude-haiku-4-5-20251001-v1:0",
106499
+ provider: "bedrock",
106500
+ contextWindow: 200000,
106501
+ maxOutput: 32000,
106502
+ tokenizer: CLAUDE_TOK,
106503
+ cost: { inUSDPerMtok: 1.1, outUSDPerMtok: 5.5, src: "seeded" },
106504
+ latency: { ttftMs: 1400, tps: 170, src: "seeded" },
106505
+ quality: { intelligenceIndex: 38, src: "seeded" },
106506
+ strengths: ["fast", "cheap", "AWS-native", "good for bounded sub-tasks"],
106507
+ weaknesses: ["weaker on hard reasoning", "10% premium over Anthropic direct"],
106508
+ asOf: "2026-06"
106509
+ },
106510
+ {
106511
+ id: "bedrock/anthropic.claude-opus-4-20250514-v1:0",
106512
+ provider: "bedrock",
106513
+ contextWindow: 200000,
106514
+ maxOutput: 128000,
106515
+ tokenizer: CLAUDE_TOK,
106516
+ cost: { inUSDPerMtok: 5.5, outUSDPerMtok: 27.5, src: "seeded" },
106517
+ latency: { ttftMs: 2500, tps: 65, src: "seeded" },
106518
+ quality: { sweBenchVerified: 0.83, intelligenceIndex: 64, src: "seeded" },
106519
+ strengths: ["most capable", "long-horizon agentic work", "AWS-native deployment", "extended thinking"],
106520
+ weaknesses: ["most expensive", "slower", "10% premium over Anthropic direct"],
106521
+ asOf: "2026-06"
106522
+ },
106523
+ {
106524
+ id: "bedrock/amazon.nova-pro-v1:0",
106525
+ provider: "bedrock",
106526
+ contextWindow: 300000,
106527
+ maxOutput: 5000,
106528
+ tokenizer: TIKTOKEN,
106529
+ cost: { inUSDPerMtok: 0.8, outUSDPerMtok: 3.2, src: "seeded" },
106530
+ latency: { ttftMs: 0, tps: 0, src: "seeded" },
106531
+ quality: { intelligenceIndex: 42, src: "seeded" },
106532
+ strengths: ["native AWS model", "multimodal (text+image+video)", "large context", "reasonable price"],
106533
+ weaknesses: ["weaker than Claude on hard coding/reasoning"],
106534
+ asOf: "2026-06"
106535
+ },
106536
+ {
106537
+ id: "bedrock/amazon.nova-lite-v1:0",
106538
+ provider: "bedrock",
106539
+ contextWindow: 300000,
106540
+ maxOutput: 5000,
106541
+ tokenizer: TIKTOKEN,
106542
+ cost: { inUSDPerMtok: 0.06, outUSDPerMtok: 0.24, src: "seeded" },
106543
+ latency: { ttftMs: 0, tps: 0, src: "seeded" },
106544
+ quality: { intelligenceIndex: 32, src: "seeded" },
106545
+ strengths: ["very cheap", "native AWS", "large context", "good for bulk tasks"],
106546
+ weaknesses: ["lower ceiling on complex tasks"],
106547
+ asOf: "2026-06"
106548
+ },
106549
+ {
106550
+ id: "bedrock/amazon.nova-micro-v1:0",
106551
+ provider: "bedrock",
106552
+ contextWindow: 128000,
106553
+ maxOutput: 5000,
106554
+ tokenizer: TIKTOKEN,
106555
+ cost: { inUSDPerMtok: 0.035, outUSDPerMtok: 0.14, src: "seeded" },
106556
+ latency: { ttftMs: 0, tps: 0, src: "seeded" },
106557
+ quality: { intelligenceIndex: 25, src: "seeded" },
106558
+ strengths: ["cheapest AWS model", "text-only, fast", "classify/summarize"],
106559
+ weaknesses: ["no image input", "lower quality ceiling"],
106560
+ asOf: "2026-06"
106561
+ },
106562
+ {
106563
+ id: "bedrock/meta.llama4-maverick-17b-instruct-v1:0",
106564
+ provider: "bedrock",
106565
+ contextWindow: 128000,
106566
+ maxOutput: 8000,
106567
+ tokenizer: LLAMA_TOK,
106568
+ cost: { inUSDPerMtok: 0.24, outUSDPerMtok: 0.97, src: "seeded" },
106569
+ latency: { ttftMs: 0, tps: 0, src: "seeded" },
106570
+ quality: { intelligenceIndex: 44, src: "seeded" },
106571
+ strengths: ["multimodal (text+image)", "competitive quality per dollar", "AWS-native"],
106572
+ weaknesses: ["smaller context than Nova", "OSS model quality ceiling"],
106573
+ asOf: "2026-06"
106574
+ },
106575
+ {
106576
+ id: "bedrock/meta.llama4-scout-17b-instruct-v1:0",
106577
+ provider: "bedrock",
106578
+ contextWindow: 128000,
106579
+ maxOutput: 8000,
106580
+ tokenizer: LLAMA_TOK,
106581
+ cost: { inUSDPerMtok: 0.17, outUSDPerMtok: 0.66, src: "seeded" },
106582
+ latency: { ttftMs: 0, tps: 0, src: "seeded" },
106583
+ quality: { intelligenceIndex: 38, src: "seeded" },
106584
+ strengths: ["cheap", "fast", "multimodal", "AWS-native"],
106585
+ weaknesses: ["lower quality than Maverick", "OSS model quality ceiling"],
106586
+ asOf: "2026-06"
106587
+ },
106588
+ {
106589
+ id: "vertex/gemini-3.1-pro-preview",
106590
+ provider: "vertex",
106591
+ contextWindow: 1e6,
106592
+ maxOutput: 64000,
106593
+ tokenizer: GEMINI_TOK,
106594
+ cost: { inUSDPerMtok: 2, outUSDPerMtok: 12, src: "seeded" },
106595
+ latency: { ttftMs: 0, tps: 0, src: "seeded" },
106596
+ quality: { sweBenchVerified: 0.76, intelligenceIndex: 60, src: "seeded" },
106597
+ strengths: ["1M context", "strong reasoning", "thinking config", "GCP-native deployment"],
106598
+ weaknesses: ["preview", "agentic tool-use behind Claude"],
106599
+ asOf: "2026-06"
106600
+ },
106601
+ {
106602
+ id: "vertex/gemini-3.5-flash",
106603
+ provider: "vertex",
106604
+ contextWindow: 1e6,
106605
+ maxOutput: 64000,
106606
+ tokenizer: GEMINI_TOK,
106607
+ cost: { inUSDPerMtok: 0.3, outUSDPerMtok: 2.5, src: "seeded" },
106608
+ latency: { ttftMs: 0, tps: 0, src: "seeded" },
106609
+ quality: { intelligenceIndex: 48, src: "seeded" },
106610
+ strengths: ["very cheap", "fast", "1M context", "thinking config", "GCP-native"],
106611
+ weaknesses: ["lower ceiling on hard tasks"],
106612
+ asOf: "2026-06"
106613
+ },
106614
+ {
106615
+ id: "vertex/gemini-3.1-flash-lite",
106616
+ provider: "vertex",
106617
+ contextWindow: 1e6,
106618
+ maxOutput: 8000,
106619
+ tokenizer: GEMINI_TOK,
106620
+ cost: { inUSDPerMtok: 0.1, outUSDPerMtok: 0.4, src: "seeded" },
106621
+ latency: { ttftMs: 0, tps: 0, src: "seeded" },
106622
+ quality: { intelligenceIndex: 30, src: "seeded" },
106623
+ strengths: ["cheapest Vertex model", "1M context", "fast", "classify/summarize"],
106624
+ weaknesses: ["no thinking config", "lower quality ceiling"],
106625
+ asOf: "2026-06"
106471
106626
  }
106472
106627
  ];
106473
106628
  BY_ID2 = new Map(PROFILES.map((p) => [p.id, p]));
106474
106629
  });
106475
106630
 
106476
106631
  // src/model/reasoning.ts
106632
+ function clampEffort(current, allowed) {
106633
+ if (!allowed.length)
106634
+ return { level: "medium", clamped: current !== "medium" };
106635
+ if (allowed.includes(current))
106636
+ return { level: current, clamped: false };
106637
+ const idx = EFFORT_ORDER.indexOf(current);
106638
+ for (let d = 1;d <= EFFORT_ORDER.length; d++) {
106639
+ const hi = EFFORT_ORDER[idx + d];
106640
+ if (hi && allowed.includes(hi))
106641
+ return { level: hi, clamped: true };
106642
+ const lo = EFFORT_ORDER[idx - d];
106643
+ if (lo && allowed.includes(lo))
106644
+ return { level: lo, clamped: true };
106645
+ }
106646
+ return { level: allowed[allowed.length - 1], clamped: true };
106647
+ }
106477
106648
  function effortLevels(spec6) {
106478
106649
  if (spec6.efforts)
106479
106650
  return spec6.efforts;
@@ -106481,6 +106652,8 @@ function effortLevels(spec6) {
106481
106652
  return [];
106482
106653
  if (spec6.provider === "openai")
106483
106654
  return OPENAI_EFFORTS;
106655
+ if (spec6.provider === "azure" || spec6.provider === "azure-foundry")
106656
+ return OPENAI_EFFORTS;
106484
106657
  if (spec6.provider === "anthropic")
106485
106658
  return ANTHROPIC_EFFORTS;
106486
106659
  if (spec6.provider === "google" || spec6.provider === "vertex")
@@ -106505,7 +106678,7 @@ function reasoningOptions(spec6, effort) {
106505
106678
  if (!level)
106506
106679
  return {};
106507
106680
  const p = spec6.provider;
106508
- if (p === "openai") {
106681
+ if (p === "openai" || p === "azure" || p === "azure-foundry") {
106509
106682
  return { openai: { reasoningEffort: level } };
106510
106683
  }
106511
106684
  if (p === "google" || p === "vertex") {
@@ -106516,11 +106689,12 @@ function reasoningOptions(spec6, effort) {
106516
106689
  }
106517
106690
  return {};
106518
106691
  }
106519
- var OPENAI_EFFORTS, ANTHROPIC_EFFORTS, GOOGLE_EFFORTS;
106692
+ var OPENAI_EFFORTS, ANTHROPIC_EFFORTS, GOOGLE_EFFORTS, EFFORT_ORDER;
106520
106693
  var init_reasoning = __esm(() => {
106521
106694
  OPENAI_EFFORTS = ["none", "minimal", "low", "medium", "high", "xhigh"];
106522
106695
  ANTHROPIC_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
106523
106696
  GOOGLE_EFFORTS = ["minimal", "low", "medium", "high"];
106697
+ EFFORT_ORDER = ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
106524
106698
  });
106525
106699
 
106526
106700
  // src/model/capabilities.ts
@@ -106555,8 +106729,10 @@ function toolSupport(spec6) {
106555
106729
  const group = catalogProvider(spec6.provider)?.group;
106556
106730
  if (spec6.provider === "anthropic" || spec6.provider === "openai" || spec6.provider === "google" || spec6.provider === "deepseek")
106557
106731
  return true;
106558
- if (spec6.provider === "bedrock" || spec6.provider === "vertex" || spec6.provider === "azure")
106559
- return "unknown";
106732
+ if (spec6.provider === "bedrock")
106733
+ return !spec6.sdkId.includes("nova-micro");
106734
+ if (spec6.provider === "vertex" || spec6.provider === "azure" || spec6.provider === "azure-foundry")
106735
+ return true;
106560
106736
  if (group === "gateway" || group === "openai-compat" || group === "local")
106561
106737
  return "unknown";
106562
106738
  return "unknown";
@@ -106568,6 +106744,10 @@ function imageSupport(spec6) {
106568
106744
  return true;
106569
106745
  if (spec6.provider === "deepseek")
106570
106746
  return false;
106747
+ if (spec6.provider === "bedrock")
106748
+ return !spec6.sdkId.includes("nova-micro");
106749
+ if (spec6.provider === "azure" || spec6.provider === "azure-foundry")
106750
+ return true;
106571
106751
  return "unknown";
106572
106752
  }
106573
106753
  function schemaSupport(spec6) {
@@ -106575,6 +106755,10 @@ function schemaSupport(spec6) {
106575
106755
  return spec6.capabilities.jsonSchema;
106576
106756
  if (spec6.provider === "openai" || spec6.provider === "google" || spec6.provider === "anthropic")
106577
106757
  return true;
106758
+ if (spec6.provider === "bedrock")
106759
+ return spec6.sdkId.startsWith("anthropic.") ? true : "unknown";
106760
+ if (spec6.provider === "vertex" || spec6.provider === "azure" || spec6.provider === "azure-foundry")
106761
+ return true;
106578
106762
  if (spec6.provider === "deepseek")
106579
106763
  return "unknown";
106580
106764
  return "unknown";
@@ -129169,9 +129353,10 @@ function awsIni(file5, profile = "default") {
129169
129353
  }
129170
129354
  function detectCloudCreds() {
129171
129355
  const out = [];
129356
+ const awsProfile = process.env.AWS_PROFILE ?? "default";
129172
129357
  const home5 = homedir8();
129173
- const creds = awsIni(join10(home5, ".aws", "credentials"));
129174
- const conf = awsIni(join10(home5, ".aws", "config"));
129358
+ const creds = awsIni(join10(home5, ".aws", "credentials"), awsProfile);
129359
+ const conf = awsIni(join10(home5, ".aws", "config"), awsProfile);
129175
129360
  const akid = process.env.AWS_ACCESS_KEY_ID ?? creds.aws_access_key_id;
129176
129361
  const secret = process.env.AWS_SECRET_ACCESS_KEY ?? creds.aws_secret_access_key;
129177
129362
  const region = process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? conf.region;
@@ -129802,7 +129987,8 @@ async function addByPastedKey(key) {
129802
129987
  }
129803
129988
  async function testAccount(a) {
129804
129989
  const creds = await resolveCreds(a);
129805
- if (!creds.apiKey && a.auth.kind !== "cli")
129990
+ const isCloud = a.auth.kind === "aws" || a.auth.kind === "azure" || a.auth.kind === "vertex";
129991
+ if (!creds.apiKey && !isCloud && a.auth.kind !== "cli")
129806
129992
  return { ok: false, message: "no key stored" };
129807
129993
  try {
129808
129994
  if (a.provider === "anthropic") {
@@ -129817,6 +130003,32 @@ async function testAccount(a) {
129817
130003
  const r3 = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${creds.apiKey ?? ""}`);
129818
130004
  return r3.ok ? { ok: true, message: "credential works" } : { ok: false, message: await errMessage(r3) };
129819
130005
  }
130006
+ if (a.provider === "azure" && creds.azure) {
130007
+ const { resourceName, apiKey, apiVersion = "2024-08-01-preview" } = creds.azure;
130008
+ if (!resourceName || !apiKey)
130009
+ return { ok: false, message: "azure: resourceName and apiKey are required" };
130010
+ const r3 = await fetch(`https://${resourceName}.openai.azure.com/openai/models?api-version=${apiVersion}`, { headers: { "api-key": apiKey } });
130011
+ return r3.ok ? { ok: true, message: "credential works" } : { ok: false, message: await errMessage(r3) };
130012
+ }
130013
+ if (a.provider === "bedrock" && creds.aws) {
130014
+ const { accessKeyId, secretAccessKey, region } = creds.aws;
130015
+ if (!accessKeyId || !secretAccessKey)
130016
+ return { ok: false, message: "bedrock: AWS access key and secret are required" };
130017
+ if (!region)
130018
+ return { ok: false, message: "bedrock: AWS_REGION is required" };
130019
+ const keyOk = /^(AKIA|ASIA)[A-Z0-9]{16}$/.test(accessKeyId);
130020
+ if (!keyOk)
130021
+ return { ok: false, message: `bedrock: access key ID looks malformed (expected AKIA… or ASIA…, got ${accessKeyId.slice(0, 8)}…)` };
130022
+ return { ok: true, message: "credential fields present (Bedrock connectivity verified on first use)" };
130023
+ }
130024
+ if (a.provider === "vertex" && creds.vertex) {
130025
+ const { project, location } = creds.vertex;
130026
+ if (!project)
130027
+ return { ok: false, message: "vertex: GOOGLE_VERTEX_PROJECT is required" };
130028
+ if (!location)
130029
+ return { ok: false, message: "vertex: GOOGLE_VERTEX_LOCATION is required" };
130030
+ return { ok: true, message: "credential fields present (Vertex connectivity verified on first use — run `gcloud auth application-default login` if not done)" };
130031
+ }
129820
130032
  const base2 = creds.baseURL ?? "https://api.openai.com/v1";
129821
130033
  const r2 = await fetch(`${base2.replace(/\/$/, "")}/models`, {
129822
130034
  headers: { Authorization: `Bearer ${creds.apiKey ?? ""}`, ...creds.headers ?? {} }
@@ -139617,7 +139829,7 @@ var GROUP_TITLES = [
139617
139829
  { id: "accounts", title: "accounts & cost" },
139618
139830
  { id: "output", title: "save & copy" },
139619
139831
  { id: "modes", title: "modes" },
139620
- { id: "settings", title: "look & settings" },
139832
+ { id: "settings", title: "settings" },
139621
139833
  { id: "other", title: "other" }
139622
139834
  ];
139623
139835
  function helpText() {
@@ -144839,7 +145051,7 @@ function firstPath(text2) {
144839
145051
  function uniq2(xs) {
144840
145052
  return [...new Set(xs)];
144841
145053
  }
144842
- var CLAUDE_CLI_EFFORTS = ["low", "medium", "high", "max"];
145054
+ var CLAUDE_CLI_EFFORTS = [];
144843
145055
  var FALLBACK_CODEX_MODELS = [
144844
145056
  { id: "gpt-5.5", label: "gpt-5.5", provider: "codex", efforts: ["low", "medium", "high", "xhigh"] },
144845
145057
  { id: "gpt-5.4", label: "gpt-5.4", provider: "codex", efforts: ["low", "medium", "high", "xhigh"] },
@@ -144929,33 +145141,8 @@ function ActivityRail({ items, width }) {
144929
145141
  }, undefined, true, undefined, this);
144930
145142
  }
144931
145143
  function SetupSplash({ state, width, skin, splashSize }) {
144932
- const providers = featuredApiKeyProviders().slice(0, width >= 92 ? 12 : 8);
144933
- const left = providers.filter((_, i2) => i2 % 2 === 0);
144934
- const right = providers.filter((_, i2) => i2 % 2 === 1);
144935
145144
  const detected = state.importable.length + state.cloudImportable.length;
144936
- const panelWidth = Math.min(Math.max(width - 4, 12), 104);
144937
- const showTwoCols = panelWidth >= 82;
144938
- const firstColumn = showTwoCols ? left : providers;
144939
- const secondColumn = showTwoCols ? right : [];
144940
- const providerLine = (id, label) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
144941
- color: color.dim,
144942
- children: [
144943
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
144944
- color: color.accent,
144945
- children: [
144946
- "/account add ",
144947
- id
144948
- ]
144949
- }, undefined, true, undefined, this),
144950
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
144951
- color: color.faint,
144952
- children: [
144953
- " ",
144954
- label
144955
- ]
144956
- }, undefined, true, undefined, this)
144957
- ]
144958
- }, id, true, undefined, this);
145145
+ const panelWidth = Math.min(Math.max(width - 4, 30), 58);
144959
145146
  return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
144960
145147
  flexDirection: "column",
144961
145148
  alignItems: "center",
@@ -144972,188 +145159,130 @@ function SetupSplash({ state, width, skin, splashSize }) {
144972
145159
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
144973
145160
  color: color.accent,
144974
145161
  bold: true,
144975
- children: "GEARBOX"
144976
- }, undefined, false, undefined, this),
144977
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
144978
- color: color.text,
144979
- children: "one terminal, every model account you already pay for"
145162
+ children: "gearbox"
144980
145163
  }, undefined, false, undefined, this),
144981
145164
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
144982
- color: color.faint,
144983
- children: "Set up one provider. Gearbox routes from there."
145165
+ color: color.dim,
145166
+ children: "one terminal · every model you already pay for"
144984
145167
  }, undefined, false, undefined, this)
144985
145168
  ]
144986
145169
  }, undefined, true, undefined, this),
144987
145170
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
144988
- marginTop: 1,
145171
+ marginTop: 2,
144989
145172
  width: panelWidth,
144990
145173
  borderStyle: "round",
144991
- borderColor: color.accentDim,
145174
+ borderColor: color.faint,
144992
145175
  paddingX: 2,
144993
145176
  paddingY: 1,
144994
145177
  flexDirection: "column",
144995
145178
  children: [
144996
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
144997
- justifyContent: "space-between",
144998
- children: [
144999
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145000
- color: color.text,
145001
- bold: true,
145002
- children: "start here"
145003
- }, undefined, false, undefined, this),
145004
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145005
- color: detected ? color.ok : color.faint,
145006
- children: detected ? `${detected} detected` : "no account yet"
145007
- }, undefined, false, undefined, this)
145008
- ]
145009
- }, undefined, true, undefined, this),
145010
- detected ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145011
- marginTop: 1,
145012
- children: [
145013
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145014
- color: color.ok,
145015
- children: [
145016
- glyph.on,
145017
- " "
145018
- ]
145019
- }, undefined, true, undefined, this),
145020
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145021
- color: color.text,
145022
- children: "Credentials found on this machine: "
145023
- }, undefined, false, undefined, this),
145024
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145025
- color: color.accent,
145026
- children: "/account import"
145027
- }, undefined, false, undefined, this)
145028
- ]
145029
- }, undefined, true, undefined, this) : null,
145030
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145031
- marginTop: 1,
145032
- flexDirection: showTwoCols ? "row" : "column",
145179
+ detected > 0 ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(jsx_dev_runtime12.Fragment, {
145033
145180
  children: [
145034
145181
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145035
- flexDirection: "column",
145036
- width: showTwoCols ? Math.floor((panelWidth - 6) / 2) : undefined,
145037
145182
  children: [
145038
145183
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145039
- color: color.faint,
145040
- children: "API key"
145041
- }, undefined, false, undefined, this),
145042
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145043
- color: color.text,
145184
+ color: color.ok,
145044
145185
  children: [
145045
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145046
- color: color.accent,
145047
- children: "/account add <api-key>"
145048
- }, undefined, false, undefined, this),
145049
- " auto-detect when possible"
145186
+ glyph.on,
145187
+ " "
145050
145188
  ]
145051
145189
  }, undefined, true, undefined, this),
145052
145190
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145053
145191
  color: color.text,
145054
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145055
- color: color.accent,
145056
- children: "/account add <provider> <api-key>"
145057
- }, undefined, false, undefined, this)
145058
- }, undefined, false, undefined, this)
145192
+ children: [
145193
+ detected,
145194
+ " credential",
145195
+ detected > 1 ? "s" : "",
145196
+ " found on this machine"
145197
+ ]
145198
+ }, undefined, true, undefined, this)
145059
145199
  ]
145060
145200
  }, undefined, true, undefined, this),
145061
145201
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145062
- flexDirection: "column",
145063
- marginLeft: showTwoCols ? 4 : 0,
145064
- marginTop: showTwoCols ? 0 : 1,
145202
+ marginTop: 1,
145065
145203
  children: [
145066
145204
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145067
- color: color.faint,
145068
- children: "Subscriptions and cloud"
145205
+ color: color.accent,
145206
+ children: "/account import"
145069
145207
  }, undefined, false, undefined, this),
145070
145208
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145071
- color: color.text,
145072
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145073
- color: color.accent,
145074
- children: "/account add azure <endpoint> <api-key>"
145075
- }, undefined, false, undefined, this)
145209
+ color: color.dim,
145210
+ children: " connect automatically"
145211
+ }, undefined, false, undefined, this)
145212
+ ]
145213
+ }, undefined, true, undefined, this),
145214
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145215
+ marginTop: 1,
145216
+ children: [
145217
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145218
+ color: color.faint,
145219
+ children: "or add a different key: "
145076
145220
  }, undefined, false, undefined, this),
145077
145221
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145078
- color: color.text,
145079
- children: [
145080
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145081
- color: color.accent,
145082
- children: "/account add claude"
145083
- }, undefined, false, undefined, this),
145084
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145085
- color: color.faint,
145086
- children: " "
145087
- }, undefined, false, undefined, this),
145088
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145089
- color: color.accent,
145090
- children: "/account add codex"
145091
- }, undefined, false, undefined, this)
145092
- ]
145093
- }, undefined, true, undefined, this)
145222
+ color: color.accent,
145223
+ children: "/account add <api-key>"
145224
+ }, undefined, false, undefined, this)
145094
145225
  ]
145095
145226
  }, undefined, true, undefined, this)
145096
145227
  ]
145097
- }, undefined, true, undefined, this),
145098
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145099
- marginTop: 1,
145100
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145101
- color: color.faint,
145102
- children: glyph.rule.repeat(Math.max(panelWidth - 6, 20))
145103
- }, undefined, false, undefined, this)
145104
- }, undefined, false, undefined, this),
145105
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145106
- marginTop: 1,
145107
- flexDirection: showTwoCols ? "row" : "column",
145228
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(jsx_dev_runtime12.Fragment, {
145108
145229
  children: [
145230
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145231
+ color: color.dim,
145232
+ children: "paste or type a key to get started"
145233
+ }, undefined, false, undefined, this),
145109
145234
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145110
- flexDirection: "column",
145111
- width: showTwoCols ? Math.floor((panelWidth - 6) / 2) : undefined,
145235
+ marginTop: 1,
145236
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145237
+ color: color.accent,
145238
+ children: "/account add <api-key>"
145239
+ }, undefined, false, undefined, this)
145240
+ }, undefined, false, undefined, this)
145241
+ ]
145242
+ }, undefined, true, undefined, this),
145243
+ (state.hasClaudeCli || state.hasCodexCli) && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145244
+ marginTop: 2,
145245
+ flexDirection: "column",
145246
+ children: [
145247
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145248
+ color: color.faint,
145249
+ children: "subscriptions detected"
145250
+ }, undefined, false, undefined, this),
145251
+ state.hasClaudeCli && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145112
145252
  children: [
145113
145253
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145114
- color: color.faint,
145115
- children: "Common providers"
145254
+ color: color.accent,
145255
+ children: "/account add claude"
145116
145256
  }, undefined, false, undefined, this),
145117
- firstColumn.map((p) => providerLine(p.id, p.label))
145257
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145258
+ color: color.faint,
145259
+ children: " Claude Pro / Max"
145260
+ }, undefined, false, undefined, this)
145118
145261
  ]
145119
145262
  }, undefined, true, undefined, this),
145120
- secondColumn.length ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145121
- flexDirection: "column",
145122
- marginLeft: 4,
145263
+ state.hasCodexCli && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145123
145264
  children: [
145124
145265
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145125
- color: color.faint,
145126
- children: " "
145266
+ color: color.accent,
145267
+ children: "/account add codex"
145127
145268
  }, undefined, false, undefined, this),
145128
- secondColumn.map((p) => providerLine(p.id, p.label))
145269
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145270
+ color: color.faint,
145271
+ children: " ChatGPT Plus"
145272
+ }, undefined, false, undefined, this)
145129
145273
  ]
145130
- }, undefined, true, undefined, this) : null
145131
- ]
145132
- }, undefined, true, undefined, this),
145133
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145134
- marginTop: 1,
145135
- justifyContent: "space-between",
145136
- children: [
145137
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145138
- color: color.faint,
145139
- children: "Full catalog: "
145140
- }, undefined, false, undefined, this),
145141
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145142
- color: color.accent,
145143
- children: "/onboard providers"
145144
- }, undefined, false, undefined, this),
145145
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145146
- color: color.faint,
145147
- children: " Help: "
145148
- }, undefined, false, undefined, this),
145149
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145150
- color: color.accent,
145151
- children: "/account"
145152
- }, undefined, false, undefined, this)
145274
+ }, undefined, true, undefined, this)
145153
145275
  ]
145154
145276
  }, undefined, true, undefined, this)
145155
145277
  ]
145156
- }, undefined, true, undefined, this)
145278
+ }, undefined, true, undefined, this),
145279
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
145280
+ marginTop: 1,
145281
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
145282
+ color: color.faint,
145283
+ children: "/onboard · /account · /help"
145284
+ }, undefined, false, undefined, this)
145285
+ }, undefined, false, undefined, this)
145157
145286
  ]
145158
145287
  }, undefined, true, undefined, this);
145159
145288
  }
@@ -145682,7 +145811,8 @@ function App2({ selector: initialSelector, runner, fullscreen = false, resumeId
145682
145811
  rows2.push(" no named subscription models exposed yet");
145683
145812
  for (const m2 of models)
145684
145813
  rows2.push(` ${m2.id === currentId ? glyph.on : glyph.off} ${m2.label}`);
145685
- rows2.push("", "API models are hidden while a subscription is active — /account off returns to API routing");
145814
+ rows2.push("", `API models are hidden while a subscription is active — /account off returns to API routing
145815
+ tip: /model haiku (or any API model name) switches directly and leaves the subscription`);
145686
145816
  return rows2.join(`
145687
145817
  `);
145688
145818
  };
@@ -145769,6 +145899,16 @@ function App2({ selector: initialSelector, runner, fullscreen = false, resumeId
145769
145899
  const subscription = activeCli ? activeCli.label : null;
145770
145900
  const routing = setupRequired || activeCli ? null : lastPick?.reason ?? choice?.reason ?? null;
145771
145901
  const ctxPct = !activeCli && model && lastInput > 0 ? Math.round(lastInput / model.contextWindow * 100) : null;
145902
+ const activeModelEfforts = (() => {
145903
+ const cli = activeCliRef.current;
145904
+ if (cli) {
145905
+ const choices = cliModelChoices(cli.binary);
145906
+ const m2 = choices.find((c) => c.id === activeCliModel) ?? choices[0];
145907
+ return m2?.efforts ?? [];
145908
+ }
145909
+ return model ? effortLevels(model) : [];
145910
+ })();
145911
+ const displayEffort = activeModelEfforts.length > 0 ? effort : undefined;
145772
145912
  const push = (it) => setItems((prev) => [...prev, it]);
145773
145913
  const pushPhase = (label, detail) => {
145774
145914
  const id = idRef.current++;
@@ -145853,7 +145993,14 @@ function App2({ selector: initialSelector, runner, fullscreen = false, resumeId
145853
145993
  onEvent({ type: "phase", label: "using subscription", detail: `${cli.binary}${modelLabel2 ? ` · ${modelLabel2}` : ""} owns tools and permissions`, state: "running" });
145854
145994
  const cliChoices = cliModelChoices(cli.binary);
145855
145995
  const cliChoice = cliChoices.find((m2) => m2.id === activeCliModelRef.current) ?? cliChoices[0];
145856
- const cliEffort = cliChoice ? normalizeEffort(effortRef.current, cliChoice.efforts ?? []) ?? undefined : undefined;
145996
+ const _cliEffortRaw = cliChoice ? normalizeEffort(effortRef.current, cliChoice.efforts ?? []) : null;
145997
+ if (_cliEffortRaw === null && effortRef.current !== "medium") {
145998
+ const supported = cliChoice?.efforts ?? [];
145999
+ const { level: nearest } = clampEffort(effortRef.current, supported);
146000
+ const hint = supported.length ? ` — try /effort ${nearest}` : "";
146001
+ throw new Error(`effort "${effortRef.current}" is not supported by ${cliChoice?.label ?? cli.binary} (supports: ${supported.join(", ") || "none"}${hint})`);
146002
+ }
146003
+ const cliEffort = _cliEffortRaw ?? undefined;
145857
146004
  const activeAccount = getAccount(cli.id);
145858
146005
  const activeName = activeAccount ? accountName(activeAccount).match(/\((.*)\)/)?.[1] : undefined;
145859
146006
  const reloginCommand = cli.binary.includes("codex") ? `/account add codex${activeName ? ` ${activeName}` : ""}` : `/account add claude${activeName ? ` ${activeName}` : ""}`;
@@ -145894,7 +146041,14 @@ function App2({ selector: initialSelector, runner, fullscreen = false, resumeId
145894
146041
  cliMetaRef.current = null;
145895
146042
  if (account)
145896
146043
  markUsed(account.id);
145897
- const modelEffort = normalizeEffort(effortRef.current, effortLevels(choice2.model)) ?? undefined;
146044
+ const _effortRaw = normalizeEffort(effortRef.current, effortLevels(choice2.model));
146045
+ if (_effortRaw === null && effortRef.current !== "medium") {
146046
+ const supported = effortLevels(choice2.model);
146047
+ const { level: nearest } = clampEffort(effortRef.current, supported);
146048
+ const hint = supported.length ? ` — try /effort ${nearest}` : "";
146049
+ throw new Error(`effort "${effortRef.current}" is not supported by ${choice2.model.label} (supports: ${supported.join(", ") || "none"}${hint})`);
146050
+ }
146051
+ const modelEffort = _effortRaw ?? undefined;
145898
146052
  const r2 = await runTask({ model: choice2.model, messages: ctx, onEvent, signal, plan, system, creds, effort: modelEffort });
145899
146053
  const produced = r2.messages.slice(ctx.length);
145900
146054
  const imageNote = activeImagesRef.current.length ? `
@@ -145945,6 +146099,17 @@ function App2({ selector: initialSelector, runner, fullscreen = false, resumeId
145945
146099
  updatePrefs({ activeAccount: null });
145946
146100
  return " (left the subscription)";
145947
146101
  };
146102
+ const applyEffortClamp = (allowed) => {
146103
+ const { level, clamped } = clampEffort(effortRef.current, allowed);
146104
+ if (!clamped)
146105
+ return "";
146106
+ const prev = effortRef.current;
146107
+ effortRef.current = level;
146108
+ setEffortState(level);
146109
+ if (!allowed.length)
146110
+ return ` — effort reset to ${level} (no reasoning support)`;
146111
+ return ` — effort clamped: ${prev} → ${level} (${prev} not supported)`;
146112
+ };
145948
146113
  const setEffort = (raw) => {
145949
146114
  const target = effortTarget();
145950
146115
  if (!target?.efforts.length) {
@@ -146538,11 +146703,27 @@ ${fetched.join(`
146538
146703
  if (cli) {
146539
146704
  const cr = resolveCliModel(cli.binary, arg);
146540
146705
  if (!cr.ok) {
146706
+ const r3 = resolveModelSwitch(arg);
146707
+ if (r3.ok && r3.modelId) {
146708
+ const left = leaveSubscription();
146709
+ setSelector(new FixedSelector(r3.modelId));
146710
+ setLastPick(null);
146711
+ routedRef.current = null;
146712
+ updatePrefs({ pinnedModel: r3.modelId });
146713
+ const newSpec2 = findModel(r3.modelId);
146714
+ const effortSuffix2 = applyEffortClamp(newSpec2 ? effortLevels(newSpec2) : []);
146715
+ notice(`${r3.message} — pinned (left subscription).${left}${effortSuffix2}`);
146716
+ const kind = classify(lastPromptRef.current ?? "").replace("code", "code");
146717
+ push({ kind: "preference", id: idRef.current++, text: `Remember ${r3.modelId} for ${kind} tasks?`, acceptCommand: `/prefer ${kind} ${r3.modelId}` });
146718
+ return;
146719
+ }
146541
146720
  notice(cr.message);
146542
146721
  return;
146543
146722
  }
146544
146723
  setActiveCliModelId(cr.modelId);
146545
- notice(`subscription model ${cr.label} — using ${cli.binary}; tools and permissions still owned by the subscription`);
146724
+ const newCliModel = cliModelChoices(cli.binary).find((m2) => m2.id === cr.modelId);
146725
+ const effortSuffix = applyEffortClamp(newCliModel?.efforts ?? []);
146726
+ notice(`subscription model → ${cr.label} — using ${cli.binary}; tools and permissions still owned by the subscription${effortSuffix}`);
146546
146727
  return;
146547
146728
  }
146548
146729
  const r2 = resolveModelSwitch(arg);
@@ -146552,7 +146733,9 @@ ${fetched.join(`
146552
146733
  setLastPick(null);
146553
146734
  routedRef.current = null;
146554
146735
  updatePrefs({ pinnedModel: r2.modelId });
146555
- notice(`${r2.message} pinned (persists across sessions). /model auto to route per task again.` + left);
146736
+ const newSpec = findModel(r2.modelId);
146737
+ const effortSuffix = applyEffortClamp(newSpec ? effortLevels(newSpec) : []);
146738
+ notice(`${r2.message} — pinned (persists across sessions). /model auto to route per task again.${left}${effortSuffix}`);
146556
146739
  const kind = classify(lastPromptRef.current ?? "").replace("code", "code");
146557
146740
  push({ kind: "preference", id: idRef.current++, text: `Remember ${r2.modelId} for ${kind} tasks?`, acceptCommand: `/prefer ${kind} ${r2.modelId}` });
146558
146741
  } else {
@@ -147603,7 +147786,7 @@ Example: /mcp add github npx -y @modelcontextprotocol/server-github`);
147603
147786
  cost: estimateCost(sessionRef.current.turns),
147604
147787
  width,
147605
147788
  mode: mode2,
147606
- effort,
147789
+ effort: displayEffort,
147607
147790
  online
147608
147791
  }, undefined, false, undefined, this),
147609
147792
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
@@ -147684,7 +147867,7 @@ init_permission();
147684
147867
  var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
147685
147868
  process.env.LANG = process.env.LANG || "en_US.UTF-8";
147686
147869
  process.env.LC_ALL = process.env.LC_ALL || "en_US.UTF-8";
147687
- var VERSION16 = "0.1.16";
147870
+ var VERSION16 = "0.1.19";
147688
147871
  var args = process.argv.slice(2);
147689
147872
  var supportsAnsi = process.env.FORCE_COLOR === "1" || process.env.TERM !== "dumb" && process.env.NO_COLOR !== "1" && process.stdout.isTTY;
147690
147873
  var ansi = (code) => supportsAnsi ? `\x1B[${code}m` : "";
@@ -147723,10 +147906,17 @@ function ghostLines(cells, pad3 = " ") {
147723
147906
  return line;
147724
147907
  });
147725
147908
  }
147726
- function onboardingBoo() {
147727
- return ghostLines(renderGhost({ palette: "default", face: "happy", scale: 1 })).join(`
147909
+ function onboardingBoo(termWidth) {
147910
+ const cells = renderGhost({ palette: "default", face: "happy", scale: 1 });
147911
+ const ghostW = cells[0]?.length ?? 20;
147912
+ const leftPad = Math.max(2, Math.floor((termWidth - ghostW) / 2));
147913
+ return ghostLines(cells, " ".repeat(leftPad)).join(`
147728
147914
  `);
147729
147915
  }
147916
+ var centerStr = (text2, width) => {
147917
+ const pad3 = Math.max(0, Math.floor((width - visibleLength(text2)) / 2));
147918
+ return " ".repeat(pad3) + text2;
147919
+ };
147730
147920
  function box(title, lines) {
147731
147921
  const width = Math.min(78, Math.max(title.length + 4, ...lines.map((l) => visibleLength(l) + 4)));
147732
147922
  const rule = "─".repeat(width - 2);
@@ -147788,12 +147978,13 @@ async function runCliOnboarding() {
147788
147978
  return true;
147789
147979
  };
147790
147980
  try {
147981
+ const termWidth = Math.min(process.stdout.columns || 80, 100);
147791
147982
  console.log("");
147792
- console.log(onboardingBoo());
147983
+ console.log(onboardingBoo(termWidth));
147793
147984
  console.log("");
147794
- console.log(bold("Gearbox setup"));
147795
- console.log("Boo needs one model account before the coding app opens.");
147796
- console.log(dim("Your credentials stay local. API keys are stored in Gearbox's credential store; subscription sign-ins stay inside the vendor CLI."));
147985
+ console.log(centerStr(bold("gearbox"), termWidth));
147986
+ console.log(centerStr("set up one account Gearbox routes from there", termWidth));
147987
+ console.log(centerStr(dim("keys stay local, never sent anywhere"), termWidth));
147797
147988
  console.log("");
147798
147989
  while (!anyProviderAvailable()) {
147799
147990
  const env3 = importableEnvCreds2();
@@ -147948,8 +148139,8 @@ Options:
147948
148139
  --model <name> e.g. sonnet-4.6, haiku, gemini-flash, deepseek
147949
148140
  -c, --continue resume the most recent session here (/resume to pick one)
147950
148141
  --yolo auto-approve writes/edits/shell (no permission prompts)
147951
- --inline use terminal scrollback instead of the fullscreen app frame
147952
- --fullscreen fullscreen app frame (default when stdout is a TTY)
148142
+ --fullscreen fullscreen app frame with fixed footer (alt-screen)
148143
+ --inline terminal scrollback mode (default)
147953
148144
  -v, --version print version
147954
148145
  -h, --help this help
147955
148146
 
@@ -148101,7 +148292,7 @@ if (process.stdout.isTTY && imageMode === "kitty")
148101
148292
  var uiPrefs = loadPrefs();
148102
148293
  var explicitInline = args.includes("--inline") || process.env.GEARBOX_INLINE === "1" || process.env.GEARBOX_FULLSCREEN === "0";
148103
148294
  var explicitFullscreen = args.includes("--fullscreen") || process.env.GEARBOX_FULLSCREEN === "1";
148104
- var wantsInline = explicitInline || !explicitFullscreen && uiPrefs.fullscreen === false;
148295
+ var wantsInline = !explicitFullscreen && (explicitInline || uiPrefs.fullscreen !== true);
148105
148296
  var wantsFullscreen = !wantsInline;
148106
148297
  var fullscreen = Boolean(process.stdout.isTTY) && wantsFullscreen;
148107
148298
  var mouse = Boolean(process.stdout.isTTY) && process.env.GEARBOX_MOUSE !== "0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gearbox-code",
3
- "version": "0.1.16",
3
+ "version": "0.1.19",
4
4
  "description": "A beautiful multi-provider coding harness for the terminal. (Intelligent model routing lands on top of this soon.)",
5
5
  "type": "module",
6
6
  "license": "MIT",