@goah/cli 0.13.1 → 0.13.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -546,15 +546,15 @@ async function setupPi(current, interaction, scope = "full", setupAuthFile = def
546
546
  const model = selected === "__custom__" ? await interaction.input({ title: "Model ID", description: `Enter the model identifier accepted by ${providerId}.`, prompt: "Model", progress: { current: 3, total: 5 }, ...before?.provider === providerId ? { initial: before.model } : {} }) : selected;
547
547
  if (!model)
548
548
  return null;
549
- if (scope === "model" && before?.provider === providerId)
550
- return { ...before, model };
551
- const config = { provider: providerId, model, thinking: before?.thinking ?? (providerId === "faux" ? "off" : "medium"), authFile: before?.authFile ?? setupAuthFile, authMode: providerId === "faux" || ["ollama", "lm-studio", "llama.cpp"].includes(providerId) ? "local" : "unconfigured" };
549
+ const config = scope === "model" && before?.provider === providerId ? { ...before, model, authFile: before.authFile ?? setupAuthFile } : { provider: providerId, model, thinking: before?.thinking ?? (providerId === "faux" ? "off" : "medium"), authFile: scope === "full" ? setupAuthFile : before?.authFile ?? setupAuthFile, authMode: providerId === "faux" || ["ollama", "lm-studio", "llama.cpp"].includes(providerId) ? "local" : "unconfigured" };
552
550
  const descriptor = providers.find((entry) => entry.id === provider);
553
551
  if (!descriptor.local && provider !== "faux") {
554
- const existing = scope === "model" ? await new JsonCredentialStore(config.authFile).read(providerId) : null;
555
- if (scope === "model")
556
- config.authMode = existing?.type === "oauth" ? "oauth" : existing ? "stored-key" : "unconfigured";
557
- else {
552
+ if (scope === "model") {
553
+ const authenticated = await requireAuthentication(config, descriptor, interaction, legacyCredential);
554
+ if (authenticated === "back")
555
+ return setupPi(current, interaction, scope, setupAuthFile);
556
+ Object.assign(config, authenticated);
557
+ } else {
558
558
  const auth = await configureAuthentication(providerId, descriptor, config.authFile, interaction, legacyCredential);
559
559
  if (auth === "back")
560
560
  return setupPi(current, interaction, scope, setupAuthFile);
@@ -620,6 +620,39 @@ async function configureAuthentication(provider, descriptor, authFile, interacti
620
620
  }
621
621
  return { authMode: "unconfigured" };
622
622
  }
623
+ async function requireAuthentication(config, descriptor, interaction, legacyCredential = false) {
624
+ if (descriptor.local || config.provider === "faux" || ["ollama", "lm-studio", "llama.cpp"].includes(config.provider)) {
625
+ const local = { ...config, authMode: "local" };
626
+ delete local.apiKeyEnv;
627
+ return local;
628
+ }
629
+ const authFile = config.authFile ?? defaultAuthFile();
630
+ const stored = await new JsonCredentialStore(authFile).read(config.provider);
631
+ if (stored) {
632
+ const saved = { ...config, authFile, authMode: stored.type === "oauth" ? "oauth" : "stored-key" };
633
+ delete saved.apiKeyEnv;
634
+ return saved;
635
+ }
636
+ if (environmentAuthenticationAvailable(config))
637
+ return { ...config, authFile, authMode: "environment", apiKeyEnv: config.apiKeyEnv ?? defaultApiKeyEnv(config.provider) };
638
+ const auth = await configureAuthentication(config.provider, descriptor, authFile, interaction, legacyCredential, false, true);
639
+ if (auth === "back")
640
+ return "back";
641
+ const next = { ...config, ...auth, authFile };
642
+ if (auth.authMode !== "environment")
643
+ delete next.apiKeyEnv;
644
+ if (next.authMode === "environment" && !environmentAuthenticationAvailable(next))
645
+ throw new Error(`Environment variable ${next.apiKeyEnv ?? defaultApiKeyEnv(next.provider)} is not set. Set it first or choose \u201CPaste an API key\u201D.`);
646
+ return next;
647
+ }
648
+ function environmentAuthenticationAvailable(config) {
649
+ const key = config.api ? "GOAH_PI_API_KEY" : defaultApiKeyEnv(config.provider);
650
+ try {
651
+ return Boolean(resolveEnvSpec(piEnvironment(config), { root: process.cwd() })[key]);
652
+ } catch {
653
+ return false;
654
+ }
655
+ }
623
656
  async function doctorPi(value, context) {
624
657
  const config = piConfig(value);
625
658
  const env = resolveEnvSpec(piEnvironment(config), { root: context?.root ?? process.cwd() });
@@ -688,7 +721,11 @@ async function runPiCommand(command, args, value, interaction) {
688
721
  const existing = provider === config.provider || provider === "faux" || ["ollama", "lm-studio", "llama.cpp"].includes(provider) ? void 0 : await new JsonCredentialStore(config.authFile ?? defaultAuthFile()).read(provider);
689
722
  const next = provider === config.provider ? { ...config, model } : { provider, model, thinking: config.thinking ?? (provider === "faux" ? "off" : "medium"), authFile: config.authFile ?? defaultAuthFile(), authMode: provider === "faux" || ["ollama", "lm-studio", "llama.cpp"].includes(provider) ? "local" : existing?.type === "oauth" ? "oauth" : existing ? "stored-key" : "unconfigured" };
690
723
  createPiModel(provider, model, piEnvironment(next));
691
- return { config: next, output: [`Pi target changed to ${provider}/${model}`] };
724
+ const descriptor = providerCatalog().find((entry) => entry.id === provider) ?? { id: provider, name: provider, oauth: false, apiKey: true, local: false, modelCount: 0 };
725
+ const authenticated = await requireAuthentication(next, descriptor, interaction);
726
+ if (authenticated === "back")
727
+ return { output: ["No change."] };
728
+ return { config: authenticated, output: [`Pi target changed to ${provider}/${model}`] };
692
729
  }
693
730
  if (command === "auth") {
694
731
  const authFile = config.authFile ?? defaultAuthFile();
@@ -3,7 +3,7 @@ const require = __goahCreateRequire(import.meta.url);
3
3
  import {
4
4
  createPiProcessRunner,
5
5
  piRunnerConfigurator
6
- } from "./chunk-X7UWW2PN.js";
6
+ } from "./chunk-7E7V6OIU.js";
7
7
 
8
8
  // node_modules/.dist-original/runner-registry.js
9
9
  var plugins = /* @__PURE__ */ new Map([
@@ -2,7 +2,7 @@ import { createRequire as __goahCreateRequire } from "node:module";
2
2
  const require = __goahCreateRequire(import.meta.url);
3
3
  import {
4
4
  runnerPlugin
5
- } from "./chunk-VWEV4LTH.js";
5
+ } from "./chunk-D2DVAH37.js";
6
6
  import {
7
7
  SQLITE_SCHEMA_VERSION,
8
8
  SqliteLedger
@@ -16,7 +16,7 @@ import {
16
16
  ProcessRunner,
17
17
  piWorkerPath,
18
18
  resolveEnvSpec
19
- } from "./chunk-X7UWW2PN.js";
19
+ } from "./chunk-7E7V6OIU.js";
20
20
  import {
21
21
  createPiModel
22
22
  } from "./chunk-6M3OOCKO.js";