gearbox-code 0.1.2 → 0.1.3

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 +259 -1061
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -1,5 +1,4 @@
1
- #!/usr/bin/env bun
2
- // @bun
1
+ #!/usr/bin/env node
3
2
  import { createRequire } from "node:module";
4
3
  var __create = Object.create;
5
4
  var __getProtoOf = Object.getPrototypeOf;
@@ -61639,6 +61638,23 @@ var require_src5 = __commonJS((exports) => {
61639
61638
  });
61640
61639
 
61641
61640
  // src/accounts/store.ts
61641
+ var exports_store = {};
61642
+ __export(exports_store, {
61643
+ setSecret: () => setSecret,
61644
+ setDefaultAccount: () => setDefaultAccount,
61645
+ secretRefs: () => secretRefs,
61646
+ saveAccounts: () => saveAccounts,
61647
+ removeAccount: () => removeAccount,
61648
+ putAccount: () => putAccount,
61649
+ markUsed: () => markUsed,
61650
+ loadAccounts: () => loadAccounts,
61651
+ listAccounts: () => listAccounts,
61652
+ getSecret: () => getSecret,
61653
+ getAccount: () => getAccount,
61654
+ deleteSecret: () => deleteSecret,
61655
+ defaultAccount: () => defaultAccount,
61656
+ accountsForProvider: () => accountsForProvider
61657
+ });
61642
61658
  import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
61643
61659
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "node:fs";
61644
61660
  import { join as join3 } from "node:path";
