@minniexcode/codex-switch 0.1.5 → 0.2.0

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.
@@ -40,8 +40,7 @@ const errors_1 = require("../domain/errors");
40
40
  const config_repo_1 = require("../storage/config-repo");
41
41
  const fs_utils_1 = require("../storage/fs-utils");
42
42
  const providers_repo_1 = require("../storage/providers-repo");
43
- const copilot_adapter_1 = require("../runtime/copilot-adapter");
44
- const copilot_installer_1 = require("../runtime/copilot-installer");
43
+ const copilot_token_1 = require("../runtime/copilot-token");
45
44
  const run_mutation_1 = require("./run-mutation");
46
45
  /**
47
46
  * Adds a new provider record to the managed providers registry.
@@ -56,34 +55,29 @@ async function addProvider(args) {
56
55
  const bridgePort = args.bridgePort ?? 41415;
57
56
  const runtime = args.copilot
58
57
  ? {
59
- kind: "copilot-sdk-bridge",
58
+ kind: "copilot-http-proxy",
60
59
  upstream: "github-copilot",
61
60
  bridgeHost,
62
61
  bridgePort,
63
62
  bridgePath: "/v1",
64
63
  premiumRequests: true,
65
- authSource: "official-sdk",
66
- sdkInstallMode: "lazy",
64
+ authSource: "github-pat",
67
65
  }
68
66
  : undefined;
69
67
  if (args.copilot) {
70
- (0, copilot_installer_1.assertCopilotNodeRuntimeSupported)();
71
- const installStatus = (0, copilot_installer_1.probeCopilotSdkInstall)(args.runtimesDir);
72
- if (!installStatus.installed) {
73
- throw (0, errors_1.cliError)("COPILOT_SDK_MISSING", "The optional Copilot SDK runtime is not installed. Run `codexs login copilot` first.", {
74
- installDir: installStatus.installDir,
75
- packageName: installStatus.packageName,
76
- suggestion: "Run `codexs login copilot` to install the Copilot SDK and complete login.",
68
+ const githubToken = (0, copilot_token_1.readGithubToken)(args.toolHomeDir);
69
+ if (!githubToken) {
70
+ throw (0, errors_1.cliError)("COPILOT_AUTH_REQUIRED", "GitHub Copilot authentication is required. Run `codexs login copilot` first.", {
71
+ suggestion: "Run `codexs login copilot` to complete GitHub Copilot login.",
77
72
  });
78
73
  }
79
74
  try {
80
- await (0, copilot_adapter_1.readCopilotAuthState)(args.runtimesDir);
75
+ await (0, copilot_token_1.exchangeForCopilotToken)(githubToken);
81
76
  }
82
77
  catch (error) {
83
78
  const normalized = (0, errors_1.normalizeError)(error);
84
- if (normalized.code === "COPILOT_AUTH_REQUIRED") {
85
- throw (0, errors_1.cliError)("COPILOT_AUTH_REQUIRED", "Copilot authentication is required before a Copilot provider can be added.", {
86
- ...(normalized.details ?? {}),
79
+ if (normalized.code === "COPILOT_AUTH_REQUIRED" || normalized.code === "COPILOT_TOKEN_EXCHANGE_FAILED") {
80
+ throw (0, errors_1.cliError)("COPILOT_AUTH_REQUIRED", "GitHub token is invalid or expired. Run `codexs login copilot` to re-authenticate.", {
87
81
  suggestion: "Run `codexs login copilot` to complete GitHub Copilot login.",
88
82
  });
89
83
  }
@@ -10,8 +10,7 @@ const providers_repo_1 = require("../storage/providers-repo");
10
10
  const interactive_1 = require("../interaction/interactive");
11
11
  const copilot_bridge_1 = require("../runtime/copilot-bridge");
12
12
  const runtime_state_repo_1 = require("../storage/runtime-state-repo");
13
- const copilot_installer_1 = require("../runtime/copilot-installer");
14
- const copilot_adapter_1 = require("../runtime/copilot-adapter");
13
+ const copilot_token_1 = require("../runtime/copilot-token");
15
14
  const DEFAULT_BRIDGE_PORT = 41415;
16
15
  /**
17
16
  * Starts or reuses the managed Copilot bridge for one provider.
@@ -28,8 +27,8 @@ async function startBridge(args) {
28
27
  commandName: "start",
29
28
  preferRuntimeState: false,
30
29
  });
31
- await requireBridgeRuntimeReadiness(args.runtimesDir);
32
- const bridge = await (0, copilot_bridge_1.ensureCopilotBridge)(target.providerName, target.provider, args.runtimeDir, args.runtimesDir);
30
+ await requireBridgeRuntimeReadiness(args.runtimesDir, args.toolHomeDir);
31
+ const bridge = await (0, copilot_bridge_1.ensureCopilotBridge)(target.providerName, target.provider, args.runtimeDir, args.runtimesDir, args.toolHomeDir);
33
32
  const nextProvider = bridge.portChanged ? rewriteBridgeProviderPort(target.provider, bridge.port) : target.provider;
34
33
  if (bridge.portChanged) {
35
34
  try {
@@ -252,16 +251,12 @@ async function promptForCopilotBridgeSelection(runtime, targets, commandName) {
252
251
  /**
253
252
  * Verifies that the local Copilot bridge prerequisites are available before startup.
254
253
  */
