@ai-sdk/harness-github-copilot 1.0.28 → 1.0.30
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/CHANGELOG.md +24 -0
- package/dist/index.d.ts +11756 -11755
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +509 -626
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
- package/src/github-copilot-harness.ts +2 -1
- package/src/index.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -1,655 +1,538 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
commonTool
|
|
5
|
-
} from "@ai-sdk/harness";
|
|
6
|
-
import {
|
|
7
|
-
createCredentialRequestTransformation,
|
|
8
|
-
isSandboxCredentialPlaceholder
|
|
9
|
-
} from "@ai-sdk/harness/utils";
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { commonTool } from "@ai-sdk/harness";
|
|
3
|
+
import { createCredentialRequestTransformation, isHarnessAuthenticationEnvironment, isLinux, isMacOS, isSandboxCredentialPlaceholder, isWindows, readLinuxSecretServicePassword, readMacOSKeychainPassword, readWindowsCredentialManagerPassword, shouldResolveNativeSubscription } from "@ai-sdk/harness/utils";
|
|
10
4
|
import { createACP } from "@ai-sdk/harness-acp";
|
|
11
|
-
import { tool } from "@ai-sdk/provider-utils";
|
|
5
|
+
import { isRecord, tool } from "@ai-sdk/provider-utils";
|
|
12
6
|
import { z } from "zod/v4";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { join, resolve } from "path";
|
|
20
|
-
import { promisify } from "util";
|
|
21
|
-
import {
|
|
22
|
-
isHarnessAuthenticationEnvironment,
|
|
23
|
-
isLinux,
|
|
24
|
-
isMacOS,
|
|
25
|
-
isWindows,
|
|
26
|
-
readLinuxSecretServicePassword,
|
|
27
|
-
readMacOSKeychainPassword,
|
|
28
|
-
readWindowsCredentialManagerPassword,
|
|
29
|
-
shouldResolveNativeSubscription
|
|
30
|
-
} from "@ai-sdk/harness/utils";
|
|
31
|
-
import { isRecord } from "@ai-sdk/provider-utils";
|
|
7
|
+
import { execFile } from "node:child_process";
|
|
8
|
+
import { constants } from "node:fs";
|
|
9
|
+
import { access, readFile } from "node:fs/promises";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import { join, resolve } from "node:path";
|
|
12
|
+
import { promisify } from "node:util";
|
|
32
13
|
import { parse } from "jsonc-parser";
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
...env,
|
|
52
|
-
COPILOT_GITHUB_TOKEN: subscription.token,
|
|
53
|
-
COPILOT_GH_HOST: normalizeGitHubHost(subscription.host)
|
|
54
|
-
};
|
|
14
|
+
//#region src/github-copilot-subscription.ts
|
|
15
|
+
const COPILOT_KEYRING_SERVICE = "copilot-cli";
|
|
16
|
+
const execFileAsync = promisify(execFile);
|
|
17
|
+
async function resolveGitHubCopilotSubscriptionEnvironment({ auth, env, readSubscription = readGitHubCopilotSubscription }) {
|
|
18
|
+
if (isHarnessAuthenticationEnvironment(auth)) return auth;
|
|
19
|
+
if (!shouldResolveNativeSubscription({
|
|
20
|
+
auth,
|
|
21
|
+
env,
|
|
22
|
+
hasDirectCredential: env.COPILOT_GITHUB_TOKEN != null || env.GH_TOKEN != null || env.GITHUB_TOKEN != null
|
|
23
|
+
})) return env;
|
|
24
|
+
const subscription = await readSubscription({ env });
|
|
25
|
+
if (subscription == null) return env;
|
|
26
|
+
return {
|
|
27
|
+
...env,
|
|
28
|
+
COPILOT_GITHUB_TOKEN: subscription.token,
|
|
29
|
+
COPILOT_GH_HOST: normalizeGitHubHost(subscription.host)
|
|
30
|
+
};
|
|
55
31
|
}
|
|
56
|
-
async function readGitHubCopilotSubscription({
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
32
|
+
async function readGitHubCopilotSubscription({ env = process.env, homeDirectory = homedir(), platform = process.platform, readSecureCredential, findGitHubCliExecutable = findHostGitHubCliExecutable, readGitHubCliToken = readHostGitHubCliToken } = {}) {
|
|
33
|
+
const copilotHome = resolve(env.COPILOT_HOME ?? join(homeDirectory, ".copilot"));
|
|
34
|
+
const config = await readGitHubCopilotConfig({ path: join(copilotHome, "config.json") });
|
|
35
|
+
const account = selectGitHubCopilotAccount({ config });
|
|
36
|
+
if (account != null) {
|
|
37
|
+
const accountKey = `${account.host}:${account.login}`;
|
|
38
|
+
const secureToken = await (readSecureCredential ?? ((options) => readGitHubCopilotSecureCredential({
|
|
39
|
+
...options,
|
|
40
|
+
platform
|
|
41
|
+
})))({
|
|
42
|
+
service: COPILOT_KEYRING_SERVICE,
|
|
43
|
+
account: accountKey
|
|
44
|
+
}).catch(() => void 0);
|
|
45
|
+
if (isNonEmptyString(secureToken)) return {
|
|
46
|
+
token: secureToken,
|
|
47
|
+
host: account.host
|
|
48
|
+
};
|
|
49
|
+
const plaintextToken = getPlaintextToken({
|
|
50
|
+
config,
|
|
51
|
+
accountKey
|
|
52
|
+
});
|
|
53
|
+
if (plaintextToken != null) return {
|
|
54
|
+
token: plaintextToken,
|
|
55
|
+
host: account.host
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const host = account?.host ?? normalizeGitHubOrigin(env.COPILOT_GH_HOST ?? env.GH_HOST ?? "github.com");
|
|
59
|
+
if (host == null) return void 0;
|
|
60
|
+
const executable = await findGitHubCliExecutable({
|
|
61
|
+
env,
|
|
62
|
+
platform
|
|
63
|
+
});
|
|
64
|
+
if (executable == null) return void 0;
|
|
65
|
+
const token = await readGitHubCliToken({
|
|
66
|
+
executable,
|
|
67
|
+
hostname: normalizeGitHubHost(host),
|
|
68
|
+
env
|
|
69
|
+
}).catch(() => void 0);
|
|
70
|
+
return isNonEmptyString(token) ? {
|
|
71
|
+
token: token.trim(),
|
|
72
|
+
host
|
|
73
|
+
} : void 0;
|
|
95
74
|
}
|
|
96
|
-
async function findHostGitHubCliExecutable({
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
} catch {
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
75
|
+
async function findHostGitHubCliExecutable({ env, platform }) {
|
|
76
|
+
const path = env.PATH ?? env.Path ?? env.path;
|
|
77
|
+
if (path == null) return void 0;
|
|
78
|
+
const separator = isWindows(platform) ? ";" : ":";
|
|
79
|
+
const names = isWindows(platform) ? getWindowsGitHubCliExecutableNames({ pathExt: env.PATHEXT }) : ["gh"];
|
|
80
|
+
const mode = isWindows(platform) ? constants.F_OK : constants.X_OK;
|
|
81
|
+
for (const directory of path.split(separator)) {
|
|
82
|
+
const normalizedDirectory = directory.replace(/^"|"$/g, "");
|
|
83
|
+
if (normalizedDirectory.length === 0) continue;
|
|
84
|
+
for (const executableName of names) {
|
|
85
|
+
const candidate = resolve(normalizedDirectory, executableName);
|
|
86
|
+
try {
|
|
87
|
+
await access(candidate, mode);
|
|
88
|
+
return candidate;
|
|
89
|
+
} catch {}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
117
92
|
}
|
|
118
|
-
async function readGitHubCopilotConfig({
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const value = parse(text, errors, { allowTrailingComma: true });
|
|
125
|
-
return errors.length === 0 && isRecord(value) ? value : void 0;
|
|
93
|
+
async function readGitHubCopilotConfig({ path }) {
|
|
94
|
+
const text = await readFile(path, "utf8").catch(() => void 0);
|
|
95
|
+
if (text == null) return void 0;
|
|
96
|
+
const errors = [];
|
|
97
|
+
const value = parse(text, errors, { allowTrailingComma: true });
|
|
98
|
+
return errors.length === 0 && isRecord(value) ? value : void 0;
|
|
126
99
|
}
|
|
127
|
-
function selectGitHubCopilotAccount({
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
}
|
|
100
|
+
function selectGitHubCopilotAccount({ config }) {
|
|
101
|
+
if (config == null) return void 0;
|
|
102
|
+
for (const value of [config.last_logged_in_user, config.lastLoggedInUser]) {
|
|
103
|
+
const account = toGitHubCopilotAccount(value);
|
|
104
|
+
if (account != null) return account;
|
|
105
|
+
}
|
|
106
|
+
for (const values of [config.logged_in_users, config.loggedInUsers]) {
|
|
107
|
+
if (!Array.isArray(values)) continue;
|
|
108
|
+
for (const value of values) {
|
|
109
|
+
const account = toGitHubCopilotAccount(value);
|
|
110
|
+
if (account != null) return account;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
142
113
|
}
|
|
143
114
|
function toGitHubCopilotAccount(value) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
115
|
+
if (!isRecord(value) || !isNonEmptyString(value.host) || !isNonEmptyString(value.login)) return;
|
|
116
|
+
const host = normalizeGitHubOrigin(value.host);
|
|
117
|
+
return host == null ? void 0 : {
|
|
118
|
+
host,
|
|
119
|
+
login: value.login
|
|
120
|
+
};
|
|
149
121
|
}
|
|
150
|
-
function getPlaintextToken({
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (config == null || !isRecord(config.copilotTokens)) return void 0;
|
|
155
|
-
const token = config.copilotTokens[accountKey];
|
|
156
|
-
return isNonEmptyString(token) ? token : void 0;
|
|
122
|
+
function getPlaintextToken({ config, accountKey }) {
|
|
123
|
+
if (config == null || !isRecord(config.copilotTokens)) return void 0;
|
|
124
|
+
const token = config.copilotTokens[accountKey];
|
|
125
|
+
return isNonEmptyString(token) ? token : void 0;
|
|
157
126
|
}
|
|
158
|
-
async function readGitHubCopilotSecureCredential({
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
attributes: { service, username: account }
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
if (isWindows(platform)) {
|
|
172
|
-
return readWindowsCredentialManagerPassword({
|
|
173
|
-
targetName: `${account}.${service}`
|
|
174
|
-
});
|
|
175
|
-
}
|
|
127
|
+
async function readGitHubCopilotSecureCredential({ service, account, platform }) {
|
|
128
|
+
if (isMacOS(platform)) return readMacOSKeychainPassword({
|
|
129
|
+
service,
|
|
130
|
+
account
|
|
131
|
+
});
|
|
132
|
+
if (isLinux(platform)) return readLinuxSecretServicePassword({ attributes: {
|
|
133
|
+
service,
|
|
134
|
+
username: account
|
|
135
|
+
} });
|
|
136
|
+
if (isWindows(platform)) return readWindowsCredentialManagerPassword({ targetName: `${account}.${service}` });
|
|
176
137
|
}
|
|
177
|
-
async function readHostGitHubCliToken({
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
} catch {
|
|
194
|
-
return void 0;
|
|
195
|
-
}
|
|
138
|
+
async function readHostGitHubCliToken({ executable, hostname, env }) {
|
|
139
|
+
try {
|
|
140
|
+
const result = await execFileAsync(executable, [
|
|
141
|
+
"auth",
|
|
142
|
+
"token",
|
|
143
|
+
"--hostname",
|
|
144
|
+
hostname
|
|
145
|
+
], {
|
|
146
|
+
env: { ...env },
|
|
147
|
+
timeout: 1e4,
|
|
148
|
+
windowsHide: true
|
|
149
|
+
});
|
|
150
|
+
return isNonEmptyString(result.stdout) ? result.stdout.trim() : void 0;
|
|
151
|
+
} catch {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
196
154
|
}
|
|
197
|
-
function getWindowsGitHubCliExecutableNames({
|
|
198
|
-
|
|
199
|
-
}) {
|
|
200
|
-
const extensions = (pathExt ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(isNonEmptyString);
|
|
201
|
-
return ["gh", ...extensions.map((extension) => `gh${extension}`)];
|
|
155
|
+
function getWindowsGitHubCliExecutableNames({ pathExt }) {
|
|
156
|
+
return ["gh", ...(pathExt ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(isNonEmptyString).map((extension) => `gh${extension}`)];
|
|
202
157
|
}
|
|
203
158
|
function normalizeGitHubOrigin(host) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
159
|
+
try {
|
|
160
|
+
return new URL(host.includes("://") ? host : `https://${host}`).origin;
|
|
161
|
+
} catch {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
209
164
|
}
|
|
210
165
|
function normalizeGitHubHost(host) {
|
|
211
|
-
|
|
166
|
+
return new URL(host.includes("://") ? host : `https://${host}`).hostname;
|
|
212
167
|
}
|
|
213
168
|
function isNonEmptyString(value) {
|
|
214
|
-
|
|
169
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
215
170
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region src/version.ts
|
|
173
|
+
const VERSION = "1.0.30";
|
|
174
|
+
//#endregion
|
|
175
|
+
//#region src/github-copilot-harness.ts
|
|
176
|
+
const GITHUB_COPILOT_CLIENT_APP = {
|
|
177
|
+
name: "ai-sdk-harness-github-copilot",
|
|
178
|
+
version: VERSION
|
|
224
179
|
};
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
180
|
+
const GITHUB_COPILOT_IMPLEMENTATION_PACKAGE_JSON = "{\n \"name\": \"harness-github-copilot-bridge\",\n \"version\": \"0.0.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@github/copilot\": \"1.0.86\"\n }\n}\n";
|
|
181
|
+
const GITHUB_COPILOT_IMPLEMENTATION_PNPM_LOCK = "lockfileVersion: '9.0'\n\nsettings:\n autoInstallPeers: true\n excludeLinksFromLockfile: false\n\nimporters:\n\n .:\n dependencies:\n '@github/copilot':\n specifier: 1.0.86\n version: 1.0.86\n\npackages:\n\n '@github/copilot-darwin-arm64@1.0.86':\n resolution: {integrity: sha512-OinxattAYZqcVCQPPdlcgMga5a8BgVOXzz9F9qulUOIv+98fWE2mRX7R1s1W+LrqxmHQts6TKROXOBWtcRpdHA==}\n cpu: [arm64]\n os: [darwin]\n hasBin: true\n\n '@github/copilot-darwin-x64@1.0.86':\n resolution: {integrity: sha512-YXOsXwDvXa6nQDdw3GRukJ1mOPiw/lCnL4hjxhs7lSlcI6Eep/6qnKHrRtWE+pGjLgrgxGRa5grjpr1oq4HitA==}\n cpu: [x64]\n os: [darwin]\n hasBin: true\n\n '@github/copilot-linux-arm64@1.0.86':\n resolution: {integrity: sha512-HbzCTIsfr7XrX+A+PzdzPrTAahkycizof/7jD66yKlUlSiDK1aOtQSymK8vIViMZfEhSZrY9OUp4atBEmnfk+w==}\n cpu: [arm64]\n os: [linux]\n libc: [glibc]\n hasBin: true\n\n '@github/copilot-linux-x64@1.0.86':\n resolution: {integrity: sha512-ROyWMEP8nKFoa+7l2majzfgA5jaqid0qEYTClf9oooS+8S6CIhKYlW1VO6Lt3lDicoCI1S2RWbR7vJ6ZQy/TFw==}\n cpu: [x64]\n os: [linux]\n libc: [glibc]\n hasBin: true\n\n '@github/copilot-linuxmusl-arm64@1.0.86':\n resolution: {integrity: sha512-JcUBGRDgoIa97pudDCfNPUsKpLwpymWf0nWaVlDiKp4U7NW4BD6AGehlsYsOOcUL6b4IooApQ6XDwjOlg/PYvw==}\n cpu: [arm64]\n os: [linux]\n libc: [musl]\n hasBin: true\n\n '@github/copilot-linuxmusl-x64@1.0.86':\n resolution: {integrity: sha512-+BmL8Ud4A5OxHTqci6mR/twNbVQh6yho6yFGermaH73cRo0CLC17Hkxo2MU3HoH8BYmtJeiXiJ2YB7lsWax1mA==}\n cpu: [x64]\n os: [linux]\n libc: [musl]\n hasBin: true\n\n '@github/copilot-win32-arm64@1.0.86':\n resolution: {integrity: sha512-sFxcEv21/6r+HS6T3LIU40KMV80jIEIU4P3enqjqhTBH5wQiF1+TVsVNn+jlI5UIV7+P1jjP6JujuLAAwoC6UA==}\n cpu: [arm64]\n os: [win32]\n hasBin: true\n\n '@github/copilot-win32-x64@1.0.86':\n resolution: {integrity: sha512-U/O/eXe/Q8ndEgSFFscZxhbYpAJ9jFRvBclFW0zsoTX8h2nGxoC1seVxpeqXGQezOsKdMT/fIYWG2XfhPQ/gsg==}\n cpu: [x64]\n os: [win32]\n hasBin: true\n\n '@github/copilot@1.0.86':\n resolution: {integrity: sha512-ytl6vkox1l6Y+UqLhX0+SOuTkS84VCp8R2CJqzgJ8QfnOlWe3U6z1ZVRm/sYWGMLchWQpnC7d+wWZ1mTUTFuuQ==}\n hasBin: true\n\n detect-libc@2.1.2:\n resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}\n engines: {node: '>=8'}\n\nsnapshots:\n\n '@github/copilot-darwin-arm64@1.0.86':\n optional: true\n\n '@github/copilot-darwin-x64@1.0.86':\n optional: true\n\n '@github/copilot-linux-arm64@1.0.86':\n optional: true\n\n '@github/copilot-linux-x64@1.0.86':\n optional: true\n\n '@github/copilot-linuxmusl-arm64@1.0.86':\n optional: true\n\n '@github/copilot-linuxmusl-x64@1.0.86':\n optional: true\n\n '@github/copilot-win32-arm64@1.0.86':\n optional: true\n\n '@github/copilot-win32-x64@1.0.86':\n optional: true\n\n '@github/copilot@1.0.86':\n dependencies:\n detect-libc: 2.1.2\n optionalDependencies:\n '@github/copilot-darwin-arm64': 1.0.86\n '@github/copilot-darwin-x64': 1.0.86\n '@github/copilot-linux-arm64': 1.0.86\n '@github/copilot-linux-x64': 1.0.86\n '@github/copilot-linuxmusl-arm64': 1.0.86\n '@github/copilot-linuxmusl-x64': 1.0.86\n '@github/copilot-win32-arm64': 1.0.86\n '@github/copilot-win32-x64': 1.0.86\n\n detect-libc@2.1.2: {}\n";
|
|
182
|
+
const GITHUB_COPILOT_IMPLEMENTATION_PNPM_WORKSPACE = "allowBuilds:\n '@github/copilot@1.0.86': true\n";
|
|
183
|
+
const GITHUB_COPILOT_TOKEN_ENVIRONMENT_VARIABLES = /* @__PURE__ */ new Set([
|
|
184
|
+
"COPILOT_GITHUB_TOKEN",
|
|
185
|
+
"GH_TOKEN",
|
|
186
|
+
"GITHUB_TOKEN"
|
|
232
187
|
]);
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
188
|
+
const GITHUB_OAUTH_SANDBOX_CREDENTIAL_MARKER = "aisdkhc";
|
|
189
|
+
const GITHUB_COPILOT_BUILTIN_TOOLS = {
|
|
190
|
+
bash: { ...commonTool("bash", {
|
|
191
|
+
nativeName: "bash",
|
|
192
|
+
toolUseKind: "bash",
|
|
193
|
+
inputSchema: z.looseObject({
|
|
194
|
+
command: z.string(),
|
|
195
|
+
description: z.string().optional(),
|
|
196
|
+
shellId: z.string().optional(),
|
|
197
|
+
mode: z.enum(["sync", "async"]).optional(),
|
|
198
|
+
detach: z.boolean().optional(),
|
|
199
|
+
initial_wait: z.number().optional()
|
|
200
|
+
})
|
|
201
|
+
}) },
|
|
202
|
+
read_bash: {
|
|
203
|
+
...tool({
|
|
204
|
+
title: "Reading shell output",
|
|
205
|
+
inputSchema: z.looseObject({
|
|
206
|
+
shellId: z.string(),
|
|
207
|
+
delay: z.number()
|
|
208
|
+
})
|
|
209
|
+
}),
|
|
210
|
+
toolUseKind: "readonly"
|
|
211
|
+
},
|
|
212
|
+
stop_bash: {
|
|
213
|
+
...tool({
|
|
214
|
+
title: "Stopping shell session",
|
|
215
|
+
inputSchema: z.looseObject({ shellId: z.string() })
|
|
216
|
+
}),
|
|
217
|
+
toolUseKind: "bash"
|
|
218
|
+
},
|
|
219
|
+
list_bash: {
|
|
220
|
+
...tool({
|
|
221
|
+
title: "list_bash",
|
|
222
|
+
inputSchema: z.looseObject({})
|
|
223
|
+
}),
|
|
224
|
+
toolUseKind: "readonly"
|
|
225
|
+
},
|
|
226
|
+
view: {
|
|
227
|
+
...tool({
|
|
228
|
+
title: "Viewing ",
|
|
229
|
+
inputSchema: z.looseObject({
|
|
230
|
+
path: z.string(),
|
|
231
|
+
view_range: z.array(z.number()).optional(),
|
|
232
|
+
forceReadLargeFiles: z.boolean().optional()
|
|
233
|
+
})
|
|
234
|
+
}),
|
|
235
|
+
toolUseKind: "readonly"
|
|
236
|
+
},
|
|
237
|
+
create: {
|
|
238
|
+
...tool({
|
|
239
|
+
title: "Creating ",
|
|
240
|
+
inputSchema: z.looseObject({
|
|
241
|
+
path: z.string(),
|
|
242
|
+
file_text: z.string()
|
|
243
|
+
})
|
|
244
|
+
}),
|
|
245
|
+
toolUseKind: "edit"
|
|
246
|
+
},
|
|
247
|
+
edit: {
|
|
248
|
+
...tool({
|
|
249
|
+
title: "Editing ",
|
|
250
|
+
inputSchema: z.looseObject({
|
|
251
|
+
path: z.string(),
|
|
252
|
+
old_str: z.string().optional(),
|
|
253
|
+
new_str: z.string()
|
|
254
|
+
})
|
|
255
|
+
}),
|
|
256
|
+
toolUseKind: "edit"
|
|
257
|
+
},
|
|
258
|
+
web_fetch: {
|
|
259
|
+
...tool({
|
|
260
|
+
title: "Fetching ",
|
|
261
|
+
inputSchema: z.looseObject({
|
|
262
|
+
url: z.string(),
|
|
263
|
+
max_length: z.number().optional(),
|
|
264
|
+
start_index: z.number().optional(),
|
|
265
|
+
raw: z.boolean().optional()
|
|
266
|
+
})
|
|
267
|
+
}),
|
|
268
|
+
toolUseKind: "readonly"
|
|
269
|
+
},
|
|
270
|
+
skill: tool({
|
|
271
|
+
title: "Using skill: ",
|
|
272
|
+
inputSchema: z.looseObject({ skill: z.string() })
|
|
273
|
+
}),
|
|
274
|
+
sql: tool({ inputSchema: z.looseObject({
|
|
275
|
+
description: z.string(),
|
|
276
|
+
query: z.string(),
|
|
277
|
+
database: z.enum(["session", "session_store"]).optional()
|
|
278
|
+
}) }),
|
|
279
|
+
read_agent: {
|
|
280
|
+
...tool({
|
|
281
|
+
title: "read_agent",
|
|
282
|
+
inputSchema: z.looseObject({
|
|
283
|
+
agent_id: z.string(),
|
|
284
|
+
wait: z.boolean().optional(),
|
|
285
|
+
timeout: z.number().optional(),
|
|
286
|
+
since_turn: z.number().int().nonnegative().optional()
|
|
287
|
+
})
|
|
288
|
+
}),
|
|
289
|
+
toolUseKind: "readonly"
|
|
290
|
+
},
|
|
291
|
+
list_agents: {
|
|
292
|
+
...tool({
|
|
293
|
+
title: "list_agents",
|
|
294
|
+
inputSchema: z.looseObject({
|
|
295
|
+
include_completed: z.boolean().optional(),
|
|
296
|
+
scope: z.enum([
|
|
297
|
+
"siblings",
|
|
298
|
+
"children",
|
|
299
|
+
"all"
|
|
300
|
+
]).optional()
|
|
301
|
+
})
|
|
302
|
+
}),
|
|
303
|
+
toolUseKind: "readonly"
|
|
304
|
+
},
|
|
305
|
+
write_agent: tool({
|
|
306
|
+
title: "write_agent",
|
|
307
|
+
inputSchema: z.looseObject({
|
|
308
|
+
message: z.string(),
|
|
309
|
+
agent_id: z.string().optional(),
|
|
310
|
+
agent_ids: z.array(z.string()).optional(),
|
|
311
|
+
scope: z.enum(["siblings", "children"]).optional()
|
|
312
|
+
})
|
|
313
|
+
}),
|
|
314
|
+
grep: {
|
|
315
|
+
...commonTool("grep", {
|
|
316
|
+
nativeName: "grep",
|
|
317
|
+
toolUseKind: "readonly",
|
|
318
|
+
inputSchema: z.looseObject({
|
|
319
|
+
pattern: z.string(),
|
|
320
|
+
path: z.string().optional(),
|
|
321
|
+
paths: z.array(z.string()).optional(),
|
|
322
|
+
glob: z.string().optional(),
|
|
323
|
+
output_mode: z.enum([
|
|
324
|
+
"content",
|
|
325
|
+
"files_with_matches",
|
|
326
|
+
"count"
|
|
327
|
+
]).optional(),
|
|
328
|
+
case_insensitive: z.boolean().optional(),
|
|
329
|
+
multiline: z.boolean().optional(),
|
|
330
|
+
head_limit: z.number().optional(),
|
|
331
|
+
context: z.number().optional(),
|
|
332
|
+
before_context: z.number().optional(),
|
|
333
|
+
after_context: z.number().optional()
|
|
334
|
+
})
|
|
335
|
+
}),
|
|
336
|
+
title: "Searching for "
|
|
337
|
+
},
|
|
338
|
+
glob: {
|
|
339
|
+
...commonTool("glob", {
|
|
340
|
+
nativeName: "glob",
|
|
341
|
+
toolUseKind: "readonly",
|
|
342
|
+
inputSchema: z.looseObject({
|
|
343
|
+
pattern: z.string(),
|
|
344
|
+
paths: z.array(z.string()).optional()
|
|
345
|
+
})
|
|
346
|
+
}),
|
|
347
|
+
title: "Finding files matching "
|
|
348
|
+
},
|
|
349
|
+
task: tool({ inputSchema: z.looseObject({
|
|
350
|
+
name: z.string(),
|
|
351
|
+
prompt: z.string(),
|
|
352
|
+
agent_type: z.enum([
|
|
353
|
+
"explore",
|
|
354
|
+
"task",
|
|
355
|
+
"general-purpose",
|
|
356
|
+
"code-review",
|
|
357
|
+
"research",
|
|
358
|
+
"security-review"
|
|
359
|
+
]),
|
|
360
|
+
description: z.string(),
|
|
361
|
+
model: z.string().optional(),
|
|
362
|
+
context_tier: z.enum(["default", "long_context"]).optional(),
|
|
363
|
+
mode: z.enum(["sync", "background"]).optional()
|
|
364
|
+
}) })
|
|
409
365
|
};
|
|
410
366
|
function createGitHubCopilot(settings = {}) {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
const providerCredential = env.COPILOT_PROVIDER_API_KEY;
|
|
559
|
-
const sandboxProviderCredential = sandboxEnv?.COPILOT_PROVIDER_API_KEY;
|
|
560
|
-
const providerBaseUrl = env.COPILOT_PROVIDER_BASE_URL;
|
|
561
|
-
if (providerCredential && sandboxProviderCredential && providerBaseUrl) {
|
|
562
|
-
transformations.push(
|
|
563
|
-
createCredentialRequestTransformation({
|
|
564
|
-
matchUrl: providerBaseUrl,
|
|
565
|
-
matchHeaders: {
|
|
566
|
-
Authorization: `Bearer ${sandboxProviderCredential}`
|
|
567
|
-
},
|
|
568
|
-
transformHeaders: {
|
|
569
|
-
...headers,
|
|
570
|
-
Authorization: `Bearer ${providerCredential}`
|
|
571
|
-
}
|
|
572
|
-
})
|
|
573
|
-
);
|
|
574
|
-
} else if (headers != null) {
|
|
575
|
-
const copilotHosts = githubHost === "github.com" ? ["githubcopilot.com", "*.githubcopilot.com"] : [githubHost, `*.${githubHost}`];
|
|
576
|
-
for (const host of copilotHosts) {
|
|
577
|
-
transformations.push({
|
|
578
|
-
match: { host },
|
|
579
|
-
transform: { headers }
|
|
580
|
-
});
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
return transformations;
|
|
584
|
-
},
|
|
585
|
-
credentialForwarding: createGitHubCopilotCredentialForwarding({
|
|
586
|
-
credentialForwarding: settings.credentialForwarding
|
|
587
|
-
}),
|
|
588
|
-
providerAuthentication: {
|
|
589
|
-
gateway: {
|
|
590
|
-
env: {
|
|
591
|
-
COPILOT_PROVIDER_BASE_URL: {
|
|
592
|
-
$source: "gateway-base-url",
|
|
593
|
-
ensureSuffix: "/v1"
|
|
594
|
-
},
|
|
595
|
-
COPILOT_PROVIDER_TYPE: "openai",
|
|
596
|
-
COPILOT_PROVIDER_API_KEY: {
|
|
597
|
-
$source: "gateway-api-key"
|
|
598
|
-
},
|
|
599
|
-
COPILOT_PROVIDER_WIRE_API: "responses",
|
|
600
|
-
COPILOT_MODEL: "openai/gpt-5.5",
|
|
601
|
-
COPILOT_PROVIDER_HEADERS: {
|
|
602
|
-
$source: "client-app",
|
|
603
|
-
prefix: "x-client-app: "
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
},
|
|
608
|
-
modelMapping: {
|
|
609
|
-
type: "session-config-option",
|
|
610
|
-
path: "model"
|
|
611
|
-
},
|
|
612
|
-
skillsDirectory: ".copilot/skills",
|
|
613
|
-
instructionMapping: {
|
|
614
|
-
type: "filesystem",
|
|
615
|
-
path: ".copilot/copilot-instructions.md"
|
|
616
|
-
},
|
|
617
|
-
builtinTools: GITHUB_COPILOT_BUILTIN_TOOLS,
|
|
618
|
-
mcpServers: settings.mcpServers,
|
|
619
|
-
isMcpToolCall: (toolCall) => mcpToolTitlePrefixes.some((prefix) => toolCall.title.startsWith(prefix)),
|
|
620
|
-
port: settings.port,
|
|
621
|
-
portEndpoint: settings.portEndpoint,
|
|
622
|
-
startupTimeoutMs: settings.startupTimeoutMs,
|
|
623
|
-
reconnect: settings.reconnect,
|
|
624
|
-
mintBridgeToken: settings.mintBridgeToken
|
|
625
|
-
});
|
|
367
|
+
const mcpToolTitlePrefixes = ["github-mcp-server-", ...Object.keys(settings.mcpServers ?? {}).map((name) => `${name}-`)];
|
|
368
|
+
return createACP({
|
|
369
|
+
version: "v1",
|
|
370
|
+
harnessId: "github-copilot",
|
|
371
|
+
clientApp: GITHUB_COPILOT_CLIENT_APP,
|
|
372
|
+
source: {
|
|
373
|
+
type: "npm-locked",
|
|
374
|
+
packageJson: GITHUB_COPILOT_IMPLEMENTATION_PACKAGE_JSON,
|
|
375
|
+
pnpmLockYaml: GITHUB_COPILOT_IMPLEMENTATION_PNPM_LOCK,
|
|
376
|
+
pnpmWorkspaceYaml: GITHUB_COPILOT_IMPLEMENTATION_PNPM_WORKSPACE
|
|
377
|
+
},
|
|
378
|
+
executable: "copilot",
|
|
379
|
+
args: [
|
|
380
|
+
"--acp",
|
|
381
|
+
"--stdio",
|
|
382
|
+
"--no-auto-update",
|
|
383
|
+
...settings.reasoningEffort == null ? [] : [`--reasoning-effort=${settings.reasoningEffort}`]
|
|
384
|
+
],
|
|
385
|
+
auth: settings.auth,
|
|
386
|
+
resolveAuthenticationEnvironment: resolveGitHubCopilotSubscriptionEnvironment,
|
|
387
|
+
hostToolMcpTransport: "http",
|
|
388
|
+
forwardEnv: ["COPILOT_GH_HOST", "GH_HOST"],
|
|
389
|
+
credentialEnv: [
|
|
390
|
+
"COPILOT_GITHUB_TOKEN",
|
|
391
|
+
"GH_TOKEN",
|
|
392
|
+
"GITHUB_TOKEN"
|
|
393
|
+
],
|
|
394
|
+
credentialBrokering: ({ env, sandboxEnv, headers }) => {
|
|
395
|
+
const transformations = [];
|
|
396
|
+
const githubHost = normalizeGitHubHost(env.COPILOT_GH_HOST ?? env.GH_HOST ?? "github.com");
|
|
397
|
+
const githubHosts = [
|
|
398
|
+
githubHost,
|
|
399
|
+
`*.${githubHost}`,
|
|
400
|
+
...githubHost === "github.com" ? ["githubcopilot.com", "*.githubcopilot.com"] : []
|
|
401
|
+
];
|
|
402
|
+
for (const host of githubHosts) {
|
|
403
|
+
if (env.COPILOT_GITHUB_TOKEN && sandboxEnv?.COPILOT_GITHUB_TOKEN) transformations.push({
|
|
404
|
+
match: {
|
|
405
|
+
host,
|
|
406
|
+
headers: [{
|
|
407
|
+
key: { exact: "Authorization" },
|
|
408
|
+
value: { exact: `Bearer ${sandboxEnv.COPILOT_GITHUB_TOKEN}` }
|
|
409
|
+
}]
|
|
410
|
+
},
|
|
411
|
+
transform: { headers: { Authorization: `Bearer ${env.COPILOT_GITHUB_TOKEN}` } }
|
|
412
|
+
}, {
|
|
413
|
+
match: {
|
|
414
|
+
host,
|
|
415
|
+
headers: [{
|
|
416
|
+
key: { exact: "Authorization" },
|
|
417
|
+
value: { exact: `token ${sandboxEnv.COPILOT_GITHUB_TOKEN}` }
|
|
418
|
+
}]
|
|
419
|
+
},
|
|
420
|
+
transform: { headers: { Authorization: `token ${env.COPILOT_GITHUB_TOKEN}` } }
|
|
421
|
+
});
|
|
422
|
+
if (env.GH_TOKEN && sandboxEnv?.GH_TOKEN) transformations.push({
|
|
423
|
+
match: {
|
|
424
|
+
host,
|
|
425
|
+
headers: [{
|
|
426
|
+
key: { exact: "Authorization" },
|
|
427
|
+
value: { exact: `Bearer ${sandboxEnv.GH_TOKEN}` }
|
|
428
|
+
}]
|
|
429
|
+
},
|
|
430
|
+
transform: { headers: { Authorization: `Bearer ${env.GH_TOKEN}` } }
|
|
431
|
+
}, {
|
|
432
|
+
match: {
|
|
433
|
+
host,
|
|
434
|
+
headers: [{
|
|
435
|
+
key: { exact: "Authorization" },
|
|
436
|
+
value: { exact: `token ${sandboxEnv.GH_TOKEN}` }
|
|
437
|
+
}]
|
|
438
|
+
},
|
|
439
|
+
transform: { headers: { Authorization: `token ${env.GH_TOKEN}` } }
|
|
440
|
+
});
|
|
441
|
+
if (env.GITHUB_TOKEN && sandboxEnv?.GITHUB_TOKEN) transformations.push({
|
|
442
|
+
match: {
|
|
443
|
+
host,
|
|
444
|
+
headers: [{
|
|
445
|
+
key: { exact: "Authorization" },
|
|
446
|
+
value: { exact: `Bearer ${sandboxEnv.GITHUB_TOKEN}` }
|
|
447
|
+
}]
|
|
448
|
+
},
|
|
449
|
+
transform: { headers: { Authorization: `Bearer ${env.GITHUB_TOKEN}` } }
|
|
450
|
+
}, {
|
|
451
|
+
match: {
|
|
452
|
+
host,
|
|
453
|
+
headers: [{
|
|
454
|
+
key: { exact: "Authorization" },
|
|
455
|
+
value: { exact: `token ${sandboxEnv.GITHUB_TOKEN}` }
|
|
456
|
+
}]
|
|
457
|
+
},
|
|
458
|
+
transform: { headers: { Authorization: `token ${env.GITHUB_TOKEN}` } }
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
const providerCredential = env.COPILOT_PROVIDER_API_KEY;
|
|
462
|
+
const sandboxProviderCredential = sandboxEnv?.COPILOT_PROVIDER_API_KEY;
|
|
463
|
+
const providerBaseUrl = env.COPILOT_PROVIDER_BASE_URL;
|
|
464
|
+
if (providerCredential && sandboxProviderCredential && providerBaseUrl) transformations.push(createCredentialRequestTransformation({
|
|
465
|
+
matchUrl: providerBaseUrl,
|
|
466
|
+
matchHeaders: { Authorization: `Bearer ${sandboxProviderCredential}` },
|
|
467
|
+
transformHeaders: {
|
|
468
|
+
...headers,
|
|
469
|
+
Authorization: `Bearer ${providerCredential}`
|
|
470
|
+
}
|
|
471
|
+
}));
|
|
472
|
+
else if (headers != null) {
|
|
473
|
+
const copilotHosts = githubHost === "github.com" ? ["githubcopilot.com", "*.githubcopilot.com"] : [githubHost, `*.${githubHost}`];
|
|
474
|
+
for (const host of copilotHosts) transformations.push({
|
|
475
|
+
match: { host },
|
|
476
|
+
transform: { headers }
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
return transformations;
|
|
480
|
+
},
|
|
481
|
+
credentialForwarding: createGitHubCopilotCredentialForwarding({ credentialForwarding: settings.credentialForwarding }),
|
|
482
|
+
providerAuthentication: { gateway: { env: {
|
|
483
|
+
COPILOT_PROVIDER_BASE_URL: {
|
|
484
|
+
$source: "gateway-base-url",
|
|
485
|
+
ensureSuffix: "/v1"
|
|
486
|
+
},
|
|
487
|
+
COPILOT_PROVIDER_TYPE: "openai",
|
|
488
|
+
COPILOT_PROVIDER_API_KEY: { $source: "gateway-api-key" },
|
|
489
|
+
COPILOT_PROVIDER_WIRE_API: "responses",
|
|
490
|
+
COPILOT_MODEL: "openai/gpt-5.5",
|
|
491
|
+
COPILOT_PROVIDER_HEADERS: {
|
|
492
|
+
$source: "client-app",
|
|
493
|
+
prefix: "x-client-app: "
|
|
494
|
+
}
|
|
495
|
+
} } },
|
|
496
|
+
modelMapping: {
|
|
497
|
+
type: "session-config-option",
|
|
498
|
+
path: "model"
|
|
499
|
+
},
|
|
500
|
+
skillsDirectory: ".copilot/skills",
|
|
501
|
+
instructionMapping: {
|
|
502
|
+
type: "filesystem",
|
|
503
|
+
path: ".copilot/copilot-instructions.md"
|
|
504
|
+
},
|
|
505
|
+
builtinTools: GITHUB_COPILOT_BUILTIN_TOOLS,
|
|
506
|
+
mcpServers: settings.mcpServers,
|
|
507
|
+
isMcpToolCall: (toolCall) => mcpToolTitlePrefixes.some((prefix) => toolCall.title.startsWith(prefix)),
|
|
508
|
+
port: settings.port,
|
|
509
|
+
portEndpoint: settings.portEndpoint,
|
|
510
|
+
startupTimeoutMs: settings.startupTimeoutMs,
|
|
511
|
+
reconnect: settings.reconnect,
|
|
512
|
+
mintBridgeToken: settings.mintBridgeToken
|
|
513
|
+
});
|
|
626
514
|
}
|
|
627
|
-
function createGitHubCopilotCredentialForwarding({
|
|
628
|
-
|
|
629
|
-
})
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
});
|
|
636
|
-
};
|
|
515
|
+
function createGitHubCopilotCredentialForwarding({ credentialForwarding }) {
|
|
516
|
+
return ({ credential, environmentVariableName }) => {
|
|
517
|
+
const sandboxCredential = GITHUB_COPILOT_TOKEN_ENVIRONMENT_VARIABLES.has(environmentVariableName) && isSandboxCredentialPlaceholder(credential) ? createGitHubOAuthSandboxCredentialPlaceholder({ credential }) : credential;
|
|
518
|
+
return credentialForwarding == null ? sandboxCredential : credentialForwarding({
|
|
519
|
+
credential: sandboxCredential,
|
|
520
|
+
environmentVariableName
|
|
521
|
+
});
|
|
522
|
+
};
|
|
637
523
|
}
|
|
638
|
-
function createGitHubOAuthSandboxCredentialPlaceholder({
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
const tokenBody = createHash("sha256").update(credential).digest("hex").slice(
|
|
642
|
-
0,
|
|
643
|
-
GITHUB_OAUTH_TOKEN_BODY_LENGTH - GITHUB_OAUTH_SANDBOX_CREDENTIAL_MARKER.length
|
|
644
|
-
);
|
|
645
|
-
return `gho_${GITHUB_OAUTH_SANDBOX_CREDENTIAL_MARKER}${tokenBody}`;
|
|
524
|
+
function createGitHubOAuthSandboxCredentialPlaceholder({ credential }) {
|
|
525
|
+
const tokenBody = createHash("sha256").update(credential).digest("hex").slice(0, 29);
|
|
526
|
+
return `gho_${GITHUB_OAUTH_SANDBOX_CREDENTIAL_MARKER}${tokenBody}`;
|
|
646
527
|
}
|
|
528
|
+
//#endregion
|
|
529
|
+
//#region src/index.ts
|
|
530
|
+
/**
|
|
531
|
+
* Default GitHub Copilot harness instance. Equivalent to
|
|
532
|
+
* `createGitHubCopilot()`.
|
|
533
|
+
*/
|
|
534
|
+
const githubCopilot = createGitHubCopilot();
|
|
535
|
+
//#endregion
|
|
536
|
+
export { VERSION, createGitHubCopilot, githubCopilot };
|
|
647
537
|
|
|
648
|
-
// src/index.ts
|
|
649
|
-
var githubCopilot = createGitHubCopilot();
|
|
650
|
-
export {
|
|
651
|
-
VERSION,
|
|
652
|
-
createGitHubCopilot,
|
|
653
|
-
githubCopilot
|
|
654
|
-
};
|
|
655
538
|
//# sourceMappingURL=index.js.map
|