@@ -61819,6 +61835,12 @@ var SERVICE = "gearbox", home2 = () => process.env.GEARBOX_HOME || join3(homedir
61819
61835
  var init_store = () => {};
61820
61836
 
61821
61837
  // src/accounts/catalog.ts
61838
+ var exports_catalog = {};
61839
+ __export(exports_catalog, {
61840
+ detectProviderByKey: () => detectProviderByKey,
61841
+ catalogProvider: () => catalogProvider,
61842
+ CATALOG: () => CATALOG
61843
+ });
61822
61844
  function catalogProvider(id) {
61823
61845
  return BY_ID.get(id);
61824
61846
  }
@@ -64032,6 +64054,123 @@ var init_resolve = __esm(() => {
64032
64054
  init_catalog();
64033
64055
  });
64034
64056
 
64057
+ // src/accounts/detect.ts
64058
+ var exports_detect = {};
64059
+ __export(exports_detect, {
64060
+ importableEnvCreds: () => importableEnvCreds,
64061
+ importableCloudCreds: () => importableCloudCreds,
64062
+ importEnvCred: () => importEnvCred,
64063
+ importCloudCred: () => importCloudCred,
64064
+ detectEnvCreds: () => detectEnvCreds,
64065
+ detectCloudCreds: () => detectCloudCreds
64066
+ });
64067
+ import { readFileSync as readFileSync11, existsSync as existsSync6 } from "node:fs";
64068
+ import { join as join9 } from "node:path";
64069
+ import { homedir as homedir7 } from "node:os";
64070
+ function detectEnvCreds() {
64071
+ const out = [];
64072
+ for (const p of CATALOG) {
64073
+ if (p.authKind !== "api-key" && p.authKind !== "openai-compat")
64074
+ continue;
64075
+ for (const ev of p.envVars) {
64076
+ const v = process.env[ev];
64077
+ if (v) {
64078
+ out.push({ provider: p.id, label: p.label, envVar: ev, value: v });
64079
+ break;
64080
+ }
64081
+ }
64082
+ }
64083
+ return out;
64084
+ }
64085
+ async function importEnvCred(c) {
64086
+ const id = `${c.provider}-env`;
64087
+ const ref = `${id}:api-key`;
64088
+ await setSecret(ref, c.value);
64089
+ const cat = CATALOG.find((p) => p.id === c.provider);
64090
+ const account = {
64091
+ id,
64092
+ label: `${c.label} (from ${c.envVar})`,
64093
+ provider: c.provider,
64094
+ exec: "in-loop",
64095
+ auth: cat.authKind === "openai-compat" ? { kind: "openai-compat", ref } : { kind: "api-key", ref },
64096
+ baseUrl: cat.baseUrl,
64097
+ enabled: true,
64098
+ addedAt: Date.now()
64099
+ };
64100
+ putAccount(account);
64101
+ return account;
64102
+ }
64103
+ function importableEnvCreds() {
64104
+ return detectEnvCreds().filter((c) => !getAccount(`${c.provider}-env`));
64105
+ }
64106
+ function awsIni(file5, profile = "default") {
64107
+ if (!existsSync6(file5))
64108
+ return {};
64109
+ const out = {};
64110
+ let cur = "";
64111
+ for (const raw of readFileSync11(file5, "utf8").split(`
64112
+ `)) {
64113
+ const line = raw.trim();
64114
+ if (line.startsWith("["))
64115
+ cur = line.slice(1, -1).replace(/^profile\s+/, "");
64116
+ else if (cur === profile && line.includes("=")) {
64117
+ const i2 = line.indexOf("=");
64118
+ out[line.slice(0, i2).trim().toLowerCase()] = line.slice(i2 + 1).trim();
64119
+ }
64120
+ }
64121
+ return out;
64122
+ }
64123
+ function detectCloudCreds() {
64124
+ const out = [];
64125
+ const home5 = homedir7();
64126
+ const creds = awsIni(join9(home5, ".aws", "credentials"));
64127
+ const conf = awsIni(join9(home5, ".aws", "config"));
64128
+ const akid = process.env.AWS_ACCESS_KEY_ID ?? creds.aws_access_key_id;
64129
+ const secret = process.env.AWS_SECRET_ACCESS_KEY ?? creds.aws_secret_access_key;
64130
+ const region = process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? conf.region;
64131
+ if (akid && secret) {
64132
+ out.push({
64133
+ provider: "bedrock",
64134
+ label: "Amazon Bedrock",
64135
+ source: process.env.AWS_ACCESS_KEY_ID ? "env" : "~/.aws/credentials",
64136
+ aws: { accessKeyId: akid, secretAccessKey: secret, sessionToken: process.env.AWS_SESSION_TOKEN ?? creds.aws_session_token, region: region ?? "us-east-1" }
64137
+ });
64138
+ }
64139
+ if (process.env.AZURE_API_KEY && process.env.AZURE_RESOURCE_NAME) {
64140
+ out.push({ provider: "azure", label: "Azure OpenAI", source: "env", azure: { resourceName: process.env.AZURE_RESOURCE_NAME, apiKey: process.env.AZURE_API_KEY } });
64141
+ }
64142
+ if (process.env.GOOGLE_VERTEX_PROJECT) {
64143
+ out.push({ provider: "vertex", label: "Google Vertex AI", source: "env", vertex: { project: process.env.GOOGLE_VERTEX_PROJECT, location: process.env.GOOGLE_VERTEX_LOCATION ?? "us-central1" } });
64144
+ }
64145
+ return out;
64146
+ }
64147
+ async function importCloudCred(c) {
64148
+ const id = `${c.provider}-import`;
64149
+ let auth;
64150
+ if (c.aws) {
64151
+ await setSecret(`${id}:akid`, c.aws.accessKeyId);
64152
+ await setSecret(`${id}:secret`, c.aws.secretAccessKey);
64153
+ if (c.aws.sessionToken)
64154
+ await setSecret(`${id}:token`, c.aws.sessionToken);
64155
+ auth = { kind: "aws", accessKeyIdRef: `${id}:akid`, secretKeyRef: `${id}:secret`, sessionTokenRef: c.aws.sessionToken ? `${id}:token` : undefined, region: c.aws.region };
64156
+ } else if (c.azure) {
64157
+ await setSecret(`${id}:api-key`, c.azure.apiKey);
64158
+ auth = { kind: "azure", resourceName: c.azure.resourceName, ref: `${id}:api-key` };
64159
+ } else {
64160
+ auth = { kind: "vertex", project: c.vertex.project, location: c.vertex.location, adc: true };
64161
+ }
64162
+ const account = { id, label: `${c.label} (from ${c.source})`, provider: c.provider, exec: "in-loop", auth, enabled: true, addedAt: Date.now() };
64163
+ putAccount(account);
64164
+ return account;
64165
+ }
64166
+ function importableCloudCreds() {
64167
+ return detectCloudCreds().filter((c) => !getAccount(`${c.provider}-import`));
64168
+ }
64169
+ var init_detect = __esm(() => {
64170
+ init_catalog();
64171
+ init_store();
64172
+ });
64173
+
64035
64174
  // src/agent/cli-backend.ts
64036
64175
  function newState() {
64037
64176
  return { text: "", usage: { inputTokens: 0, outputTokens: 0 }, rates: new Map, toolNames: new Map };
@@ -64267,345 +64406,23 @@ var init_cli_backend = __esm(() => {
64267
64406
  CONFIG_DIR_VAR = { claude: "CLAUDE_CONFIG_DIR", codex: "CODEX_HOME" };
64268
64407
  });
64269
64408
 
64270
- // node_modules/react/jsx-dev-runtime.js
64271
- var require_jsx_dev_runtime2 = __commonJS((exports, module) => {
64272
- var react_jsx_dev_runtime_development = __toESM(require_react_jsx_dev_runtime_development());
64273
- if (false) {} else {
64274
- module.exports = react_jsx_dev_runtime_development;
64275
- }
64276
- });
64277
-
64278
- // src/accounts/store.ts
64279
- var exports_store = {};
64280
- __export(exports_store, {
64281
- setSecret: () => setSecret2,
64282
- setDefaultAccount: () => setDefaultAccount2,
64283
- secretRefs: () => secretRefs2,
64284
- saveAccounts: () => saveAccounts2,
64285
- removeAccount: () => removeAccount2,
64286
- putAccount: () => putAccount2,
64287
- markUsed: () => markUsed2,
64288
- loadAccounts: () => loadAccounts3,
64289
- listAccounts: () => listAccounts2,
64290
- getSecret: () => getSecret2,
64291
- getAccount: () => getAccount2,
64292
- deleteSecret: () => deleteSecret2,
64293
- defaultAccount: () => defaultAccount2,
64294
- accountsForProvider: () => accountsForProvider2
64295
- });
64296
- import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes2 } from "node:crypto";
64297
- import { readFileSync as readFileSync15, writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, existsSync as existsSync8 } from "node:fs";
64298
- import { join as join13 } from "node:path";
64299
- import { homedir as homedir11 } from "node:os";
64300
- async function setSecret2(ref, value) {
64301
- if (typeof Bun !== "undefined" && mode2() !== "file") {
64302
- try {
64303
- await Bun.secrets.set({ service: SERVICE2, name: ref, value });
64304
- return;
64305
- } catch (e2) {
64306
- if (mode2() === "keychain")
64307
- throw e2;
64308
- }
64309
- }
64310
- fileSet2(ref, value);
64311
- }
64312
- async function getSecret2(ref) {
64313
- if (typeof Bun !== "undefined" && mode2() !== "file") {
64314
- try {
64315
- const v = await Bun.secrets.get({ service: SERVICE2, name: ref });
64316
- if (v != null)
64317
- return v;
64318
- } catch {
64319
- if (mode2() === "keychain")
64320
- return null;
64321
- }
64322
- }
64323
- return fileGet2(ref);
64324
- }
64325
- async function deleteSecret2(ref) {
64326
- if (typeof Bun !== "undefined" && mode2() !== "file") {
64327
- try {
64328
- await Bun.secrets.delete({ service: SERVICE2, name: ref });
64329
- } catch {}
64330
- }
64331
- fileDelete2(ref);
64332
- }
64333
- function masterKey2() {
64334
- ensure3();
64335
- if (existsSync8(keyFile2()))
64336
- return Buffer.from(readFileSync15(keyFile2(), "utf8").trim(), "base64");
64337
- const k = randomBytes2(32);
64338
- writeFileSync9(keyFile2(), k.toString("base64"), { mode: 384 });
64339
- return k;
64340
- }
64341
- function encrypt2(plain) {
64342
- const iv = randomBytes2(12);
64343
- const c = createCipheriv2("aes-256-gcm", masterKey2(), iv);
64344
- const data = Buffer.concat([c.update(plain, "utf8"), c.final()]);
64345
- return [iv.toString("base64"), c.getAuthTag().toString("base64"), data.toString("base64")].join(".");
64346
- }
64347
- function decrypt2(blob) {
64348
- try {
64349
- const [iv, tag2, data] = blob.split(".").map((x2) => Buffer.from(x2, "base64"));
64350
- const d = createDecipheriv2("aes-256-gcm", masterKey2(), iv);
64351
- d.setAuthTag(tag2);
64352
- return Buffer.concat([d.update(data), d.final()]).toString("utf8");
64353
- } catch {
64354
- return null;
64355
- }
64356
- }
64357
- function readEnc2() {
64358
- try {
64359
- return JSON.parse(readFileSync15(encFile2(), "utf8"));
64360
- } catch {
64361
- return {};
64362
- }
64363
- }
64364
- function writeEnc2(m2) {
64365
- ensure3();
64366
- writeFileSync9(encFile2(), JSON.stringify(m2), { mode: 384 });
64367
- }
64368
- function fileSet2(ref, v) {
64369
- const m2 = readEnc2();
64370
- m2[ref] = encrypt2(v);
64371
- writeEnc2(m2);
64372
- }
64373
- function fileGet2(ref) {
64374
- const blob = readEnc2()[ref];
64375
- return blob ? decrypt2(blob) : null;
64376
- }
64377
- function fileDelete2(ref) {
64378
- const m2 = readEnc2();
64379
- delete m2[ref];
64380
- writeEnc2(m2);
64381
- }
64382
- function loadAccounts3() {
64383
- try {
64384
- const f3 = JSON.parse(readFileSync15(accountsFile2(), "utf8"));
64385
- if (f3 && Array.isArray(f3.accounts))
64386
- return { version: 1, defaults: {}, ...f3 };
64387
- } catch {}
64388
- return { version: 1, accounts: [], defaults: {} };
64389
- }
64390
- function saveAccounts2(f3) {
64391
- try {
64392
- ensure3();
64393
- writeFileSync9(accountsFile2(), JSON.stringify(f3, null, 2), { mode: 384 });
64394
- } catch {}
64395
- }
64396
- function listAccounts2() {
64397
- return loadAccounts3().accounts;
64398
- }
64399
- function accountsForProvider2(provider) {
64400
- return listAccounts2().filter((a) => a.provider === provider && a.enabled);
64401
- }
64402
- function getAccount2(id) {
64403
- return listAccounts2().find((a) => a.id === id);
64404
- }
64405
- function putAccount2(account) {
64406
- const f3 = loadAccounts3();
64407
- const i2 = f3.accounts.findIndex((a) => a.id === account.id);
64408
- if (i2 >= 0)
64409
- f3.accounts[i2] = account;
64410
- else
64411
- f3.accounts.push(account);
64412
- if (!f3.defaults[account.provider])
64413
- f3.defaults[account.provider] = account.id;
64414
- saveAccounts2(f3);
64415
- }
64416
- async function removeAccount2(id) {
64417
- const f3 = loadAccounts3();
64418
- const acc = f3.accounts.find((a) => a.id === id);
64419
- f3.accounts = f3.accounts.filter((a) => a.id !== id);
64420
- for (const [p, aid] of Object.entries(f3.defaults)) {
64421
- if (aid === id) {
64422
- const next = f3.accounts.find((a) => a.provider === p);
64423
- if (next)
64424
- f3.defaults[p] = next.id;
64425
- else
64426
- delete f3.defaults[p];
64427
- }
64428
- }
64429
- saveAccounts2(f3);
64430
- if (acc)
64431
- for (const ref of secretRefs2(acc))
64432
- await deleteSecret2(ref);
64433
- }
64434
- function setDefaultAccount2(provider, id) {
64435
- const f3 = loadAccounts3();
64436
- if (!f3.accounts.some((a) => a.id === id && a.provider === provider))
64437
- return;
64438
- f3.defaults[provider] = id;
64439
- saveAccounts2(f3);
64440
- }
64441
- function defaultAccount2(provider) {
64442
- const f3 = loadAccounts3();
64443
- const id = f3.defaults[provider];
64444
- const byDefault = id ? f3.accounts.find((a) => a.id === id && a.enabled) : undefined;
64445
- return byDefault ?? f3.accounts.find((a) => a.provider === provider && a.enabled);
64446
- }
64447
- function markUsed2(id) {
64448
- const f3 = loadAccounts3();
64449
- const a = f3.accounts.find((x2) => x2.id === id);
64450
- if (a) {
64451
- a.lastUsedAt = Date.now();
64452
- saveAccounts2(f3);
64453
- }
64454
- }
64455
- function secretRefs2(a) {
64456
- const refs = [];
64457
- const auth = a.auth;
64458
- if (auth.kind === "api-key" || auth.kind === "azure" || auth.kind === "openai-compat")
64459
- refs.push(auth.ref);
64460
- if (auth.kind === "aws") {
64461
- refs.push(auth.accessKeyIdRef, auth.secretKeyRef);
64462
- if (auth.sessionTokenRef)
64463
- refs.push(auth.sessionTokenRef);
64464
- }
64465
- if (auth.kind === "vertex" && auth.serviceAccountRef)
64466
- refs.push(auth.serviceAccountRef);
64467
- return refs;
64468
- }
64469
- var SERVICE2 = "gearbox", home5 = () => process.env.GEARBOX_HOME || join13(homedir11(), ".gearbox"), ensure3 = () => mkdirSync10(home5(), { recursive: true }), mode2 = () => {
64470
- const m2 = process.env.GEARBOX_SECRET_STORE;
64471
- return m2 === "file" || m2 === "keychain" ? m2 : "auto";
64472
- }, encFile2 = () => join13(home5(), "credentials.enc"), keyFile2 = () => join13(home5(), ".enckey"), accountsFile2 = () => join13(home5(), "accounts.json");
64473
- var init_store2 = () => {};
64474
-
64475
- // src/accounts/detect.ts
64476
- var exports_detect = {};
64477
- __export(exports_detect, {
64478
- importableEnvCreds: () => importableEnvCreds2,
64479
- importableCloudCreds: () => importableCloudCreds2,
64480
- importEnvCred: () => importEnvCred2,
64481
- importCloudCred: () => importCloudCred2,
64482
- detectEnvCreds: () => detectEnvCreds2,
64483
- detectCloudCreds: () => detectCloudCreds2
64484
- });
64485
- import { readFileSync as readFileSync16, existsSync as existsSync9 } from "node:fs";
64486
- import { join as join14 } from "node:path";
64487
- import { homedir as homedir12 } from "node:os";
64488
- function detectEnvCreds2() {
64489
- const out = [];
64490
- for (const p of CATALOG) {
64491
- if (p.authKind !== "api-key" && p.authKind !== "openai-compat")
64492
- continue;
64493
- for (const ev of p.envVars) {
64494
- const v = process.env[ev];
64495
- if (v) {
64496
- out.push({ provider: p.id, label: p.label, envVar: ev, value: v });
64497
- break;
64498
- }
64499
- }
64500
- }
64501
- return out;
64502
- }
64503
- async function importEnvCred2(c) {
64504
- const id = `${c.provider}-env`;
64505
- const ref = `${id}:api-key`;
64506
- await setSecret(ref, c.value);
64507
- const cat = CATALOG.find((p) => p.id === c.provider);
64508
- const account = {
64509
- id,
64510
- label: `${c.label} (from ${c.envVar})`,
64511
- provider: c.provider,
64512
- exec: "in-loop",
64513
- auth: cat.authKind === "openai-compat" ? { kind: "openai-compat", ref } : { kind: "api-key", ref },
64514
- baseUrl: cat.baseUrl,
64515
- enabled: true,
64516
- addedAt: Date.now()
64517
- };
64518
- putAccount(account);
64519
- return account;
64520
- }
64521
- function importableEnvCreds2() {
64522
- return detectEnvCreds2().filter((c) => !getAccount(`${c.provider}-env`));
64523
- }
64524
- function awsIni2(file6, profile = "default") {
64525
- if (!existsSync9(file6))
64526
- return {};
64527
- const out = {};
64528
- let cur = "";
64529
- for (const raw of readFileSync16(file6, "utf8").split(`
64530
- `)) {
64531
- const line = raw.trim();
64532
- if (line.startsWith("["))
64533
- cur = line.slice(1, -1).replace(/^profile\s+/, "");
64534
- else if (cur === profile && line.includes("=")) {
64535
- const i2 = line.indexOf("=");
64536
- out[line.slice(0, i2).trim().toLowerCase()] = line.slice(i2 + 1).trim();
64537
- }
64538
- }
64539
- return out;
64540
- }
64541
- function detectCloudCreds2() {
64542
- const out = [];
64543
- const home6 = homedir12();
64544
- const creds = awsIni2(join14(home6, ".aws", "credentials"));
64545
- const conf = awsIni2(join14(home6, ".aws", "config"));
64546
- const akid = process.env.AWS_ACCESS_KEY_ID ?? creds.aws_access_key_id;
64547
- const secret = process.env.AWS_SECRET_ACCESS_KEY ?? creds.aws_secret_access_key;
64548
- const region = process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? conf.region;
64549
- if (akid && secret) {
64550
- out.push({
64551
- provider: "bedrock",
64552
- label: "Amazon Bedrock",
64553
- source: process.env.AWS_ACCESS_KEY_ID ? "env" : "~/.aws/credentials",
64554
- aws: { accessKeyId: akid, secretAccessKey: secret, sessionToken: process.env.AWS_SESSION_TOKEN ?? creds.aws_session_token, region: region ?? "us-east-1" }
64555
- });
64556
- }
64557
- if (process.env.AZURE_API_KEY && process.env.AZURE_RESOURCE_NAME) {
64558
- out.push({ provider: "azure", label: "Azure OpenAI", source: "env", azure: { resourceName: process.env.AZURE_RESOURCE_NAME, apiKey: process.env.AZURE_API_KEY } });
64559
- }
64560
- if (process.env.GOOGLE_VERTEX_PROJECT) {
64561
- out.push({ provider: "vertex", label: "Google Vertex AI", source: "env", vertex: { project: process.env.GOOGLE_VERTEX_PROJECT, location: process.env.GOOGLE_VERTEX_LOCATION ?? "us-central1" } });
64562
- }
64563
- return out;
64564
- }
64565
- async function importCloudCred2(c) {
64566
- const id = `${c.provider}-import`;
64567
- let auth;
64568
- if (c.aws) {
64569
- await setSecret(`${id}:akid`, c.aws.accessKeyId);
64570
- await setSecret(`${id}:secret`, c.aws.secretAccessKey);
64571
- if (c.aws.sessionToken)
64572
- await setSecret(`${id}:token`, c.aws.sessionToken);
64573
- auth = { kind: "aws", accessKeyIdRef: `${id}:akid`, secretKeyRef: `${id}:secret`, sessionTokenRef: c.aws.sessionToken ? `${id}:token` : undefined, region: c.aws.region };
64574
- } else if (c.azure) {
64575
- await setSecret(`${id}:api-key`, c.azure.apiKey);
64576
- auth = { kind: "azure", resourceName: c.azure.resourceName, ref: `${id}:api-key` };
64577
- } else {
64578
- auth = { kind: "vertex", project: c.vertex.project, location: c.vertex.location, adc: true };
64579
- }
64580
- const account = { id, label: `${c.label} (from ${c.source})`, provider: c.provider, exec: "in-loop", auth, enabled: true, addedAt: Date.now() };
64581
- putAccount(account);
64582
- return account;
64583
- }
64584
- function importableCloudCreds2() {
64585
- return detectCloudCreds2().filter((c) => !getAccount(`${c.provider}-import`));
64586
- }
64587
- var init_detect = __esm(() => {
64588
- init_catalog();
64589
- init_store();
64590
- });
64591
-
64592
64409
  // src/accounts/onboard.ts
64593
64410
  var exports_onboard = {};
64594
64411
  __export(exports_onboard, {
64595
- testAccount: () => testAccount2,
64596
- cliLoginArgs: () => cliLoginArgs2,
64597
- cliAuthStatus: () => cliAuthStatus2,
64412
+ testAccount: () => testAccount,
64413
+ cliLoginArgs: () => cliLoginArgs,
64414
+ cliAuthStatus: () => cliAuthStatus,
64598
64415
  addableProviders: () => addableProviders,
64599
- addCliAccount: () => addCliAccount2,
64600
- addByPastedKey: () => addByPastedKey2,
64601
- addAzureFoundryAccount: () => addAzureFoundryAccount2,
64602
- addAzureAccount: () => addAzureAccount2,
64603
- addApiKeyAccount: () => addApiKeyAccount2
64604
- });
64605
- import { mkdirSync as mkdirSync11 } from "node:fs";
64606
- import { join as join15 } from "node:path";
64607
- import { homedir as homedir13 } from "node:os";
64608
- async function addApiKeyAccount2(provider, key, opts = {}) {
64416
+ addCliAccount: () => addCliAccount,
64417
+ addByPastedKey: () => addByPastedKey,
64418
+ addAzureFoundryAccount: () => addAzureFoundryAccount,
64419
+ addAzureAccount: () => addAzureAccount,
64420
+ addApiKeyAccount: () => addApiKeyAccount
64421
+ });
64422
+ import { mkdirSync as mkdirSync7 } from "node:fs";
64423
+ import { join as join10 } from "node:path";
64424
+ import { homedir as homedir8 } from "node:os";
64425
+ async function addApiKeyAccount(provider, key, opts = {}) {
64609
64426
  const cat = catalogProvider(provider);
64610
64427
  if (!cat)
64611
64428
  return { ok: false, message: `unknown provider "${provider}" — see /accounts catalog` };
@@ -64614,7 +64431,7 @@ async function addApiKeyAccount2(provider, key, opts = {}) {
64614
64431
  if (cat.authKind !== "api-key" && cat.authKind !== "openai-compat") {
64615
64432
  return { ok: false, message: `${cat.label} needs ${cat.authKind} credentials — use the guided add (P2)` };
64616
64433
  }
64617
- const id = opts.id ?? `${provider}-${shortId2()}`;
64434
+ const id = opts.id ?? `${provider}-${shortId()}`;
64618
64435
  const ref = `${id}:api-key`;
64619
64436
  await setSecret(ref, key.trim());
64620
64437
  const account = {
@@ -64630,7 +64447,7 @@ async function addApiKeyAccount2(provider, key, opts = {}) {
64630
64447
  putAccount(account);
64631
64448
  return { ok: true, account, message: `added ${account.label} (${id})` };
64632
64449
  }
64633
- function azureResourceName2(input) {
64450
+ function azureResourceName(input) {
64634
64451
  const s2 = input.trim();
64635
64452
  try {
64636
64453
  const host = new URL(s2).hostname;
@@ -64639,7 +64456,7 @@ function azureResourceName2(input) {
64639
64456
  return s2;
64640
64457
  }
64641
64458
  }
64642
- function azureFoundryBaseUrl2(endpoint) {
64459
+ function azureFoundryBaseUrl(endpoint) {
64643
64460
  const trimmed = endpoint.trim().replace(/\/+$/, "");
64644
64461
  if (/\/openai\/v1$/i.test(trimmed))
64645
64462
  return trimmed;
@@ -64647,32 +64464,32 @@ function azureFoundryBaseUrl2(endpoint) {
64647
64464
  return `${trimmed}/v1`;
64648
64465
  return `${trimmed}/openai/v1`;
64649
64466
  }
64650
- async function addAzureFoundryAccount2(endpoint, key, opts = {}) {
64467
+ async function addAzureFoundryAccount(endpoint, key, opts = {}) {
64651
64468
  if (!/^https?:\/\//i.test(endpoint) || !key.trim())
64652
64469
  return { ok: false, message: "usage: /account add azure <foundry-endpoint> <api-key>" };
64653
64470
  const host = new URL(endpoint).hostname;
64654
- const slug4 = host.split(".")[0]?.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || shortId2();
64655
- const id = opts.id ?? `azure-foundry-${slug4}`;
64471
+ const slug3 = host.split(".")[0]?.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || shortId();
64472
+ const id = opts.id ?? `azure-foundry-${slug3}`;
64656
64473
  const ref = `${id}:api-key`;
64657
64474
  await setSecret(ref, key.trim());
64658
64475
  const account = {
64659
64476
  id,
64660
- label: opts.label ?? `Azure Foundry (${slug4})`,
64477
+ label: opts.label ?? `Azure Foundry (${slug3})`,
64661
64478
  provider: "azure-foundry",
64662
64479
  exec: "in-loop",
64663
64480
  auth: { kind: "openai-compat", ref },
64664
- baseUrl: azureFoundryBaseUrl2(endpoint),
64481
+ baseUrl: azureFoundryBaseUrl(endpoint),
64665
64482
  enabled: true,
64666
64483
  addedAt: Date.now()
64667
64484
  };
64668
64485
  putAccount(account);
64669
64486
  return { ok: true, account, message: `added ${account.label} (${id})` };
64670
64487
  }
64671
- async function addAzureAccount2(resourceOrEndpoint, key, opts = {}) {
64672
- const resourceName = azureResourceName2(resourceOrEndpoint);
64488
+ async function addAzureAccount(resourceOrEndpoint, key, opts = {}) {
64489
+ const resourceName = azureResourceName(resourceOrEndpoint);
64673
64490
  if (!resourceName || !key.trim())
64674
64491
  return { ok: false, message: "usage: /account add azure <resource-or-endpoint> <api-key> [api-version]" };
64675
- const id = opts.id ?? `azure-${resourceName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || shortId2()}`;
64492
+ const id = opts.id ?? `azure-${resourceName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || shortId()}`;
64676
64493
  const ref = `${id}:api-key`;
64677
64494
  await setSecret(ref, key.trim());
64678
64495
  const account = {
@@ -64687,24 +64504,24 @@ async function addAzureAccount2(resourceOrEndpoint, key, opts = {}) {
64687
64504
  putAccount(account);
64688
64505
  return { ok: true, account, message: `added ${account.label} (${id})` };
64689
64506
  }
64690
- function cliProfileDir2(id) {
64691
- const home6 = process.env.GEARBOX_HOME || join15(homedir13(), ".gearbox");
64692
- return join15(home6, "cli", id);
64507
+ function cliProfileDir(id) {
64508
+ const home5 = process.env.GEARBOX_HOME || join10(homedir8(), ".gearbox");
64509
+ return join10(home5, "cli", id);
64693
64510
  }
64694
- function addCliAccount2(provider, name31) {
64511
+ function addCliAccount(provider, name31) {
64695
64512
  const cat = catalogProvider(provider);
64696
64513
  if (!cat || cat.group !== "cli" || !cat.binary)
64697
64514
  return { ok: false, message: `"${provider}" is not a CLI subscription provider` };
64698
64515
  if (!which(cat.binary))
64699
64516
  return { ok: false, message: `the ${cat.binary} binary isn't on your PATH — install it first` };
64700
- const slug4 = name31 ? name31.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") : "";
64701
- const id = slug4 ? `${provider}-${slug4}` : provider;
64702
- const profile = slug4 ? cliProfileDir2(id) : undefined;
64517
+ const slug3 = name31 ? name31.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") : "";
64518
+ const id = slug3 ? `${provider}-${slug3}` : provider;
64519
+ const profile = slug3 ? cliProfileDir(id) : undefined;
64703
64520
  if (profile)
64704
- mkdirSync11(profile, { recursive: true });
64521
+ mkdirSync7(profile, { recursive: true });
64705
64522
  const account = {
64706
64523
  id,
64707
- label: slug4 ? `${cat.label.replace(/ \(.*\)$/, "")} (${name31.trim()})` : cat.label,
64524
+ label: slug3 ? `${cat.label.replace(/ \(.*\)$/, "")} (${name31.trim()})` : cat.label,
64708
64525
  provider,
64709
64526
  exec: "cli",
64710
64527
  auth: { kind: "cli", binary: cat.binary, loginProfile: profile },
@@ -64715,7 +64532,7 @@ function addCliAccount2(provider, name31) {
64715
64532
  putAccount(account);
64716
64533
  return { ok: true, account, message: `${account.label} ready — runs via the ${cat.binary} CLI${profile ? " (separate login)" : ""}` };
64717
64534
  }
64718
- async function cliAuthStatus2(binary, profile) {
64535
+ async function cliAuthStatus(binary, profile) {
64719
64536
  const env3 = subscriptionEnv(binary, profile);
64720
64537
  const readBoth = async (cmd, timeoutMs = 5000) => {
64721
64538
  const p = spawnProc(cmd, { stdin: "ignore", stdout: "pipe", stderr: "pipe", env: env3 });
@@ -64768,16 +64585,16 @@ ${e2}`.trim(), timedOut };
64768
64585
  return { loggedIn: false };
64769
64586
  }
64770
64587
  }
64771
- function cliLoginArgs2(binary) {
64588
+ function cliLoginArgs(binary) {
64772
64589
  return binary === "codex" ? ["login"] : ["auth", "login"];
64773
64590
  }
64774
- async function addByPastedKey2(key) {
64591
+ async function addByPastedKey(key) {
64775
64592
  const provider = detectProviderByKey(key);
64776
64593
  if (!provider)
64777
64594
  return { ok: false, message: "couldn't identify the provider from that key — use /accounts add <provider> <key>" };
64778
- return addApiKeyAccount2(provider, key);
64595
+ return addApiKeyAccount(provider, key);
64779
64596
  }
64780
- async function testAccount2(a) {
64597
+ async function testAccount(a) {
64781
64598
  const creds = await resolveCreds(a);
64782
64599
  if (!creds.apiKey && a.auth.kind !== "cli")
64783
64600
  return { ok: false, message: "no key stored" };
@@ -64788,17 +64605,17 @@ async function testAccount2(a) {
64788
64605
  headers: { "x-api-key": creds.apiKey ?? "", "anthropic-version": "2023-06-01", "content-type": "application/json" },
64789
64606
  body: JSON.stringify({ model: "claude-haiku-4-5", messages: [{ role: "user", content: "hi" }] })
64790
64607
  });
64791
- return r3.ok ? { ok: true, message: "credential works" } : { ok: false, message: await errMessage2(r3) };
64608
+ return r3.ok ? { ok: true, message: "credential works" } : { ok: false, message: await errMessage(r3) };
64792
64609
  }
64793
64610
  if (a.provider === "google") {
64794
64611
  const r3 = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${creds.apiKey ?? ""}`);
64795
- return r3.ok ? { ok: true, message: "credential works" } : { ok: false, message: await errMessage2(r3) };
64612
+ return r3.ok ? { ok: true, message: "credential works" } : { ok: false, message: await errMessage(r3) };
64796
64613
  }
64797
64614
  const base2 = creds.baseURL ?? "https://api.openai.com/v1";
64798
64615
  const r2 = await fetch(`${base2.replace(/\/$/, "")}/models`, {
64799
64616
  headers: { Authorization: `Bearer ${creds.apiKey ?? ""}`, ...creds.headers ?? {} }
64800
64617
  });
64801
- return r2.ok ? { ok: true, message: "credential works" } : { ok: false, message: await errMessage2(r2) };
64618
+ return r2.ok ? { ok: true, message: "credential works" } : { ok: false, message: await errMessage(r2) };
64802
64619
  } catch (e2) {
64803
64620
  return { ok: false, message: e2?.message ?? "request failed" };
64804
64621
  }
@@ -64806,7 +64623,7 @@ async function testAccount2(a) {
64806
64623
  function addableProviders() {
64807
64624
  return CATALOG.filter((p) => p.authKind === "api-key" || p.authKind === "openai-compat").map((p) => ({ id: p.id, label: p.label, group: p.group }));
64808
64625
  }
64809
- async function errMessage2(r2) {
64626
+ async function errMessage(r2) {
64810
64627
  try {
64811
64628
  const j = await r2.json();
64812
64629
  const m2 = j?.error?.message ?? j?.message ?? j?.error;
@@ -64815,7 +64632,7 @@ async function errMessage2(r2) {
64815
64632
  } catch {}
64816
64633
  return `HTTP ${r2.status}`;
64817
64634
  }
64818
- function shortId2() {
64635
+ function shortId() {
64819
64636
  return Date.now().toString(36).slice(-4) + Math.floor(Math.random() * 1296).toString(36).padStart(2, "0");
64820
64637
  }
64821
64638
  var init_onboard = __esm(() => {
@@ -64826,62 +64643,6 @@ var init_onboard = __esm(() => {
64826
64643
  init_proc();
64827
64644
  });
64828
64645
 
64829
- // src/accounts/catalog.ts
64830
- var exports_catalog = {};
64831
- __export(exports_catalog, {
64832
- detectProviderByKey: () => detectProviderByKey2,
64833
- catalogProvider: () => catalogProvider2,
64834
- CATALOG: () => CATALOG2
64835
- });
64836
- function catalogProvider2(id) {
64837
- return BY_ID3.get(id);
64838
- }
64839
- function detectProviderByKey2(key) {
64840
- const k = key.trim();
64841
- const ranked = CATALOG2.flatMap((p) => (p.keyPrefix ?? []).map((pre) => ({ id: p.id, pre }))).sort((a, b) => b.pre.length - a.pre.length);
64842
- return ranked.find(({ pre }) => k.startsWith(pre))?.id;
64843
- }
64844
- var CATALOG2, BY_ID3;
64845
- var init_catalog2 = __esm(() => {
64846
- CATALOG2 = [
64847
- { id: "anthropic", label: "Anthropic", group: "native", exec: "in-loop", authKind: "api-key", envVars: ["ANTHROPIC_API_KEY"], keyPrefix: ["sk-ant-"], signupUrl: "https://console.anthropic.com/settings/keys", defaultModels: ["claude-sonnet-4-6", "claude-haiku-4-5", "claude-opus-4-8"] },
64848
- { id: "openai", label: "OpenAI", group: "native", exec: "in-loop", authKind: "api-key", envVars: ["OPENAI_API_KEY"], keyPrefix: ["sk-proj-", "sk-"], signupUrl: "https://platform.openai.com/api-keys", defaultModels: ["gpt-5.5", "gpt-5.5-pro", "gpt-5.5-mini"] },
64849
- { id: "google", label: "Google Gemini", group: "native", exec: "in-loop", authKind: "api-key", envVars: ["GOOGLE_GENERATIVE_AI_API_KEY", "GEMINI_API_KEY"], keyPrefix: ["AIza"], signupUrl: "https://aistudio.google.com/apikey", defaultModels: ["gemini-3.5-flash", "gemini-3.1-pro-preview", "gemini-3.1-flash-lite"] },
64850
- { 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"] },
64851
- { 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"] },
64852
- { 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"] },
64853
- { 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"] },
64854
- { 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"] },
64855
- { 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"] },
64856
- { 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" },
64857
- { id: "cerebras", label: "Cerebras", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["CEREBRAS_API_KEY"], keyPrefix: ["csk-"], baseUrl: "https://api.cerebras.ai/v1", signupUrl: "https://cloud.cerebras.ai", defaultModels: ["qwen-3-coder-480b", "llama-3.3-70b"] },
64858
- { id: "perplexity", label: "Perplexity", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["PERPLEXITY_API_KEY"], keyPrefix: ["pplx-"], baseUrl: "https://api.perplexity.ai", signupUrl: "https://www.perplexity.ai/settings/api", defaultModels: ["sonar-pro", "sonar-reasoning-pro"] },
64859
- { id: "baseten", label: "Baseten", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["BASETEN_API_KEY"], baseUrl: "https://inference.baseten.co/v1", signupUrl: "https://app.baseten.co/settings/api_keys" },
64860
- { id: "moonshot", label: "Moonshot (Kimi)", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["MOONSHOT_API_KEY"], baseUrl: "https://api.moonshot.ai/v1", signupUrl: "https://platform.moonshot.ai/console/api-keys", defaultModels: ["kimi-k2-0905-preview"] },
64861
- { id: "zai", label: "Z.ai (GLM)", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["ZAI_API_KEY", "ZHIPU_API_KEY"], baseUrl: "https://api.z.ai/api/paas/v4", signupUrl: "https://z.ai/manage-apikey/apikey-list", defaultModels: ["glm-4.6", "glm-4.5-air"] },
64862
- { id: "nebius", label: "Nebius AI Studio", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["NEBIUS_API_KEY"], baseUrl: "https://api.studio.nebius.com/v1", signupUrl: "https://studio.nebius.com" },
64863
- { id: "hyperbolic", label: "Hyperbolic", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["HYPERBOLIC_API_KEY"], baseUrl: "https://api.hyperbolic.xyz/v1", signupUrl: "https://app.hyperbolic.xyz/settings" },
64864
- { id: "sambanova", label: "SambaNova", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["SAMBANOVA_API_KEY"], baseUrl: "https://api.sambanova.ai/v1", signupUrl: "https://cloud.sambanova.ai/apis" },
64865
- { id: "novita", label: "Novita", group: "openai-compat", exec: "in-loop", authKind: "openai-compat", envVars: ["NOVITA_API_KEY"], baseUrl: "https://api.novita.ai/v3/openai", signupUrl: "https://novita.ai/settings/key-management" },
64866
- { id: "openrouter", label: "OpenRouter", group: "gateway", exec: "in-loop", authKind: "openai-compat", envVars: ["OPENROUTER_API_KEY"], keyPrefix: ["sk-or-"], baseUrl: "https://openrouter.ai/api/v1", signupUrl: "https://openrouter.ai/keys", notes: "Hundreds of models via one key. extraHeaders HTTP-Referer/X-Title recommended." },
64867
- { id: "vercel-gateway", label: "Vercel AI Gateway", group: "gateway", exec: "in-loop", authKind: "openai-compat", envVars: ["AI_GATEWAY_API_KEY"], baseUrl: "https://ai-gateway.vercel.sh/v1", signupUrl: "https://vercel.com/docs/ai-gateway", notes: "Spend + credit telemetry; feeds the future ACCOUNT pillar." },
64868
- { id: "requesty", label: "Requesty", group: "gateway", exec: "in-loop", authKind: "openai-compat", envVars: ["REQUESTY_API_KEY"], baseUrl: "https://router.requesty.ai/v1", signupUrl: "https://app.requesty.ai" },
64869
- { 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." },
64870
- { 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." },
64871
- { 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." },
64872
- { 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)." },
64873
- { 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." },
64874
- { 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." },
64875
- { 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." },
64876
- { id: "lmstudio", label: "LM Studio (local)", group: "local", exec: "in-loop", authKind: "openai-compat", envVars: [], baseUrl: "http://localhost:1234/v1", signupUrl: "https://lmstudio.ai" },
64877
- { 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" },
64878
- { id: "llamacpp", label: "llama.cpp (local)", group: "local", exec: "in-loop", authKind: "openai-compat", envVars: [], baseUrl: "http://localhost:8080/v1", signupUrl: "https://github.com/ggml-org/llama.cpp" },
64879
- { id: "claude-cli", label: "Claude (Pro/Max via claude CLI)", group: "cli", exec: "cli", authKind: "cli", envVars: [], binary: "claude", signupUrl: "https://claude.com/product/claude-code", defaultModels: ["claude-opus-4-8", "claude-sonnet-4-6"], notes: "Wraps the official binary (like Conductor). Runs its own tools/permissions. ToS-clean: no token is read." },
64880
- { id: "codex-cli", label: "ChatGPT (Plus/Pro via codex CLI)", group: "cli", exec: "cli", authKind: "cli", envVars: [], binary: "codex", signupUrl: "https://developers.openai.com/codex/cli", defaultModels: ["gpt-5.5", "gpt-5.4", "gpt-5.4-mini"], notes: "Wraps the official binary. Runs its own tools/permissions. ToS-clean." }
64881
- ];
64882
- BY_ID3 = new Map(CATALOG2.map((p) => [p.id, p]));
64883
- });
64884
-
64885
64646
  // node_modules/ink/build/render.js
64886
64647
  import { Stream } from "node:stream";
64887
64648
  import process12 from "node:process";
@@ -70406,12 +70167,13 @@ var import_react20 = __toESM(require_react(), 1);
70406
70167
  // node_modules/ink/build/hooks/use-focus-manager.js
70407
70168
  var import_react21 = __toESM(require_react(), 1);
70408
70169
  // src/cli.tsx
70409
- import { execFileSync as execFileSync4 } from "child_process";
70410
- import { resolve as resolve11 } from "path";
70411
- import { existsSync as existsSync10 } from "fs";
70170
+ import { execFileSync as execFileSync4 } from "node:child_process";
70171
+ import { resolve as resolve11 } from "node:path";
70172
+ import { existsSync as existsSync8 } from "node:fs";
70412
70173
 
70413
70174
  // src/ui/App.tsx
70414
70175
  var import_react26 = __toESM(require_react(), 1);
70176
+
70415
70177
  // src/ui/theme.ts
70416
70178
  var color = {
70417
70179
  accent: "#7DD3FC",
@@ -119403,6 +119165,9 @@ function detectImageMode() {
119403
119165
  return "blocks";
119404
119166
  }
119405
119167
  var resolved = null;
119168
+ function setImageMode(m2) {
119169
+ resolved = m2;
119170
+ }
119406
119171
  function getImageMode() {
119407
119172
  return resolved ?? detectImageMode();
119408
119173
  }
@@ -119413,6 +119178,30 @@ function idColor(id) {
119413
119178
  const bytes = [id >> 16 & 255, id >> 8 & 255, id & 255];
119414
119179
  return "#" + bytes.map((x2) => x2.toString(16).padStart(2, "0")).join("");
119415
119180
  }
119181
+ function transmitOne(id, b64, cols, rows) {
119182
+ const ESC2 = "\x1B";
119183
+ const CHUNK = 4096;
119184
+ if (b64.length <= CHUNK) {
119185
+ return `${ESC2}_Ga=T,U=1,i=${id},c=${cols},r=${rows},f=100,q=2;${b64}${ESC2}\\`;
119186
+ }
119187
+ let out = "";
119188
+ for (let i2 = 0;i2 < b64.length; i2 += CHUNK) {
119189
+ const chunk2 = b64.slice(i2, i2 + CHUNK);
119190
+ const more = i2 + CHUNK < b64.length ? 1 : 0;
119191
+ out += i2 === 0 ? `${ESC2}_Ga=T,U=1,i=${id},c=${cols},r=${rows},f=100,q=2,m=${more};${chunk2}${ESC2}\\` : `${ESC2}_Gm=${more};${chunk2}${ESC2}\\`;
119192
+ }
119193
+ return out;
119194
+ }
119195
+ function transmitAll() {
119196
+ let out = "";
119197
+ for (const variant of VARIANTS) {
119198
+ for (const size2 of SIZES) {
119199
+ const data = GHOSTS[variant][size2];
119200
+ out += transmitOne(imageId(variant, size2), GHOST_PNG[variant], data[0]?.length ?? 0, data.length);
119201
+ }
119202
+ }
119203
+ return out;
119204
+ }
119416
119205
  function placeholderRows(cols, rows) {
119417
119206
  const lines = [];
119418
119207
  for (let r2 = 0;r2 < rows; r2++) {
@@ -121297,6 +121086,9 @@ function listSessions() {
121297
121086
  return [];
121298
121087
  }
121299
121088
  }
121089
+ function latestSession() {
121090
+ return listSessions()[0] ?? null;
121091
+ }
121300
121092
  var histFile = () => join4(dir(), "history.json");
121301
121093
  function loadHistory() {
121302
121094
  try {
@@ -121395,6 +121187,9 @@ function pickDefaultModel(preferredId) {
121395
121187
  return wanted;
121396
121188
  return MODELS.find((m2) => providerAvailable(m2.provider));
121397
121189
  }
121190
+ function anyProviderAvailable() {
121191
+ return MODELS.some((m2) => providerAvailable(m2.provider));
121192
+ }
121398
121193
 
121399
121194
  // src/model/selector.ts
121400
121195
  class FixedSelector {
@@ -133323,334 +133118,8 @@ function friendlyToolPhase(name31) {
133323
133118
  // src/ui/App.tsx
133324
133119
  init_resolve();
133325
133120
  init_store();
133326
-
133327
- // src/accounts/detect.ts
133328
- init_catalog();
133329
- init_store();
133330
- import { readFileSync as readFileSync11, existsSync as existsSync6 } from "node:fs";
133331
- import { join as join9 } from "node:path";
133332
- import { homedir as homedir7 } from "node:os";
133333
- function detectEnvCreds() {
133334
- const out = [];
133335
- for (const p of CATALOG) {
133336
- if (p.authKind !== "api-key" && p.authKind !== "openai-compat")
133337
- continue;
133338
- for (const ev of p.envVars) {
133339
- const v = process.env[ev];
133340
- if (v) {
133341
- out.push({ provider: p.id, label: p.label, envVar: ev, value: v });
133342
- break;
133343
- }
133344
- }
133345
- }
133346
- return out;
133347
- }
133348
- async function importEnvCred(c) {
133349
- const id = `${c.provider}-env`;
133350
- const ref = `${id}:api-key`;
133351
- await setSecret(ref, c.value);
133352
- const cat = CATALOG.find((p) => p.id === c.provider);
133353
- const account = {
133354
- id,
133355
- label: `${c.label} (from ${c.envVar})`,
133356
- provider: c.provider,
133357
- exec: "in-loop",
133358
- auth: cat.authKind === "openai-compat" ? { kind: "openai-compat", ref } : { kind: "api-key", ref },
133359
- baseUrl: cat.baseUrl,
133360
- enabled: true,
133361
- addedAt: Date.now()
133362
- };
133363
- putAccount(account);
133364
- return account;
133365
- }
133366
- function importableEnvCreds() {
133367
- return detectEnvCreds().filter((c) => !getAccount(`${c.provider}-env`));
133368
- }
133369
- function awsIni(file5, profile = "default") {
133370
- if (!existsSync6(file5))
133371
- return {};
133372
- const out = {};
133373
- let cur = "";
133374
- for (const raw of readFileSync11(file5, "utf8").split(`
133375
- `)) {
133376
- const line = raw.trim();
133377
- if (line.startsWith("["))
133378
- cur = line.slice(1, -1).replace(/^profile\s+/, "");
133379
- else if (cur === profile && line.includes("=")) {
133380
- const i2 = line.indexOf("=");
133381
- out[line.slice(0, i2).trim().toLowerCase()] = line.slice(i2 + 1).trim();
133382
- }
133383
- }
133384
- return out;
133385
- }
133386
- function detectCloudCreds() {
133387
- const out = [];
133388
- const home5 = homedir7();
133389
- const creds = awsIni(join9(home5, ".aws", "credentials"));
133390
- const conf = awsIni(join9(home5, ".aws", "config"));
133391
- const akid = process.env.AWS_ACCESS_KEY_ID ?? creds.aws_access_key_id;
133392
- const secret = process.env.AWS_SECRET_ACCESS_KEY ?? creds.aws_secret_access_key;
133393
- const region = process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? conf.region;
133394
- if (akid && secret) {
133395
- out.push({
133396
- provider: "bedrock",
133397
- label: "Amazon Bedrock",
133398
- source: process.env.AWS_ACCESS_KEY_ID ? "env" : "~/.aws/credentials",
133399
- aws: { accessKeyId: akid, secretAccessKey: secret, sessionToken: process.env.AWS_SESSION_TOKEN ?? creds.aws_session_token, region: region ?? "us-east-1" }
133400
- });
133401
- }
133402
- if (process.env.AZURE_API_KEY && process.env.AZURE_RESOURCE_NAME) {
133403
- out.push({ provider: "azure", label: "Azure OpenAI", source: "env", azure: { resourceName: process.env.AZURE_RESOURCE_NAME, apiKey: process.env.AZURE_API_KEY } });
133404
- }
133405
- if (process.env.GOOGLE_VERTEX_PROJECT) {
133406
- out.push({ provider: "vertex", label: "Google Vertex AI", source: "env", vertex: { project: process.env.GOOGLE_VERTEX_PROJECT, location: process.env.GOOGLE_VERTEX_LOCATION ?? "us-central1" } });
133407
- }
133408
- return out;
133409
- }
133410
- async function importCloudCred(c) {
133411
- const id = `${c.provider}-import`;
133412
- let auth;
133413
- if (c.aws) {
133414
- await setSecret(`${id}:akid`, c.aws.accessKeyId);
133415
- await setSecret(`${id}:secret`, c.aws.secretAccessKey);
133416
- if (c.aws.sessionToken)
133417
- await setSecret(`${id}:token`, c.aws.sessionToken);
133418
- auth = { kind: "aws", accessKeyIdRef: `${id}:akid`, secretKeyRef: `${id}:secret`, sessionTokenRef: c.aws.sessionToken ? `${id}:token` : undefined, region: c.aws.region };
133419
- } else if (c.azure) {
133420
- await setSecret(`${id}:api-key`, c.azure.apiKey);
133421
- auth = { kind: "azure", resourceName: c.azure.resourceName, ref: `${id}:api-key` };
133422
- } else {
133423
- auth = { kind: "vertex", project: c.vertex.project, location: c.vertex.location, adc: true };
133424
- }
133425
- const account = { id, label: `${c.label} (from ${c.source})`, provider: c.provider, exec: "in-loop", auth, enabled: true, addedAt: Date.now() };
133426
- putAccount(account);
133427
- return account;
133428
- }
133429
- function importableCloudCreds() {
133430
- return detectCloudCreds().filter((c) => !getAccount(`${c.provider}-import`));
133431
- }
133432
-
133433
- // src/accounts/onboard.ts
133434
- init_store();
133435
- init_catalog();
133436
- init_resolve();
133437
- init_cli_backend();
133438
- init_proc();
133439
- import { mkdirSync as mkdirSync7 } from "node:fs";
133440
- import { join as join10 } from "node:path";
133441
- import { homedir as homedir8 } from "node:os";
133442
- async function addApiKeyAccount(provider, key, opts = {}) {
133443
- const cat = catalogProvider(provider);
133444
- if (!cat)
133445
- return { ok: false, message: `unknown provider "${provider}" — see /accounts catalog` };
133446
- if (cat.group === "cli")
133447
- return { ok: false, message: `${cat.label} is a subscription account — use /login ${provider} (P3), not a key` };
133448
- if (cat.authKind !== "api-key" && cat.authKind !== "openai-compat") {
133449
- return { ok: false, message: `${cat.label} needs ${cat.authKind} credentials — use the guided add (P2)` };
133450
- }
133451
- const id = opts.id ?? `${provider}-${shortId()}`;
133452
- const ref = `${id}:api-key`;
133453
- await setSecret(ref, key.trim());
133454
- const account = {
133455
- id,
133456
- label: opts.label ?? cat.label,
133457
- provider,
133458
- exec: "in-loop",
133459
- auth: cat.authKind === "openai-compat" ? { kind: "openai-compat", ref } : { kind: "api-key", ref },
133460
- baseUrl: cat.baseUrl,
133461
- enabled: true,
133462
- addedAt: Date.now()
133463
- };
133464
- putAccount(account);
133465
- return { ok: true, account, message: `added ${account.label} (${id})` };
133466
- }
133467
- function azureResourceName(input) {
133468
- const s2 = input.trim();
133469
- try {
133470
- const host = new URL(s2).hostname;
133471
- return host.split(".")[0] || s2;
133472
- } catch {
133473
- return s2;
133474
- }
133475
- }
133476
- function azureFoundryBaseUrl(endpoint) {
133477
- const trimmed = endpoint.trim().replace(/\/+$/, "");
133478
- if (/\/openai\/v1$/i.test(trimmed))
133479
- return trimmed;
133480
- if (/\/openai$/i.test(trimmed))
133481
- return `${trimmed}/v1`;
133482
- return `${trimmed}/openai/v1`;
133483
- }
133484
- async function addAzureFoundryAccount(endpoint, key, opts = {}) {
133485
- if (!/^https?:\/\//i.test(endpoint) || !key.trim())
133486
- return { ok: false, message: "usage: /account add azure <foundry-endpoint> <api-key>" };
133487
- const host = new URL(endpoint).hostname;
133488
- const slug3 = host.split(".")[0]?.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || shortId();
133489
- const id = opts.id ?? `azure-foundry-${slug3}`;
133490
- const ref = `${id}:api-key`;
133491
- await setSecret(ref, key.trim());
133492
- const account = {
133493
- id,
133494
- label: opts.label ?? `Azure Foundry (${slug3})`,
133495
- provider: "azure-foundry",
133496
- exec: "in-loop",
133497
- auth: { kind: "openai-compat", ref },
133498
- baseUrl: azureFoundryBaseUrl(endpoint),
133499
- enabled: true,
133500
- addedAt: Date.now()
133501
- };
133502
- putAccount(account);
133503
- return { ok: true, account, message: `added ${account.label} (${id})` };
133504
- }
133505
- async function addAzureAccount(resourceOrEndpoint, key, opts = {}) {
133506
- const resourceName = azureResourceName(resourceOrEndpoint);
133507
- if (!resourceName || !key.trim())
133508
- return { ok: false, message: "usage: /account add azure <resource-or-endpoint> <api-key> [api-version]" };
133509
- const id = opts.id ?? `azure-${resourceName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || shortId()}`;
133510
- const ref = `${id}:api-key`;
133511
- await setSecret(ref, key.trim());
133512
- const account = {
133513
- id,
133514
- label: opts.label ?? `Azure (${resourceName})`,
133515
- provider: "azure",
133516
- exec: "in-loop",
133517
- auth: { kind: "azure", resourceName, ref, apiVersion: opts.apiVersion },
133518
- enabled: true,
133519
- addedAt: Date.now()
133520
- };
133521
- putAccount(account);
133522
- return { ok: true, account, message: `added ${account.label} (${id})` };
133523
- }
133524
- function cliProfileDir(id) {
133525
- const home5 = process.env.GEARBOX_HOME || join10(homedir8(), ".gearbox");
133526
- return join10(home5, "cli", id);
133527
- }
133528
- function addCliAccount(provider, name31) {
133529
- const cat = catalogProvider(provider);
133530
- if (!cat || cat.group !== "cli" || !cat.binary)
133531
- return { ok: false, message: `"${provider}" is not a CLI subscription provider` };
133532
- if (!which(cat.binary))
133533
- return { ok: false, message: `the ${cat.binary} binary isn't on your PATH — install it first` };
133534
- const slug3 = name31 ? name31.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") : "";
133535
- const id = slug3 ? `${provider}-${slug3}` : provider;
133536
- const profile = slug3 ? cliProfileDir(id) : undefined;
133537
- if (profile)
133538
- mkdirSync7(profile, { recursive: true });
133539
- const account = {
133540
- id,
133541
- label: slug3 ? `${cat.label.replace(/ \(.*\)$/, "")} (${name31.trim()})` : cat.label,
133542
- provider,
133543
- exec: "cli",
133544
- auth: { kind: "cli", binary: cat.binary, loginProfile: profile },
133545
- models: cat.defaultModels,
133546
- enabled: true,
133547
- addedAt: Date.now()
133548
- };
133549
- putAccount(account);
133550
- return { ok: true, account, message: `${account.label} ready — runs via the ${cat.binary} CLI${profile ? " (separate login)" : ""}` };
133551
- }
133552
- async function cliAuthStatus(binary, profile) {
133553
- const env3 = subscriptionEnv(binary, profile);
133554
- const readBoth = async (cmd, timeoutMs = 5000) => {
133555
- const p = spawnProc(cmd, { stdin: "ignore", stdout: "pipe", stderr: "pipe", env: env3 });
133556
- let timedOut = false;
133557
- const timer = setTimeout(() => {
133558
- timedOut = true;
133559
- try {
133560
- p.kill();
133561
- } catch {}
133562
- }, timeoutMs);
133563
- try {
133564
- const [o, e2] = await Promise.all([readStream(p.stdout), readStream(p.stderr)]);
133565
- await p.exited.catch(() => {});
133566
- return { out: `${o}
133567
- ${e2}`.trim(), timedOut };
133568
- } finally {
133569
- clearTimeout(timer);
133570
- }
133571
- };
133572
- try {
133573
- if (binary === "codex") {
133574
- const { out: out2, timedOut: timedOut2 } = await readBoth(["codex", "login", "status"]);
133575
- if (timedOut2)
133576
- return { loggedIn: false, detail: "`codex login status` timed out" };
133577
- const loggedIn = /logged in|signed in|account:|email|using chatgpt/i.test(out2) && !/not logged in|not signed in/i.test(out2);
133578
- const email3 = out2.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i)?.[0]?.toLowerCase();
133579
- const detail = loggedIn ? out2.split(`
133580
- `).map((l) => l.trim()).find((l) => /@|plan|chatgpt/i.test(l))?.slice(0, 80) || "ChatGPT" : undefined;
133581
- return { loggedIn, detail, identity: email3 ? `codex:${email3}` : undefined, identityLabel: email3 };
133582
- }
133583
- const { out, timedOut } = await readBoth(["claude", "auth", "status"]);
133584
- if (timedOut)
133585
- return { loggedIn: false, detail: "`claude auth status` timed out" };
133586
- const m2 = out.match(/\{[^{}]*"loggedIn"[\s\S]*?\}/);
133587
- try {
133588
- const j = JSON.parse(m2 ? m2[0] : out);
133589
- const parts = [];
133590
- if (j.email)
133591
- parts.push(j.email);
133592
- if (j.subscriptionType)
133593
- parts.push(`Claude ${String(j.subscriptionType).replace(/^\w/, (c) => c.toUpperCase())}`);
133594
- else if (j.authMethod && j.authMethod !== "claude.ai")
133595
- parts.push(`auth: ${j.authMethod}`);
133596
- const email3 = typeof j.email === "string" ? j.email.toLowerCase() : undefined;
133597
- return { loggedIn: !!j.loggedIn, detail: parts.join(" · ") || undefined, identity: email3 ? `claude:${email3}` : undefined, identityLabel: email3 };
133598
- } catch {
133599
- return { loggedIn: /"loggedIn"\s*:\s*true/.test(out) };
133600
- }
133601
- } catch {
133602
- return { loggedIn: false };
133603
- }
133604
- }
133605
- function cliLoginArgs(binary) {
133606
- return binary === "codex" ? ["login"] : ["auth", "login"];
133607
- }
133608
- async function addByPastedKey(key) {
133609
- const provider = detectProviderByKey(key);
133610
- if (!provider)
133611
- return { ok: false, message: "couldn't identify the provider from that key — use /accounts add <provider> <key>" };
133612
- return addApiKeyAccount(provider, key);
133613
- }
133614
- async function testAccount(a) {
133615
- const creds = await resolveCreds(a);
133616
- if (!creds.apiKey && a.auth.kind !== "cli")
133617
- return { ok: false, message: "no key stored" };
133618
- try {
133619
- if (a.provider === "anthropic") {
133620
- const r3 = await fetch("https://api.anthropic.com/v1/messages/count_tokens", {
133621
- method: "POST",
133622
- headers: { "x-api-key": creds.apiKey ?? "", "anthropic-version": "2023-06-01", "content-type": "application/json" },
133623
- body: JSON.stringify({ model: "claude-haiku-4-5", messages: [{ role: "user", content: "hi" }] })
133624
- });
133625
- return r3.ok ? { ok: true, message: "credential works" } : { ok: false, message: await errMessage(r3) };
133626
- }
133627
- if (a.provider === "google") {
133628
- const r3 = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${creds.apiKey ?? ""}`);
133629
- return r3.ok ? { ok: true, message: "credential works" } : { ok: false, message: await errMessage(r3) };
133630
- }
133631
- const base2 = creds.baseURL ?? "https://api.openai.com/v1";
133632
- const r2 = await fetch(`${base2.replace(/\/$/, "")}/models`, {
133633
- headers: { Authorization: `Bearer ${creds.apiKey ?? ""}`, ...creds.headers ?? {} }
133634
- });
133635
- return r2.ok ? { ok: true, message: "credential works" } : { ok: false, message: await errMessage(r2) };
133636
- } catch (e2) {
133637
- return { ok: false, message: e2?.message ?? "request failed" };
133638
- }
133639
- }
133640
- async function errMessage(r2) {
133641
- try {
133642
- const j = await r2.json();
133643
- const m2 = j?.error?.message ?? j?.message ?? j?.error;
133644
- if (typeof m2 === "string" && m2)
133645
- return `${m2} (HTTP ${r2.status})`;
133646
- } catch {}
133647
- return `HTTP ${r2.status}`;
133648
- }
133649
- function shortId() {
133650
- return Date.now().toString(36).slice(-4) + Math.floor(Math.random() * 1296).toString(36).padStart(2, "0");
133651
- }
133652
-
133653
- // src/ui/App.tsx
133121
+ init_detect();
133122
+ init_onboard();
133654
133123
  init_catalog();
133655
133124
  init_cli_backend();
133656
133125
 
@@ -136484,304 +135953,33 @@ function App2({ selector: initialSelector, demo, runner, fullscreen = false, res
136484
135953
  }, undefined, true, undefined, this);
136485
135954
  }
136486
135955
 
136487
- // src/model/selector.ts
136488
- class FixedSelector2 {
136489
- preferredId;
136490
- constructor(preferredId) {
136491
- this.preferredId = preferredId;
136492
- }
136493
- select(_task) {
136494
- const model = pickDefaultModel(this.preferredId);
136495
- if (!model) {
136496
- throw new Error("No model available. Set a key: ANTHROPIC_API_KEY / OPENAI_API_KEY / GOOGLE_GENERATIVE_AI_API_KEY / DEEPSEEK_API_KEY");
136497
- }
136498
- return { model, reason: "fixed default · routing not enabled yet" };
136499
- }
136500
- }
136501
-
136502
- // src/model/router.ts
136503
- var BAR2 = {
136504
- summarize: 0,
136505
- classify: 0,
136506
- search: 0.2,
136507
- chat: 0.3,
136508
- plan: 0.7,
136509
- code: 0.7
136510
- };
136511
- var MUTATION2 = /\b(fix|implement|refactor|edit|modif|debug|rewrite|replace|add|create|delete|remove|patch|migrat|rename)\b/;
136512
- function classify2(prompt) {
136513
- const p = prompt.toLowerCase().trim();
136514
- if (!p)
136515
- return "code";
136516
- if (MUTATION2.test(p))
136517
- return "code";
136518
- if (/\b(summari[sz]e|tl;?dr|recap|condense|digest|gist)\b/.test(p))
136519
- return "summarize";
136520
- if (/\bclassif|\bcategori[sz]|\blabel this\b|\bsentiment\b/.test(p))
136521
- return "classify";
136522
- if (/^(find|search|locate|grep)\b|\bwhere is\b|\bwhich file\b/.test(p))
136523
- return "search";
136524
- return "code";
136525
- }
136526
- function qualityOf2(m2) {
136527
- const pr = profileFor(m2.id);
136528
- if (!pr)
136529
- return 0.5;
136530
- if (pr.quality.sweBenchVerified != null)
136531
- return pr.quality.sweBenchVerified;
136532
- if (pr.quality.intelligenceIndex != null)
136533
- return pr.quality.intelligenceIndex / 100;
136534
- return 0.5;
136535
- }
136536
- function costOf2(m2) {
136537
- const pr = profileFor(m2.id);
136538
- if (!pr)
136539
- return Number.POSITIVE_INFINITY;
136540
- return pr.cost.inUSDPerMtok + 0.2 * pr.cost.outUSDPerMtok;
136541
- }
136542
- function tpsOf2(m2) {
136543
- return profileFor(m2.id)?.latency?.tps ?? 0;
136544
- }
136545
-
136546
- class RoutingSelector2 {
136547
- fallbackId;
136548
- constructor(fallbackId) {
136549
- this.fallbackId = fallbackId;
136550
- }
136551
- select(task) {
136552
- const kind = task.kind ?? classify2(task.prompt);
136553
- const bar = BAR2[kind];
136554
- const available = MODELS.filter((m2) => providerAvailable(m2.provider) && profileFor(m2.id));
136555
- if (available.length === 0) {
136556
- const m2 = pickDefaultModel(this.fallbackId);
136557
- if (!m2) {
136558
- throw new Error("No model available. Set a key: ANTHROPIC_API_KEY / OPENAI_API_KEY / GOOGLE_GENERATIVE_AI_API_KEY / DEEPSEEK_API_KEY");
136559
- }
136560
- return { model: m2, reason: "only model with a key" };
136561
- }
136562
- const need = (task.estTokens ?? 0) * 1.2;
136563
- const fits = need > 0 ? available.filter((m2) => m2.contextWindow >= need) : available;
136564
- const pool = fits.length ? fits : available;
136565
- const clears = pool.filter((m2) => qualityOf2(m2) >= bar);
136566
- const candidates = clears.length ? clears : pool;
136567
- const pref = preferenceFor(kind);
136568
- const preferredPool = pref?.modelId ? pool.find((m2) => m2.id === pref.modelId) : pref?.provider ? pool.find((m2) => m2.provider === pref.provider) : undefined;
136569
- const preferred = pref?.modelId ? candidates.find((m2) => m2.id === pref.modelId) : pref?.provider ? candidates.find((m2) => m2.provider === pref.provider) : undefined;
136570
- if (preferred && qualityOf2(preferred) >= bar) {
136571
- return { model: preferred, reason: `${kind} · remembered preference` };
136572
- }
136573
- candidates.sort((a, b) => costOf2(a) - costOf2(b) || tpsOf2(b) - tpsOf2(a) || qualityOf2(b) - qualityOf2(a));
136574
- const model = candidates[0];
136575
- const skipped = preferredPool && qualityOf2(preferredPool) < bar ? ` · ${preferredPool.label} skipped below quality bar` : "";
136576
- const reason = `${kind} · $${costOf2(model).toFixed(2)}/Mtok${skipped}`;
136577
- return { model, reason };
136578
- }
136579
- }
136580
-
136581
- // src/config.ts
136582
- var config3 = {
136583
- defaultModelId: process.env.GEARBOX_MODEL ?? "claude-sonnet-4-6",
136584
- maxSteps: Number(process.env.GEARBOX_MAX_STEPS ?? 24)
136585
- };
136586
- function anyProviderAvailable() {
136587
- return MODELS.some((m2) => providerAvailable(m2.provider));
136588
- }
136589
-
136590
- // src/providers.ts
136591
- init_store();
136592
- init_catalog();
136593
- var NATIVE2 = new Set(["anthropic", "openai", "google", "deepseek"]);
136594
- var CURATED2 = [
136595
- { id: "claude-opus-4-8", provider: "anthropic", sdkId: "claude-opus-4-8", label: "opus-4.8", contextWindow: 1e6, cost: { inUSDPerMtok: 5, outUSDPerMtok: 25 }, reasoning: true, efforts: ["low", "medium", "high", "xhigh", "max"] },
136596
- { id: "claude-sonnet-4-6", provider: "anthropic", sdkId: "claude-sonnet-4-6", label: "sonnet-4.6", contextWindow: 1e6, cost: { inUSDPerMtok: 3, outUSDPerMtok: 15 }, reasoning: true, efforts: ["low", "medium", "high", "xhigh", "max"] },
136597
- { id: "claude-haiku-4-5", provider: "anthropic", sdkId: "claude-haiku-4-5", label: "haiku-4.5", contextWindow: 200000, cost: { inUSDPerMtok: 1, outUSDPerMtok: 5 } },
136598
- { id: "gpt-5.5", provider: "openai", sdkId: "gpt-5.5", label: "gpt-5.5", contextWindow: 400000, cost: { inUSDPerMtok: 2.5, outUSDPerMtok: 10 }, reasoning: true, efforts: ["none", "minimal", "low", "medium", "high", "xhigh"] },
136599
- { 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"] },
136600
- { 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"] },
136601
- { 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"] },
136602
- { 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 },
136603
- { id: "deepseek-v4-flash", provider: "deepseek", sdkId: "deepseek-v4-flash", label: "deepseek-v4-flash", contextWindow: 128000, cost: { inUSDPerMtok: 0.27, outUSDPerMtok: 1.1 } }
136604
- ];
136605
- function generatedModels2() {
136606
- const out = [];
136607
- for (const p of CATALOG) {
136608
- if (p.group === "cli")
136609
- continue;
136610
- for (const m2 of p.defaultModels ?? []) {
136611
- if (CURATED2.some((c) => c.provider === p.id && c.sdkId === m2))
136612
- continue;
136613
- out.push({ id: `${p.id}/${m2}`, provider: p.id, sdkId: m2, label: m2.length > 24 ? m2.slice(0, 24) : m2, contextWindow: 128000 });
136614
- }
136615
- }
136616
- return out;
136617
- }
136618
- var MODELS2 = [...CURATED2, ...generatedModels2()];
136619
-
136620
- // src/ui/image.ts
136621
- var SIZES2 = ["big", "mini", "micro"];
136622
- var VARIANTS2 = Object.keys(GHOST_PNG);
136623
- var DIACRITICS2 = [
136624
- 773,
136625
- 781,
136626
- 782,
136627
- 784,
136628
- 786,
136629
- 829,
136630
- 830,
136631
- 831,
136632
- 838,
136633
- 842,
136634
- 843,
136635
- 844,
136636
- 848,
136637
- 849,
136638
- 850,
136639
- 855,
136640
- 859,
136641
- 867,
136642
- 868,
136643
- 869,
136644
- 870,
136645
- 871,
136646
- 872,
136647
- 873,
136648
- 874,
136649
- 875,
136650
- 876,
136651
- 877,
136652
- 878,
136653
- 879,
136654
- 1155,
136655
- 1156,
136656
- 1157,
136657
- 1158,
136658
- 1159,
136659
- 1426,
136660
- 1427,
136661
- 1428,
136662
- 1429,
136663
- 1431,
136664
- 1432,
136665
- 1433,
136666
- 1436,
136667
- 1437,
136668
- 1438,
136669
- 1439,
136670
- 1440,
136671
- 1441,
136672
- 1448,
136673
- 1449
136674
- ].map((c) => String.fromCodePoint(c));
136675
- function detectImageMode2() {
136676
- const force = process.env.GEARBOX_GHOST;
136677
- if (force === "kitty" || force === "iterm")
136678
- return force;
136679
- return "blocks";
136680
- }
136681
- var resolved2 = null;
136682
- function setImageMode(m2) {
136683
- resolved2 = m2;
136684
- }
136685
- function imageId2(variant, size2) {
136686
- return VARIANTS2.indexOf(variant) * SIZES2.length + SIZES2.indexOf(size2) + 1;
136687
- }
136688
- function transmitOne(id, b64, cols, rows) {
136689
- const ESC2 = "\x1B";
136690
- const CHUNK = 4096;
136691
- if (b64.length <= CHUNK) {
136692
- return `${ESC2}_Ga=T,U=1,i=${id},c=${cols},r=${rows},f=100,q=2;${b64}${ESC2}\\`;
136693
- }
136694
- let out = "";
136695
- for (let i2 = 0;i2 < b64.length; i2 += CHUNK) {
136696
- const chunk2 = b64.slice(i2, i2 + CHUNK);
136697
- const more = i2 + CHUNK < b64.length ? 1 : 0;
136698
- out += i2 === 0 ? `${ESC2}_Ga=T,U=1,i=${id},c=${cols},r=${rows},f=100,q=2,m=${more};${chunk2}${ESC2}\\` : `${ESC2}_Gm=${more};${chunk2}${ESC2}\\`;
136699
- }
136700
- return out;
136701
- }
136702
- function transmitAll() {
136703
- let out = "";
136704
- for (const variant of VARIANTS2) {
136705
- for (const size2 of SIZES2) {
136706
- const data = GHOSTS[variant][size2];
136707
- out += transmitOne(imageId2(variant, size2), GHOST_PNG[variant], data[0]?.length ?? 0, data.length);
136708
- }
136709
- }
136710
- return out;
136711
- }
136712
-
136713
- // src/ui/prefs.ts
136714
- import { homedir as homedir9 } from "node:os";
136715
- import { join as join11, dirname as dirname3 } from "node:path";
136716
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync7, mkdirSync as mkdirSync8 } from "node:fs";
136717
- function file5() {
136718
- const dir2 = process.env.GEARBOX_HOME || join11(homedir9(), ".gearbox");
136719
- return join11(dir2, "prefs.json");
136720
- }
136721
- function loadPrefs2() {
136722
- try {
136723
- return JSON.parse(readFileSync13(file5(), "utf8"));
136724
- } catch {
136725
- return {};
136726
- }
136727
- }
136728
-
136729
- // src/permission.ts
136730
- var granted2 = new Set;
136731
- var yolo2 = false;
136732
- function setYolo2(on) {
136733
- yolo2 = on;
136734
- }
136735
-
136736
- // src/session.ts
136737
- import { mkdirSync as mkdirSync9, readFileSync as readFileSync14, writeFileSync as writeFileSync8, readdirSync as readdirSync4 } from "node:fs";
136738
- import { join as join12 } from "node:path";
136739
- import { homedir as homedir10 } from "node:os";
136740
- var root2 = () => join12(process.env.GEARBOX_HOME || join12(homedir10(), ".gearbox"), "sessions");
136741
- var slug3 = () => process.cwd().replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "root";
136742
- var dir2 = () => join12(root2(), slug3());
136743
- function listSessions2() {
136744
- try {
136745
- return readdirSync4(dir2()).filter((f3) => f3.endsWith(".json") && f3 !== "history.json").map((f3) => {
136746
- try {
136747
- return JSON.parse(readFileSync14(join12(dir2(), f3), "utf8"));
136748
- } catch {
136749
- return null;
136750
- }
136751
- }).filter((s2) => s2 !== null && Array.isArray(s2.items)).sort((a, b) => b.updatedAt - a.updatedAt);
136752
- } catch {
136753
- return [];
136754
- }
136755
- }
136756
- function latestSession() {
136757
- return listSessions2()[0] ?? null;
136758
- }
136759
-
136760
135956
  // src/cli.tsx
136761
- var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime2(), 1);
135957
+ var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
135958
+ process.env.LANG = process.env.LANG || "en_US.UTF-8";
135959
+ process.env.LC_ALL = process.env.LC_ALL || "en_US.UTF-8";
136762
135960
  var VERSION16 = "0.1.0";
136763
135961
  var args = process.argv.slice(2);
136764
135962
  if (args[0] === "upgrade" || args[0] === "update") {
136765
- const root3 = resolve11(import.meta.dir, "..");
136766
- if (!existsSync10(resolve11(root3, ".git"))) {
135963
+ const root2 = resolve11(import.meta.dir, "..");
135964
+ if (!existsSync8(resolve11(root2, ".git"))) {
136767
135965
  console.log("This build can't self-update (not a git checkout).");
136768
135966
  console.log("Update by pulling the repo and reinstalling: git pull && bun install");
136769
135967
  process.exit(0);
136770
135968
  }
136771
135969
  try {
136772
- console.log("\u2192 Pulling latest\u2026");
136773
- console.log(execFileSync4("git", ["-C", root3, "pull", "--ff-only"], { encoding: "utf8" }).trim());
136774
- console.log("\u2192 Installing dependencies\u2026");
136775
- execFileSync4("bun", ["install"], { cwd: root3, stdio: "inherit" });
136776
- console.log("\u2713 Gearbox is up to date. Restart any running session to use the new version.");
135970
+ console.log(" Pulling latest");
135971
+ console.log(execFileSync4("git", ["-C", root2, "pull", "--ff-only"], { encoding: "utf8" }).trim());
135972
+ console.log(" Installing dependencies");
135973
+ execFileSync4("bun", ["install"], { cwd: root2, stdio: "inherit" });
135974
+ console.log(" Gearbox is up to date. Restart any running session to use the new version.");
136777
135975
  } catch (e2) {
136778
135976
  console.log("Upgrade failed: " + (e2?.message ?? String(e2)));
136779
- console.log(`Try manually: cd ${root3} && git pull && bun install`);
135977
+ console.log(`Try manually: cd ${root2} && git pull && bun install`);
136780
135978
  }
136781
135979
  process.exit(0);
136782
135980
  }
136783
135981
  if (args.includes("--help") || args.includes("-h")) {
136784
- console.log(`gearbox ${VERSION16} \u2014 multi-provider coding agent for the terminal
135982
+ console.log(`gearbox ${VERSION16} multi-provider coding agent for the terminal
136785
135983
 
136786
135984
  Usage:
136787
135985
  gearbox start in the current directory (it becomes the workspace)
@@ -136799,9 +135997,9 @@ Options:
136799
135997
  -h, --help this help
136800
135998
 
136801
135999
  Set at least one provider key first (each user uses their own):
136802
- ANTHROPIC_API_KEY \xB7 OPENAI_API_KEY \xB7 GOOGLE_GENERATIVE_AI_API_KEY \xB7 DEEPSEEK_API_KEY
136000
+ ANTHROPIC_API_KEY · OPENAI_API_KEY · GOOGLE_GENERATIVE_AI_API_KEY · DEEPSEEK_API_KEY
136803
136001
 
136804
- Models: ${MODELS2.map((m2) => m2.label).join(", ")}
136002
+ Models: ${MODELS.map((m2) => m2.label).join(", ")}
136805
136003
  In-app: / for commands, @ for files, !cmd for shell, shift+tab for plan mode.`);
136806
136004
  process.exit(0);
136807
136005
  }
@@ -136810,43 +136008,43 @@ if (args.includes("--version") || args.includes("-v")) {
136810
136008
  process.exit(0);
136811
136009
  }
136812
136010
  if (args[0] === "auth") {
136813
- const { listAccounts: listAccounts3, loadAccounts: loadAccounts4, removeAccount: removeAccount3 } = await Promise.resolve().then(() => (init_store2(), exports_store));
136814
- const { importableEnvCreds: importableEnvCreds3, importEnvCred: importEnvCred3, importableCloudCreds: importableCloudCreds3, importCloudCred: importCloudCred3 } = await Promise.resolve().then(() => (init_detect(), exports_detect));
136815
- const { addApiKeyAccount: addApiKeyAccount3, addByPastedKey: addByPastedKey3, testAccount: testAccount3, addableProviders: addableProviders2 } = await Promise.resolve().then(() => (init_onboard(), exports_onboard));
136816
- const { detectProviderByKey: detectProviderByKey3 } = await Promise.resolve().then(() => (init_catalog2(), exports_catalog));
136011
+ const { listAccounts: listAccounts2, loadAccounts: loadAccounts3, removeAccount: removeAccount2 } = await Promise.resolve().then(() => (init_store(), exports_store));
136012
+ const { importableEnvCreds: importableEnvCreds2, importEnvCred: importEnvCred2, importableCloudCreds: importableCloudCreds2, importCloudCred: importCloudCred2 } = await Promise.resolve().then(() => (init_detect(), exports_detect));
136013
+ const { addApiKeyAccount: addApiKeyAccount2, addByPastedKey: addByPastedKey2, testAccount: testAccount2, addableProviders: addableProviders2 } = await Promise.resolve().then(() => (init_onboard(), exports_onboard));
136014
+ const { detectProviderByKey: detectProviderByKey2 } = await Promise.resolve().then(() => (init_catalog(), exports_catalog));
136817
136015
  const sub = args[1];
136818
136016
  const rest2 = args.slice(2);
136819
136017
  if (sub === "list" || !sub) {
136820
- const f3 = loadAccounts4();
136018
+ const f3 = loadAccounts3();
136821
136019
  if (!f3.accounts.length)
136822
136020
  console.log("No accounts yet. Add one: gearbox auth add <key> (or) gearbox auth import");
136823
136021
  for (const a of f3.accounts)
136824
- console.log(`${f3.defaults[a.provider] === a.id ? "*" : " "} ${a.id.padEnd(22)} ${a.label}${a.exec === "cli" ? " \xB7 cli" : ""}`);
136825
- const imp = importableEnvCreds3();
136022
+ console.log(`${f3.defaults[a.provider] === a.id ? "*" : " "} ${a.id.padEnd(22)} ${a.label}${a.exec === "cli" ? " · cli" : ""}`);
136023
+ const imp = importableEnvCreds2();
136826
136024
  if (imp.length)
136827
136025
  console.log(`
136828
136026
  Importable from your env (gearbox auth import): ${imp.map((c) => c.envVar).join(", ")}`);
136829
136027
  } else if (sub === "import") {
136830
- const keys2 = importableEnvCreds3();
136831
- const cloud = importableCloudCreds3();
136028
+ const keys2 = importableEnvCreds2();
136029
+ const cloud = importableCloudCreds2();
136832
136030
  for (const c of keys2)
136833
- await importEnvCred3(c);
136031
+ await importEnvCred2(c);
136834
136032
  for (const c of cloud)
136835
- await importCloudCred3(c);
136033
+ await importCloudCred2(c);
136836
136034
  const names = [...keys2.map((c) => c.provider), ...cloud.map((c) => c.provider)];
136837
136035
  console.log(names.length ? `Imported ${names.length}: ${names.join(", ")}` : "Nothing to import.");
136838
136036
  } else if (sub === "add") {
136839
- const res = rest2[0] && !rest2[1] && detectProviderByKey3(rest2[0]) ? await addByPastedKey3(rest2[0]) : rest2[0] && rest2[1] ? await addApiKeyAccount3(rest2[0], rest2[1]) : { ok: false, message: "usage: gearbox auth add <key> | gearbox auth add <provider> <key>" };
136037
+ const res = rest2[0] && !rest2[1] && detectProviderByKey2(rest2[0]) ? await addByPastedKey2(rest2[0]) : rest2[0] && rest2[1] ? await addApiKeyAccount2(rest2[0], rest2[1]) : { ok: false, message: "usage: gearbox auth add <key> | gearbox auth add <provider> <key>" };
136840
136038
  console.log(res.message);
136841
136039
  if (res.ok && res.account) {
136842
- const t2 = await testAccount3(res.account);
136843
- console.log(t2.ok ? " test: \u2713 " + t2.message : " test: \u2717 " + t2.message + " (stored anyway)");
136040
+ const t2 = await testAccount2(res.account);
136041
+ console.log(t2.ok ? " test: " + t2.message : " test: " + t2.message + " (stored anyway)");
136844
136042
  }
136845
136043
  } else if (sub === "test" && rest2[0]) {
136846
- const a = listAccounts3().find((x2) => x2.id === rest2[0]);
136847
- console.log(a ? `${rest2[0]}: ${(await testAccount3(a)).message}` : `no account ${rest2[0]}`);
136044
+ const a = listAccounts2().find((x2) => x2.id === rest2[0]);
136045
+ console.log(a ? `${rest2[0]}: ${(await testAccount2(a)).message}` : `no account ${rest2[0]}`);
136848
136046
  } else if (sub === "rm" && rest2[0]) {
136849
- await removeAccount3(rest2[0]);
136047
+ await removeAccount2(rest2[0]);
136850
136048
  console.log(`removed ${rest2[0]}`);
136851
136049
  } else if (sub === "providers") {
136852
136050
  for (const p of addableProviders2())
@@ -136859,16 +136057,16 @@ Importable from your env (gearbox auth import): ${imp.map((c) => c.envVar).join(
136859
136057
  var mi = args.indexOf("--model");
136860
136058
  var preferred = mi >= 0 ? args[mi + 1] : undefined;
136861
136059
  var demo = !anyProviderAvailable();
136862
- var pinned = preferred ?? loadPrefs2().pinnedModel;
136863
- var selector = pinned ? new FixedSelector2(pinned) : new RoutingSelector2;
136060
+ var pinned = preferred ?? loadPrefs().pinnedModel;
136061
+ var selector = pinned ? new FixedSelector(pinned) : new RoutingSelector;
136864
136062
  if (args.includes("--yolo"))
136865
- setYolo2(true);
136063
+ setYolo(true);
136866
136064
  var resumeId = args.includes("--continue") || args.includes("-c") ? latestSession()?.id ?? undefined : undefined;
136867
- var imageMode = detectImageMode2();
136065
+ var imageMode = detectImageMode();
136868
136066
  setImageMode(imageMode);
136869
136067
  if (process.stdout.isTTY && imageMode === "kitty")
136870
136068
  process.stdout.write(transmitAll());
136871
- var uiPrefs = loadPrefs2();
136069
+ var uiPrefs = loadPrefs();
136872
136070
  var explicitInline = args.includes("--inline") || process.env.GEARBOX_INLINE === "1" || process.env.GEARBOX_FULLSCREEN === "0";
136873
136071
  var explicitFullscreen = args.includes("--fullscreen") || process.env.GEARBOX_FULLSCREEN === "1";
136874
136072
  var wantsInline = explicitInline || !explicitFullscreen && uiPrefs.fullscreen === false;