claudish 7.8.0 → 7.8.2

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 +201 -22
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -581,7 +581,7 @@ var init_onepassword_config = __esm(() => {
581
581
  });
582
582
 
583
583
  // src/version.ts
584
- var VERSION = "7.8.0";
584
+ var VERSION = "7.8.2";
585
585
 
586
586
  // src/providers/onepassword-wasm.ts
587
587
  var exports_onepassword_wasm = {};
@@ -3071,6 +3071,7 @@ __export(exports_onepassword, {
3071
3071
  resolveGlobImport: () => resolveGlobImport,
3072
3072
  resolveDesktopAccount: () => resolveDesktopAccount,
3073
3073
  resetSdkClientCache: () => resetSdkClientCache,
3074
+ recordOpHydratedVars: () => recordOpHydratedVars,
3074
3075
  readEnvironment: () => readEnvironment,
3075
3076
  parseOpFlag: () => parseOpFlag,
3076
3077
  parseGlobImport: () => parseGlobImport,
@@ -3079,6 +3080,7 @@ __export(exports_onepassword, {
3079
3080
  listItems: () => listItems,
3080
3081
  isTransientSdkError: () => isTransientSdkError,
3081
3082
  isOpReference: () => isOpReference,
3083
+ isOpHydratedVar: () => isOpHydratedVar,
3082
3084
  isGlobImport: () => isGlobImport,
3083
3085
  globToRegExp: () => globToRegExp,
3084
3086
  filterGlobFields: () => filterGlobFields,
@@ -3097,6 +3099,15 @@ import { spawnSync } from "child_process";
3097
3099
  function isOpReference(v) {
3098
3100
  return typeof v === "string" && OP_REF_RE.test(v);
3099
3101
  }
3102
+ function recordOpHydratedVars(names) {
3103
+ for (const n of names) {
3104
+ if (typeof n === "string" && n.length > 0)
3105
+ opHydratedVars.add(n);
3106
+ }
3107
+ }
3108
+ function isOpHydratedVar(name) {
3109
+ return !!name && opHydratedVars.has(name);
3110
+ }
3100
3111
  function buildAuthError(detail) {
3101
3112
  return new Error(`${detail}
3102
3113
  ` + "Set OP_SERVICE_ACCOUNT_TOKEN (service account, headless) or OP_ACCOUNT " + "(your 1Password account URL, e.g. my-team.1password.com) for the desktop " + "app \u2014 or set `onepasswordAccount` in ~/.claudish/config.json.");
@@ -3557,7 +3568,7 @@ async function readEnvironment(environmentId, opts = {}) {
3557
3568
  }
3558
3569
  return out;
3559
3570
  }
3560
- var OP_REF_RE, ENV_VAR_NAME_RE, sdkClientCache, defaultSdkClientFactory = async (auth) => {
3571
+ var OP_REF_RE, opHydratedVars, ENV_VAR_NAME_RE, sdkClientCache, defaultSdkClientFactory = async (auth) => {
3561
3572
  const key = sdkAuthCacheKey(auth);
3562
3573
  const cached = sdkClientCache.get(key);
3563
3574
  if (cached)
@@ -3605,6 +3616,7 @@ var OP_REF_RE, ENV_VAR_NAME_RE, sdkClientCache, defaultSdkClientFactory = async
3605
3616
  };
3606
3617
  var init_onepassword = __esm(() => {
3607
3618
  OP_REF_RE = /^op:\/\/[^\s]+$/;
3619
+ opHydratedVars = new Set;
3608
3620
  ENV_VAR_NAME_RE = /^[A-Z_][A-Z0-9_]*$/;
3609
3621
  sdkClientCache = new Map;
3610
3622
  sdkQueue = Promise.resolve();
@@ -38986,7 +38998,7 @@ class ApiKeyCredentialProvider {
38986
38998
  this.oauthFallback = descriptor.oauthFallback;
38987
38999
  }
38988
39000
  resolveSync() {
38989
- return process.env[this.envVar] || this.aliases.find((a) => process.env[a]) || getApiKey(this.envVar);
39001
+ return process.env[this.envVar] || this.aliases.map((a) => process.env[a]).find((v) => !!v) || getApiKey(this.envVar);
38990
39002
  }
38991
39003
  hasOauthFallbackFile() {
38992
39004
  if (!this.oauthFallback)
@@ -40474,7 +40486,13 @@ function makeKimiCredential() {
40474
40486
  return new CompositeCredentialProvider("kimi", new KimiOAuthHalf, new ApiKeyCredentialProvider({
40475
40487
  catalogName: "kimi",
40476
40488
  envVar: "MOONSHOT_API_KEY",
40477
- aliases: ["KIMI_API_KEY", "KIMI_CODING_API_KEY"]
40489
+ aliases: ["KIMI_API_KEY"]
40490
+ }), { fallbackSignal: "OAuth_FALLBACK_TO_API_KEY" });
40491
+ }
40492
+ function makeKimiCodingCredential() {
40493
+ return new CompositeCredentialProvider("kimi-coding", new KimiOAuthHalf, new ApiKeyCredentialProvider({
40494
+ catalogName: "kimi-coding",
40495
+ envVar: "KIMI_CODING_API_KEY"
40478
40496
  }), { fallbackSignal: "OAuth_FALLBACK_TO_API_KEY" });
40479
40497
  }
40480
40498
  var init_kimi_credential = __esm(() => {
@@ -40727,7 +40745,8 @@ class CredentialAuthority {
40727
40745
  const authority = new CredentialAuthority;
40728
40746
  authority.register(makeCodexCredential(), ["openai-codex"]);
40729
40747
  authority.register(new GeminiCodeAssistCredentialProvider, ["gemini-codeassist", "google"]);
40730
- authority.register(makeKimiCredential(), ["kimi", "kimi-coding"]);
40748
+ authority.register(makeKimiCredential(), ["kimi"]);
40749
+ authority.register(makeKimiCodingCredential(), ["kimi-coding"]);
40731
40750
  authority.register(new VertexCredentialProvider, ["vertex"]);
40732
40751
  for (const name of LOCAL_PROVIDER_NAMES) {
40733
40752
  authority.register(new LocalCredentialProvider(name), [name]);
@@ -42096,7 +42115,6 @@ function maskKey(key) {
42096
42115
  }
42097
42116
  function resolveApiKeyProvenance(envVar, aliases) {
42098
42117
  const layers = [];
42099
- const effectiveValue = process.env[envVar] || null;
42100
42118
  let effectiveSource = "not set";
42101
42119
  const allVars = [envVar, ...aliases || []];
42102
42120
  const dotenvValue = readDotenvKey(allVars);
@@ -42136,6 +42154,9 @@ function resolveApiKeyProvenance(envVar, aliases) {
42136
42154
  effectiveSource = "~/.claudish/config.json";
42137
42155
  layers[1].isActive = true;
42138
42156
  layers[2].isActive = false;
42157
+ } else if (isOpHydratedVar(runtimeVar)) {
42158
+ effectiveSource = "1Password";
42159
+ layers[2].source = `process.env[${runtimeVar}] (from 1Password)`;
42139
42160
  } else {
42140
42161
  effectiveSource = "shell environment";
42141
42162
  }
@@ -42182,6 +42203,7 @@ function readConfigKey(envVar) {
42182
42203
  }
42183
42204
  var import_dotenv;
42184
42205
  var init_api_key_provenance = __esm(() => {
42206
+ init_onepassword();
42185
42207
  import_dotenv = __toESM(require_main(), 1);
42186
42208
  });
42187
42209
 
@@ -44243,6 +44265,7 @@ function toProviderDef(def) {
44243
44265
  defaultEndpoint: def.baseUrl || undefined,
44244
44266
  aliases: def.apiKeyAliases,
44245
44267
  isLocal: def.isLocal,
44268
+ publicKeyFallback: !!def.publicKeyFallback,
44246
44269
  oauthSlug: def.oauthLoginSlug
44247
44270
  };
44248
44271
  }
@@ -44259,11 +44282,21 @@ function providerAuthSource(p, config3) {
44259
44282
  return "env";
44260
44283
  if (hasCfg)
44261
44284
  return "cfg";
44285
+ if (p.publicKeyFallback)
44286
+ return "public";
44262
44287
  return null;
44263
44288
  }
44264
44289
  function providerIsReady(p, config3) {
44290
+ if (!p.oauthSlug) {
44291
+ return providerAuthSource(p, config3) !== null;
44292
+ }
44265
44293
  return credentials.isAuthenticated(p.catalogName) || providerAuthSource(p, config3) !== null;
44266
44294
  }
44295
+ function providerIsReadyForDisplay(p, config3, localLiveness) {
44296
+ if (p.isLocal && localLiveness[p.catalogName] === "running")
44297
+ return true;
44298
+ return providerIsReady(p, config3);
44299
+ }
44267
44300
  function providerAuthCapabilities(p, config3) {
44268
44301
  const apiKeySupported = !!p.apiKeyEnvVar;
44269
44302
  const apiKeySet = apiKeySupported && (!!process.env[p.apiKeyEnvVar] || !!config3.apiKeys?.[p.apiKeyEnvVar]);
@@ -63270,6 +63303,48 @@ var init_probe_catalog = __esm(() => {
63270
63303
  PROBE_MODELS_CACHE_PATH = join24(homedir23(), ".claudish", "probe-models.json");
63271
63304
  });
63272
63305
 
63306
+ // src/providers/local-liveness.ts
63307
+ function localBaseUrl(catalogName) {
63308
+ const def = getProviderByName(catalogName);
63309
+ if (!def || !def.isLocal)
63310
+ return null;
63311
+ for (const envVar of def.baseUrlEnvVars ?? []) {
63312
+ const v = process.env[envVar];
63313
+ if (v)
63314
+ return v.replace(/\/+$/, "");
63315
+ }
63316
+ return (def.baseUrl || "").replace(/\/+$/, "") || null;
63317
+ }
63318
+ async function pingLocalProvider(catalogName, timeoutMs = PING_TIMEOUT_MS) {
63319
+ const base = localBaseUrl(catalogName);
63320
+ const path2 = HEALTH_PATH[catalogName];
63321
+ if (!base || !path2)
63322
+ return "unknown";
63323
+ try {
63324
+ await fetch(`${base}${path2}`, {
63325
+ method: "GET",
63326
+ signal: AbortSignal.timeout(timeoutMs)
63327
+ });
63328
+ return "running";
63329
+ } catch {
63330
+ return "down";
63331
+ }
63332
+ }
63333
+ async function pingLocalProviders(catalogNames, timeoutMs = PING_TIMEOUT_MS) {
63334
+ const results = await Promise.all(catalogNames.map(async (name) => [name, await pingLocalProvider(name, timeoutMs)]));
63335
+ return Object.fromEntries(results);
63336
+ }
63337
+ var PING_TIMEOUT_MS = 2000, HEALTH_PATH;
63338
+ var init_local_liveness = __esm(() => {
63339
+ init_provider_definitions();
63340
+ HEALTH_PATH = {
63341
+ ollama: "/api/tags",
63342
+ lmstudio: "/v1/models",
63343
+ vllm: "/v1/models",
63344
+ mlx: "/v1/models"
63345
+ };
63346
+ });
63347
+
63273
63348
  // src/tui/probe-proxy.ts
63274
63349
  async function ensureProbeProxy() {
63275
63350
  if (probeProxy)
@@ -64093,11 +64168,12 @@ function ProvidersContent({
64093
64168
  displayProviders,
64094
64169
  providerIndex,
64095
64170
  testResults,
64171
+ localLiveness,
64096
64172
  contentH,
64097
64173
  isInputMode,
64098
64174
  animTick
64099
64175
  }) {
64100
- const firstUnreadyIdx = displayProviders.findIndex((p) => providerAuthSource(p, config3) === null);
64176
+ const firstUnreadyIdx = displayProviders.findIndex((p) => !providerIsReadyForDisplay(p, config3, localLiveness));
64101
64177
  const hasDivider = firstUnreadyIdx >= 0;
64102
64178
  const listH = contentH - 4 - (hasDivider ? 1 : 0);
64103
64179
  const scrollOffset = (() => {
@@ -64111,7 +64187,7 @@ function ProvidersContent({
64111
64187
  const getRow = (p, idx) => {
64112
64188
  const auth = providerAuthSource(p, config3);
64113
64189
  const caps = providerAuthCapabilities(p, config3);
64114
- const isReady = auth !== null;
64190
+ const isReady = providerIsReadyForDisplay(p, config3, localLiveness);
64115
64191
  const isOauthOnly = auth === "oauth";
64116
64192
  const selected = idx === providerIndex;
64117
64193
  const tr = testResults[p.name];
@@ -64123,6 +64199,8 @@ function ProvidersContent({
64123
64199
  keyDisplay = "local";
64124
64200
  } else if (isOauthOnly) {
64125
64201
  keyDisplay = "oauth\xB7\xB7\xB7";
64202
+ } else if (auth === "public") {
64203
+ keyDisplay = "free";
64126
64204
  } else if (auth === "cfg") {
64127
64205
  keyDisplay = maskKey2(config3.apiKeys?.[p.apiKeyEnvVar]);
64128
64206
  } else if (auth === "env" || auth === "e+c") {
@@ -64133,6 +64211,24 @@ function ProvidersContent({
64133
64211
  const isFirstUnready = idx === firstUnreadyIdx;
64134
64212
  let statusFg = isReady ? C.green : C.dim;
64135
64213
  let statusText = p.isLocal ? isReady ? "enabled" : "disabled" : isReady ? "ready" : "not set";
64214
+ if (p.isLocal) {
64215
+ const live = localLiveness[p.catalogName];
64216
+ const enabled = providerAuthSource(p, config3) !== null;
64217
+ if (enabled) {
64218
+ if (live === "running") {
64219
+ statusFg = C.green;
64220
+ statusText = "running";
64221
+ } else if (live === "down") {
64222
+ statusFg = C.yellow;
64223
+ statusText = "down";
64224
+ }
64225
+ } else {
64226
+ if (live === "running") {
64227
+ statusFg = C.cyan;
64228
+ statusText = "running \xB7 off";
64229
+ }
64230
+ }
64231
+ }
64136
64232
  if (tr) {
64137
64233
  if (tr.status === "testing") {
64138
64234
  statusFg = C.yellow;
@@ -64368,13 +64464,15 @@ function ProviderDetail({
64368
64464
  hasCfgKey,
64369
64465
  hasEnvKey,
64370
64466
  hasKey,
64467
+ isOpKey,
64468
+ isPublicKey,
64371
64469
  cfgKeyMask,
64372
64470
  envKeyMask,
64373
64471
  activeEndpoint,
64374
64472
  testResults,
64375
64473
  isInputMode
64376
64474
  }) {
64377
- const displayKey = selectedProvider.isLocal ? hasKey ? "enabled" : "disabled" : hasEnvKey ? envKeyMask : hasCfgKey ? cfgKeyMask : "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500";
64475
+ const displayKey = selectedProvider.isLocal ? hasKey ? "enabled" : "disabled" : hasEnvKey ? envKeyMask : hasCfgKey ? cfgKeyMask : isPublicKey ? "free" : "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500";
64378
64476
  if (isInputMode) {
64379
64477
  return /* @__PURE__ */ jsxDEV6("box", {
64380
64478
  height: DETAIL_H,
@@ -64498,7 +64596,25 @@ function ProviderDetail({
64498
64596
  }, undefined, false, undefined, this)
64499
64597
  ]
64500
64598
  }, undefined, true, undefined, this),
64501
- hasKey && !selectedProvider.isLocal && /* @__PURE__ */ jsxDEV6(Fragment3, {
64599
+ hasKey && !selectedProvider.isLocal && isPublicKey && /* @__PURE__ */ jsxDEV6(Fragment3, {
64600
+ children: [
64601
+ /* @__PURE__ */ jsxDEV6("span", {
64602
+ fg: C.dim,
64603
+ children: " "
64604
+ }, undefined, false, undefined, this),
64605
+ /* @__PURE__ */ jsxDEV6("span", {
64606
+ fg: C.blue,
64607
+ attributes: A.bold,
64608
+ children: "From: "
64609
+ }, undefined, false, undefined, this),
64610
+ /* @__PURE__ */ jsxDEV6("span", {
64611
+ fg: C.green,
64612
+ attributes: A.bold,
64613
+ children: "public key (free)"
64614
+ }, undefined, false, undefined, this)
64615
+ ]
64616
+ }, undefined, true, undefined, this),
64617
+ hasKey && !selectedProvider.isLocal && !isPublicKey && /* @__PURE__ */ jsxDEV6(Fragment3, {
64502
64618
  children: [
64503
64619
  /* @__PURE__ */ jsxDEV6("span", {
64504
64620
  fg: C.dim,
@@ -64512,7 +64628,7 @@ function ProviderDetail({
64512
64628
  hasEnvKey && /* @__PURE__ */ jsxDEV6("span", {
64513
64629
  fg: C.green,
64514
64630
  attributes: A.bold,
64515
- children: "env"
64631
+ children: isOpKey ? "1Password" : "env"
64516
64632
  }, undefined, false, undefined, this),
64517
64633
  hasEnvKey && hasCfgKey && /* @__PURE__ */ jsxDEV6("span", {
64518
64634
  fg: C.fgMuted,
@@ -67728,6 +67844,7 @@ function App({ requestLogin } = {}) {
67728
67844
  const [editingExistingPattern, setEditingExistingPattern] = useState5(null);
67729
67845
  const [statusMsg, setStatusMsg] = useState5(null);
67730
67846
  const [testResults, setTestResults] = useState5({});
67847
+ const [localLiveness, setLocalLiveness] = useState5({});
67731
67848
  const [animTick, setAnimTick] = useState5(0);
67732
67849
  const anyTesting = useMemo2(() => Object.values(testResults).some((r) => r?.status === "testing"), [testResults]);
67733
67850
  useEffect4(() => {
@@ -67736,6 +67853,25 @@ function App({ requestLogin } = {}) {
67736
67853
  const id = setInterval(() => setAnimTick((tick) => (tick + 1) % 1e6), 90);
67737
67854
  return () => clearInterval(id);
67738
67855
  }, [anyTesting]);
67856
+ useEffect4(() => {
67857
+ if (activeTab !== "providers")
67858
+ return;
67859
+ let cancelled = false;
67860
+ const localNames = PROVIDERS.filter((p) => p.isLocal).map((p) => p.catalogName);
67861
+ if (localNames.length === 0)
67862
+ return;
67863
+ const sweep = async () => {
67864
+ const map3 = await pingLocalProviders(localNames);
67865
+ if (!cancelled)
67866
+ setLocalLiveness(map3);
67867
+ };
67868
+ sweep();
67869
+ const id = setInterval(() => void sweep(), 1e4);
67870
+ return () => {
67871
+ cancelled = true;
67872
+ clearInterval(id);
67873
+ };
67874
+ }, [activeTab]);
67739
67875
  const [profileIndex, setProfileIndex] = useState5(0);
67740
67876
  const [opIndex, setOpIndex] = useState5(0);
67741
67877
  const [opScopeCursor, setOpScopeCursor] = useState5(0);
@@ -67765,13 +67901,13 @@ function App({ requestLogin } = {}) {
67765
67901
  const quit = useCallback3(() => renderer.destroy(), [renderer]);
67766
67902
  const displayProviders = useMemo2(() => {
67767
67903
  return [...PROVIDERS].sort((a, b) => {
67768
- const aReady = providerIsReady(a, config3);
67769
- const bReady = providerIsReady(b, config3);
67904
+ const aReady = providerIsReadyForDisplay(a, config3, localLiveness);
67905
+ const bReady = providerIsReadyForDisplay(b, config3, localLiveness);
67770
67906
  if (aReady === bReady)
67771
67907
  return PROVIDERS.indexOf(a) - PROVIDERS.indexOf(b);
67772
67908
  return aReady ? -1 : 1;
67773
67909
  });
67774
- }, [config3]);
67910
+ }, [config3, localLiveness]);
67775
67911
  const selectedProvider = displayProviders[providerIndex];
67776
67912
  const selectedProviderDef = getProviderByName(selectedProvider.catalogName);
67777
67913
  const selectedProviderIsLocal = !!(selectedProvider.isLocal || selectedProviderDef?.isLocal);
@@ -67781,6 +67917,15 @@ function App({ requestLogin } = {}) {
67781
67917
  setBufStats(getBufferStats());
67782
67918
  setOpTick((t) => t + 1);
67783
67919
  }, []);
67920
+ const clearTestResult = useCallback3((provName) => {
67921
+ setTestResults((prev) => {
67922
+ if (!(provName in prev))
67923
+ return prev;
67924
+ const next = { ...prev };
67925
+ delete next[provName];
67926
+ return next;
67927
+ });
67928
+ }, []);
67784
67929
  const probe = useRouteProbe(config3);
67785
67930
  const { probeMode, probeModel, probeResults } = probe;
67786
67931
  const wizard = useProfileWizard({ mode, setMode, refreshConfig, setStatusMsg });
@@ -67793,7 +67938,9 @@ function App({ requestLogin } = {}) {
67793
67938
  } = wizard;
67794
67939
  const hasCfgKey = !!config3.apiKeys?.[selectedProvider.apiKeyEnvVar];
67795
67940
  const hasEnvKey = !!process.env[selectedProvider.apiKeyEnvVar];
67796
- const hasKey = hasCfgKey || hasEnvKey || selectedLocalEnabled;
67941
+ const selectedPublicKey = !!selectedProvider.publicKeyFallback && !hasCfgKey && !hasEnvKey;
67942
+ const hasKey = hasCfgKey || hasEnvKey || selectedLocalEnabled || selectedPublicKey;
67943
+ const isOpKey = hasEnvKey && isOpHydratedVar(selectedProvider.apiKeyEnvVar);
67797
67944
  const cfgKeyMask = maskKey2(config3.apiKeys?.[selectedProvider.apiKeyEnvVar]);
67798
67945
  const envKeyMask = maskKey2(process.env[selectedProvider.apiKeyEnvVar]);
67799
67946
  const activeEndpointEnvVar = selectedProvider.endpointEnvVar;
@@ -68141,6 +68288,20 @@ function App({ requestLogin } = {}) {
68141
68288
  const runProbeTest = useCallback3(async (prov) => {
68142
68289
  const provName = prov.name;
68143
68290
  setTestResults((prev) => ({ ...prev, [provName]: { status: "testing" } }));
68291
+ if (prov.isLocal) {
68292
+ const live = await pingLocalProvider(prov.catalogName);
68293
+ if (live === "down") {
68294
+ const base = localBaseUrl(prov.catalogName);
68295
+ setTestResults((prev) => ({
68296
+ ...prev,
68297
+ [provName]: {
68298
+ status: "failed",
68299
+ error: `not running${base ? ` (${base} unreachable)` : ""}`
68300
+ }
68301
+ }));
68302
+ return;
68303
+ }
68304
+ }
68144
68305
  const outcome = await ensureProbeModelsCached();
68145
68306
  if (outcome.kind !== "ok") {
68146
68307
  setTestResults((prev) => ({
@@ -68292,6 +68453,7 @@ function App({ requestLogin } = {}) {
68292
68453
  }
68293
68454
  invalidateProbeProxyHandlers(selectedProvider.catalogName);
68294
68455
  invalidateProbeDiscovery(selectedProvider.catalogName);
68456
+ clearTestResult(selectedProvider.name);
68295
68457
  refreshConfig();
68296
68458
  setInputValue("");
68297
68459
  setMode("browse");
@@ -68809,6 +68971,7 @@ function App({ requestLogin } = {}) {
68809
68971
  if (changed) {
68810
68972
  invalidateProbeProxyHandlers(selectedProvider.catalogName);
68811
68973
  invalidateProbeDiscovery(selectedProvider.catalogName);
68974
+ clearTestResult(selectedProvider.name);
68812
68975
  refreshConfig();
68813
68976
  setStatusMsg(`Stored config removed for ${selectedProvider.displayName}.`);
68814
68977
  } else {
@@ -68830,7 +68993,8 @@ function App({ requestLogin } = {}) {
68830
68993
  } else if (key.raw === "T") {
68831
68994
  const fired = [];
68832
68995
  for (const prov of PROVIDERS) {
68833
- if (!providerIsReady(prov, config3))
68996
+ const localRunning = prov.isLocal && localLiveness[prov.catalogName] === "running";
68997
+ if (!providerIsReady(prov, config3) && !localRunning)
68834
68998
  continue;
68835
68999
  fired.push(prov.displayName);
68836
69000
  runProbeTest(prov);
@@ -68843,10 +69007,11 @@ function App({ requestLogin } = {}) {
68843
69007
  }
68844
69008
  } else if (key.name === "t") {
68845
69009
  const caps = providerAuthCapabilities(selectedProvider, config3);
68846
- const ready = providerIsReady(selectedProvider, config3);
69010
+ const localRunning = selectedProviderIsLocal && localLiveness[selectedProvider.catalogName] === "running";
69011
+ const ready = providerIsReady(selectedProvider, config3) || localRunning;
68847
69012
  if (!ready) {
68848
69013
  if (selectedProviderIsLocal) {
68849
- setStatusMsg(`${selectedProvider.displayName}: disabled. Press e to enable in global config.`);
69014
+ setStatusMsg(`${selectedProvider.displayName}: not running / disabled. Start the server, or press e to enable.`);
68850
69015
  } else if (caps.apiKey.supported && caps.oauth.supported) {
68851
69016
  setStatusMsg(`${selectedProvider.displayName}: no credentials. Press s to set a key or l to login.`);
68852
69017
  } else if (caps.oauth.supported) {
@@ -69156,6 +69321,7 @@ function App({ requestLogin } = {}) {
69156
69321
  displayProviders,
69157
69322
  providerIndex,
69158
69323
  testResults,
69324
+ localLiveness,
69159
69325
  contentH,
69160
69326
  isInputMode,
69161
69327
  animTick
@@ -69169,6 +69335,8 @@ function App({ requestLogin } = {}) {
69169
69335
  hasCfgKey,
69170
69336
  hasEnvKey,
69171
69337
  hasKey,
69338
+ isOpKey,
69339
+ isPublicKey: selectedPublicKey,
69172
69340
  cfgKeyMask,
69173
69341
  envKeyMask,
69174
69342
  activeEndpoint,
@@ -69303,6 +69471,7 @@ var init_App = __esm(() => {
69303
69471
  init_probe_discovery();
69304
69472
  init_probe_live();
69305
69473
  init_probe_runner();
69474
+ init_local_liveness();
69306
69475
  init_stats_buffer();
69307
69476
  init_providers();
69308
69477
  init_theme2();
@@ -70375,13 +70544,14 @@ async function applyOpEnvironment() {
70375
70544
  if (envIds.length === 0)
70376
70545
  return;
70377
70546
  try {
70378
- const { readEnvironment: readEnvironment2 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
70547
+ const { readEnvironment: readEnvironment2, recordOpHydratedVars: recordOpHydratedVars2 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
70379
70548
  const auth = await getSdkAuth();
70380
70549
  for (const envId of envIds) {
70381
70550
  const vars = await readEnvironment2(envId, { auth });
70382
70551
  for (const [key, value] of Object.entries(vars)) {
70383
70552
  process.env[key] = value;
70384
70553
  }
70554
+ recordOpHydratedVars2(Object.keys(vars));
70385
70555
  }
70386
70556
  } catch (err) {
70387
70557
  const message = err instanceof Error ? err.message : String(err);
@@ -70413,12 +70583,13 @@ async function applyOpImport() {
70413
70583
  process.exit(0);
70414
70584
  }
70415
70585
  try {
70416
- const { resolveGlobImport: resolveGlobImport2 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
70586
+ const { resolveGlobImport: resolveGlobImport2, recordOpHydratedVars: recordOpHydratedVars2 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
70417
70587
  const auth = await getSdkAuth();
70418
70588
  const resolved = await resolveGlobImport2(glob, { auth });
70419
70589
  for (const [key, value] of Object.entries(resolved)) {
70420
70590
  process.env[key] = value;
70421
70591
  }
70592
+ recordOpHydratedVars2(Object.keys(resolved));
70422
70593
  } catch (err) {
70423
70594
  const message = err instanceof Error ? err.message : String(err);
70424
70595
  console.error(`[claudish] 1Password --op import failed: ${message}`);
@@ -70483,13 +70654,19 @@ async function loadStoredApiKeys(neededEnvVars) {
70483
70654
  if (refKeys.length === 0 && globImports.length === 0)
70484
70655
  return;
70485
70656
  try {
70486
- const { resolveSecrets: resolveSecrets2, resolveGlobImport: resolveGlobImport2, resolveGlobImportForEnvVars: resolveGlobImportForEnvVars2 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
70657
+ const {
70658
+ resolveSecrets: resolveSecrets2,
70659
+ resolveGlobImport: resolveGlobImport2,
70660
+ resolveGlobImportForEnvVars: resolveGlobImportForEnvVars2,
70661
+ recordOpHydratedVars: recordOpHydratedVars2
70662
+ } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
70487
70663
  const auth = await getSdkAuth();
70488
70664
  if (refKeys.length > 0) {
70489
70665
  const resolved = await resolveSecrets2(opRefs, { auth });
70490
70666
  for (const [envVar, value] of Object.entries(resolved)) {
70491
70667
  process.env[envVar] = value;
70492
70668
  }
70669
+ recordOpHydratedVars2(Object.keys(resolved));
70493
70670
  }
70494
70671
  for (const globPath of globImports) {
70495
70672
  try {
@@ -70503,6 +70680,7 @@ async function loadStoredApiKeys(neededEnvVars) {
70503
70680
  for (const [envVar, value] of Object.entries(resolved)) {
70504
70681
  if (!process.env[envVar]) {
70505
70682
  process.env[envVar] = value;
70683
+ recordOpHydratedVars2([envVar]);
70506
70684
  }
70507
70685
  }
70508
70686
  } catch (globErr) {
@@ -70546,12 +70724,13 @@ async function applyCustomEndpointOpKeys(neededEnvVars) {
70546
70724
  if (Object.keys(refs).length === 0)
70547
70725
  return;
70548
70726
  try {
70549
- const { resolveSecrets: resolveSecrets2 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
70727
+ const { resolveSecrets: resolveSecrets2, recordOpHydratedVars: recordOpHydratedVars2 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
70550
70728
  const auth = await getSdkAuth();
70551
70729
  const resolved = await resolveSecrets2(refs, { auth });
70552
70730
  for (const [envVar, value] of Object.entries(resolved)) {
70553
70731
  process.env[envVar] = value;
70554
70732
  }
70733
+ recordOpHydratedVars2(Object.keys(resolved));
70555
70734
  } catch (err) {
70556
70735
  const message = err instanceof Error ? err.message : String(err);
70557
70736
  console.error(`[claudish] 1Password custom-endpoint key resolution failed: ${message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "7.8.0",
3
+ "version": "7.8.2",
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",
@@ -60,10 +60,10 @@
60
60
  "ai"
61
61
  ],
62
62
  "optionalDependencies": {
63
- "@claudish/magmux-darwin-arm64": "7.8.0",
64
- "@claudish/magmux-darwin-x64": "7.8.0",
65
- "@claudish/magmux-linux-arm64": "7.8.0",
66
- "@claudish/magmux-linux-x64": "7.8.0"
63
+ "@claudish/magmux-darwin-arm64": "7.8.2",
64
+ "@claudish/magmux-darwin-x64": "7.8.2",
65
+ "@claudish/magmux-linux-arm64": "7.8.2",
66
+ "@claudish/magmux-linux-x64": "7.8.2"
67
67
  },
68
68
  "author": "Jack Rudenko <i@madappgang.com>",
69
69
  "license": "MIT",