255
- async function requireBridgeRuntimeReadiness(runtimesDir) {
256
- (0, copilot_installer_1.assertCopilotNodeRuntimeSupported)();
257
- const installStatus = (0, copilot_installer_1.probeCopilotSdkInstall)(runtimesDir);
258
- if (!installStatus.installed) {
259
- throw (0, errors_1.cliError)("COPILOT_SDK_MISSING", "The optional Copilot SDK runtime is not installed.", {
260
- installDir: installStatus.installDir,
261
- packageName: installStatus.packageName,
262
- });
254
+ async function requireBridgeRuntimeReadiness(_runtimesDir, toolHomeDir) {
255
+ const githubToken = (0, copilot_token_1.readGithubToken)(toolHomeDir);
256
+ if (!githubToken) {
257
+ throw (0, errors_1.cliError)("COPILOT_AUTH_REQUIRED", "GitHub Copilot authentication is required. Run `codexs login copilot` first.");
263
258
  }
264
- await (0, copilot_adapter_1.readCopilotAuthState)(runtimesDir);
259
+ await (0, copilot_token_1.exchangeForCopilotToken)(githubToken);
265
260
  }
266
261
  /**
267
262
  * Rewrites one Copilot bridge provider record with a recovered runtime port.
@@ -41,9 +41,8 @@ const providers_1 = require("../domain/providers");
41
41
  const config_repo_1 = require("../storage/config-repo");
42
42
  const providers_repo_1 = require("../storage/providers-repo");
43
43
  const auth_repo_1 = require("../storage/auth-repo");
44
- const copilot_installer_1 = require("../runtime/copilot-installer");
44
+ const copilot_token_1 = require("../runtime/copilot-token");
45
45
  const copilot_bridge_1 = require("../runtime/copilot-bridge");
46
- const copilot_adapter_1 = require("../runtime/copilot-adapter");
47
46
  const runtime_state_repo_1 = require("../storage/runtime-state-repo");
48
47
  /**
49
48
  * Reports the current on-disk runtime state and how it maps back to managed providers.
@@ -73,7 +72,7 @@ async function getStatus(codexDir, configPath, providersPath, authPath, options)
73
72
  const activeProvider = liveState.providerResolvable && providers && liveState.mappedProvider
74
73
  ? providers.providers[liveState.mappedProvider]
75
74
  : null;
76
- const copilotInstall = (0, copilot_installer_1.probeCopilotSdkInstall)(options?.runtimesDir);
75
+ const copilotInstall = { installed: Boolean((0, copilot_token_1.readGithubToken)(options?.toolHomeDir)), source: "github-pat" };
77
76
  const runtimeStateInspection = (0, runtime_state_repo_1.inspectCopilotBridgeState)(options?.runtimeDir);
78
77
  const runtimeState = runtimeStateInspection.state;
79
78
  const runtimeStateProvider = runtimeState && providers ? providers.providers[runtimeState.provider] ?? null : null;
@@ -107,12 +106,18 @@ async function getStatus(codexDir, configPath, providersPath, authPath, options)
107
106
  }
108
107
  : null;
109
108
  const copilotAuth = activeProvider && (0, providers_1.isCopilotBridgeProvider)(activeProvider)
110
- ? await (0, copilot_adapter_1.readCopilotAuthState)(options?.runtimesDir).catch((error) => ({
111
- ready: false,
112
- source: "official-sdk",
113
- mode: "session",
114
- error: error instanceof Error ? error.message : String(error),
115
- }))
109
+ ? await (async () => {
110
+ const token = (0, copilot_token_1.readGithubToken)(options?.toolHomeDir);
111
+ if (!token)
112
+ return { ready: false, source: "github-pat", mode: "token", error: "No GitHub token found" };
113
+ try {
114
+ await (0, copilot_token_1.exchangeForCopilotToken)(token);
115
+ return { ready: true, source: "github-pat", mode: "token" };
116
+ }
117
+ catch (error) {
118
+ return { ready: false, source: "github-pat", mode: "token", error: error instanceof Error ? error.message : String(error) };
119
+ }
120
+ })()
116
121
  : null;
117
122
  if (liveState.canBackfillActiveProvider) {
118
123
  // Surface unmanaged live state without mutating anything during a read-only status call.
@@ -147,9 +152,7 @@ async function getStatus(codexDir, configPath, providersPath, authPath, options)
147
152
  runtimeProvider: activeProvider && (0, providers_1.isCopilotBridgeProvider)(activeProvider) ? activeProvider.runtime?.kind ?? null : null,
148
153
  copilotSdk: {
149
154
  installed: copilotInstall.installed,
150
- installDir: copilotInstall.installDir,
151
- packageName: copilotInstall.packageName,
152
- packageVersion: copilotInstall.packageVersion ?? null,
155
+ source: copilotInstall.source,
153
156
  },
154
157
  copilotAuth,
155
158
  copilotBridge,
@@ -43,9 +43,8 @@ const errors_1 = require("../domain/errors");
43
43
  const codex_probe_1 = require("../runtime/codex-probe");
44
44
  const auth_repo_1 = require("../storage/auth-repo");
45
45
  const providers_1 = require("../domain/providers");
46
- const copilot_installer_1 = require("../runtime/copilot-installer");
46
+ const copilot_token_1 = require("../runtime/copilot-token");
47
47
  const copilot_bridge_1 = require("../runtime/copilot-bridge");
48
- const copilot_adapter_1 = require("../runtime/copilot-adapter");
49
48
  const runtime_state_repo_1 = require("../storage/runtime-state-repo");
50
49
  const codex_version_1 = require("../runtime/codex-version");
51
50
  /**
@@ -125,25 +124,25 @@ async function runDoctor(args) {
125
124
  if (matches.length === 1) {
126
125
  const activeProvider = providers.providers[matches[0]];
127
126
  if ((0, providers_1.isCopilotBridgeProvider)(activeProvider)) {
128
- const installStatus = (0, copilot_installer_1.probeCopilotSdkInstall)(args.runtimesDir);
129
- if (!installStatus.installed) {
127
+ const githubToken = (0, copilot_token_1.readGithubToken)(args.toolHomeDir);
128
+ if (!githubToken) {
130
129
  issues.push({
131
- code: "COPILOT_SDK_MISSING",
132
- message: "The optional Copilot SDK runtime is not installed.",
133
- installDir: installStatus.installDir,
134
- packageName: installStatus.packageName,
130
+ code: "COPILOT_AUTH_REQUIRED",
131
+ message: "GitHub Copilot authentication is required. Run `codexs login copilot`.",
135
132
  });
136
133
  }
137
- try {
138
- await (0, copilot_adapter_1.readCopilotAuthState)(args.runtimesDir);
139
- }
140
- catch (error) {
141
- const normalized = (0, errors_1.normalizeError)(error);
142
- issues.push({
143
- code: normalized.code,
144
- message: normalized.message,
145
- ...(normalized.details ?? {}),
146
- });
134
+ else {
135
+ try {
136
+ await (0, copilot_token_1.exchangeForCopilotToken)(githubToken);
137
+ }
138
+ catch (error) {
139
+ const normalized = (0, errors_1.normalizeError)(error);
140
+ issues.push({
141
+ code: normalized.code,
142
+ message: normalized.message,
143
+ ...(normalized.details ?? {}),
144
+ });
145
+ }
147
146
  }
148
147
  const bridge = await (0, copilot_bridge_1.probeCopilotBridgeRuntime)(activeProvider, runtimeState, args.runtimeDir);
149
148
  if (!bridge.ok) {
@@ -6,8 +6,7 @@ const config_repo_1 = require("../storage/config-repo");
6
6
  const auth_repo_1 = require("../storage/auth-repo");
7
7
  const providers_repo_1 = require("../storage/providers-repo");
8
8
  const copilot_bridge_1 = require("../runtime/copilot-bridge");
9
- const copilot_installer_1 = require("../runtime/copilot-installer");
10
- const copilot_adapter_1 = require("../runtime/copilot-adapter");
9
+ const copilot_token_1 = require("../runtime/copilot-token");
11
10
  const run_mutation_1 = require("./run-mutation");
12
11
  const providers_1 = require("../domain/providers");
13
12
  /**
@@ -33,16 +32,12 @@ async function switchProvider(args) {
33
32
  });
34
33
  }
35
34
  if ((0, providers_1.isCopilotBridgeProvider)(provider)) {
36
- (0, copilot_installer_1.assertCopilotNodeRuntimeSupported)();
37
- const installStatus = (0, copilot_installer_1.probeCopilotSdkInstall)(args.runtimesDir);
38
- if (!installStatus.installed) {
39
- throw (0, errors_1.cliError)("COPILOT_SDK_MISSING", "The optional Copilot SDK runtime is not installed.", {
40
- installDir: installStatus.installDir,
41
- packageName: installStatus.packageName,
42
- });
35
+ const githubToken = (0, copilot_token_1.readGithubToken)(args.toolHomeDir);
36
+ if (!githubToken) {
37
+ throw (0, errors_1.cliError)("COPILOT_AUTH_REQUIRED", "GitHub Copilot authentication is required. Run `codexs login copilot` first.");
43
38
  }
44
- await (0, copilot_adapter_1.readCopilotAuthState)(args.runtimesDir);
45
- const bridge = await (0, copilot_bridge_1.ensureCopilotBridge)(args.providerName, provider, args.runtimeDir, args.runtimesDir);
39
+ await (0, copilot_token_1.exchangeForCopilotToken)(githubToken);
40
+ const bridge = await (0, copilot_bridge_1.ensureCopilotBridge)(args.providerName, provider, args.runtimeDir, args.runtimesDir, args.toolHomeDir);
46
41
  const nextProvider = bridge.portChanged
47
42
  ? (0, providers_1.cleanProviderRecord)({
48
43
  ...provider,
@@ -60,9 +60,7 @@ const providers_1 = require("../domain/providers");
60
60
  const add_interactive_1 = require("../interaction/add-interactive");
61
61
  const interactive_1 = require("../interaction/interactive");
62
62
  const prompt_1 = require("../interaction/prompt");
63
- const copilot_adapter_1 = require("../runtime/copilot-adapter");
64
- const copilot_cli_1 = require("../runtime/copilot-cli");
65
- const copilot_installer_1 = require("../runtime/copilot-installer");
63
+ const copilot_token_1 = require("../runtime/copilot-token");
66
64
  const config_repo_1 = require("../storage/config-repo");
67
65
  const codex_paths_1 = require("../storage/codex-paths");
68
66
  const providers_repo_1 = require("../storage/providers-repo");
@@ -100,6 +98,7 @@ async function handleRegisteredCommand(ctx, parsed, runtime = (0, prompt_1.creat
100
98
  return (0, get_status_1.getStatus)(paths.codexDir, paths.configPath, paths.providersPath, paths.authPath, {
101
99
  runtimeDir: paths.runtimeDir,
102
100
  runtimesDir: paths.runtimesDir,
101
+ toolHomeDir: paths.toolHomeDir,
103
102
  });
104
103
  case "bridge-start": {
105
104
  const providerName = parsed.positionals[0] ?? null;
@@ -108,6 +107,7 @@ async function handleRegisteredCommand(ctx, parsed, runtime = (0, prompt_1.creat
108
107
  configPath: paths.configPath,
109
108
  runtimeDir: paths.runtimeDir,
110
109
  runtimesDir: paths.runtimesDir,
110
+ toolHomeDir: paths.toolHomeDir,
111
111
  providerName,
112
112
  runtime,
113
113
  json: ctx.options.json,
@@ -156,80 +156,41 @@ async function handleRegisteredCommand(ctx, parsed, runtime = (0, prompt_1.creat
156
156
  supportedUpstreams: ["copilot", "github-copilot"],
157
157
  });
158
158
  }
159
- (0, copilot_installer_1.assertCopilotNodeRuntimeSupported)();
160
- const installed = (0, copilot_installer_1.probeCopilotSdkInstall)(paths.runtimesDir);
161
- let installedNow = false;
162
- if (!installed.installed) {
163
- const confirmInstall = await runtime.confirmAction("The Copilot SDK runtime is not installed. Install it now?", {
164
- defaultValue: true,
165
- });
166
- if (!confirmInstall) {
167
- throw (0, errors_1.cliError)("COPILOT_SDK_MISSING", "The optional Copilot SDK runtime is not installed.", {
168
- installDir: installed.installDir,
169
- packageName: installed.packageName,
170
- });
171
- }
172
- runtime.writeLine("Installing Copilot SDK runtime...");
173
- (0, copilot_installer_1.installCopilotSdk)(paths.runtimesDir);
174
- installedNow = true;
175
- }
176
- const availability = (0, copilot_cli_1.checkCopilotCliAvailable)(paths.runtimesDir);
177
- try {
178
- await (0, copilot_adapter_1.readCopilotAuthState)(paths.runtimesDir);
179
- return {
180
- data: {
181
- upstream: "github-copilot",
182
- sdkInstalled: true,
183
- sdkInstalledNow: installedNow,
184
- authReady: true,
185
- loginLaunched: false,
186
- cliSource: availability.ok ? availability.source ?? null : null,
187
- cliCommand: availability.command ?? null,
188
- },
189
- };
190
- }
191
- catch (error) {
192
- const normalized = (0, errors_1.normalizeError)(error);
193
- if (normalized.code !== "COPILOT_AUTH_REQUIRED") {
194
- throw error;
159
+ // Check if already authenticated
160
+ const existingToken = (0, copilot_token_1.readGithubToken)(paths.toolHomeDir);
161
+ if (existingToken) {
162
+ try {
163
+ await (0, copilot_token_1.exchangeForCopilotToken)(existingToken);
164
+ return {
165
+ data: {
166
+ upstream: "github-copilot",
167
+ authReady: true,
168
+ loginLaunched: false,
169
+ authSource: "github-pat",
170
+ },
171
+ };
195
172
  }
196
- }
197
- if (!availability.ok) {
198
- throw (0, errors_1.cliError)("COPILOT_CLI_MISSING", "The official Copilot CLI could not be resolved from the installed runtime or PATH.", {
199
- cause: availability.cause,
200
- source: availability.source ?? null,
201
- command: availability.command ?? null,
202
- });
203
- }
204
- try {
205
- (0, copilot_cli_1.runCopilotLogin)({ runtimesDir: paths.runtimesDir });
206
- }
207
- catch (error) {
208
- throw (0, errors_1.cliError)("COPILOT_LOGIN_LAUNCH_FAILED", "Failed to launch `copilot login`.", {
209
- cause: error instanceof Error ? error.message : String(error),
210
- });
211
- }
212
- try {
213
- await (0, copilot_adapter_1.readCopilotAuthState)(paths.runtimesDir);
214
- }
215
- catch (error) {
216
- const normalized = (0, errors_1.normalizeError)(error);
217
- if (normalized.code === "COPILOT_AUTH_REQUIRED") {
218
- throw (0, errors_1.cliError)("COPILOT_LOGIN_RECHECK_FAILED", "Copilot login completed but auth readiness recheck still failed.", {
219
- ...(normalized.details ?? {}),
220
- });
173
+ catch {
174
+ // Token is invalid, proceed with new login
221
175
  }
222
- throw error;
223
176
  }
177
+ // Start GitHub OAuth Device Flow
178
+ runtime.writeLine("Starting GitHub authentication...");
179
+ const deviceFlow = await (0, copilot_token_1.startDeviceFlow)();
180
+ runtime.writeLine(`\nPlease visit: ${deviceFlow.verificationUri}`);
181
+ runtime.writeLine(`And enter code: ${deviceFlow.userCode}\n`);
182
+ runtime.writeLine("Waiting for authorization...");
183
+ const githubPat = await (0, copilot_token_1.pollDeviceFlowToken)(deviceFlow.deviceCode, deviceFlow.interval, deviceFlow.expiresIn);
184
+ // Validate the token by doing a test exchange
185
+ await (0, copilot_token_1.exchangeForCopilotToken)(githubPat);
186
+ (0, copilot_token_1.writeGithubToken)(githubPat, paths.toolHomeDir);
187
+ runtime.writeLine("GitHub Copilot authentication successful!");
224
188
  return {
225
189
  data: {
226
190
  upstream: "github-copilot",
227
- sdkInstalled: true,
228
- sdkInstalledNow: installedNow,
229
191
  authReady: true,
230
192
  loginLaunched: true,
231
- cliSource: availability.source ?? null,
232
- cliCommand: availability.command ?? null,
193
+ authSource: "github-pat",
233
194
  },
234
195
  };
235
196
  }
@@ -267,6 +228,7 @@ async function handleRegisteredCommand(ctx, parsed, runtime = (0, prompt_1.creat
267
228
  authPath: paths.authPath,
268
229
  runtimeDir: paths.runtimeDir,
269
230
  runtimesDir: paths.runtimesDir,
231
+ toolHomeDir: paths.toolHomeDir,
270
232
  providerName,
271
233
  });
272
234
  }
@@ -507,6 +469,7 @@ async function handleRegisteredCommand(ctx, parsed, runtime = (0, prompt_1.creat
507
469
  authPath: paths.authPath,
508
470
  runtimeDir: paths.runtimeDir,
509
471
  runtimesDir: paths.runtimesDir,
472
+ toolHomeDir: paths.toolHomeDir,
510
473
  });
511
474
  case "migrate": {
512
475
  let codexDir = ctx.options.codexDir;
@@ -88,7 +88,7 @@ function cleanProviderRecord(record) {
88
88
  next.tags = record.tags.map((tag) => tag.trim()).filter((tag) => tag.length > 0);
89
89
  }
90
90
  if (record.runtime) {
91
- next.runtime = {
91
+ const cleanedRuntime = {
92
92
  kind: record.runtime.kind,
93
93
  upstream: record.runtime.upstream,
94
94
  bridgeHost: record.runtime.bridgeHost.trim(),
@@ -96,8 +96,11 @@ function cleanProviderRecord(record) {
96
96
  bridgePath: record.runtime.bridgePath,
97
97
  premiumRequests: record.runtime.premiumRequests,
98
98
  authSource: record.runtime.authSource,
99
- sdkInstallMode: record.runtime.sdkInstallMode,
100
99
  };
100
+ if (record.runtime.sdkInstallMode) {
101
+ cleanedRuntime.sdkInstallMode = record.runtime.sdkInstallMode;
102
+ }
103
+ next.runtime = cleanedRuntime;
101
104
  }
102
105
  return next;
103
106
  }
@@ -148,10 +151,10 @@ function isRuntimeBackedProvider(provider) {
148
151
  return Boolean(provider.runtime);
149
152
  }
150
153
  /**
151
- * Returns whether one provider uses the GitHub Copilot SDK bridge runtime.
154
+ * Returns whether one provider uses the GitHub Copilot bridge runtime.
152
155
  */
153
156
  function isCopilotBridgeProvider(provider) {
154
- return provider.runtime?.kind === "copilot-sdk-bridge";
157
+ return provider.runtime?.kind === "copilot-http-proxy" || provider.runtime?.kind === "copilot-sdk-bridge";
155
158
  }
156
159
  /**
157
160
  * Builds the canonical local bridge URL for one Copilot runtime provider.
@@ -194,7 +197,7 @@ function validateProviderRuntime(name, runtime) {
194
197
  throw new Error(`Provider "${name}" has an invalid runtime block.`);
195
198
  }
196
199
  const record = runtime;
197
- if (record.kind !== "copilot-sdk-bridge") {
200
+ if (record.kind !== "copilot-http-proxy" && record.kind !== "copilot-sdk-bridge") {
198
201
  throw new Error(`Provider "${name}" has an unsupported runtime kind.`);
199
202
  }
200
203
  if (record.upstream !== "github-copilot") {
@@ -212,10 +215,7 @@ function validateProviderRuntime(name, runtime) {
212
215
  if (record.premiumRequests !== true) {
213
216
  throw new Error(`Provider "${name}" must enable runtime premiumRequests.`);
214
217
  }
215
- if (record.authSource !== "official-sdk") {
218
+ if (record.authSource !== "github-pat" && record.authSource !== "official-sdk") {
216
219
  throw new Error(`Provider "${name}" has an invalid runtime authSource.`);
217
220
  }
218
- if (record.sdkInstallMode !== "lazy") {
219
- throw new Error(`Provider "${name}" has an invalid runtime sdkInstallMode.`);
220
- }
221
221
  }
@@ -340,7 +340,12 @@ async function stopCopilotClient(client) {
340
340
  async function abortCopilotSession(session) {
341
341
  const abort = resolveCallable(session, "abort");
342
342
  if (abort) {
343
- await Promise.resolve(abort());
343
+ try {
344
+ await Promise.resolve(abort());
345
+ }
346
+ catch {
347
+ // Session may already be closed or unknown — safe to ignore
348
+ }
344
349
  }
345
350
  }
346
351
  async function disconnectCopilotSession(session) {