@minniexcode/codex-switch 0.0.8 → 0.0.10

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 (44) hide show
  1. package/README.AI.md +5 -3
  2. package/README.CN.md +25 -3
  3. package/README.md +3 -2
  4. package/dist/app/add-provider.js +1 -12
  5. package/dist/app/bridge.js +295 -0
  6. package/dist/app/edit-provider.js +1 -17
  7. package/dist/app/get-status.js +32 -2
  8. package/dist/app/list-providers.js +0 -1
  9. package/dist/app/run-doctor.js +45 -38
  10. package/dist/app/setup-codex.js +27 -17
  11. package/dist/app/show-config.js +1 -5
  12. package/dist/app/switch-provider.js +33 -20
  13. package/dist/cli/output.js +4 -6
  14. package/dist/cli.js +1 -1
  15. package/dist/commands/handlers.js +223 -39
  16. package/dist/commands/help.js +1 -0
  17. package/dist/commands/registry.js +48 -4
  18. package/dist/domain/config.js +4 -68
  19. package/dist/domain/providers.js +0 -5
  20. package/dist/domain/runtime-state.js +2 -1
  21. package/dist/domain/setup.js +58 -3
  22. package/dist/interaction/add-interactive.js +55 -1
  23. package/dist/interaction/interactive.js +1 -5
  24. package/dist/runtime/copilot-adapter.js +44 -1
  25. package/dist/runtime/copilot-bridge-worker.js +1 -1
  26. package/dist/runtime/copilot-bridge.js +60 -19
  27. package/dist/runtime/copilot-cli.js +70 -0
  28. package/dist/runtime/copilot-installer.js +49 -2
  29. package/dist/storage/auth-repo.js +28 -77
  30. package/dist/storage/config-repo.js +1 -36
  31. package/dist/storage/runtime-state-repo.js +32 -0
  32. package/docs/Design/codex-switch-copilot-integration-design.md +517 -0
  33. package/docs/Design/codex-switch-v0.0.10-design.md +669 -0
  34. package/docs/Design/codex-switch-v0.0.9-design.md +182 -0
  35. package/docs/PRD/codex-switch-prd-v0.0.10.md +406 -0
  36. package/docs/PRD/codex-switch-prd-v0.0.9.md +166 -0
  37. package/docs/Tests/testing-bridge-v0.0.9.md +367 -0
  38. package/docs/cli-usage.md +38 -14
  39. package/docs/codex-switch-product-overview.md +2 -2
  40. package/docs/codex-switch-technical-architecture.md +6 -5
  41. package/package.json +1 -1
  42. /package/docs/{test-report-0.0.5.md → Tests/test-report-0.0.5.md} +0 -0
  43. /package/docs/{test-report-0.0.7.md → Tests/test-report-0.0.7.md} +0 -0
  44. /package/docs/{testing.md → Tests/testing.md} +0 -0
@@ -46,6 +46,7 @@ const providers_1 = require("../domain/providers");
46
46
  const copilot_installer_1 = require("../runtime/copilot-installer");
47
47
  const copilot_bridge_1 = require("../runtime/copilot-bridge");
48
48
  const copilot_adapter_1 = require("../runtime/copilot-adapter");
49
+ const runtime_state_repo_1 = require("../storage/runtime-state-repo");
49
50
  /**
50
51
  * Performs consistency checks across config.toml, providers.json, and the local Codex CLI.
51
52
  */
@@ -101,7 +102,9 @@ async function runDoctor(args) {
101
102
  });
102
103
  }
103
104
  }
