claudish 14.15.0 → 14.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +511 -179
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -5491,7 +5491,7 @@ var init_onepassword_config = __esm(() => {
5491
5491
  });
5492
5492
 
5493
5493
  // src/version.ts
5494
- var VERSION = "14.15.0";
5494
+ var VERSION = "14.16.0";
5495
5495
 
5496
5496
  // src/redact.ts
5497
5497
  function isPlaceholder(value) {
@@ -49347,10 +49347,11 @@ var init_devin_request = __esm(() => {
49347
49347
  function unaryMetadata(apiKey) {
49348
49348
  return msg(bytes(1, "chisel"), bytes(2, DEVIN_CLI_VERSION), bytes(3, apiKey), bytes(4, "en"), bytes(5, process.platform), bytes(7, DEVIN_CLI_VERSION));
49349
49349
  }
49350
- async function postUnary(path, apiKey) {
49350
+ async function postDevinUnaryRaw(path, apiKey, opts = {}) {
49351
49351
  const url = `${readDevinServerUrl()}${path}`;
49352
+ let response;
49352
49353
  try {
49353
- const response = await fetch(url, {
49354
+ response = await fetch(url, {
49354
49355
  method: "POST",
49355
49356
  headers: {
49356
49357
  authorization: `Basic ${apiKey}-${apiKey}`,
@@ -49358,17 +49359,38 @@ async function postUnary(path, apiKey) {
49358
49359
  "connect-protocol-version": "1"
49359
49360
  },
49360
49361
  body: msg(bytes(1, unaryMetadata(apiKey))),
49361
- signal: AbortSignal.timeout(UNARY_TIMEOUT_MS)
49362
+ signal: opts.signal
49362
49363
  });
49363
- if (!response.ok) {
49364
- log(`[Devin] ${path} failed: HTTP ${response.status}`);
49365
- return null;
49366
- }
49367
- return new Uint8Array(await response.arrayBuffer());
49368
- } catch (err) {
49369
- log(`[Devin] ${path} error: ${err}`);
49364
+ } catch (error) {
49365
+ return { kind: "unreachable", url, error };
49366
+ }
49367
+ if (!response.ok) {
49368
+ return { kind: "answered", url, status: response.status, body: { kind: "unread" } };
49369
+ }
49370
+ try {
49371
+ const bytes = new Uint8Array(await response.arrayBuffer());
49372
+ return { kind: "answered", url, status: response.status, body: { kind: "bytes", bytes } };
49373
+ } catch (error) {
49374
+ return { kind: "answered", url, status: response.status, body: { kind: "read-failed", error } };
49375
+ }
49376
+ }
49377
+ async function postUnary(path, apiKey) {
49378
+ const raw = await postDevinUnaryRaw(path, apiKey, {
49379
+ signal: AbortSignal.timeout(UNARY_TIMEOUT_MS)
49380
+ });
49381
+ if (raw.kind === "unreachable") {
49382
+ log(`[Devin] ${path} error: ${raw.error}`);
49383
+ return null;
49384
+ }
49385
+ if (raw.status < 200 || raw.status >= 300) {
49386
+ log(`[Devin] ${path} failed: HTTP ${raw.status}`);
49387
+ return null;
49388
+ }
49389
+ if (raw.body.kind === "read-failed") {
49390
+ log(`[Devin] ${path} error: ${raw.body.error}`);
49370
49391
  return null;
49371
49392
  }
49393
+ return raw.body.kind === "bytes" ? raw.body.bytes : null;
49372
49394
  }
49373
49395
  function decodeModelDetails(payload) {
49374
49396
  let maxOutput = 0;
@@ -49496,13 +49518,17 @@ async function fetchDevinAllowedUids(apiKey) {
49496
49518
  const body = await postUnary(TEAM_SETTINGS_PATH, apiKey);
49497
49519
  if (!body)
49498
49520
  return [];
49521
+ const uids = decodeAllowedUids(body);
49522
+ log(`[Devin] GetCliTeamSettings: ${uids.length} allowed uids`);
49523
+ return uids;
49524
+ }
49525
+ function decodeAllowedUids(body) {
49499
49526
  const uids = [];
49500
49527
  for (const field of topLevelDelimited(body, 7)) {
49501
49528
  const uid = readString(field).trim();
49502
49529
  if (uid)
49503
49530
  uids.push(uid);
49504
49531
  }
49505
- log(`[Devin] GetCliTeamSettings: ${uids.length} allowed uids`);
49506
49532
  return uids;
49507
49533
  }
49508
49534
  async function getServedDevinModels(opts) {
@@ -53744,6 +53770,7 @@ data: ${JSON.stringify(data)}
53744
53770
  if (frame.flags === FRAME_FLAG_END_OF_STREAM) {
53745
53771
  const raw = new TextDecoder().decode(frame.payload).trim();
53746
53772
  if (!raw || raw === "{}") {
53773
+ opts.onEndOfStream?.();
53747
53774
  finalize("done");
53748
53775
  return;
53749
53776
  }
@@ -94280,6 +94307,13 @@ ${h("SUBCOMMANDS")}
94280
94307
  Send the file's Gemini request once through the
94281
94308
  Antigravity login (generateContent, no retry, model
94282
94309
  ${dim("id unchanged); print the raw answer as one JSON line")}
94310
+ ${green("claudish subscription models devin")} ${yellow("--raw --json")}
94311
+ Print Devin's decoded GetCliModelConfigs rows and
94312
+ ${dim("allowed model uids as one JSON line (for models-index)")}
94313
+ ${green("claudish subscription probe devin")} ${yellow("--model <uid> --request-file <path> --raw --json")}
94314
+ Send the file's Anthropic Messages request once through
94315
+ the Devin login (GetChatMessage, no retry, uid unchanged);
94316
+ ${dim("print the decoded answer as one JSON line")}
94283
94317
  ${green("claudish update")} Check for updates and install the latest version
94284
94318
 
94285
94319
  ${bold("Profiles:")}
@@ -95207,7 +95241,8 @@ function buildReplayArgv(claudeSessionId, forkUuid, settingsJson) {
95207
95241
  function replaySettingsJson(statusLine) {
95208
95242
  return JSON.stringify({
95209
95243
  ...statusLine === null ? {} : { statusLine },
95210
- wheelScrollAccelerationEnabled: false
95244
+ wheelScrollAccelerationEnabled: false,
95245
+ tui: "fullscreen"
95211
95246
  });
95212
95247
  }
95213
95248
  function readUserStatusLine(configDir) {
@@ -96693,6 +96728,7 @@ function buildClaudishSettingsOverlay(statusLine, proxyAuthMode, paneChild = isP
96693
96728
  settings.skipDangerousModePermissionPrompt = true;
96694
96729
  settings.editorMode = "normal";
96695
96730
  settings.wheelScrollAccelerationEnabled = false;
96731
+ settings.tui = "fullscreen";
96696
96732
  }
96697
96733
  return settings;
96698
96734
  }
@@ -96720,6 +96756,9 @@ function mergeUserSettingsIfPresent(config, tempSettingsPath, statusLine, proxyA
96720
96756
  if (paneChild) {
96721
96757
  userSettings.wheelScrollAccelerationEnabled = false;
96722
96758
  }
96759
+ if (paneChild) {
96760
+ userSettings.tui = "fullscreen";
96761
+ }
96723
96762
  chmodSync5(tempSettingsPath, 384);
96724
96763
  writeFileSync19(tempSettingsPath, JSON.stringify(userSettings, null, 2), {
96725
96764
  encoding: "utf-8",
@@ -110399,6 +110438,94 @@ var init_subscription_antigravity_session = __esm(() => {
110399
110438
  TIMED_OUT = Symbol("timed-out");
110400
110439
  });
110401
110440
 
110441
+ // src/subscription-devin-models.ts
110442
+ var exports_subscription_devin_models = {};
110443
+ __export(exports_subscription_devin_models, {
110444
+ readDevinSecrets: () => readDevinSecrets,
110445
+ runDevinRawModelList: () => runDevinRawModelList
110446
+ });
110447
+ function readDevinSecrets(secrets) {
110448
+ const apiKey = readDevinApiKey();
110449
+ if (!apiKey)
110450
+ return;
110451
+ addSecret(secrets, apiKey);
110452
+ if (apiKey.startsWith(DEVIN_SESSION_TOKEN_PREFIX)) {
110453
+ addSecret(secrets, apiKey.slice(DEVIN_SESSION_TOKEN_PREFIX.length));
110454
+ }
110455
+ return apiKey;
110456
+ }
110457
+ async function postBounded(path, apiKey, timeoutMs) {
110458
+ const controller = new AbortController;
110459
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
110460
+ try {
110461
+ const raw = await postDevinUnaryRaw(path, apiKey, { signal: controller.signal });
110462
+ return { raw, timedOut: controller.signal.aborted };
110463
+ } finally {
110464
+ clearTimeout(timer);
110465
+ }
110466
+ }
110467
+ async function determineDevin(deps, secrets, facts) {
110468
+ const apiKey = readDevinSecrets(secrets);
110469
+ if (!apiKey) {
110470
+ return modelListFail(facts, modelListFailureOf("credential_missing", "devin_credential_absent"));
110471
+ }
110472
+ const configsCall = await postBounded(MODEL_CONFIGS_PATH, apiKey, deps.httpTimeoutMs);
110473
+ facts.sourceUrl = stripUserinfo(configsCall.raw.url);
110474
+ facts.clientVersion = DEVIN_CLI_VERSION;
110475
+ const configsNetwork = configsCall.timedOut ? "model_configs_timeout" : "model_configs_network_error";
110476
+ if (configsCall.raw.kind === "unreachable") {
110477
+ return modelListFail(facts, modelListFailureOf("network", configsNetwork));
110478
+ }
110479
+ facts.fetchedAt = new Date(deps.now()).toISOString();
110480
+ facts.httpStatus = configsCall.raw.status;
110481
+ if (configsCall.raw.status < 200 || configsCall.raw.status >= 300) {
110482
+ return { envelope: buildModelListEnvelope(facts), exitCode: EXIT.ok };
110483
+ }
110484
+ if (configsCall.raw.body.kind !== "bytes") {
110485
+ return modelListFail(facts, modelListFailureOf("network", configsNetwork, configsCall.raw.status));
110486
+ }
110487
+ const configs = decodeModelConfigs(configsCall.raw.body.bytes);
110488
+ if (configs.length === 0) {
110489
+ return modelListFail(facts, modelListFailureOf("list_incomplete", "configs_empty", configsCall.raw.status));
110490
+ }
110491
+ const teamCall = await postBounded(TEAM_SETTINGS_PATH, apiKey, deps.httpTimeoutMs);
110492
+ facts.teamSettingsUrl = stripUserinfo(teamCall.raw.url);
110493
+ const teamNetwork = teamCall.timedOut ? "team_settings_timeout" : "team_settings_network_error";
110494
+ if (teamCall.raw.kind === "unreachable") {
110495
+ return modelListFail(facts, modelListFailureOf("network", teamNetwork));
110496
+ }
110497
+ facts.teamSettingsHttpStatus = teamCall.raw.status;
110498
+ if (teamCall.raw.status < 200 || teamCall.raw.status >= 300) {
110499
+ return modelListFail(facts, modelListFailureOf("list_incomplete", "team_settings_http_error", teamCall.raw.status));
110500
+ }
110501
+ if (teamCall.raw.body.kind !== "bytes") {
110502
+ return modelListFail(facts, modelListFailureOf("network", teamNetwork, teamCall.raw.status));
110503
+ }
110504
+ const allowedModelUids = decodeAllowedUids(teamCall.raw.body.bytes);
110505
+ if (allowedModelUids.length === 0) {
110506
+ return modelListFail(facts, modelListFailureOf("list_incomplete", "allowed_uids_empty", teamCall.raw.status));
110507
+ }
110508
+ const body = JSON.stringify({ configs, allowedModelUids });
110509
+ return {
110510
+ envelope: buildModelListEnvelope(facts, undefined, body),
110511
+ exitCode: EXIT.ok,
110512
+ bodyText: body
110513
+ };
110514
+ }
110515
+ async function runDevinRawModelList(deps) {
110516
+ const secrets = newSecrets();
110517
+ const facts = { provider: "devin", tokenRefreshed: false };
110518
+ return runModelListWith(deps, facts, secrets, () => determineDevin(deps, secrets, facts));
110519
+ }
110520
+ var DEVIN_SESSION_TOKEN_PREFIX = "devin-session-token$";
110521
+ var init_subscription_devin_models = __esm(() => {
110522
+ init_devin_credentials();
110523
+ init_devin_models();
110524
+ init_devin_request();
110525
+ init_subscription_antigravity_session();
110526
+ init_subscription_models_command();
110527
+ });
110528
+
110402
110529
  // src/subscription-models-command.ts
110403
110530
  var exports_subscription_models_command = {};
110404
110531
  __export(exports_subscription_models_command, {
@@ -110408,11 +110535,15 @@ __export(exports_subscription_models_command, {
110408
110535
  SECRET_GUARD_MESSAGE: () => SECRET_GUARD_MESSAGE,
110409
110536
  SUBSCRIPTION_MODELS_USAGE: () => SUBSCRIPTION_MODELS_USAGE,
110410
110537
  SUBSCRIPTION_MODEL_LIST_SCHEMA: () => SUBSCRIPTION_MODEL_LIST_SCHEMA,
110538
+ buildModelListEnvelope: () => buildModelListEnvelope,
110411
110539
  defaultSubscriptionModelsDeps: () => defaultSubscriptionModelsDeps,
110412
110540
  exitCodeFor: () => exitCodeFor,
110541
+ modelListFail: () => modelListFail,
110542
+ modelListFailureOf: () => modelListFailureOf,
110413
110543
  parseSubscriptionModelsArgs: () => parseSubscriptionModelsArgs,
110414
110544
  reportSubscriptionInternalError: () => reportSubscriptionInternalError,
110415
110545
  runAntigravityRawModelList: () => runAntigravityRawModelList,
110546
+ runModelListWith: () => runModelListWith,
110416
110547
  subscriptionModelsCommand: () => subscriptionModelsCommand
110417
110548
  });
110418
110549
  function exitCodeFor(failure) {
@@ -110439,11 +110570,11 @@ function defaultSubscriptionModelsDeps() {
110439
110570
  function parseSubscriptionModelsArgs(argv) {
110440
110571
  const positionals = argv.filter((a) => !a.startsWith("-"));
110441
110572
  const flags = argv.filter((a) => a.startsWith("-"));
110442
- const positionalsOk = positionals.length === 2 && positionals[0] === "models" && positionals[1] === "antigravity";
110573
+ const positionalsOk = positionals.length === 2 && positionals[0] === "models" && MODEL_LIST_PROVIDERS.includes(positionals[1]);
110443
110574
  const flagsOk = flags.length === 2 && flags.includes("--raw") && flags.includes("--json");
110444
- return positionalsOk && flagsOk ? { ok: true, provider: "antigravity" } : { ok: false };
110575
+ return positionalsOk && flagsOk ? { ok: true, provider: positionals[1] } : { ok: false };
110445
110576
  }
110446
- function buildEnvelope(facts, failure, body) {
110577
+ function buildModelListEnvelope(facts, failure, body) {
110447
110578
  return {
110448
110579
  schema: SUBSCRIPTION_MODEL_LIST_SCHEMA,
110449
110580
  ...facts.provider !== undefined ? { provider: facts.provider } : {},
@@ -110454,25 +110585,27 @@ function buildEnvelope(facts, failure, body) {
110454
110585
  ...facts.clientVersionSource !== undefined ? { clientVersionSource: facts.clientVersionSource } : {},
110455
110586
  tokenRefreshed: facts.tokenRefreshed,
110456
110587
  ...facts.httpStatus !== undefined ? { httpStatus: facts.httpStatus } : {},
110588
+ ...facts.teamSettingsUrl !== undefined ? { teamSettingsUrl: facts.teamSettingsUrl } : {},
110589
+ ...facts.teamSettingsHttpStatus !== undefined ? { teamSettingsHttpStatus: facts.teamSettingsHttpStatus } : {},
110457
110590
  ...failure ? { failure } : {},
110458
110591
  ...body !== undefined ? { body } : {}
110459
110592
  };
110460
110593
  }
110461
- function failureOf3(cls, code, httpStatus) {
110594
+ function modelListFailureOf(cls, code, httpStatus) {
110462
110595
  return failureOf2(cls, code, httpStatus);
110463
110596
  }
110464
110597
  function listFailure(value, status) {
110465
110598
  const models = value !== null && typeof value === "object" && !Array.isArray(value) ? value.models : undefined;
110466
110599
  if (models === null || typeof models !== "object" || Array.isArray(models)) {
110467
- return failureOf3("list_incomplete", "models_absent", status);
110600
+ return modelListFailureOf("list_incomplete", "models_absent", status);
110468
110601
  }
110469
110602
  if (Object.keys(models).length === 0) {
110470
- return failureOf3("list_incomplete", "models_empty", status);
110603
+ return modelListFailureOf("list_incomplete", "models_empty", status);
110471
110604
  }
110472
110605
  return null;
110473
110606
  }
110474
- function fail(facts, failure) {
110475
- return { envelope: buildEnvelope(facts, failure), exitCode: exitCodeFor(failure) };
110607
+ function modelListFail(facts, failure) {
110608
+ return { envelope: buildModelListEnvelope(facts, failure), exitCode: exitCodeFor(failure) };
110476
110609
  }
110477
110610
  function lineOf(envelope) {
110478
110611
  return `${JSON.stringify(envelope)}
@@ -110484,15 +110617,16 @@ function safeStderr(deps, line) {
110484
110617
  } catch {}
110485
110618
  }
110486
110619
  async function writeInternalFailure(deps, facts, code, stderrLine, secrets) {
110487
- const failure = failureOf3("internal", code);
110620
+ const failure = modelListFailureOf("internal", code);
110488
110621
  safeStderr(deps, `${stderrLine}
110489
110622
  `);
110490
- const line = lineOf(buildEnvelope(facts, failure));
110491
- if (!secrets || !containsSecret(secrets, line)) {
110492
- try {
110493
- await deps.writeStdout(line);
110494
- } catch {}
110623
+ let line = lineOf(buildModelListEnvelope(facts, failure));
110624
+ if (secrets && containsSecret(secrets, line)) {
110625
+ line = lineOf(buildModelListEnvelope({ tokenRefreshed: facts.tokenRefreshed }, failure));
110495
110626
  }
110627
+ try {
110628
+ await deps.writeStdout(line);
110629
+ } catch {}
110496
110630
  return exitCodeFor(failure);
110497
110631
  }
110498
110632
  async function reportSubscriptionInternalError(deps) {
@@ -110511,34 +110645,35 @@ function classifyAvailableModels(facts, raw, timedOut) {
110511
110645
  facts.clientVersion = raw.clientVersion;
110512
110646
  facts.clientVersionSource = raw.clientVersionSource;
110513
110647
  const networkCode = timedOut ? "fetch_available_models_timeout" : "fetch_available_models_network_error";
110514
- if (raw.kind === "unreachable")
110515
- return fail(facts, failureOf3("network", networkCode));
110648
+ if (raw.kind === "unreachable") {
110649
+ return modelListFail(facts, modelListFailureOf("network", networkCode));
110650
+ }
110516
110651
  facts.fetchedAt = raw.fetchedAt;
110517
110652
  facts.httpStatus = raw.status;
110518
110653
  if (raw.status < 200 || raw.status >= 300) {
110519
- return { envelope: buildEnvelope(facts), exitCode: EXIT.ok };
110654
+ return { envelope: buildModelListEnvelope(facts), exitCode: EXIT.ok };
110520
110655
  }
110521
110656
  switch (raw.body.kind) {
110522
110657
  case "json": {
110523
110658
  const incomplete = listFailure(raw.body.value, raw.status);
110524
110659
  if (incomplete)
110525
- return fail(facts, incomplete);
110660
+ return modelListFail(facts, incomplete);
110526
110661
  return {
110527
- envelope: buildEnvelope(facts, undefined, raw.body.text),
110662
+ envelope: buildModelListEnvelope(facts, undefined, raw.body.text),
110528
110663
  exitCode: EXIT.ok,
110529
110664
  bodyText: raw.body.text
110530
110665
  };
110531
110666
  }
110532
110667
  case "not-json":
110533
- return fail(facts, failureOf3("list_incomplete", "body_not_json", raw.status));
110668
+ return modelListFail(facts, modelListFailureOf("list_incomplete", "body_not_json", raw.status));
110534
110669
  default:
110535
- return fail(facts, failureOf3("network", networkCode, raw.status));
110670
+ return modelListFail(facts, modelListFailureOf("network", networkCode, raw.status));
110536
110671
  }
110537
110672
  }
110538
- async function determine(deps, secrets, facts) {
110673
+ async function determineAntigravity(deps, secrets, facts) {
110539
110674
  const session = await establishAntigravitySession(deps, secrets, facts);
110540
110675
  if (!session.ok)
110541
- return fail(facts, session.failure);
110676
+ return modelListFail(facts, session.failure);
110542
110677
  const { accessToken, projectId } = session;
110543
110678
  const controller = new AbortController;
110544
110679
  const timer = setTimeout(() => controller.abort(), deps.httpTimeoutMs);
@@ -110552,14 +110687,12 @@ async function determine(deps, secrets, facts) {
110552
110687
  clearTimeout(timer);
110553
110688
  }
110554
110689
  }
110555
- async function runAntigravityRawModelList(deps) {
110556
- const secrets = newSecrets();
110557
- const facts = { provider: "antigravity", tokenRefreshed: false };
110690
+ async function runModelListWith(deps, facts, secrets, determine) {
110558
110691
  let line;
110559
110692
  let exitCode;
110560
110693
  let bodyText;
110561
110694
  try {
110562
- const result = await determine(deps, secrets, facts);
110695
+ const result = await determine();
110563
110696
  line = lineOf(result.envelope);
110564
110697
  exitCode = result.exitCode;
110565
110698
  bodyText = result.bodyText;
@@ -110578,27 +110711,53 @@ async function runAntigravityRawModelList(deps) {
110578
110711
  }
110579
110712
  return exitCode;
110580
110713
  }
110714
+ async function runAntigravityRawModelList(deps) {
110715
+ const secrets = newSecrets();
110716
+ const facts = { provider: "antigravity", tokenRefreshed: false };
110717
+ return runModelListWith(deps, facts, secrets, () => determineAntigravity(deps, secrets, facts));
110718
+ }
110581
110719
  async function subscriptionModelsCommand(argv, deps = defaultSubscriptionModelsDeps()) {
110582
- if (!parseSubscriptionModelsArgs(argv).ok) {
110720
+ const args = parseSubscriptionModelsArgs(argv);
110721
+ if (!args.ok) {
110583
110722
  return writeInternalFailure(deps, { tokenRefreshed: false }, "usage", SUBSCRIPTION_MODELS_USAGE);
110584
110723
  }
110724
+ if (args.provider === "devin") {
110725
+ let devin;
110726
+ try {
110727
+ devin = await Promise.resolve().then(() => (init_subscription_devin_models(), exports_subscription_devin_models));
110728
+ } catch {
110729
+ return writeInternalFailure(deps, { provider: args.provider, tokenRefreshed: false }, "internal_error", INTERNAL_ERROR_MESSAGE);
110730
+ }
110731
+ return devin.runDevinRawModelList(deps);
110732
+ }
110585
110733
  return runAntigravityRawModelList(deps);
110586
110734
  }
110587
- var SUBSCRIPTION_MODEL_LIST_SCHEMA = "claudish.subscription-model-list.v1", FAILURE_CODES, EXIT, SUBSCRIPTION_MODELS_USAGE = "usage: claudish subscription models antigravity --raw --json", SECRET_GUARD_MESSAGE = "[claudish subscription] refused: output contained a credential value", INTERNAL_ERROR_MESSAGE = "[claudish subscription] internal error";
110735
+ var SUBSCRIPTION_MODEL_LIST_SCHEMA = "claudish.subscription-model-list.v1", FAILURE_CODES, EXIT, SUBSCRIPTION_MODELS_USAGE = "usage: claudish subscription models antigravity|devin --raw --json", SECRET_GUARD_MESSAGE = "[claudish subscription] refused: output contained a credential value", INTERNAL_ERROR_MESSAGE = "[claudish subscription] internal error", MODEL_LIST_PROVIDERS;
110588
110736
  var init_subscription_models_command = __esm(() => {
110589
110737
  init_antigravity_token();
110590
110738
  init_antigravity_user();
110591
110739
  init_subscription_antigravity_session();
110592
110740
  FAILURE_CODES = {
110593
- credential_missing: SESSION_FAILURE_CODES.credential_missing,
110741
+ credential_missing: [...SESSION_FAILURE_CODES.credential_missing, "devin_credential_absent"],
110594
110742
  keychain_locked: SESSION_FAILURE_CODES.keychain_locked,
110595
110743
  mint_failed: SESSION_FAILURE_CODES.mint_failed,
110596
110744
  network: [
110597
110745
  ...SESSION_FAILURE_CODES.network,
110598
110746
  "fetch_available_models_network_error",
110599
- "fetch_available_models_timeout"
110747
+ "fetch_available_models_timeout",
110748
+ "model_configs_network_error",
110749
+ "model_configs_timeout",
110750
+ "team_settings_network_error",
110751
+ "team_settings_timeout"
110752
+ ],
110753
+ list_incomplete: [
110754
+ "models_absent",
110755
+ "models_empty",
110756
+ "body_not_json",
110757
+ "configs_empty",
110758
+ "team_settings_http_error",
110759
+ "allowed_uids_empty"
110600
110760
  ],
110601
- list_incomplete: ["models_absent", "models_empty", "body_not_json"],
110602
110761
  internal: ["usage", "secret_guard", "internal_error"]
110603
110762
  };
110604
110763
  EXIT = {
@@ -110611,6 +110770,7 @@ var init_subscription_models_command = __esm(() => {
110611
110770
  network: 6,
110612
110771
  list_incomplete: 7
110613
110772
  };
110773
+ MODEL_LIST_PROVIDERS = ["antigravity", "devin"];
110614
110774
  });
110615
110775
 
110616
110776
  // src/subscription-dispatch.ts
@@ -110638,6 +110798,232 @@ function probeLoadFailureLine() {
110638
110798
  var SUBSCRIPTION_PROBE_SCHEMA = "claudish.subscription-probe.v1";
110639
110799
  var init_subscription_dispatch = () => {};
110640
110800
 
110801
+ // src/subscription-secret-guard.ts
110802
+ import { readFile as readFile8, stat as stat2 } from "fs/promises";
110803
+ function redactSecretValues(text, secrets) {
110804
+ let out = text;
110805
+ const values = [...secrets.values].sort((a, b) => b.length - a.length);
110806
+ for (const value of values) {
110807
+ for (const form of new Set([value, value.replaceAll("/", "\\/")])) {
110808
+ if (out.includes(form))
110809
+ out = out.replaceAll(form, REDACTED2);
110810
+ }
110811
+ }
110812
+ return { text: out, redacted: out !== text };
110813
+ }
110814
+ function jsonUnescapedForms(text) {
110815
+ const forms = [];
110816
+ if (text === undefined)
110817
+ return { forms, complete: true };
110818
+ let current = text;
110819
+ for (let round = 0;round < MAX_UNESCAPE_ROUNDS; round++) {
110820
+ const next = current.replace(JSON_ESCAPE, (_match, hex, letter) => hex !== undefined ? String.fromCharCode(Number.parseInt(hex, 16)) : SIMPLE_ESCAPES[letter]);
110821
+ if (next === current)
110822
+ return { forms, complete: true };
110823
+ forms.push(next);
110824
+ current = next;
110825
+ }
110826
+ return { forms, complete: false };
110827
+ }
110828
+ async function readCapped(res, cap) {
110829
+ if (!res.body)
110830
+ return "";
110831
+ const reader = res.body.getReader();
110832
+ const chunks = [];
110833
+ let size = 0;
110834
+ for (;; ) {
110835
+ const { done, value } = await reader.read();
110836
+ if (done)
110837
+ break;
110838
+ size += value.byteLength;
110839
+ if (size > cap) {
110840
+ await reader.cancel().catch(() => {});
110841
+ return null;
110842
+ }
110843
+ chunks.push(value);
110844
+ }
110845
+ return Buffer.concat(chunks).toString("utf8");
110846
+ }
110847
+ async function defaultReadRequestFile(path) {
110848
+ const info = await stat2(path);
110849
+ if (!info.isFile())
110850
+ throw new Error("not a file");
110851
+ if (info.size > PROBE_REQUEST_FILE_CAP_BYTES)
110852
+ return null;
110853
+ return readFile8(path, "utf8");
110854
+ }
110855
+ async function readRequestFileChecked(read, path) {
110856
+ let text;
110857
+ try {
110858
+ text = await read(path);
110859
+ } catch {
110860
+ return { ok: false, code: "request_file_unreadable" };
110861
+ }
110862
+ if (text === null)
110863
+ return { ok: false, code: "request_file_invalid" };
110864
+ let value;
110865
+ try {
110866
+ value = JSON.parse(text);
110867
+ } catch {
110868
+ return { ok: false, code: "request_file_invalid" };
110869
+ }
110870
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
110871
+ return { ok: false, code: "request_file_invalid" };
110872
+ }
110873
+ return { ok: true, text, value };
110874
+ }
110875
+ var PROBE_BODY_CAP_BYTES, PROBE_REQUEST_FILE_CAP_BYTES, REDACTED2 = "[REDACTED]", JSON_ESCAPE, SIMPLE_ESCAPES, MAX_UNESCAPE_ROUNDS = 64;
110876
+ var init_subscription_secret_guard = __esm(() => {
110877
+ PROBE_BODY_CAP_BYTES = 512 * 1024;
110878
+ PROBE_REQUEST_FILE_CAP_BYTES = 8 * 1024 * 1024;
110879
+ JSON_ESCAPE = /\\(?:u([0-9a-fA-F]{4})|(["\\/bfnrt]))/g;
110880
+ SIMPLE_ESCAPES = {
110881
+ '"': '"',
110882
+ "\\": "\\",
110883
+ "/": "/",
110884
+ b: "\b",
110885
+ f: "\f",
110886
+ n: `
110887
+ `,
110888
+ r: "\r",
110889
+ t: "\t"
110890
+ };
110891
+ });
110892
+
110893
+ // src/subscription-devin-probe.ts
110894
+ var exports_subscription_devin_probe = {};
110895
+ __export(exports_subscription_devin_probe, {
110896
+ DEVIN_PROBE_REQUEST_FILE_MESSAGE: () => DEVIN_PROBE_REQUEST_FILE_MESSAGE,
110897
+ buildDevinProbePayload: () => buildDevinProbePayload,
110898
+ runDevinProbe: () => runDevinProbe
110899
+ });
110900
+ function buildDevinProbePayload(model, claudeRequest) {
110901
+ const adapter = new DevinAPIFormat(model);
110902
+ adapter.setResponseWireFormat("connect-proto");
110903
+ adapter.reset();
110904
+ const messages = adapter.convertMessages(claudeRequest, filterIdentity);
110905
+ const tools = adapter.convertTools(claudeRequest);
110906
+ const payload = adapter.buildPayload(claudeRequest, messages, tools);
110907
+ adapter.prepareRequest(payload, claudeRequest);
110908
+ payload.modelUid = model;
110909
+ delete payload.effort;
110910
+ return { payload, toolNameMap: adapter.getToolNameMap() };
110911
+ }
110912
+ async function decodeDevinAnswer(res, facts, model, toolNameMap) {
110913
+ const head = await sniffDevinStreamHead(res);
110914
+ if (head.kind !== "clean") {
110915
+ facts.streamError = { code: head.code, retryable: head.kind === "retryable" };
110916
+ return JSON.stringify({ error: { code: head.code, message: head.message } });
110917
+ }
110918
+ let apiError;
110919
+ let measured;
110920
+ let endOfStream = false;
110921
+ const sse = createDevinConnectStream({}, head.response, {
110922
+ modelName: model,
110923
+ toolNameMap,
110924
+ onTokenUpdate: (input, output) => {
110925
+ measured = { input_tokens: input, output_tokens: output };
110926
+ },
110927
+ onServedModel: (uid) => {
110928
+ facts.servedModel = uid;
110929
+ },
110930
+ onApiError: (code, message) => {
110931
+ apiError ??= { code, message };
110932
+ },
110933
+ onEndOfStream: () => {
110934
+ endOfStream = true;
110935
+ }
110936
+ });
110937
+ const collected = await collectSseMessage(sse, model);
110938
+ if (apiError) {
110939
+ facts.streamError = {
110940
+ code: apiError.code,
110941
+ retryable: classifyDevinStreamError(apiError.code, apiError.message) === "retryable"
110942
+ };
110943
+ } else if (collected.streamError || !endOfStream) {
110944
+ return null;
110945
+ }
110946
+ const { streamError: _internal, ...message } = collected;
110947
+ if (measured)
110948
+ message.usage = measured;
110949
+ return JSON.stringify(message);
110950
+ }
110951
+ async function determineDevin2(deps, secrets, facts, args) {
110952
+ const request = await readRequestFileChecked(deps.readRequestFile, args.requestFile);
110953
+ if (!request.ok)
110954
+ return probeFail(facts, probeFailureOf("internal", request.code));
110955
+ const apiKey = readDevinSecrets(secrets);
110956
+ if (!apiKey) {
110957
+ return probeFail(facts, probeFailureOf("credential_missing", "devin_credential_absent"));
110958
+ }
110959
+ const { payload, toolNameMap } = buildDevinProbePayload(args.model, request.value);
110960
+ const body = encodeDevinRequest(payload, { apiKey });
110961
+ const url = `${readDevinServerUrl()}${CHAT_PATH}`;
110962
+ facts.sourceUrl = stripUserinfo(url);
110963
+ facts.clientVersion = DEVIN_CLI_VERSION;
110964
+ const controller = new AbortController;
110965
+ const timer = setTimeout(() => controller.abort(), deps.requestTimeoutMs);
110966
+ const networkFailure = () => probeFailureOf("network", controller.signal.aborted ? "get_chat_message_timeout" : "get_chat_message_network_error", facts.httpStatus);
110967
+ try {
110968
+ let res;
110969
+ try {
110970
+ res = await fetch(url, {
110971
+ method: "POST",
110972
+ headers: { ...devinAuthHeaders(apiKey), "content-type": CHAT_CONTENT_TYPE2 },
110973
+ body,
110974
+ signal: controller.signal,
110975
+ redirect: "manual"
110976
+ });
110977
+ } catch {
110978
+ return probeFail(facts, networkFailure());
110979
+ }
110980
+ facts.fetchedAt = new Date(deps.now()).toISOString();
110981
+ facts.httpStatus = res.status;
110982
+ if (!res.ok) {
110983
+ let text;
110984
+ try {
110985
+ text = await readCapped(res, PROBE_BODY_CAP_BYTES);
110986
+ } catch {
110987
+ return probeFail(facts, networkFailure());
110988
+ }
110989
+ if (text === null) {
110990
+ return probeFail(facts, probeFailureOf("list_incomplete", "body_too_large", res.status));
110991
+ }
110992
+ return probeBodyResult(facts, text, secrets, res.status);
110993
+ }
110994
+ const text = await decodeDevinAnswer(res, facts, args.model, toolNameMap);
110995
+ if (text === null)
110996
+ return probeFail(facts, networkFailure());
110997
+ if (Buffer.byteLength(text, "utf8") > PROBE_BODY_CAP_BYTES) {
110998
+ return probeFail(facts, probeFailureOf("list_incomplete", "body_too_large", res.status));
110999
+ }
111000
+ return probeBodyResult(facts, text, secrets, res.status);
111001
+ } finally {
111002
+ clearTimeout(timer);
111003
+ }
111004
+ }
111005
+ async function runDevinProbe(deps, args) {
111006
+ const secrets = newSecrets();
111007
+ const facts = { provider: "devin", model: args.model, tokenRefreshed: false };
111008
+ return runProbeWith(deps, facts, secrets, DEVIN_PROBE_REQUEST_FILE_MESSAGE, () => determineDevin2(deps, secrets, facts, args));
111009
+ }
111010
+ var DEVIN_PROBE_REQUEST_FILE_MESSAGE = "[claudish subscription] the request file must hold one JSON object (an Anthropic Messages request)", CHAT_CONTENT_TYPE2 = "application/connect+proto";
111011
+ var init_subscription_devin_probe = __esm(() => {
111012
+ init_devin_api_format();
111013
+ init_devin_credential();
111014
+ init_collect_sse_message();
111015
+ init_devin_stream_head_sniffer();
111016
+ init_openai_compat();
111017
+ init_devin_connect();
111018
+ init_devin_credentials();
111019
+ init_devin_request();
111020
+ init_devin2();
111021
+ init_subscription_antigravity_session();
111022
+ init_subscription_devin_models();
111023
+ init_subscription_probe_command();
111024
+ init_subscription_secret_guard();
111025
+ });
111026
+
110641
111027
  // src/subscription-probe-command.ts
110642
111028
  var exports_subscription_probe_command = {};
110643
111029
  __export(exports_subscription_probe_command, {
@@ -110650,33 +111036,30 @@ __export(exports_subscription_probe_command, {
110650
111036
  REDACTED: () => REDACTED2,
110651
111037
  SUBSCRIPTION_PROBE_SCHEMA: () => SUBSCRIPTION_PROBE_SCHEMA,
110652
111038
  SUBSCRIPTION_PROBE_USAGE: () => SUBSCRIPTION_PROBE_USAGE,
111039
+ buildProbeEnvelope: () => buildProbeEnvelope,
110653
111040
  buildProbeEnvelopeBody: () => buildProbeEnvelopeBody,
110654
111041
  defaultSubscriptionProbeDeps: () => defaultSubscriptionProbeDeps,
110655
111042
  isSubscriptionProbeArgv: () => isSubscriptionProbeArgv,
110656
111043
  jsonUnescapedForms: () => jsonUnescapedForms,
110657
111044
  parseSubscriptionProbeArgs: () => parseSubscriptionProbeArgs,
111045
+ probeBodyResult: () => probeBodyResult,
110658
111046
  probeExitCodeFor: () => probeExitCodeFor,
111047
+ probeFail: () => probeFail,
111048
+ probeFailureOf: () => probeFailureOf,
111049
+ readCapped: () => readCapped,
110659
111050
  redactSecretValues: () => redactSecretValues,
110660
111051
  reportProbeInternalError: () => reportProbeInternalError,
110661
111052
  runAntigravityProbe: () => runAntigravityProbe,
111053
+ runProbeWith: () => runProbeWith,
110662
111054
  subscriptionProbeCommand: () => subscriptionProbeCommand
110663
111055
  });
110664
111056
  import { randomUUID as randomUUID12 } from "crypto";
110665
- import { readFile as readFile8, stat as stat2 } from "fs/promises";
110666
111057
  function probeExitCodeFor(failure) {
110667
111058
  if (failure.class === "internal") {
110668
111059
  return CALLER_CODES.includes(failure.code) ? PROBE_EXIT.usage : PROBE_EXIT.internal;
110669
111060
  }
110670
111061
  return PROBE_EXIT[failure.class];
110671
111062
  }
110672
- async function defaultReadRequestFile(path) {
110673
- const info = await stat2(path);
110674
- if (!info.isFile())
110675
- throw new Error("not a file");
110676
- if (info.size > PROBE_REQUEST_FILE_CAP_BYTES)
110677
- return null;
110678
- return readFile8(path, "utf8");
110679
- }
110680
111063
  function defaultSubscriptionProbeDeps() {
110681
111064
  return {
110682
111065
  platform: () => process.platform,
@@ -110720,15 +111103,20 @@ function parseSubscriptionProbeArgs(argv) {
110720
111103
  }
110721
111104
  const model = values.get("--model");
110722
111105
  const requestFile = values.get("--request-file");
110723
- if (positionals.length !== 2 || positionals[0] !== "probe" || positionals[1] !== "antigravity" || switches.size !== 2 || model === undefined || requestFile === undefined) {
111106
+ if (positionals.length !== 2 || positionals[0] !== "probe" || !PROBE_PROVIDERS.includes(positionals[1]) || switches.size !== 2 || model === undefined || requestFile === undefined) {
110724
111107
  return { ok: false };
110725
111108
  }
110726
- return { ok: true, provider: "antigravity", model, requestFile };
111109
+ return {
111110
+ ok: true,
111111
+ provider: positionals[1],
111112
+ model,
111113
+ requestFile
111114
+ };
110727
111115
  }
110728
- function failureOf4(cls, code, httpStatus) {
111116
+ function probeFailureOf(cls, code, httpStatus) {
110729
111117
  return failureOf2(cls, code, httpStatus);
110730
111118
  }
110731
- function buildEnvelope2(facts, failure, body) {
111119
+ function buildProbeEnvelope(facts, failure, body) {
110732
111120
  return {
110733
111121
  schema: SUBSCRIPTION_PROBE_SCHEMA,
110734
111122
  ...facts.provider !== undefined ? { provider: facts.provider } : {},
@@ -110740,12 +111128,27 @@ function buildEnvelope2(facts, failure, body) {
110740
111128
  ...facts.clientVersionSource !== undefined ? { clientVersionSource: facts.clientVersionSource } : {},
110741
111129
  tokenRefreshed: facts.tokenRefreshed,
110742
111130
  ...facts.httpStatus !== undefined ? { httpStatus: facts.httpStatus } : {},
111131
+ ...facts.servedModel !== undefined ? { servedModel: facts.servedModel } : {},
111132
+ ...facts.streamError !== undefined ? { streamError: facts.streamError } : {},
110743
111133
  ...failure ? { failure } : {},
110744
111134
  ...body ? { bodyRedacted: body.redacted, body: body.text } : {}
110745
111135
  };
110746
111136
  }
110747
- function fail2(facts, failure) {
110748
- return { envelope: buildEnvelope2(facts, failure), exitCode: probeExitCodeFor(failure) };
111137
+ function probeFail(facts, failure) {
111138
+ return { envelope: buildProbeEnvelope(facts, failure), exitCode: probeExitCodeFor(failure) };
111139
+ }
111140
+ function probeBodyResult(facts, text, secrets, status) {
111141
+ const body = redactSecretValues(text, secrets);
111142
+ const unescaped = jsonUnescapedForms(body.text);
111143
+ if (!unescaped.complete) {
111144
+ return probeFail(facts, probeFailureOf("list_incomplete", "body_unverifiable", status));
111145
+ }
111146
+ return {
111147
+ envelope: buildProbeEnvelope(facts, undefined, body),
111148
+ exitCode: PROBE_EXIT.ok,
111149
+ bodyText: body.text,
111150
+ bodyForms: unescaped.forms
111151
+ };
110749
111152
  }
110750
111153
  function lineOf2(envelope) {
110751
111154
  return `${JSON.stringify(envelope)}
@@ -110757,62 +111160,41 @@ function safeStderr2(deps, line) {
110757
111160
  } catch {}
110758
111161
  }
110759
111162
  async function writeInternalFailure2(deps, facts, code, stderrLine, secrets) {
110760
- const failure = failureOf4("internal", code);
111163
+ const failure = probeFailureOf("internal", code);
110761
111164
  safeStderr2(deps, `${stderrLine}
110762
111165
  `);
110763
- let line = lineOf2(buildEnvelope2(facts, failure));
111166
+ let line = lineOf2(buildProbeEnvelope(facts, failure));
110764
111167
  if (secrets && containsSecret(secrets, line)) {
110765
- line = lineOf2(buildEnvelope2({ tokenRefreshed: facts.tokenRefreshed }, failure));
111168
+ line = lineOf2(buildProbeEnvelope({ tokenRefreshed: facts.tokenRefreshed }, failure));
110766
111169
  }
110767
111170
  try {
110768
111171
  await deps.writeStdout(line);
110769
111172
  } catch {}
110770
111173
  return probeExitCodeFor(failure);
110771
111174
  }
110772
- function redactSecretValues(text, secrets) {
110773
- let out = text;
110774
- const values = [...secrets.values].sort((a, b) => b.length - a.length);
110775
- for (const value of values) {
110776
- for (const form of new Set([value, value.replaceAll("/", "\\/")])) {
110777
- if (out.includes(form))
110778
- out = out.replaceAll(form, REDACTED2);
110779
- }
110780
- }
110781
- return { text: out, redacted: out !== text };
110782
- }
110783
- function jsonUnescapedForms(text) {
110784
- const forms = [];
110785
- if (text === undefined)
110786
- return { forms, complete: true };
110787
- let current = text;
110788
- for (let round = 0;round < MAX_UNESCAPE_ROUNDS; round++) {
110789
- const next = current.replace(JSON_ESCAPE, (_match, hex, letter) => hex !== undefined ? String.fromCharCode(Number.parseInt(hex, 16)) : SIMPLE_ESCAPES[letter]);
110790
- if (next === current)
110791
- return { forms, complete: true };
110792
- forms.push(next);
110793
- current = next;
110794
- }
110795
- return { forms, complete: false };
110796
- }
110797
- async function readRequest(deps, path) {
110798
- let text;
111175
+ async function runProbeWith(deps, facts, secrets, requestFileMessage, determine) {
111176
+ let result;
110799
111177
  try {
110800
- text = await deps.readRequestFile(path);
111178
+ result = await determine();
110801
111179
  } catch {
110802
- return { ok: false, code: "request_file_unreadable" };
111180
+ return writeInternalFailure2(deps, { provider: facts.provider, model: facts.model, tokenRefreshed: facts.tokenRefreshed }, "internal_error", INTERNAL_ERROR_MESSAGE2, secrets);
111181
+ }
111182
+ if (result.envelope.failure?.code === "request_file_unreadable" || result.envelope.failure?.code === "request_file_invalid") {
111183
+ safeStderr2(deps, `${requestFileMessage}
111184
+ `);
111185
+ }
111186
+ const line = lineOf2(result.envelope);
111187
+ if (containsSecret(secrets, line, result.bodyText, ...result.bodyForms ?? [])) {
111188
+ return writeInternalFailure2(deps, facts, "secret_guard", SECRET_GUARD_MESSAGE2, secrets);
110803
111189
  }
110804
- if (text === null)
110805
- return { ok: false, code: "request_file_invalid" };
110806
- let value;
110807
111190
  try {
110808
- value = JSON.parse(text);
111191
+ await deps.writeStdout(line);
110809
111192
  } catch {
110810
- return { ok: false, code: "request_file_invalid" };
110811
- }
110812
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
110813
- return { ok: false, code: "request_file_invalid" };
111193
+ safeStderr2(deps, `${INTERNAL_ERROR_MESSAGE2}
111194
+ `);
111195
+ return PROBE_EXIT.internal;
110814
111196
  }
110815
- return { ok: true, text };
111197
+ return result.exitCode;
110816
111198
  }
110817
111199
  function buildProbeEnvelopeBody(model, projectId, tierId, requestText, userPromptId = randomUUID12()) {
110818
111200
  const head = JSON.stringify({ model, project: projectId, user_prompt_id: userPromptId });
@@ -110822,32 +111204,13 @@ function buildProbeEnvelopeBody(model, projectId, tierId, requestText, userPromp
110822
111204
  function createActivityRequestId3() {
110823
111205
  return Math.random().toString(36).substring(7);
110824
111206
  }
110825
- async function readCapped(res, cap) {
110826
- if (!res.body)
110827
- return "";
110828
- const reader = res.body.getReader();
110829
- const chunks = [];
110830
- let size = 0;
110831
- for (;; ) {
110832
- const { done, value } = await reader.read();
110833
- if (done)
110834
- break;
110835
- size += value.byteLength;
110836
- if (size > cap) {
110837
- await reader.cancel().catch(() => {});
110838
- return null;
110839
- }
110840
- chunks.push(value);
110841
- }
110842
- return Buffer.concat(chunks).toString("utf8");
110843
- }
110844
- async function determine2(deps, secrets, facts, args) {
110845
- const request = await readRequest(deps, args.requestFile);
111207
+ async function determineAntigravity2(deps, secrets, facts, args) {
111208
+ const request = await readRequestFileChecked(deps.readRequestFile, args.requestFile);
110846
111209
  if (!request.ok)
110847
- return fail2(facts, failureOf4("internal", request.code));
111210
+ return probeFail(facts, probeFailureOf("internal", request.code));
110848
111211
  const session = await establishAntigravitySession(deps, secrets, facts);
110849
111212
  if (!session.ok)
110850
- return fail2(facts, session.failure);
111213
+ return probeFail(facts, session.failure);
110851
111214
  const url = `${antigravityHost()}/v1internal:generateContent`;
110852
111215
  const version = resolveAntigravityClientVersion();
110853
111216
  facts.sourceUrl = stripUserinfo(url);
@@ -110855,7 +111218,7 @@ async function determine2(deps, secrets, facts, args) {
110855
111218
  facts.clientVersionSource = version.source;
110856
111219
  const controller = new AbortController;
110857
111220
  const timer = setTimeout(() => controller.abort(), deps.requestTimeoutMs);
110858
- const networkFailure = () => failureOf4("network", controller.signal.aborted ? "generate_content_timeout" : "generate_content_network_error", facts.httpStatus);
111221
+ const networkFailure = () => probeFailureOf("network", controller.signal.aborted ? "generate_content_timeout" : "generate_content_network_error", facts.httpStatus);
110859
111222
  try {
110860
111223
  let res;
110861
111224
  try {
@@ -110872,7 +111235,7 @@ async function determine2(deps, secrets, facts, args) {
110872
111235
  redirect: "manual"
110873
111236
  });
110874
111237
  } catch {
110875
- return fail2(facts, networkFailure());
111238
+ return probeFail(facts, networkFailure());
110876
111239
  }
110877
111240
  facts.fetchedAt = new Date(deps.now()).toISOString();
110878
111241
  facts.httpStatus = res.status;
@@ -110880,28 +111243,18 @@ async function determine2(deps, secrets, facts, args) {
110880
111243
  try {
110881
111244
  text = await readCapped(res, PROBE_BODY_CAP_BYTES);
110882
111245
  } catch {
110883
- return fail2(facts, networkFailure());
111246
+ return probeFail(facts, networkFailure());
110884
111247
  }
110885
111248
  if (text === null)
110886
- return fail2(facts, failureOf4("list_incomplete", "body_too_large", res.status));
111249
+ return probeFail(facts, probeFailureOf("list_incomplete", "body_too_large", res.status));
110887
111250
  if (res.ok) {
110888
111251
  try {
110889
111252
  JSON.parse(text);
110890
111253
  } catch {
110891
- return fail2(facts, failureOf4("list_incomplete", "body_not_json", res.status));
111254
+ return probeFail(facts, probeFailureOf("list_incomplete", "body_not_json", res.status));
110892
111255
  }
110893
111256
  }
110894
- const body = redactSecretValues(text, secrets);
110895
- const unescaped = jsonUnescapedForms(body.text);
110896
- if (!unescaped.complete) {
110897
- return fail2(facts, failureOf4("list_incomplete", "body_unverifiable", res.status));
110898
- }
110899
- return {
110900
- envelope: buildEnvelope2(facts, undefined, body),
110901
- exitCode: PROBE_EXIT.ok,
110902
- bodyText: body.text,
110903
- bodyForms: unescaped.forms
110904
- };
111257
+ return probeBodyResult(facts, text, secrets, res.status);
110905
111258
  } finally {
110906
111259
  clearTimeout(timer);
110907
111260
  }
@@ -110909,28 +111262,7 @@ async function determine2(deps, secrets, facts, args) {
110909
111262
  async function runAntigravityProbe(deps, args) {
110910
111263
  const secrets = newSecrets();
110911
111264
  const facts = { provider: "antigravity", model: args.model, tokenRefreshed: false };
110912
- let result;
110913
- try {
110914
- result = await determine2(deps, secrets, facts, args);
110915
- } catch {
110916
- return writeInternalFailure2(deps, { provider: facts.provider, model: facts.model, tokenRefreshed: facts.tokenRefreshed }, "internal_error", INTERNAL_ERROR_MESSAGE2, secrets);
110917
- }
110918
- if (result.envelope.failure?.code === "request_file_unreadable" || result.envelope.failure?.code === "request_file_invalid") {
110919
- safeStderr2(deps, `${PROBE_REQUEST_FILE_MESSAGE}
110920
- `);
110921
- }
110922
- const line = lineOf2(result.envelope);
110923
- if (containsSecret(secrets, line, result.bodyText, ...result.bodyForms ?? [])) {
110924
- return writeInternalFailure2(deps, facts, "secret_guard", SECRET_GUARD_MESSAGE2, secrets);
110925
- }
110926
- try {
110927
- await deps.writeStdout(line);
110928
- } catch {
110929
- safeStderr2(deps, `${INTERNAL_ERROR_MESSAGE2}
110930
- `);
110931
- return PROBE_EXIT.internal;
110932
- }
110933
- return result.exitCode;
111265
+ return runProbeWith(deps, facts, secrets, PROBE_REQUEST_FILE_MESSAGE, () => determineAntigravity2(deps, secrets, facts, args));
110934
111266
  }
110935
111267
  async function reportProbeInternalError(deps) {
110936
111268
  let resolved;
@@ -110948,23 +111280,36 @@ async function subscriptionProbeCommand(argv, deps = defaultSubscriptionProbeDep
110948
111280
  if (!args.ok) {
110949
111281
  return writeInternalFailure2(deps, { tokenRefreshed: false }, "usage", SUBSCRIPTION_PROBE_USAGE);
110950
111282
  }
111283
+ if (args.provider === "devin") {
111284
+ let devin;
111285
+ try {
111286
+ devin = await Promise.resolve().then(() => (init_subscription_devin_probe(), exports_subscription_devin_probe));
111287
+ } catch {
111288
+ return writeInternalFailure2(deps, { provider: args.provider, model: args.model, tokenRefreshed: false }, "internal_error", INTERNAL_ERROR_MESSAGE2);
111289
+ }
111290
+ return devin.runDevinProbe(deps, args);
111291
+ }
110951
111292
  return runAntigravityProbe(deps, args);
110952
111293
  }
110953
- var PROBE_FAILURE_CODES, PROBE_EXIT, CALLER_CODES, PROBE_BODY_CAP_BYTES, PROBE_REQUEST_FILE_CAP_BYTES, REDACTED2 = "[REDACTED]", SUBSCRIPTION_PROBE_USAGE = "usage: claudish subscription probe antigravity --model <wire-model-id> --request-file <path> --raw --json", PROBE_REQUEST_FILE_MESSAGE = "[claudish subscription] the request file must hold one JSON object (the inner Gemini request)", SECRET_GUARD_MESSAGE2 = "[claudish subscription] refused: output contained a credential value", INTERNAL_ERROR_MESSAGE2 = "[claudish subscription] internal error", JSON_ESCAPE, SIMPLE_ESCAPES, MAX_UNESCAPE_ROUNDS = 64;
111294
+ var PROBE_FAILURE_CODES, PROBE_EXIT, CALLER_CODES, SUBSCRIPTION_PROBE_USAGE = "usage: claudish subscription probe antigravity|devin --model <wire-model-id> --request-file <path> --raw --json", PROBE_REQUEST_FILE_MESSAGE = "[claudish subscription] the request file must hold one JSON object (the inner Gemini request)", SECRET_GUARD_MESSAGE2 = "[claudish subscription] refused: output contained a credential value", INTERNAL_ERROR_MESSAGE2 = "[claudish subscription] internal error", PROBE_PROVIDERS;
110954
111295
  var init_subscription_probe_command = __esm(() => {
110955
111296
  init_antigravity_token();
110956
111297
  init_antigravity_user();
110957
111298
  init_subscription_antigravity_session();
110958
111299
  init_subscription_dispatch();
111300
+ init_subscription_secret_guard();
110959
111301
  init_subscription_dispatch();
111302
+ init_subscription_secret_guard();
110960
111303
  PROBE_FAILURE_CODES = {
110961
- credential_missing: SESSION_FAILURE_CODES.credential_missing,
111304
+ credential_missing: [...SESSION_FAILURE_CODES.credential_missing, "devin_credential_absent"],
110962
111305
  keychain_locked: SESSION_FAILURE_CODES.keychain_locked,
110963
111306
  mint_failed: SESSION_FAILURE_CODES.mint_failed,
110964
111307
  network: [
110965
111308
  ...SESSION_FAILURE_CODES.network,
110966
111309
  "generate_content_network_error",
110967
- "generate_content_timeout"
111310
+ "generate_content_timeout",
111311
+ "get_chat_message_network_error",
111312
+ "get_chat_message_timeout"
110968
111313
  ],
110969
111314
  list_incomplete: ["body_too_large", "body_not_json", "body_unverifiable"],
110970
111315
  internal: [
@@ -110990,20 +111335,7 @@ var init_subscription_probe_command = __esm(() => {
110990
111335
  "request_file_unreadable",
110991
111336
  "request_file_invalid"
110992
111337
  ];
110993
- PROBE_BODY_CAP_BYTES = 512 * 1024;
110994
- PROBE_REQUEST_FILE_CAP_BYTES = 8 * 1024 * 1024;
110995
- JSON_ESCAPE = /\\(?:u([0-9a-fA-F]{4})|(["\\/bfnrt]))/g;
110996
- SIMPLE_ESCAPES = {
110997
- '"': '"',
110998
- "\\": "\\",
110999
- "/": "/",
111000
- b: "\b",
111001
- f: "\f",
111002
- n: `
111003
- `,
111004
- r: "\r",
111005
- t: "\t"
111006
- };
111338
+ PROBE_PROVIDERS = ["antigravity", "devin"];
111007
111339
  });
111008
111340
 
111009
111341
  // src/account-forecast-render.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "14.15.0",
3
+ "version": "14.16.0",
4
4
  "description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -71,10 +71,10 @@
71
71
  "ai"
72
72
  ],
73
73
  "optionalDependencies": {
74
- "@claudish/magmux-darwin-arm64": "14.15.0",
75
- "@claudish/magmux-darwin-x64": "14.15.0",
76
- "@claudish/magmux-linux-arm64": "14.15.0",
77
- "@claudish/magmux-linux-x64": "14.15.0"
74
+ "@claudish/magmux-darwin-arm64": "14.16.0",
75
+ "@claudish/magmux-darwin-x64": "14.16.0",
76
+ "@claudish/magmux-linux-arm64": "14.16.0",
77
+ "@claudish/magmux-linux-x64": "14.16.0"
78
78
  },
79
79
  "author": "Jack Rudenko <i@madappgang.com>",
80
80
  "license": "MIT",