@minniexcode/codex-switch 0.0.11 → 0.0.12

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.
@@ -30,6 +30,10 @@ function buildHelpText(commandName) {
30
30
  "codex-switch",
31
31
  "",
32
32
  "Manage and switch local Codex provider/profile configuration safely.",
33
+ "Primary workflows: direct providers use init -> add -> switch -> status -> doctor.",
34
+ "Primary workflows: Copilot providers use init -> login copilot -> add --copilot -> switch -> status -> doctor.",
35
+ "Advanced adopt flows use migrate only when you already have Codex runtime state to import.",
36
+ "Deprecated entry: setup still exists only to point callers to init or migrate.",
33
37
  "",
34
38
  "Usage:",
35
39
  " codexs <command> [options]",
@@ -61,14 +65,14 @@ function buildHelpText(commandName) {
61
65
  "",
62
66
  "Examples:",
63
67
  " codexs init",
68
+ " codexs add packycode --profile packycode --api-key sk-xxx",
69
+ " codexs switch packycode",
70
+ " codexs status",
71
+ " codexs doctor",
64
72
  " codexs login copilot",
73
+ " codexs add copilot-main --copilot --profile copilot-main",
65
74
  " codexs migrate",
66
- " codexs list",
67
- " codexs switch",
68
- " codexs bridge start",
69
- " codexs add packycode --profile packycode --api-key sk-xxx",
70
75
  " codexs config show",
71
- " codexs remove freemodel",
72
76
  " codexs backups list",
73
77
  " codexs rollback",
74
78
  " codexs help add",
@@ -88,13 +88,14 @@ exports.COMMANDS = [
88
88
  tokens: ["init"],
89
89
  handler: handlers_1.handleRegisteredCommand,
90
90
  group: "write",
91
- summary: "Initialize the codex-switch tool home and registry files.",
91
+ summary: "Initialize the codex-switch tool home for the primary workflow.",
92
92
  usage: ["codexs init [--json] [--codex-dir <path>]"],
93
93
  details: [
94
94
  "Creates codex-switch.json and providers.json under the tool home when they do not exist yet.",
95
95
  "Does not create or validate config.toml, auth.json, or the target Codex directory.",
96
96
  "When --codex-dir is passed explicitly and codex-switch.json does not exist yet, init persists it as defaultCodexDir.",
97
97
  "Otherwise init stays scoped to tool-home state and does not persist fallback Codex directory resolution.",
98
+ "Use init first for fresh direct-provider or Copilot setups.",
98
99
  ],
99
100
  examples: ["codexs init", "codexs init --json --codex-dir ~/.codex"],
100
101
  },
@@ -119,13 +120,14 @@ exports.COMMANDS = [
119
120
  tokens: ["migrate"],
120
121
  handler: handlers_1.handleRegisteredCommand,
121
122
  group: "write",
122
- summary: "Adopt unmanaged Codex config profiles into providers.json.",
123
+ summary: "Adopt existing Codex runtime profiles into managed providers.json state.",
123
124
  usage: ["codexs migrate [--json] [--codex-dir <path>] [--merge|--overwrite]"],
124
125
  details: [
125
126
  "Reads config.toml profiles, collects complete provider records, then writes providers.json under managed backup flow.",
126
127
  "TTY mode can collect missing provider details and choose merge or overwrite when providers.json already exists.",
127
128
  "Migrate adopts only runtime profiles that already expose model, model_provider, and matching base_url.",
128
129
  "Non-TTY and --json runs still fail fast because migrate profile selection and provider details remain interactive in this release.",
130
+ "Treat migrate as an advanced adopt helper for existing runtime state, not the default first step for fresh installs.",
129
131
  ],
130
132
  examples: ["codexs migrate", "codexs migrate --overwrite --json --codex-dir ~/.codex"],
131
133
  },
@@ -134,12 +136,12 @@ exports.COMMANDS = [
134
136
  tokens: ["setup"],
135
137
  handler: handlers_1.handleRegisteredCommand,
136
138
  group: "write",
137
- summary: "Deprecated. Use init or migrate instead.",
139
+ summary: "Deprecated. Kept only to point callers to init or migrate.",
138
140
  usage: ["codexs setup"],
139
141
  details: [
140
142
  "setup no longer performs initialization or migration work.",
141
- "Use init for AI-friendly idempotent providers.json initialization.",
142
- "Use migrate for interactive adoption from existing config.toml profiles.",
143
+ "Use init for the primary fresh-install workflow.",
144
+ "Use migrate only when adopting from existing config.toml profiles.",
143
145
  ],
144
146
  examples: ["codexs help init", "codexs help migrate"],
145
147
  },
@@ -182,12 +184,12 @@ exports.COMMANDS = [
182
184
  tokens: ["status"],
183
185
  handler: handlers_1.handleRegisteredCommand,
184
186
  group: "read",
185
- summary: "Show a quick status summary for the local Codex directory.",
187
+ summary: "Show tool-home, target-runtime, provider, and runtime-health status.",
186
188
  usage: ["codexs status [--json] [--codex-dir <path>]"],
187
189
  details: [
188
- "Reports file presence, current profile, and whether the live profile is mapped.",
189
- "When the active provider uses a local runtime bridge, status also reports bridge and SDK state.",
190
- "Surfaces config consistency signals without mutating any files.",
190
+ "Reports the target Codex runtime, tool-home storage roles, current profile, and whether the live profile is mapped.",
191
+ "When the active provider uses a local runtime bridge, status also reports bridge, Copilot SDK, and upstream auth state.",
192
+ "Surfaces dual-path config consistency signals without mutating any files.",
191
193
  "Use doctor for deeper diagnostics.",
192
194
  ],
193
195
  examples: ["codexs status", "codexs status --json --codex-dir ./.tmp-codex"],
@@ -216,7 +218,7 @@ exports.COMMANDS = [
216
218
  tokens: ["add"],
217
219
  handler: handlers_1.handleRegisteredCommand,
218
220
  group: "write",
219
- summary: "Add a provider with explicit flags or progressive TTY prompts.",
221
+ summary: "Add a managed provider for the primary direct or Copilot workflows.",
220
222
  usage: [
221
223
  "codexs add <provider> --profile <name> --api-key <key> [--base-url <url>] [--note <text>] [--tag <tag> ...]",
222
224
  "codexs add <provider> --copilot --profile <name> [--bridge-host <host>] [--bridge-port <port>] [--bridge-api-key <secret>] [--install-copilot-sdk]",
@@ -247,7 +249,7 @@ exports.COMMANDS = [
247
249
  tokens: ["switch"],
248
250
  handler: handlers_1.handleRegisteredCommand,
249
251
  group: "write",
250
- summary: "Switch the active config profile to a provider.",
252
+ summary: "Switch the active runtime to a managed provider.",
251
253
  usage: ["codexs switch <provider> [--json] [--codex-dir <path>]"],
252
254
  details: [
253
255
  "When <provider> is omitted in a TTY, an interactive provider selector is shown.",
@@ -255,6 +257,7 @@ exports.COMMANDS = [
255
257
  "Direct providers update the active config profile and rewrite auth.json with auth_mode=apikey plus OPENAI_API_KEY.",
256
258
  "Copilot bridge providers also rewrite OPENAI_API_KEY to the local bridge secret while managing runtime routing and bridge state.",
257
259
  "Copilot bridge providers probe the optional official SDK before switching and fail fast if it is missing.",
260
+ "Switch succeeds only after the managed profile projection is written to the target runtime.",
258
261
  "Backs up config.toml and auth.json and rolls back on failure.",
259
262
  ],
260
263
  examples: ["codexs switch freemodel", "codexs switch packycode --json"],
@@ -321,7 +324,7 @@ exports.COMMANDS = [
321
324
  tokens: ["doctor"],
322
325
  handler: handlers_1.handleRegisteredCommand,
323
326
  group: "recovery",
324
- summary: "Run configuration and environment diagnostics.",
327
+ summary: "Run repair-oriented diagnostics across tool-home and target-runtime state.",
325
328
  usage: ["codexs doctor [--json] [--codex-dir <path>]"],
326
329
  details: [
327
330
  "Checks the expected config files, provider/profile consistency, and Codex CLI availability.",
@@ -97,7 +97,9 @@ function inspectLiveStateDrift(currentProfile, providers) {
97
97
  return {
98
98
  currentProfile,
99
99
  mappedProvider: null,
100
+ mappedProviders: [],
100
101
  profileMapped: false,
102
+ providerResolvable: false,
101
103
  canBackfillActiveProvider: false,
102
104
  reason: providers ? "profile-missing" : "config-missing",
103
105
  };
@@ -106,27 +108,47 @@ function inspectLiveStateDrift(currentProfile, providers) {
106
108
  return {
107
109
  currentProfile,
108
110
  mappedProvider: null,
111
+ mappedProviders: [],
109
112
  profileMapped: false,
113
+ providerResolvable: false,
110
114
  canBackfillActiveProvider: false,
111
115
  reason: "providers-missing",
112
116
  };
113
117
  }
118
+ const mappedProviders = [];
114
119
  for (const [name, provider] of Object.entries(providers.providers)) {
115
- // A direct profile match means the runtime state is still managed.
116
120
  if (provider.profile === currentProfile) {
117
- return {
118
- currentProfile,
119
- mappedProvider: name,
120
- profileMapped: true,
121
- canBackfillActiveProvider: false,
122
- reason: "ok",
123
- };
121
+ mappedProviders.push(name);
124
122
  }
125
123
  }
124
+ if (mappedProviders.length === 1) {
125
+ return {
126
+ currentProfile,
127
+ mappedProvider: mappedProviders[0],
128
+ mappedProviders,
129
+ profileMapped: true,
130
+ providerResolvable: true,
131
+ canBackfillActiveProvider: false,
132
+ reason: "ok",
133
+ };
134
+ }
135
+ if (mappedProviders.length > 1) {
136
+ return {
137
+ currentProfile,
138
+ mappedProvider: null,
139
+ mappedProviders,
140
+ profileMapped: true,
141
+ providerResolvable: false,
142
+ canBackfillActiveProvider: false,
143
+ reason: "shared-profile",
144
+ };
145
+ }
126
146
  return {
127
147
  currentProfile,
128
148
  mappedProvider: null,
149
+ mappedProviders: [],
129
150
  profileMapped: false,
151
+ providerResolvable: false,
130
152
  canBackfillActiveProvider: true,
131
153
  reason: "provider-unmapped",
132
154
  };
@@ -1,208 +1,18 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.readConfigFile = readConfigFile;
37
- exports.readStructuredConfig = readStructuredConfig;
38
- exports.readCurrentProfile = readCurrentProfile;
39
- exports.listConfigProfiles = listConfigProfiles;
40
- exports.ensureProfileExists = ensureProfileExists;
41
- exports.requireManagedProfileRuntime = requireManagedProfileRuntime;
42
- exports.requireModelProviderRuntimeSection = requireModelProviderRuntimeSection;
43
- exports.updateTopLevelProfile = updateTopLevelProfile;
44
- exports.createConfigMutationPlan = createConfigMutationPlan;
45
- exports.applyConfigMutation = applyConfigMutation;
46
- exports.findCodexDirCandidates = findCodexDirCandidates;
47
- const fs = __importStar(require("node:fs"));
48
- const os = __importStar(require("node:os"));
49
- const path = __importStar(require("node:path"));
50
- const config_1 = require("../domain/config");
51
- const errors_1 = require("../domain/errors");
52
- const codex_paths_1 = require("./codex-paths");
53
- const fs_utils_1 = require("./fs-utils");
54
- /**
55
- * Reads config.toml and throws a typed error when the file is missing.
56
- */
57
- function readConfigFile(configPath) {
58
- return (0, fs_utils_1.readRequiredFile)(configPath, "CONFIG_NOT_FOUND", "config.toml");
59
- }
60
- /**
61
- * Reads and parses config.toml into the managed structured document shape.
62
- */
63
- function readStructuredConfig(configPath) {
64
- const content = readConfigFile(configPath);
65
- try {
66
- return (0, config_1.parseStructuredConfig)(content);
67
- }
68
- catch (error) {
69
- throw (0, errors_1.cliError)("CONFIG_PARSE_ERROR", "Failed to parse config.toml.", {
70
- file: configPath,
71
- cause: (0, errors_1.normalizeError)(error).message,
72
- });
73
- }
74
- }
75
- /**
76
- * Reads the active top-level profile from config.toml.
77
- */
78
- function readCurrentProfile(configPath) {
79
- const profile = readStructuredConfig(configPath).activeProfile ?? (0, config_1.parseTopLevelProfile)(readConfigFile(configPath));
80
- if (!profile) {
81
- throw (0, errors_1.cliError)("PROFILE_NOT_FOUND", "No top-level profile is set in config.toml.", {
82
- file: configPath,
83
- });
84
- }
85
- return profile;
86
- }
87
- /**
88
- * Lists all named profile sections declared in config.toml.
89
- */
90
- function listConfigProfiles(configPath) {
91
- return new Set(readStructuredConfig(configPath).profiles.map((profile) => profile.name));
92
- }
93
- /**
94
- * Verifies that a provider's target profile exists before a switch operation proceeds.
95
- */
96
- function ensureProfileExists(configPath, profile, provider) {
97
- const document = readStructuredConfig(configPath);
98
- if (!document.profiles.some((entry) => entry.name === profile)) {
99
- throw (0, errors_1.cliError)("PROFILE_NOT_FOUND", `Profile "${profile}" does not exist in config.toml.`, {
100
- file: configPath,
101
- provider,
102
- profile,
103
- });
104
- }
105
- return document;
106
- }
107
- /**
108
- * Resolves one profile view and enforces the managed model_provider contract.
109
- */
110
- function requireManagedProfileRuntime(document, providers, profile) {
111
- const view = (0, config_1.buildManagedProfileViews)(document, providers).find((entry) => entry.name === profile);
112
- if (!view) {
113
- throw (0, errors_1.cliError)("PROFILE_NOT_FOUND", `Profile "${profile}" does not exist in config.toml.`, {
114
- profile,
115
- });
116
- }
117
- if (!view.modelProvider) {
118
- throw (0, errors_1.cliError)("MANAGED_PROFILE_FIELDS_MISSING", `Managed profile "${profile}" requires model_provider.`, {
119
- profile,
120
- missingFields: ["model_provider"],
121
- });
122
- }
123
- if (view.modelProvider !== profile) {
124
- throw (0, errors_1.cliError)("INVALID_ARGUMENT", `Managed profile "${profile}" must use the same model_provider name.`, {
125
- profile,
126
- modelProvider: view.modelProvider,
127
- });
128
- }
129
- const modelProviderSection = document.modelProviders.find((entry) => entry.name === view.modelProvider);
130
- if (!modelProviderSection) {
131
- throw (0, errors_1.cliError)("PROFILE_NOT_FOUND", `Model provider "${view.modelProvider}" does not exist in config.toml.`, {
132
- profile,
133
- modelProvider: view.modelProvider,
134
- });
135
- }
136
- if (!modelProviderSection.baseUrl) {
137
- throw (0, errors_1.cliError)("MANAGED_PROFILE_FIELDS_MISSING", `Model provider "${view.modelProvider}" requires base_url.`, {
138
- profile,
139
- modelProvider: view.modelProvider,
140
- missingFields: ["base_url"],
141
- });
142
- }
143
- return view;
144
- }
145
- /**
146
- * Verifies that a same-named model_provider runtime section exists and has base_url.
147
- */
148
- function requireModelProviderRuntimeSection(document, profile) {
149
- const modelProviderSection = document.modelProviders.find((entry) => entry.name === profile);
150
- if (!modelProviderSection) {
151
- throw (0, errors_1.cliError)("PROFILE_NOT_FOUND", `Model provider "${profile}" does not exist in config.toml.`, {
152
- profile,
153
- modelProvider: profile,
154
- });
155
- }
156
- if (!modelProviderSection.baseUrl) {
157
- throw (0, errors_1.cliError)("MANAGED_PROFILE_FIELDS_MISSING", `Model provider "${profile}" requires base_url.`, {
158
- profile,
159
- modelProvider: profile,
160
- missingFields: ["base_url"],
161
- });
162
- }
163
- }
164
- /**
165
- * Rewrites config.toml so the requested profile becomes the active top-level profile.
166
- */
167
- function updateTopLevelProfile(configPath, configContent, profile) {
168
- (0, fs_utils_1.writeTextFileAtomic)(configPath, (0, config_1.applyPatchOperations)(configContent, (0, config_1.planConfigMutation)((0, config_1.parseStructuredConfig)(configContent), {
169
- setActiveProfile: profile,
170
- }).operations));
171
- }
172
- /**
173
- * Exposes the config mutation planner to application services.
174
- */
175
- function createConfigMutationPlan(document, args) {
176
- return (0, config_1.planConfigMutation)(document, args);
177
- }
178
- /**
179
- * Applies a previously generated mutation plan to config.toml in one write.
180
- */
181
- function applyConfigMutation(configPath, document, plan) {
182
- (0, fs_utils_1.writeTextFileAtomic)(configPath, (0, config_1.applyPatchOperations)(document.rawText, plan.operations));
183
- }
184
- /**
185
- * Finds candidate Codex directories in a stable, non-recursive order.
186
- */
187
- function findCodexDirCandidates(explicitCodexDir) {
188
- if (explicitCodexDir) {
189
- return [(0, codex_paths_1.resolveCodexDir)(explicitCodexDir)];
190
- }
191
- const candidates = new Set();
192
- const ordered = [];
193
- const envCandidate = process.env[codex_paths_1.CODEX_DIR_ENV_NAME];
194
- if (envCandidate) {
195
- ordered.push((0, codex_paths_1.resolveCodexDir)(envCandidate));
196
- }
197
- if (process.env.NODE_ENV === "development") {
198
- ordered.push(path.resolve(process.cwd(), "dev-codex", "local-sandbox"));
199
- }
200
- ordered.push(path.join(os.homedir(), ".codex"));
201
- for (const candidate of ordered) {
202
- if (!candidate || candidates.has(candidate) || !fs.existsSync(candidate)) {
203
- continue;
204
- }
205
- candidates.add(candidate);
206
- }
207
- return [...candidates];
208
- }
3
+ exports.updateTopLevelProfile = exports.requireModelProviderRuntimeSection = exports.requireManagedProfileRuntime = exports.readStructuredConfig = exports.readCurrentProfile = exports.readConfigFile = exports.listConfigProfiles = exports.findCodexDirCandidates = exports.ensureProfileExists = exports.createConfigMutationPlan = exports.applyConfigMutation = void 0;
4
+ /**
5
+ * Compatibility facade that re-exports config repository helpers from storage.
6
+ */
7
+ var config_repo_1 = require("../storage/config-repo");
8
+ Object.defineProperty(exports, "applyConfigMutation", { enumerable: true, get: function () { return config_repo_1.applyConfigMutation; } });
9
+ Object.defineProperty(exports, "createConfigMutationPlan", { enumerable: true, get: function () { return config_repo_1.createConfigMutationPlan; } });
10
+ Object.defineProperty(exports, "ensureProfileExists", { enumerable: true, get: function () { return config_repo_1.ensureProfileExists; } });
11
+ Object.defineProperty(exports, "findCodexDirCandidates", { enumerable: true, get: function () { return config_repo_1.findCodexDirCandidates; } });
12
+ Object.defineProperty(exports, "listConfigProfiles", { enumerable: true, get: function () { return config_repo_1.listConfigProfiles; } });
13
+ Object.defineProperty(exports, "readConfigFile", { enumerable: true, get: function () { return config_repo_1.readConfigFile; } });
14
+ Object.defineProperty(exports, "readCurrentProfile", { enumerable: true, get: function () { return config_repo_1.readCurrentProfile; } });
15
+ Object.defineProperty(exports, "readStructuredConfig", { enumerable: true, get: function () { return config_repo_1.readStructuredConfig; } });
16
+ Object.defineProperty(exports, "requireManagedProfileRuntime", { enumerable: true, get: function () { return config_repo_1.requireManagedProfileRuntime; } });
17
+ Object.defineProperty(exports, "requireModelProviderRuntimeSection", { enumerable: true, get: function () { return config_repo_1.requireModelProviderRuntimeSection; } });
18
+ Object.defineProperty(exports, "updateTopLevelProfile", { enumerable: true, get: function () { return config_repo_1.updateTopLevelProfile; } });
@@ -52,7 +52,10 @@ const fs = __importStar(require("node:fs"));
52
52
  const path = __importStar(require("node:path"));
53
53
  const errors_1 = require("../domain/errors");
54
54
  const backups_1 = require("../domain/backups");
55
+ const providers_1 = require("../domain/providers");
56
+ const runtime_state_1 = require("../domain/runtime-state");
55
57
  const codex_paths_1 = require("../storage/codex-paths");
58
+ const config_repo_1 = require("../storage/config-repo");
56
59
  const providers_repo_1 = require("../storage/providers-repo");
57
60
  const backup_repo_1 = require("../storage/backup-repo");
58
61
  const add_interactive_1 = require("./add-interactive");
@@ -65,15 +68,22 @@ function canPrompt(runtime, jsonMode) {
65
68
  /**
66
69
  * Prompts the user to choose one configured provider when a command omitted its target.
67
70
  */
68
- async function promptForProviderSelection(runtime, providersPath, message) {
71
+ async function promptForProviderSelection(runtime, providersPath, configPath, message) {
69
72
  const providers = (0, providers_repo_1.readProvidersFile)(providersPath);
73
+ const currentProfile = fs.existsSync(configPath) ? (0, config_repo_1.readStructuredConfig)(configPath).activeProfile : null;
74
+ const liveState = (0, runtime_state_1.inspectLiveStateDrift)(currentProfile, providers);
70
75
  const choices = Object.entries(providers.providers)
71
76
  .sort(([left], [right]) => left.localeCompare(right))
72
- .map(([providerName, provider]) => ({
73
- value: providerName,
74
- label: providerName,
75
- hint: provider.profile,
76
- }));
77
+ .map(([providerName, provider]) => {
78
+ const providerType = (0, providers_1.isCopilotBridgeProvider)(provider) ? "copilot" : "direct";
79
+ const currentMarker = liveState.providerResolvable && liveState.mappedProvider === providerName ? " | current" : "";
80
+ const ambiguousMarker = !liveState.providerResolvable && liveState.mappedProviders.includes(providerName) ? " | current=ambiguous" : "";
81
+ return {
82
+ value: providerName,
83
+ label: providerName,
84
+ hint: `profile=${provider.profile} | type=${providerType}${currentMarker}${ambiguousMarker}`,
85
+ };
86
+ });
77
87
  if (choices.length === 0) {
78
88
  throw (0, errors_1.cliError)("PROVIDER_NOT_FOUND", "No providers are configured.");
79
89
  }
@@ -221,7 +221,8 @@ async function startOrReuseCopilotBridge(providerName, provider, runtimeDir) {
221
221
  }
222
222
  child.unref();
223
223
  const startedAt = new Date().toISOString();
224
- const healthy = await waitForCopilotBridgeStartup(child, runtime.bridgeHost, selectedPort, 15, 200);
224
+ // The worker can take a little longer to become healthy on Windows or under loaded test runs.
225
+ const healthy = await waitForCopilotBridgeStartup(child, runtime.bridgeHost, selectedPort, 25, 200);
225
226
  if (!healthy.ok) {
226
227
  (0, runtime_state_repo_1.clearCopilotBridgeState)(runtimeDir);
227
228
  if (healthy.reason === "start-failed") {
@@ -40,7 +40,6 @@ exports.listConfigProfiles = listConfigProfiles;
40
40
  exports.ensureProfileExists = ensureProfileExists;
41
41
  exports.requireManagedProfileRuntime = requireManagedProfileRuntime;
42
42
  exports.requireModelProviderRuntimeSection = requireModelProviderRuntimeSection;
43
- exports.resolveActiveProviderName = resolveActiveProviderName;
44
43
  exports.updateTopLevelProfile = updateTopLevelProfile;
45
44
  exports.createConfigMutationPlan = createConfigMutationPlan;
46
45
  exports.applyConfigMutation = applyConfigMutation;
@@ -50,7 +49,6 @@ const os = __importStar(require("node:os"));
50
49
  const path = __importStar(require("node:path"));
51
50
  const config_1 = require("../domain/config");
52
51
  const errors_1 = require("../domain/errors");
53
- const providers_1 = require("../domain/providers");
54
52
  const codex_paths_1 = require("./codex-paths");
55
53
  const fs_utils_1 = require("./fs-utils");
56
54
  /**
@@ -163,27 +161,6 @@ function requireModelProviderRuntimeSection(document, profile) {
163
161
  });
164
162
  }
165
163
  }
166
- /**
167
- * Resolves the current active provider and requires the mapping to be unique.
168
- */
169
- function resolveActiveProviderName(document, providers) {
170
- if (!document.activeProfile) {
171
- throw (0, errors_1.cliError)("PROFILE_NOT_FOUND", "No top-level profile is set in config.toml.");
172
- }
173
- const matches = (0, providers_1.findProvidersByProfile)(providers, document.activeProfile);
174
- if (matches.length === 0) {
175
- throw (0, errors_1.cliError)("UNMANAGED_ACTIVE_PROFILE", `Active profile "${document.activeProfile}" is not mapped by providers.json.`, {
176
- profile: document.activeProfile,
177
- });
178
- }
179
- if (matches.length > 1) {
180
- throw (0, errors_1.cliError)("ACTIVE_PROVIDER_UNRESOLVED", `Active profile "${document.activeProfile}" maps to multiple providers, so the active managed provider is ambiguous.`, {
181
- profile: document.activeProfile,
182
- providers: matches,
183
- });
184
- }
185
- return matches[0];
186
- }
187
164
  /**
188
165
  * Rewrites config.toml so the requested profile becomes the active top-level profile.
189
166
  */