104
- const authState = (0, auth_repo_1.readManagedAuthState)(args.authPath);
105
+ const authState = (0, auth_repo_1.readAuthFileState)(args.authPath);
106
+ const runtimeStateInspection = (0, runtime_state_repo_1.inspectCopilotBridgeState)();
107
+ const runtimeState = runtimeStateInspection.state;
105
108
  if (authState.exists && !authState.valid) {
106
109
  issues.push({
107
110
  code: "AUTH_JSON_INVALID",
@@ -109,34 +112,16 @@ async function runDoctor(args) {
109
112
  file: args.authPath,
110
113
  });
111
114
  }
115
+ if (runtimeStateInspection.exists && !runtimeStateInspection.valid) {
116
+ issues.push({
117
+ code: "BRIDGE_STATE_STALE",
118
+ message: `Copilot bridge runtime state is unreadable: ${runtimeStateInspection.parseError ?? "unknown parse failure"}`,
119
+ });
120
+ }
112
121
  if (document?.activeProfile && providers) {
113
122
  const matches = (0, providers_1.findProvidersByProfile)(providers, document.activeProfile);
114
123
  if (matches.length === 1) {
115
124
  const activeProvider = providers.providers[matches[0]];
116
- const payload = authState.payload ?? {};
117
- const actualKeys = authState.managedSecretKeys;
118
- if (authState.authMode !== null && authState.authMode !== "apikey") {
119
- issues.push({
120
- code: "AUTH_JSON_INVALID",
121
- message: `auth.json auth_mode must be "apikey", found "${authState.authMode}".`,
122
- });
123
- }
124
- if (!actualKeys.includes(activeProvider.envKey) || actualKeys.length !== 1) {
125
- issues.push({
126
- code: "AUTH_JSON_ENV_KEY_MISMATCH",
127
- message: `auth.json managed env key does not match active provider "${matches[0]}".`,
128
- provider: matches[0],
129
- expectedEnvKey: activeProvider.envKey,
130
- actualEnvKeys: actualKeys,
131
- });
132
- }
133
- if (payload[activeProvider.envKey] !== activeProvider.apiKey) {
134
- issues.push({
135
- code: "AUTH_JSON_APIKEY_MISMATCH",
136
- message: `auth.json secret value does not match active provider "${matches[0]}".`,
137
- provider: matches[0],
138
- });
139
- }
140
125
  if ((0, providers_1.isCopilotBridgeProvider)(activeProvider)) {
141
126
  const installStatus = (0, copilot_installer_1.probeCopilotSdkInstall)();
142
127
  if (!installStatus.installed) {
@@ -158,12 +143,10 @@ async function runDoctor(args) {
158
143
  ...(normalized.details ?? {}),
159
144
  });
160
145
  }
161
- const bridge = await (0, copilot_bridge_1.probeCopilotBridgeRuntime)(activeProvider);
146
+ const bridge = await (0, copilot_bridge_1.probeCopilotBridgeRuntime)(activeProvider, runtimeState);
162
147
  if (!bridge.ok) {
163
148
  issues.push({
164
- code: bridge.cause === "Copilot bridge state base URL does not match the provider runtime configuration."
165
- ? "PROVIDER_BASE_URL_MISMATCH"
166
- : "BRIDGE_HEALTHCHECK_FAILED",
149
+ code: mapBridgeDiagnosticCode(bridge.cause),
167
150
  message: bridge.cause,
168
151
  ...(bridge.details ?? {}),
169
152
  });
@@ -171,6 +154,26 @@ async function runDoctor(args) {
171
154
  }
172
155
  }
173
156
  }
157
+ if (runtimeState && providers) {
158
+ const runtimeProvider = providers.providers[runtimeState.provider] ?? null;
159
+ if (!runtimeProvider || !(0, providers_1.isCopilotBridgeProvider)(runtimeProvider)) {
160
+ issues.push({
161
+ code: "BRIDGE_STATE_STALE",
162
+ message: "Copilot bridge runtime state exists but no matching managed Copilot provider is available.",
163
+ ...runtimeState,
164
+ });
165
+ }
166
+ else if (!document?.activeProfile || runtimeProvider.profile !== document.activeProfile) {
167
+ issues.push({
168
+ code: "BRIDGE_STATE_STALE",
169
+ message: "Copilot bridge runtime state exists for a provider that is not the current active profile.",
170
+ activeProfile: document?.activeProfile ?? null,
171
+ runtimeProvider: runtimeState.provider,
172
+ runtimeProfile: runtimeProvider.profile,
173
+ ...runtimeState,
174
+ });
175
+ }
176
+ }
174
177
  // Drift inspection still runs when files are missing so status output can explain partial state.
175
178
  const drift = (0, runtime_state_1.inspectLiveStateDrift)(currentProfile, providers);
176
179
  const codexCheck = (0, codex_probe_1.probeCodexRuntime)();
@@ -202,6 +205,18 @@ async function runDoctor(args) {
202
205
  warnings: issues.length === 0 ? [] : [`doctor found ${issues.length} issue(s)`],
203
206
  };
204
207
  }
208
+ function mapBridgeDiagnosticCode(cause) {
209
+ if (cause === "Copilot bridge state manifest is missing.") {
210
+ return "BRIDGE_STATE_MISSING";
211
+ }
212
+ if (cause === "Copilot bridge runtime state exists but no active Copilot bridge provider is selected.") {
213
+ return "BRIDGE_STATE_STALE";
214
+ }
215
+ if (cause === "Copilot bridge state base URL does not match the provider runtime configuration.") {
216
+ return "PROVIDER_BASE_URL_MISMATCH";
217
+ }
218
+ return "BRIDGE_HEALTHCHECK_FAILED";
219
+ }
205
220
  /**
206
221
  * Maps structured config consistency issues onto stable human-readable diagnostic text.
207
222
  */
@@ -223,18 +238,10 @@ function renderConfigIssueMessage(issue) {
223
238
  return `Model provider section "${issue.modelProvider}" for profile "${issue.profile}" is missing from config.toml.`;
224
239
  case "MODEL_PROVIDER_BASE_URL_MISSING":
225
240
  return `Model provider section "${issue.modelProvider}" for profile "${issue.profile}" is missing base_url.`;
226
- case "MODEL_PROVIDER_ENV_KEY_MISSING":
227
- return `Model provider section "${issue.modelProvider}" for profile "${issue.profile}" is missing env_key.`;
228
- case "PROVIDER_ENV_KEY_MISMATCH":
229
- return `Provider "${issue.provider}" envKey does not match runtime env_key for profile "${issue.profile}".`;
230
241
  case "ACTIVE_PROVIDER_UNRESOLVED":
231
- return `Active profile "${issue.profile}" maps to multiple providers and cannot determine the current auth mirror owner.`;
242
+ return `Active profile "${issue.profile}" maps to multiple providers, so the active managed provider cannot be resolved uniquely.`;
232
243
  case "AUTH_JSON_INVALID":
233
244
  return String(issue.message ?? issue.reason ?? "auth.json is invalid.");
234
- case "AUTH_JSON_ENV_KEY_MISMATCH":
235
- return `auth.json managed env key does not match provider "${String(issue.provider ?? "")}".`;
236
- case "AUTH_JSON_APIKEY_MISMATCH":
237
- return `auth.json secret does not match provider "${String(issue.provider ?? "")}".`;
238
245
  case "DESTRUCTIVE_REMOVE_BLOCKED":
239
246
  return `Provider "${issue.provider}" cannot be removed while "${issue.activeProfile}" remains active.`;
240
247
  default:
@@ -42,7 +42,6 @@ const codex_cli_1 = require("../runtime/codex-cli");
42
42
  const config_repo_1 = require("../storage/config-repo");
43
43
  const fs_utils_1 = require("../storage/fs-utils");
44
44
  const providers_repo_1 = require("../storage/providers-repo");
45
- const auth_repo_1 = require("../storage/auth-repo");
46
45
  const run_doctor_1 = require("./run-doctor");
47
46
  const run_mutation_1 = require("./run-mutation");
48
47
  const MIN_CODEX_VERSION = "0.0.1";
@@ -70,30 +69,46 @@ async function migrateCodex(args) {
70
69
  });
71
70
  }
