@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.
- package/dist/app/add-provider.js +10 -16
- package/dist/app/bridge.js +8 -13
- package/dist/app/get-status.js +15 -12
- package/dist/app/run-doctor.js +17 -18
- package/dist/app/switch-provider.js +6 -11
- package/dist/commands/handlers.js +32 -69
- package/dist/domain/providers.js +9 -9
- package/dist/runtime/copilot-adapter.js +6 -1
- package/dist/runtime/copilot-bridge.js +109 -76
- package/dist/runtime/copilot-http-bridge-worker.js +228 -0
- package/dist/runtime/copilot-token.js +294 -0
- package/docs/Design/codex-switch-v0.2.0-design.md +56 -0
- package/package.json +1 -1
package/dist/app/add-provider.js
CHANGED
|
@@ -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
|
|
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-
|
|
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: "
|
|
66
|
-
sdkInstallMode: "lazy",
|
|
64
|
+
authSource: "github-pat",
|
|
67
65
|
}
|
|
68
66
|
: undefined;
|
|
69
67
|
if (args.copilot) {
|
|
70
|
-
(0,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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,
|
|
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", "
|
|
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
|
}
|
package/dist/app/bridge.js
CHANGED
|
@@ -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
|
|
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(
|
|
256
|
-
(0,
|
|
257
|
-
|
|
258
|
-
|
|
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,
|
|
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.
|
package/dist/app/get-status.js
CHANGED
|
@@ -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
|
|
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,
|
|
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 (
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
151
|
-
packageName: copilotInstall.packageName,
|
|
152
|
-
packageVersion: copilotInstall.packageVersion ?? null,
|
|
155
|
+
source: copilotInstall.source,
|
|
153
156
|
},
|
|
154
157
|
copilotAuth,
|
|
155
158
|
copilotBridge,
|
package/dist/app/run-doctor.js
CHANGED
|
@@ -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
|
|
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
|
|
129
|
-
if (!
|
|
127
|
+
const githubToken = (0, copilot_token_1.readGithubToken)(args.toolHomeDir);
|
|
128
|
+
if (!githubToken) {
|
|
130
129
|
issues.push({
|
|
131
|
-
code: "
|
|
132
|
-
message: "
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
|
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,
|
|
37
|
-
|
|
38
|
-
|
|
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,
|
|
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
|
|
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
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
package/dist/domain/providers.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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) {
|