claudish 14.15.1 → 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 +505 -178
  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.1";
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:")}
@@ -110404,6 +110438,94 @@ var init_subscription_antigravity_session = __esm(() => {
110404
110438
  TIMED_OUT = Symbol("timed-out");
110405
110439
  });
110406
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
+
110407
110529
  // src/subscription-models-command.ts
110408
110530
  var exports_subscription_models_command = {};
110409
110531
  __export(exports_subscription_models_command, {
@@ -110413,11 +110535,15 @@ __export(exports_subscription_models_command, {
110413
110535
  SECRET_GUARD_MESSAGE: () => SECRET_GUARD_MESSAGE,
110414
110536
  SUBSCRIPTION_MODELS_USAGE: () => SUBSCRIPTION_MODELS_USAGE,
110415
110537
  SUBSCRIPTION_MODEL_LIST_SCHEMA: () => SUBSCRIPTION_MODEL_LIST_SCHEMA,
110538
+ buildModelListEnvelope: () => buildModelListEnvelope,
110416
110539
  defaultSubscriptionModelsDeps: () => defaultSubscriptionModelsDeps,
110417
110540
  exitCodeFor: () => exitCodeFor,
110541
+ modelListFail: () => modelListFail,
110542
+ modelListFailureOf: () => modelListFailureOf,
110418
110543
  parseSubscriptionModelsArgs: () => parseSubscriptionModelsArgs,
110419
110544
  reportSubscriptionInternalError: () => reportSubscriptionInternalError,
110420
110545
  runAntigravityRawModelList: () => runAntigravityRawModelList,
110546
+ runModelListWith: () => runModelListWith,
110421
110547
  subscriptionModelsCommand: () => subscriptionModelsCommand
110422
110548
  });
110423
110549
  function exitCodeFor(failure) {
@@ -110444,11 +110570,11 @@ function defaultSubscriptionModelsDeps() {
110444
110570
  function parseSubscriptionModelsArgs(argv) {
110445
110571
  const positionals = argv.filter((a) => !a.startsWith("-"));
110446
110572
  const flags = argv.filter((a) => a.startsWith("-"));
110447
- 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]);
110448
110574
  const flagsOk = flags.length === 2 && flags.includes("--raw") && flags.includes("--json");
110449
- return positionalsOk && flagsOk ? { ok: true, provider: "antigravity" } : { ok: false };
110575
+ return positionalsOk && flagsOk ? { ok: true, provider: positionals[1] } : { ok: false };
110450
110576
  }
110451
- function buildEnvelope(facts, failure, body) {
110577
+ function buildModelListEnvelope(facts, failure, body) {
110452
110578
  return {
110453
110579
  schema: SUBSCRIPTION_MODEL_LIST_SCHEMA,
110454
110580
  ...facts.provider !== undefined ? { provider: facts.provider } : {},
@@ -110459,25 +110585,27 @@ function buildEnvelope(facts, failure, body) {
110459
110585
  ...facts.clientVersionSource !== undefined ? { clientVersionSource: facts.clientVersionSource } : {},
110460
110586
  tokenRefreshed: facts.tokenRefreshed,
110461
110587
  ...facts.httpStatus !== undefined ? { httpStatus: facts.httpStatus } : {},
110588
+ ...facts.teamSettingsUrl !== undefined ? { teamSettingsUrl: facts.teamSettingsUrl } : {},
110589
+ ...facts.teamSettingsHttpStatus !== undefined ? { teamSettingsHttpStatus: facts.teamSettingsHttpStatus } : {},
110462
110590
  ...failure ? { failure } : {},
110463
110591
  ...body !== undefined ? { body } : {}
110464
110592
  };
110465
110593
  }
110466
- function failureOf3(cls, code, httpStatus) {
110594
+ function modelListFailureOf(cls, code, httpStatus) {
110467
110595
  return failureOf2(cls, code, httpStatus);
110468
110596
  }
110469
110597
  function listFailure(value, status) {
110470
110598
  const models = value !== null && typeof value === "object" && !Array.isArray(value) ? value.models : undefined;
110471
110599
  if (models === null || typeof models !== "object" || Array.isArray(models)) {
110472
- return failureOf3("list_incomplete", "models_absent", status);
110600
+ return modelListFailureOf("list_incomplete", "models_absent", status);
110473
110601
  }
110474
110602
  if (Object.keys(models).length === 0) {
110475
- return failureOf3("list_incomplete", "models_empty", status);
110603
+ return modelListFailureOf("list_incomplete", "models_empty", status);
110476
110604
  }
110477
110605
  return null;
110478
110606
  }
110479
- function fail(facts, failure) {
110480
- return { envelope: buildEnvelope(facts, failure), exitCode: exitCodeFor(failure) };
110607
+ function modelListFail(facts, failure) {
110608
+ return { envelope: buildModelListEnvelope(facts, failure), exitCode: exitCodeFor(failure) };
110481
110609
  }
110482
110610
  function lineOf(envelope) {
110483
110611
  return `${JSON.stringify(envelope)}
@@ -110489,15 +110617,16 @@ function safeStderr(deps, line) {
110489
110617
  } catch {}
110490
110618
  }
110491
110619
  async function writeInternalFailure(deps, facts, code, stderrLine, secrets) {
110492
- const failure = failureOf3("internal", code);
110620
+ const failure = modelListFailureOf("internal", code);
110493
110621
  safeStderr(deps, `${stderrLine}
110494
110622
  `);
110495
- const line = lineOf(buildEnvelope(facts, failure));
110496
- if (!secrets || !containsSecret(secrets, line)) {
110497
- try {
110498
- await deps.writeStdout(line);
110499
- } catch {}
110623
+ let line = lineOf(buildModelListEnvelope(facts, failure));
110624
+ if (secrets && containsSecret(secrets, line)) {
110625
+ line = lineOf(buildModelListEnvelope({ tokenRefreshed: facts.tokenRefreshed }, failure));
110500
110626
  }
110627
+ try {
110628
+ await deps.writeStdout(line);
110629
+ } catch {}
110501
110630
  return exitCodeFor(failure);
110502
110631
  }
110503
110632
  async function reportSubscriptionInternalError(deps) {
@@ -110516,34 +110645,35 @@ function classifyAvailableModels(facts, raw, timedOut) {
110516
110645
  facts.clientVersion = raw.clientVersion;
110517
110646
  facts.clientVersionSource = raw.clientVersionSource;
110518
110647
  const networkCode = timedOut ? "fetch_available_models_timeout" : "fetch_available_models_network_error";
110519
- if (raw.kind === "unreachable")
110520
- return fail(facts, failureOf3("network", networkCode));
110648
+ if (raw.kind === "unreachable") {
110649
+ return modelListFail(facts, modelListFailureOf("network", networkCode));
110650
+ }
110521
110651
  facts.fetchedAt = raw.fetchedAt;
110522
110652
  facts.httpStatus = raw.status;
110523
110653
  if (raw.status < 200 || raw.status >= 300) {
110524
- return { envelope: buildEnvelope(facts), exitCode: EXIT.ok };
110654
+ return { envelope: buildModelListEnvelope(facts), exitCode: EXIT.ok };
110525
110655
  }
110526
110656
  switch (raw.body.kind) {
110527
110657
  case "json": {
110528
110658
  const incomplete = listFailure(raw.body.value, raw.status);
110529
110659
  if (incomplete)
110530
- return fail(facts, incomplete);
110660
+ return modelListFail(facts, incomplete);
110531
110661
  return {
110532
- envelope: buildEnvelope(facts, undefined, raw.body.text),
110662
+ envelope: buildModelListEnvelope(facts, undefined, raw.body.text),
110533
110663
  exitCode: EXIT.ok,
110534
110664
  bodyText: raw.body.text
110535
110665
  };
110536
110666
  }
110537
110667
  case "not-json":
110538
- return fail(facts, failureOf3("list_incomplete", "body_not_json", raw.status));
110668
+ return modelListFail(facts, modelListFailureOf("list_incomplete", "body_not_json", raw.status));
110539
110669
  default:
110540
- return fail(facts, failureOf3("network", networkCode, raw.status));
110670
+ return modelListFail(facts, modelListFailureOf("network", networkCode, raw.status));
110541
110671
  }
110542
110672
  }
110543
- async function determine(deps, secrets, facts) {
110673
+ async function determineAntigravity(deps, secrets, facts) {
110544
110674
  const session = await establishAntigravitySession(deps, secrets, facts);
110545
110675
  if (!session.ok)
110546
- return fail(facts, session.failure);
110676
+ return modelListFail(facts, session.failure);
110547
110677
  const { accessToken, projectId } = session;
110548
110678
  const controller = new AbortController;
110549
110679
  const timer = setTimeout(() => controller.abort(), deps.httpTimeoutMs);
@@ -110557,14 +110687,12 @@ async function determine(deps, secrets, facts) {
110557
110687
  clearTimeout(timer);
110558
110688
  }
110559
110689
  }
110560
- async function runAntigravityRawModelList(deps) {
110561
- const secrets = newSecrets();
110562
- const facts = { provider: "antigravity", tokenRefreshed: false };
110690
+ async function runModelListWith(deps, facts, secrets, determine) {
110563
110691
  let line;
110564
110692
  let exitCode;
110565
110693
  let bodyText;
110566
110694
  try {
110567
- const result = await determine(deps, secrets, facts);
110695
+ const result = await determine();
110568
110696
  line = lineOf(result.envelope);
110569
110697
  exitCode = result.exitCode;
110570
110698
  bodyText = result.bodyText;
@@ -110583,27 +110711,53 @@ async function runAntigravityRawModelList(deps) {
110583
110711
  }
110584
110712
  return exitCode;
110585
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
+ }
110586
110719
  async function subscriptionModelsCommand(argv, deps = defaultSubscriptionModelsDeps()) {
110587
- if (!parseSubscriptionModelsArgs(argv).ok) {
110720
+ const args = parseSubscriptionModelsArgs(argv);
110721
+ if (!args.ok) {
110588
110722
  return writeInternalFailure(deps, { tokenRefreshed: false }, "usage", SUBSCRIPTION_MODELS_USAGE);
110589
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
+ }
110590
110733
  return runAntigravityRawModelList(deps);
110591
110734
  }
110592
- 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;
110593
110736
  var init_subscription_models_command = __esm(() => {
110594
110737
  init_antigravity_token();
110595
110738
  init_antigravity_user();
110596
110739
  init_subscription_antigravity_session();
110597
110740
  FAILURE_CODES = {
110598
- credential_missing: SESSION_FAILURE_CODES.credential_missing,
110741
+ credential_missing: [...SESSION_FAILURE_CODES.credential_missing, "devin_credential_absent"],
110599
110742
  keychain_locked: SESSION_FAILURE_CODES.keychain_locked,
110600
110743
  mint_failed: SESSION_FAILURE_CODES.mint_failed,
110601
110744
  network: [
110602
110745
  ...SESSION_FAILURE_CODES.network,
110603
110746
  "fetch_available_models_network_error",
110604
- "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"
110605
110760
  ],
110606
- list_incomplete: ["models_absent", "models_empty", "body_not_json"],
110607
110761
  internal: ["usage", "secret_guard", "internal_error"]
110608
110762
  };
110609
110763
  EXIT = {
@@ -110616,6 +110770,7 @@ var init_subscription_models_command = __esm(() => {
110616
110770
  network: 6,
110617
110771
  list_incomplete: 7
110618
110772
  };
110773
+ MODEL_LIST_PROVIDERS = ["antigravity", "devin"];
110619
110774
  });
110620
110775
 
110621
110776
  // src/subscription-dispatch.ts
@@ -110643,6 +110798,232 @@ function probeLoadFailureLine() {
110643
110798
  var SUBSCRIPTION_PROBE_SCHEMA = "claudish.subscription-probe.v1";
110644
110799
  var init_subscription_dispatch = () => {};
110645
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
+
110646
111027
  // src/subscription-probe-command.ts
110647
111028
  var exports_subscription_probe_command = {};
110648
111029
  __export(exports_subscription_probe_command, {
@@ -110655,33 +111036,30 @@ __export(exports_subscription_probe_command, {
110655
111036
  REDACTED: () => REDACTED2,
110656
111037
  SUBSCRIPTION_PROBE_SCHEMA: () => SUBSCRIPTION_PROBE_SCHEMA,
110657
111038
  SUBSCRIPTION_PROBE_USAGE: () => SUBSCRIPTION_PROBE_USAGE,
111039
+ buildProbeEnvelope: () => buildProbeEnvelope,
110658
111040
  buildProbeEnvelopeBody: () => buildProbeEnvelopeBody,
110659
111041
  defaultSubscriptionProbeDeps: () => defaultSubscriptionProbeDeps,
110660
111042
  isSubscriptionProbeArgv: () => isSubscriptionProbeArgv,
110661
111043
  jsonUnescapedForms: () => jsonUnescapedForms,
110662
111044
  parseSubscriptionProbeArgs: () => parseSubscriptionProbeArgs,
111045
+ probeBodyResult: () => probeBodyResult,
110663
111046
  probeExitCodeFor: () => probeExitCodeFor,
111047
+ probeFail: () => probeFail,
111048
+ probeFailureOf: () => probeFailureOf,
111049
+ readCapped: () => readCapped,
110664
111050
  redactSecretValues: () => redactSecretValues,
110665
111051
  reportProbeInternalError: () => reportProbeInternalError,
110666
111052
  runAntigravityProbe: () => runAntigravityProbe,
111053
+ runProbeWith: () => runProbeWith,
110667
111054
  subscriptionProbeCommand: () => subscriptionProbeCommand
110668
111055
  });
110669
111056
  import { randomUUID as randomUUID12 } from "crypto";
110670
- import { readFile as readFile8, stat as stat2 } from "fs/promises";
110671
111057
  function probeExitCodeFor(failure) {
110672
111058
  if (failure.class === "internal") {
110673
111059
  return CALLER_CODES.includes(failure.code) ? PROBE_EXIT.usage : PROBE_EXIT.internal;
110674
111060
  }
110675
111061
  return PROBE_EXIT[failure.class];
110676
111062
  }
110677
- async function defaultReadRequestFile(path) {
110678
- const info = await stat2(path);
110679
- if (!info.isFile())
110680
- throw new Error("not a file");
110681
- if (info.size > PROBE_REQUEST_FILE_CAP_BYTES)
110682
- return null;
110683
- return readFile8(path, "utf8");
110684
- }
110685
111063
  function defaultSubscriptionProbeDeps() {
110686
111064
  return {
110687
111065
  platform: () => process.platform,
@@ -110725,15 +111103,20 @@ function parseSubscriptionProbeArgs(argv) {
110725
111103
  }
110726
111104
  const model = values.get("--model");
110727
111105
  const requestFile = values.get("--request-file");
110728
- 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) {
110729
111107
  return { ok: false };
110730
111108
  }
110731
- return { ok: true, provider: "antigravity", model, requestFile };
111109
+ return {
111110
+ ok: true,
111111
+ provider: positionals[1],
111112
+ model,
111113
+ requestFile
111114
+ };
110732
111115
  }
110733
- function failureOf4(cls, code, httpStatus) {
111116
+ function probeFailureOf(cls, code, httpStatus) {
110734
111117
  return failureOf2(cls, code, httpStatus);
110735
111118
  }
110736
- function buildEnvelope2(facts, failure, body) {
111119
+ function buildProbeEnvelope(facts, failure, body) {
110737
111120
  return {
110738
111121
  schema: SUBSCRIPTION_PROBE_SCHEMA,
110739
111122
  ...facts.provider !== undefined ? { provider: facts.provider } : {},
@@ -110745,12 +111128,27 @@ function buildEnvelope2(facts, failure, body) {
110745
111128
  ...facts.clientVersionSource !== undefined ? { clientVersionSource: facts.clientVersionSource } : {},
110746
111129
  tokenRefreshed: facts.tokenRefreshed,
110747
111130
  ...facts.httpStatus !== undefined ? { httpStatus: facts.httpStatus } : {},
111131
+ ...facts.servedModel !== undefined ? { servedModel: facts.servedModel } : {},
111132
+ ...facts.streamError !== undefined ? { streamError: facts.streamError } : {},
110748
111133
  ...failure ? { failure } : {},
110749
111134
  ...body ? { bodyRedacted: body.redacted, body: body.text } : {}
110750
111135
  };
110751
111136
  }
110752
- function fail2(facts, failure) {
110753
- 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
+ };
110754
111152
  }
110755
111153
  function lineOf2(envelope) {
110756
111154
  return `${JSON.stringify(envelope)}
@@ -110762,62 +111160,41 @@ function safeStderr2(deps, line) {
110762
111160
  } catch {}
110763
111161
  }
110764
111162
  async function writeInternalFailure2(deps, facts, code, stderrLine, secrets) {
110765
- const failure = failureOf4("internal", code);
111163
+ const failure = probeFailureOf("internal", code);
110766
111164
  safeStderr2(deps, `${stderrLine}
110767
111165
  `);
110768
- let line = lineOf2(buildEnvelope2(facts, failure));
111166
+ let line = lineOf2(buildProbeEnvelope(facts, failure));
110769
111167
  if (secrets && containsSecret(secrets, line)) {
110770
- line = lineOf2(buildEnvelope2({ tokenRefreshed: facts.tokenRefreshed }, failure));
111168
+ line = lineOf2(buildProbeEnvelope({ tokenRefreshed: facts.tokenRefreshed }, failure));
110771
111169
  }
110772
111170
  try {
110773
111171
  await deps.writeStdout(line);
110774
111172
  } catch {}
110775
111173
  return probeExitCodeFor(failure);
110776
111174
  }
110777
- function redactSecretValues(text, secrets) {
110778
- let out = text;
110779
- const values = [...secrets.values].sort((a, b) => b.length - a.length);
110780
- for (const value of values) {
110781
- for (const form of new Set([value, value.replaceAll("/", "\\/")])) {
110782
- if (out.includes(form))
110783
- out = out.replaceAll(form, REDACTED2);
110784
- }
110785
- }
110786
- return { text: out, redacted: out !== text };
110787
- }
110788
- function jsonUnescapedForms(text) {
110789
- const forms = [];
110790
- if (text === undefined)
110791
- return { forms, complete: true };
110792
- let current = text;
110793
- for (let round = 0;round < MAX_UNESCAPE_ROUNDS; round++) {
110794
- const next = current.replace(JSON_ESCAPE, (_match, hex, letter) => hex !== undefined ? String.fromCharCode(Number.parseInt(hex, 16)) : SIMPLE_ESCAPES[letter]);
110795
- if (next === current)
110796
- return { forms, complete: true };
110797
- forms.push(next);
110798
- current = next;
110799
- }
110800
- return { forms, complete: false };
110801
- }
110802
- async function readRequest(deps, path) {
110803
- let text;
111175
+ async function runProbeWith(deps, facts, secrets, requestFileMessage, determine) {
111176
+ let result;
110804
111177
  try {
110805
- text = await deps.readRequestFile(path);
111178
+ result = await determine();
110806
111179
  } catch {
110807
- 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);
110808
111189
  }
110809
- if (text === null)
110810
- return { ok: false, code: "request_file_invalid" };
110811
- let value;
110812
111190
  try {
110813
- value = JSON.parse(text);
111191
+ await deps.writeStdout(line);
110814
111192
  } catch {
110815
- return { ok: false, code: "request_file_invalid" };
110816
- }
110817
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
110818
- return { ok: false, code: "request_file_invalid" };
111193
+ safeStderr2(deps, `${INTERNAL_ERROR_MESSAGE2}
111194
+ `);
111195
+ return PROBE_EXIT.internal;
110819
111196
  }
110820
- return { ok: true, text };
111197
+ return result.exitCode;
110821
111198
  }
110822
111199
  function buildProbeEnvelopeBody(model, projectId, tierId, requestText, userPromptId = randomUUID12()) {
110823
111200
  const head = JSON.stringify({ model, project: projectId, user_prompt_id: userPromptId });
@@ -110827,32 +111204,13 @@ function buildProbeEnvelopeBody(model, projectId, tierId, requestText, userPromp
110827
111204
  function createActivityRequestId3() {
110828
111205
  return Math.random().toString(36).substring(7);
110829
111206
  }
110830
- async function readCapped(res, cap) {
110831
- if (!res.body)
110832
- return "";
110833
- const reader = res.body.getReader();
110834
- const chunks = [];
110835
- let size = 0;
110836
- for (;; ) {
110837
- const { done, value } = await reader.read();
110838
- if (done)
110839
- break;
110840
- size += value.byteLength;
110841
- if (size > cap) {
110842
- await reader.cancel().catch(() => {});
110843
- return null;
110844
- }
110845
- chunks.push(value);
110846
- }
110847
- return Buffer.concat(chunks).toString("utf8");
110848
- }
110849
- async function determine2(deps, secrets, facts, args) {
110850
- const request = await readRequest(deps, args.requestFile);
111207
+ async function determineAntigravity2(deps, secrets, facts, args) {
111208
+ const request = await readRequestFileChecked(deps.readRequestFile, args.requestFile);
110851
111209
  if (!request.ok)
110852
- return fail2(facts, failureOf4("internal", request.code));
111210
+ return probeFail(facts, probeFailureOf("internal", request.code));
110853
111211
  const session = await establishAntigravitySession(deps, secrets, facts);
110854
111212
  if (!session.ok)
110855
- return fail2(facts, session.failure);
111213
+ return probeFail(facts, session.failure);
110856
111214
  const url = `${antigravityHost()}/v1internal:generateContent`;
110857
111215
  const version = resolveAntigravityClientVersion();
110858
111216
  facts.sourceUrl = stripUserinfo(url);
@@ -110860,7 +111218,7 @@ async function determine2(deps, secrets, facts, args) {
110860
111218
  facts.clientVersionSource = version.source;
110861
111219
  const controller = new AbortController;
110862
111220
  const timer = setTimeout(() => controller.abort(), deps.requestTimeoutMs);
110863
- 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);
110864
111222
  try {
110865
111223
  let res;
110866
111224
  try {
@@ -110877,7 +111235,7 @@ async function determine2(deps, secrets, facts, args) {
110877
111235
  redirect: "manual"
110878
111236
  });
110879
111237
  } catch {
110880
- return fail2(facts, networkFailure());
111238
+ return probeFail(facts, networkFailure());
110881
111239
  }
110882
111240
  facts.fetchedAt = new Date(deps.now()).toISOString();
110883
111241
  facts.httpStatus = res.status;
@@ -110885,28 +111243,18 @@ async function determine2(deps, secrets, facts, args) {
110885
111243
  try {
110886
111244
  text = await readCapped(res, PROBE_BODY_CAP_BYTES);
110887
111245
  } catch {
110888
- return fail2(facts, networkFailure());
111246
+ return probeFail(facts, networkFailure());
110889
111247
  }
110890
111248
  if (text === null)
110891
- return fail2(facts, failureOf4("list_incomplete", "body_too_large", res.status));
111249
+ return probeFail(facts, probeFailureOf("list_incomplete", "body_too_large", res.status));
110892
111250
  if (res.ok) {
110893
111251
  try {
110894
111252
  JSON.parse(text);
110895
111253
  } catch {
110896
- return fail2(facts, failureOf4("list_incomplete", "body_not_json", res.status));
111254
+ return probeFail(facts, probeFailureOf("list_incomplete", "body_not_json", res.status));
110897
111255
  }
110898
111256
  }
110899
- const body = redactSecretValues(text, secrets);
110900
- const unescaped = jsonUnescapedForms(body.text);
110901
- if (!unescaped.complete) {
110902
- return fail2(facts, failureOf4("list_incomplete", "body_unverifiable", res.status));
110903
- }
110904
- return {
110905
- envelope: buildEnvelope2(facts, undefined, body),
110906
- exitCode: PROBE_EXIT.ok,
110907
- bodyText: body.text,
110908
- bodyForms: unescaped.forms
110909
- };
111257
+ return probeBodyResult(facts, text, secrets, res.status);
110910
111258
  } finally {
110911
111259
  clearTimeout(timer);
110912
111260
  }
@@ -110914,28 +111262,7 @@ async function determine2(deps, secrets, facts, args) {
110914
111262
  async function runAntigravityProbe(deps, args) {
110915
111263
  const secrets = newSecrets();
110916
111264
  const facts = { provider: "antigravity", model: args.model, tokenRefreshed: false };
110917
- let result;
110918
- try {
110919
- result = await determine2(deps, secrets, facts, args);
110920
- } catch {
110921
- return writeInternalFailure2(deps, { provider: facts.provider, model: facts.model, tokenRefreshed: facts.tokenRefreshed }, "internal_error", INTERNAL_ERROR_MESSAGE2, secrets);
110922
- }
110923
- if (result.envelope.failure?.code === "request_file_unreadable" || result.envelope.failure?.code === "request_file_invalid") {
110924
- safeStderr2(deps, `${PROBE_REQUEST_FILE_MESSAGE}
110925
- `);
110926
- }
110927
- const line = lineOf2(result.envelope);
110928
- if (containsSecret(secrets, line, result.bodyText, ...result.bodyForms ?? [])) {
110929
- return writeInternalFailure2(deps, facts, "secret_guard", SECRET_GUARD_MESSAGE2, secrets);
110930
- }
110931
- try {
110932
- await deps.writeStdout(line);
110933
- } catch {
110934
- safeStderr2(deps, `${INTERNAL_ERROR_MESSAGE2}
110935
- `);
110936
- return PROBE_EXIT.internal;
110937
- }
110938
- return result.exitCode;
111265
+ return runProbeWith(deps, facts, secrets, PROBE_REQUEST_FILE_MESSAGE, () => determineAntigravity2(deps, secrets, facts, args));
110939
111266
  }
110940
111267
  async function reportProbeInternalError(deps) {
110941
111268
  let resolved;
@@ -110953,23 +111280,36 @@ async function subscriptionProbeCommand(argv, deps = defaultSubscriptionProbeDep
110953
111280
  if (!args.ok) {
110954
111281
  return writeInternalFailure2(deps, { tokenRefreshed: false }, "usage", SUBSCRIPTION_PROBE_USAGE);
110955
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
+ }
110956
111292
  return runAntigravityProbe(deps, args);
110957
111293
  }
110958
- 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;
110959
111295
  var init_subscription_probe_command = __esm(() => {
110960
111296
  init_antigravity_token();
110961
111297
  init_antigravity_user();
110962
111298
  init_subscription_antigravity_session();
110963
111299
  init_subscription_dispatch();
111300
+ init_subscription_secret_guard();
110964
111301
  init_subscription_dispatch();
111302
+ init_subscription_secret_guard();
110965
111303
  PROBE_FAILURE_CODES = {
110966
- credential_missing: SESSION_FAILURE_CODES.credential_missing,
111304
+ credential_missing: [...SESSION_FAILURE_CODES.credential_missing, "devin_credential_absent"],
110967
111305
  keychain_locked: SESSION_FAILURE_CODES.keychain_locked,
110968
111306
  mint_failed: SESSION_FAILURE_CODES.mint_failed,
110969
111307
  network: [
110970
111308
  ...SESSION_FAILURE_CODES.network,
110971
111309
  "generate_content_network_error",
110972
- "generate_content_timeout"
111310
+ "generate_content_timeout",
111311
+ "get_chat_message_network_error",
111312
+ "get_chat_message_timeout"
110973
111313
  ],
110974
111314
  list_incomplete: ["body_too_large", "body_not_json", "body_unverifiable"],
110975
111315
  internal: [
@@ -110995,20 +111335,7 @@ var init_subscription_probe_command = __esm(() => {
110995
111335
  "request_file_unreadable",
110996
111336
  "request_file_invalid"
110997
111337
  ];
110998
- PROBE_BODY_CAP_BYTES = 512 * 1024;
110999
- PROBE_REQUEST_FILE_CAP_BYTES = 8 * 1024 * 1024;
111000
- JSON_ESCAPE = /\\(?:u([0-9a-fA-F]{4})|(["\\/bfnrt]))/g;
111001
- SIMPLE_ESCAPES = {
111002
- '"': '"',
111003
- "\\": "\\",
111004
- "/": "/",
111005
- b: "\b",
111006
- f: "\f",
111007
- n: `
111008
- `,
111009
- r: "\r",
111010
- t: "\t"
111011
- };
111338
+ PROBE_PROVIDERS = ["antigravity", "devin"];
111012
111339
  });
111013
111340
 
111014
111341
  // src/account-forecast-render.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "14.15.1",
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.1",
75
- "@claudish/magmux-darwin-x64": "14.15.1",
76
- "@claudish/magmux-linux-arm64": "14.15.1",
77
- "@claudish/magmux-linux-x64": "14.15.1"
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",