72
71
  const document = (0, config_repo_1.readStructuredConfig)(args.configPath);
73
- const profileViews = (0, config_1.buildManagedProfileViews)(document, null);
74
- // Migrate can only adopt unmanaged profiles that already contain enough runtime data to become managed.
75
- const adoptableProfiles = profileViews
76
- .filter((view) => view.source === "unmanaged" && view.model && view.modelProvider === view.name && view.baseUrl && view.envKey)
77
- .map((view) => view.name)
78
- .sort();
72
+ const currentProviders = (0, providers_repo_1.readProvidersFileIfExists)(args.providersPath);
73
+ const profileViews = (0, config_1.buildManagedProfileViews)(document, currentProviders);
74
+ const adoptability = (0, setup_1.collectMigrateAdoptability)(document, currentProviders);
79
75
  if (profileViews.length === 0) {
80
76
  throw (0, errors_1.cliError)("PROFILE_NOT_FOUND", "No profiles were found in config.toml.", {
81
77
  file: args.configPath,
82
78
  });
83
79
  }
84
- const invalidAdoptProfiles = args.adoptProfiles.filter((profile) => !adoptableProfiles.includes(profile));
80
+ if (adoptability.adoptableProfiles.length === 0) {
81
+ throw (0, errors_1.cliError)("MIGRATE_NO_ADOPTABLE_PROFILES", "No adoptable profiles were found for migrate.", {
82
+ availableProfiles: adoptability.availableProfiles,
83
+ adoptableProfiles: adoptability.adoptableProfiles,
84
+ blockingReasonsByProfile: adoptability.blockingReasonsByProfile,
85
+ });
86
+ }
87
+ const invalidAdoptProfiles = args.adoptProfiles.filter((profile) => !adoptability.adoptableProfiles.includes(profile));
85
88
  if (invalidAdoptProfiles.length > 0) {
86
- throw (0, errors_1.cliError)("INVALID_ARGUMENT", "migrate only adopts unmanaged profiles that already contain model, model_provider, and matching model_providers base_url/env_key.", {
89
+ throw (0, errors_1.cliError)("INVALID_ARGUMENT", "migrate only adopts unmanaged profiles that already contain model, model_provider, and matching model_providers base_url.", {
87
90
  invalidProfiles: invalidAdoptProfiles.sort(),
88
- adoptableProfiles,
91
+ availableProfiles: adoptability.availableProfiles,
92
+ adoptableProfiles: adoptability.adoptableProfiles,
93
+ blockingReasonsByProfile: adoptability.blockingReasonsByProfile,
89
94
  });
90
95
  }
91
96
  if (args.adoptProfiles.length === 0) {
92
97
  throw (0, errors_1.cliError)("INVALID_ARGUMENT", "migrate requires at least one explicit profile to adopt.", {
93
- adoptableProfiles,
98
+ availableProfiles: adoptability.availableProfiles,
99
+ adoptableProfiles: adoptability.adoptableProfiles,
100
+ blockingReasonsByProfile: adoptability.blockingReasonsByProfile,
94
101
  });
95
102
  }
96
- const drafts = (0, setup_1.buildSetupDrafts)(args.adoptProfiles, args.providerDetailsByProfile);
103
+ const runtimeByProfile = profileViews.reduce((accumulator, view) => {
104
+ if (view.source === "unmanaged") {
105
+ accumulator[view.name] = {
106
+ baseUrl: view.baseUrl ?? undefined,
107
+ };
108
+ }
109
+ return accumulator;
110
+ }, {});
111
+ const drafts = (0, setup_1.buildSetupDrafts)(args.adoptProfiles, args.providerDetailsByProfile, runtimeByProfile);
97
112
  const incompleteProfiles = (0, setup_1.findIncompleteSetupProfiles)(drafts);
98
113
  if (incompleteProfiles.length > 0) {
99
114
  throw (0, errors_1.cliError)("INVALID_ARGUMENT", "migrate requires complete provider data for every selected profile.", {
@@ -101,7 +116,6 @@ async function migrateCodex(args) {
101
116
  });
102
117
  }
103
118
  (0, fs_utils_1.ensureDir)(args.codexDir);
104
- const currentProviders = (0, providers_repo_1.readProvidersFileIfExists)(args.providersPath);
105
119
  const providersExists = fs.existsSync(args.providersPath);
106
120
  if (providersExists && args.strategy !== "merge" && args.strategy !== "overwrite") {
107
121
  throw (0, errors_1.cliError)("PROVIDERS_ALREADY_EXISTS", "providers.json already exists.", {
@@ -123,16 +137,12 @@ async function migrateCodex(args) {
123
137
  files: [
124
138
  { absolutePath: args.providersPath, relativePath: "providers.json" },
125
139
  { absolutePath: args.configPath, relativePath: "config.toml" },
126
- { absolutePath: args.authPath, relativePath: "auth.json" },
127
140
  ],
128
141
  mutate: () => {
129
142
  // migrate currently preserves config structure and only asserts that the file remains writable inside the mutation flow.
130
143
  const configPlan = (0, config_repo_1.createConfigMutationPlan)(document, {});
131
144
  (0, providers_repo_1.writeProvidersFile)(args.providersPath, finalProviders);
132
145
  (0, config_repo_1.applyConfigMutation)(args.configPath, document, configPlan);
133
- const activeProviderName = (0, config_repo_1.resolveActiveProviderName)(document, finalProviders);
134
- const existingAuth = (0, auth_repo_1.readAuthFileIfExists)(args.authPath);
135
- (0, auth_repo_1.writeAuthFile)(args.authPath, finalProviders.providers[activeProviderName], existingAuth ?? undefined);
136
146
  return {
137
147
  codexDir: args.codexDir,
138
148
  strategy: args.strategy,
@@ -31,11 +31,7 @@ function showConfig(args) {
31
31
  selectedProfile,
32
32
  profiles: profiles.map((profile) => ({
33
33
  ...profile,
34
- managedProviderEnvKeys: (0, providers_1.findProvidersByProfile)(providers, profile.name).map((providerName) => ({
35
- providerName,
36
- envKey: providers.providers[providerName].envKey,
37
- matchesRuntime: providers.providers[providerName].envKey === profile.envKey,
38
- })),
34
+ linkedProviderNames: (0, providers_1.findProvidersByProfile)(providers, profile.name),
39
35
  })),
40
36
  },
41
37
  };
@@ -4,14 +4,14 @@ exports.switchProvider = switchProvider;
4
4
  const errors_1 = require("../domain/errors");
5
5
  const providers_1 = require("../domain/providers");
6
6
  const config_repo_1 = require("../storage/config-repo");
7
- const providers_repo_1 = require("../storage/providers-repo");
8
7
  const auth_repo_1 = require("../storage/auth-repo");
8
+ const providers_repo_1 = require("../storage/providers-repo");
9
9
  const copilot_bridge_1 = require("../runtime/copilot-bridge");
10
10
  const copilot_installer_1 = require("../runtime/copilot-installer");
11
11
  const copilot_adapter_1 = require("../runtime/copilot-adapter");
12
12
  const run_mutation_1 = require("./run-mutation");
13
13
  /**
14
- * Switches the active Codex profile and rewrites auth.json for the target provider.
14
+ * Switches the active Codex profile to the target provider.
15
15
  */
16
16
  async function switchProvider(args) {
17
17
  const providers = (0, providers_repo_1.readProvidersFile)(args.providersPath);
@@ -22,15 +22,6 @@ async function switchProvider(args) {
22
22
  });
23
23
  }
24
24
  const document = (0, config_repo_1.ensureProfileExists)(args.configPath, provider.profile, args.providerName);
25
- const envKey = (0, config_repo_1.requireRuntimeEnvKey)(document, provider.profile);
26
- if (provider.envKey !== envKey) {
27
- throw (0, errors_1.cliError)("PROVIDER_ENV_KEY_MISMATCH", `Provider "${args.providerName}" envKey does not match runtime env_key.`, {
28
- provider: args.providerName,
29
- profile: provider.profile,
30
- providerEnvKey: provider.envKey,
31
- runtimeEnvKey: envKey,
32
- });
33
- }
34
25
  if ((0, providers_1.isCopilotBridgeProvider)(provider)) {
35
26
  const installStatus = (0, copilot_installer_1.probeCopilotSdkInstall)();
36
27
  if (!installStatus.installed) {
@@ -41,6 +32,16 @@ async function switchProvider(args) {
41
32
  }
42
33
  await (0, copilot_adapter_1.readCopilotAuthState)();
43
34
  const bridge = await (0, copilot_bridge_1.ensureCopilotBridge)(args.providerName, provider);
35
+ const nextProvider = bridge.portChanged
36
+ ? (0, providers_1.cleanProviderRecord)({
37
+ ...provider,
38
+ baseUrl: bridge.baseUrl,
39
+ runtime: {
40
+ ...provider.runtime,
41
+ bridgePort: bridge.port,
42
+ },
43
+ })
44
+ : provider;
44
45
  try {
45
46
  return (0, run_mutation_1.runMutation)({
46
47
  codexDir: args.codexDir,
@@ -48,20 +49,34 @@ async function switchProvider(args) {
48
49
  latestBackupPath: args.latestBackupPath,
49
50
  operation: "switch",
50
51
  files: [
52
+ { absolutePath: args.providersPath, relativePath: "providers.json" },
51
53
  { absolutePath: args.configPath, relativePath: "config.toml" },
52
- { absolutePath: args.authPath, relativePath: "auth.json" },
53
54
  ],
54
55
  mutate: () => {
55
56
  const configPlan = (0, config_repo_1.createConfigMutationPlan)(document, {
56
57
  setActiveProfile: provider.profile,
58
+ upsertModelProviders: bridge.portChanged
59
+ ? {
60
+ [provider.profile]: {
61
+ baseUrl: (0, providers_1.buildCopilotBridgeBaseUrl)(nextProvider.runtime),
62
+ },
63
+ }
64
+ : undefined,
57
65
  });
66
+ if (bridge.portChanged) {
67
+ (0, providers_repo_1.writeProvidersFile)(args.providersPath, {
68
+ providers: {
69
+ ...providers.providers,
70
+ [args.providerName]: nextProvider,
71
+ },
72
+ });
73
+ }
58
74
  (0, config_repo_1.applyConfigMutation)(args.configPath, document, configPlan);
59
- const existingAuth = (0, auth_repo_1.readAuthFileIfExists)(args.authPath);
60
- (0, auth_repo_1.writeAuthFile)(args.authPath, provider, existingAuth ?? undefined);
61
75
  return {
62
76
  provider: args.providerName,
63
- profile: provider.profile,
64
- envKey: provider.envKey,
77
+ profile: nextProvider.profile,
78
+ portChanged: bridge.portChanged,
79
+ bridgePort: bridge.port,
65
80
  };
66
81
  },
67
82
  });
@@ -79,20 +94,18 @@ async function switchProvider(args) {
79
94
  latestBackupPath: args.latestBackupPath,
80
95
  operation: "switch",
81
96
  files: [
82
- { absolutePath: args.configPath, relativePath: "config.toml" },
83
97
  { absolutePath: args.authPath, relativePath: "auth.json" },
98
+ { absolutePath: args.configPath, relativePath: "config.toml" },
84
99
  ],
85
100
  mutate: () => {
86
101
  const configPlan = (0, config_repo_1.createConfigMutationPlan)(document, {
87
102
  setActiveProfile: provider.profile,
88
103
  });
89
104
  (0, config_repo_1.applyConfigMutation)(args.configPath, document, configPlan);
90
- const existingAuth = (0, auth_repo_1.readAuthFileIfExists)(args.authPath);
91
- (0, auth_repo_1.writeAuthFile)(args.authPath, provider, existingAuth ?? undefined);
105
+ (0, auth_repo_1.writeOpenAiApiKeyAuth)(args.authPath, provider.apiKey);
92
106
  return {
93
107
  provider: args.providerName,
94
108
  profile: provider.profile,
95
- envKey: provider.envKey,
96
109
  };
97
110
  },
98
111
  });
@@ -90,8 +90,7 @@ function renderHumanSuccess(command, data, warnings) {
90
90
  ? ` tags=${provider.tags.join(",")}`
91
91
  : "";
92
92
  const note = provider.note ? ` note=${provider.note}` : "";
93
- const envKey = provider.envKey ? ` envKey=${provider.envKey}` : "";
94
- lines.push(`${provider.name} -> ${provider.profile}${envKey}${tags}${note}`);
93
+ lines.push(`${provider.name} -> ${provider.profile}${tags}${note}`);
95
94
  }
96
95
  }
97
96
  break;
@@ -101,7 +100,6 @@ function renderHumanSuccess(command, data, warnings) {
101
100
  lines.push(`Provider: ${String(data?.providerName ?? "")}`);
102
101
  lines.push(`profile: ${String(provider.profile ?? "")}`);
103
102
  lines.push(`apiKey: ${String(provider.apiKey ?? "")}`);
104
- lines.push(`envKey: ${String(provider.envKey ?? "")}`);
105
103
  if (provider.baseUrl) {
106
104
  lines.push(`baseUrl: ${String(provider.baseUrl)}`);
107
105
  }
@@ -125,14 +123,15 @@ function renderHumanSuccess(command, data, warnings) {
125
123
  lines.push(`activeProviderResolvable: ${String(data?.activeProviderResolvable ?? false)}`);
126
124
  const auth = data?.auth ?? {};
127
125
  lines.push(`authExists: ${String(auth.exists ?? false)}`);
128
- lines.push(`authManagedKeys: ${Array.isArray(auth.managedSecretKeys) ? auth.managedSecretKeys.join(",") : ""}`);
126
+ lines.push(`authValid: ${String(auth.valid ?? false)}`);
127
+ lines.push(`authMode: ${String(auth.authMode ?? "")}`);
129
128
  lines.push(`issues: ${Array.isArray(data?.issues) ? (data?.issues).length : 0}`);
130
129
  break;
131
130
  case "config-show": {
132
131
  lines.push(`activeProfile: ${String(data?.activeProfile ?? "")}`);
133
132
  const profiles = data?.profiles ?? [];
134
133
  for (const profile of profiles) {
135
- lines.push(`${String(profile.name)} managed=${String(profile.managed)} active=${String(profile.isActive)} source=${String(profile.source)} model=${String(profile.model ?? "")} modelProvider=${String(profile.modelProvider ?? "")} baseUrl=${String(profile.baseUrl ?? "")} envKey=${String(profile.envKey ?? "")}`);
134
+ lines.push(`${String(profile.name)} managed=${String(profile.managed)} active=${String(profile.isActive)} source=${String(profile.source)} model=${String(profile.model ?? "")} modelProvider=${String(profile.modelProvider ?? "")} baseUrl=${String(profile.baseUrl ?? "")}`);
136
135
  }
137
136
  break;
138
137
  }
@@ -145,7 +144,6 @@ function renderHumanSuccess(command, data, warnings) {
145
144
  }
146
145
  case "switch":
147
146
  lines.push(`Switched to provider ${String(data?.provider ?? "")} using profile ${String(data?.profile ?? "")}.`);
148
- lines.push(`envKey: ${String(data?.envKey ?? "")}`);
149
147
  lines.push(`Backup: ${String(data?.backupPath ?? "")}`);
150
148
  break;
151
149
  case "import":
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ const args_1 = require("./commands/args");
9
9
  const help_1 = require("./commands/help");
10
10
  const errors_1 = require("./domain/errors");
11
11
  const output_1 = require("./cli/output");
12
- const VERSION = "0.0.8";
12
+ const VERSION = require("../package.json").version ?? "0.0.0";
13
13
  /**
14
14
  * Prints the command help text to stdout.
15
15
  */