@mrciphersmith/keryx 0.2.24 → 0.2.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +77 -12
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -8068,7 +8068,7 @@ function providerByName(name) {
8068
8068
  async function fetchOpenAiCompatModelsDetailed(fetchFn, provider, apiKey, opts) {
8069
8069
  const url = `${provider.baseUrl.replace(/\/+$/, "")}${provider.modelsPath ?? DEFAULT_MODELS_PATH}`;
8070
8070
  const timeoutMs = opts?.timeoutMs ?? MODELS_FETCH_TIMEOUT_MS;
8071
- const fallback = { models: [...provider.models], source: "fallback" };
8071
+ const fallback = { models: [], source: "fallback" };
8072
8072
  const controller = new AbortController;
8073
8073
  const timer = setTimeout(() => controller.abort(), timeoutMs);
8074
8074
  try {
@@ -8188,7 +8188,7 @@ var init_providers = __esm(() => {
8188
8188
  requiresApiKey: false,
8189
8189
  allowLoopback: true,
8190
8190
  platforms: ["darwin"],
8191
- models: ["qwen3.5-9b-4bit"],
8191
+ models: [],
8192
8192
  note: "local \xB7 no key"
8193
8193
  },
8194
8194
  {
@@ -9908,6 +9908,7 @@ var exports_shell_config = {};
9908
9908
  __export(exports_shell_config, {
9909
9909
  shellConfigPath: () => shellConfigPath,
9910
9910
  saveShellConfig: () => saveShellConfig,
9911
+ saveProviderBaseUrl: () => saveProviderBaseUrl,
9911
9912
  saveApiKey: () => saveApiKey,
9912
9913
  loadShellConfig: () => loadShellConfig,
9913
9914
  envWithSavedApiKeys: () => envWithSavedApiKeys,
@@ -9946,6 +9947,10 @@ function saveApiKey(envKey, value, dir) {
9946
9947
  const existing = loadShellConfig(dir).apiKeys ?? {};
9947
9948
  saveShellConfig({ apiKeys: { ...existing, [envKey]: value } }, dir);
9948
9949
  }
9950
+ function saveProviderBaseUrl(provider, baseUrl, dir) {
9951
+ const existing = loadShellConfig(dir).baseUrls ?? {};
9952
+ saveShellConfig({ baseUrls: { ...existing, [provider]: baseUrl } }, dir);
9953
+ }
9949
9954
  function envWithSavedApiKeys(env = process.env, dir) {
9950
9955
  const merged = { ...env };
9951
9956
  try {
@@ -40353,7 +40358,7 @@ var AGENT_SLASH_COMMANDS = [
40353
40358
  description: "Switch provider / API key",
40354
40359
  modes: BOTH,
40355
40360
  modeDescriptions: {
40356
- agent: "Switch provider / API key (interactive picker, key entry)",
40361
+ agent: "Switch connected provider (interactive picker)",
40357
40362
  chat: "Show how to set a provider API key in the environment"
40358
40363
  }
40359
40364
  },
@@ -40362,7 +40367,7 @@ var AGENT_SLASH_COMMANDS = [
40362
40367
  description: "Switch provider \u2014 /provider <name>, or no arg to re-select",
40363
40368
  modes: BOTH,
40364
40369
  modeDescriptions: {
40365
- agent: "Switch provider / API key (interactive picker)"
40370
+ agent: "Add or configure a provider (interactive picker)"
40366
40371
  }
40367
40372
  },
40368
40373
  { name: "/think", description: "Expand the last reasoning block", modes: AGENT_ONLY },
@@ -43536,6 +43541,34 @@ function onKeypress3(r, handler) {
43536
43541
  r._internalKeyInput.onInternal("keypress", handler);
43537
43542
  return () => r._internalKeyInput.offInternal("keypress", handler);
43538
43543
  }
43544
+ function promptBaseUrlStep(otui, r, label, baseUrl) {
43545
+ return new Promise((resolve3) => {
43546
+ const box = overlayBox(otui, r, "base-url-picker");
43547
+ r.root.add(box);
43548
+ box.add(new otui.TextRenderable(r, { id: "bp-title", content: otui.t`${otui.bold(`${label} endpoint URL`)} ${otui.dim("(Enter \xB7 Esc to go back)")}` }));
43549
+ box.add(new otui.TextRenderable(r, { id: "bp-note", content: otui.t`${otui.dim("Edit host and port before discovering models")}`, marginTop: 1 }));
43550
+ const input2 = new otui.InputRenderable(r, { id: "bp-input", value: baseUrl, marginTop: 1 });
43551
+ box.add(input2);
43552
+ input2.focus();
43553
+ const cleanup = () => {
43554
+ unsub();
43555
+ r.root.remove(box);
43556
+ };
43557
+ const unsub = onKeypress3(r, (key) => {
43558
+ if (key.name === "escape") {
43559
+ cleanup();
43560
+ resolve3(undefined);
43561
+ key.preventDefault();
43562
+ key.stopPropagation();
43563
+ }
43564
+ });
43565
+ input2.on(otui.InputRenderableEvents.ENTER, () => {
43566
+ const value = input2.value.trim();
43567
+ cleanup();
43568
+ resolve3(value.length > 0 ? value : undefined);
43569
+ });
43570
+ });
43571
+ }
43539
43572
  function promptApiKeyStep(otui, r, opts) {
43540
43573
  return new Promise((resolve3) => {
43541
43574
  const box = overlayBox(otui, r, "key-picker");
@@ -43622,6 +43655,13 @@ function selectProviderModelInTui(otui, r, detected) {
43622
43655
  resolve3(undefined);
43623
43656
  return;
43624
43657
  }
43658
+ const selectedBaseUrl = prov.baseUrl !== undefined ? await promptBaseUrlStep(otui, r, prov.label ?? prov.name, prov.baseUrl) : prov.baseUrl;
43659
+ if (prov.baseUrl !== undefined && selectedBaseUrl === undefined) {
43660
+ continue;
43661
+ }
43662
+ if (selectedBaseUrl !== undefined)
43663
+ saveProviderBaseUrl(prov.name, selectedBaseUrl);
43664
+ const selectedProvider = selectedBaseUrl === undefined ? prov : { ...prov, baseUrl: selectedBaseUrl };
43625
43665
  const envKey = prov.envKey;
43626
43666
  if (envKey !== undefined) {
43627
43667
  const existingKey = process.env[envKey];
@@ -43636,12 +43676,12 @@ function selectProviderModelInTui(otui, r, detected) {
43636
43676
  }
43637
43677
  }
43638
43678
  }
43639
- const models = await modelsForPicker(prov);
43679
+ const models = await modelsForPicker(selectedProvider);
43640
43680
  const model = await pickModelInTui(otui, r, models);
43641
43681
  if (model === undefined) {
43642
43682
  continue;
43643
43683
  }
43644
- resolve3(prov.baseUrl === undefined ? { provider: prov.name, model } : { provider: prov.name, model, baseUrl: prov.baseUrl });
43684
+ resolve3(selectedBaseUrl === undefined ? { provider: prov.name, model } : { provider: prov.name, model, baseUrl: selectedBaseUrl });
43645
43685
  return;
43646
43686
  }
43647
43687
  })();
@@ -43649,7 +43689,8 @@ function selectProviderModelInTui(otui, r, detected) {
43649
43689
  }
43650
43690
  function pickModelInTui(otui, r, models) {
43651
43691
  return new Promise((resolve3) => {
43652
- const all = models.length > 0 ? models : ["fake-echo"];
43692
+ const all = models;
43693
+ const NO_MODELS = "(no models found)";
43653
43694
  const box = overlayBox(otui, r, "model-picker");
43654
43695
  r.root.add(box);
43655
43696
  box.add(new otui.TextRenderable(r, { id: "mp-title", content: otui.t`${otui.bold("Select a model")}` }));
@@ -43663,7 +43704,7 @@ function pickModelInTui(otui, r, models) {
43663
43704
  height: 14,
43664
43705
  showScrollIndicator: true,
43665
43706
  wrapSelection: true,
43666
- options: all.map((m) => ({ name: m, description: "" })),
43707
+ options: (all.length > 0 ? all : [NO_MODELS]).map((m) => ({ name: m, description: "" })),
43667
43708
  selectedTextColor: "#ffd166"
43668
43709
  });
43669
43710
  box.add(sel);
@@ -43706,7 +43747,7 @@ function pickModelInTui(otui, r, models) {
43706
43747
  sel.on(otui.SelectRenderableEvents.ITEM_SELECTED, () => {
43707
43748
  const chosen = sel.getSelectedOption();
43708
43749
  cleanup();
43709
- resolve3(chosen === null || chosen.name === NO_MATCH ? undefined : chosen.name);
43750
+ resolve3(chosen === null || chosen.name === NO_MATCH || chosen.name === NO_MODELS ? undefined : chosen.name);
43710
43751
  });
43711
43752
  });
43712
43753
  }
@@ -44680,7 +44721,24 @@ Staying in the current session.
44680
44721
  if (command.name === "/connect" || command.name === "/provider") {
44681
44722
  (async () => {
44682
44723
  const detected = opts.redetect !== undefined ? await opts.redetect() : opts.detected;
44683
- const ns = await chrome.withOverlay(() => selectProviderModelInTui(otui, r, detected));
44724
+ const candidates = command.name === "/provider" ? detected : (await Promise.all(detected.map(async (provider) => {
44725
+ if (provider.name === "fake")
44726
+ return;
44727
+ if (provider.name === "rapid-mlx") {
44728
+ return (await modelsForPicker(provider)).length > 0 ? provider : undefined;
44729
+ }
44730
+ if (provider.envKey !== undefined) {
44731
+ return process.env[provider.envKey]?.length ? provider : undefined;
44732
+ }
44733
+ return provider;
44734
+ }))).filter((provider) => provider !== undefined);
44735
+ if (candidates.length === 0) {
44736
+ io.onSystem?.(`No connected providers found. Use /provider to add or configure one.
44737
+ `);
44738
+ input2.focus();
44739
+ return;
44740
+ }
44741
+ const ns = await chrome.withOverlay(() => selectProviderModelInTui(otui, r, candidates));
44684
44742
  if (ns !== undefined) {
44685
44743
  await switchTo(ns);
44686
44744
  } else {
@@ -45198,7 +45256,7 @@ init_shell_config();
45198
45256
  // package.json
45199
45257
  var package_default = {
45200
45258
  name: "@mrciphersmith/keryx",
45201
- version: "0.2.24",
45259
+ version: "0.2.25",
45202
45260
  description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
45203
45261
  private: false,
45204
45262
  publishConfig: {
@@ -46309,7 +46367,14 @@ async function resolveTuiStartup(opts) {
46309
46367
  appliedKeys
46310
46368
  };
46311
46369
  }
46312
- return { detected: await opts.detect(), appliedKeys };
46370
+ const detected = await opts.detect();
46371
+ return {
46372
+ detected: detected.map((provider) => {
46373
+ const savedBaseUrl = savedCfg.baseUrls?.[provider.name];
46374
+ return typeof savedBaseUrl === "string" && savedBaseUrl.length > 0 ? { ...provider, baseUrl: savedBaseUrl } : provider;
46375
+ }),
46376
+ appliedKeys
46377
+ };
46313
46378
  }
46314
46379
  function parseShellCliFlags(args2) {
46315
46380
  let providerArg;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrciphersmith/keryx",
3
- "version": "0.2.24",
3
+ "version": "0.2.25",
4
4
  "description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
5
5
  "private": false,
6
6
  "publishConfig": {