@ai-ide-bridge/copilot 1.0.4 → 1.1.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/.turbo/turbo-build.log +1 -1
- package/dist/auth.d.ts +2 -2
- package/dist/auth.js +40 -6
- package/dist/plugin.js +3 -3
- package/package.json +3 -2
- package/src/auth.ts +42 -7
- package/src/plugin.ts +3 -3
- package/test/auth.test.ts +8 -8
package/.turbo/turbo-build.log
CHANGED
package/dist/auth.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CopilotConfig } from './types.js';
|
|
2
2
|
export declare function validateToken(token: string): Promise<boolean>;
|
|
3
|
-
export declare function getToken(config: CopilotConfig): string | null
|
|
4
|
-
export declare function refreshOAuthToken(
|
|
3
|
+
export declare function getToken(config: CopilotConfig): Promise<string | null>;
|
|
4
|
+
export declare function refreshOAuthToken(refreshToken: string, clientId: string, _clientSecret: string): Promise<{
|
|
5
5
|
accessToken: string;
|
|
6
6
|
refreshToken: string;
|
|
7
7
|
} | null>;
|
package/dist/auth.js
CHANGED
|
@@ -14,11 +14,45 @@ export async function validateToken(token) {
|
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
export function getToken(config) {
|
|
18
|
-
|
|
17
|
+
export async function getToken(config) {
|
|
18
|
+
if (config.COPILOT_TOKEN)
|
|
19
|
+
return config.COPILOT_TOKEN;
|
|
20
|
+
try {
|
|
21
|
+
const { createTokenStore } = await import('@ai-ide-bridge/oauth');
|
|
22
|
+
const store = createTokenStore();
|
|
23
|
+
const token = await store.get('copilot');
|
|
24
|
+
if (token && Date.now() < token.expiresAt) {
|
|
25
|
+
return token.accessToken;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// OAuth package may not be available
|
|
30
|
+
}
|
|
31
|
+
return config.COPILOT_OAUTH_TOKEN ?? null;
|
|
19
32
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
33
|
+
export async function refreshOAuthToken(refreshToken, clientId, _clientSecret) {
|
|
34
|
+
try {
|
|
35
|
+
const params = new URLSearchParams({
|
|
36
|
+
grant_type: 'refresh_token',
|
|
37
|
+
refresh_token: refreshToken,
|
|
38
|
+
client_id: clientId,
|
|
39
|
+
});
|
|
40
|
+
const response = await fetch('https://github.com/login/oauth/access_token', {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
43
|
+
body: params.toString(),
|
|
44
|
+
});
|
|
45
|
+
if (!response.ok)
|
|
46
|
+
return null;
|
|
47
|
+
const data = (await response.json());
|
|
48
|
+
if (!data.access_token)
|
|
49
|
+
return null;
|
|
50
|
+
return {
|
|
51
|
+
accessToken: data.access_token,
|
|
52
|
+
refreshToken: data.refresh_token ?? refreshToken,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
24
58
|
}
|
package/dist/plugin.js
CHANGED
|
@@ -5,13 +5,13 @@ export class CopilotBridgePlugin {
|
|
|
5
5
|
name = 'copilot';
|
|
6
6
|
version = '2.0.0';
|
|
7
7
|
async authenticate(config) {
|
|
8
|
-
const token = getToken(config);
|
|
8
|
+
const token = await getToken(config);
|
|
9
9
|
if (!token)
|
|
10
10
|
return false;
|
|
11
11
|
return validateToken(token);
|
|
12
12
|
}
|
|
13
13
|
async listModels(config) {
|
|
14
|
-
const token = getToken(config);
|
|
14
|
+
const token = await getToken(config);
|
|
15
15
|
if (!token)
|
|
16
16
|
throw new Error('Missing COPILOT_TOKEN');
|
|
17
17
|
return COPILOT_MODELS.map((m) => ({
|
|
@@ -21,7 +21,7 @@ export class CopilotBridgePlugin {
|
|
|
21
21
|
}));
|
|
22
22
|
}
|
|
23
23
|
async createSession(config, model) {
|
|
24
|
-
const token = getToken(config);
|
|
24
|
+
const token = await getToken(config);
|
|
25
25
|
if (!token)
|
|
26
26
|
throw new Error('Missing COPILOT_TOKEN');
|
|
27
27
|
return new CopilotBridgeSession(token, model);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-ide-bridge/copilot",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"dev": "tsc --watch"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@ai-ide-bridge/core": "workspace:*"
|
|
15
|
+
"@ai-ide-bridge/core": "workspace:*",
|
|
16
|
+
"@ai-ide-bridge/oauth": "workspace:*"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
18
19
|
"@types/node": "^22.15.0",
|
package/src/auth.ts
CHANGED
|
@@ -17,16 +17,51 @@ export async function validateToken(token: string): Promise<boolean> {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export function getToken(config: CopilotConfig): string | null {
|
|
21
|
-
|
|
20
|
+
export async function getToken(config: CopilotConfig): Promise<string | null> {
|
|
21
|
+
if (config.COPILOT_TOKEN) return config.COPILOT_TOKEN;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const { createTokenStore } = await import('@ai-ide-bridge/oauth');
|
|
25
|
+
const store = createTokenStore();
|
|
26
|
+
const token = await store.get('copilot');
|
|
27
|
+
if (token && Date.now() < token.expiresAt) {
|
|
28
|
+
return token.accessToken;
|
|
29
|
+
}
|
|
30
|
+
} catch {
|
|
31
|
+
// OAuth package may not be available
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return config.COPILOT_OAUTH_TOKEN ?? null;
|
|
22
35
|
}
|
|
23
36
|
|
|
24
|
-
// OAuth placeholder — wired up when OAuth Phase 2 is implemented
|
|
25
37
|
export async function refreshOAuthToken(
|
|
26
|
-
|
|
27
|
-
|
|
38
|
+
refreshToken: string,
|
|
39
|
+
clientId: string,
|
|
28
40
|
_clientSecret: string,
|
|
29
41
|
): Promise<{ accessToken: string; refreshToken: string } | null> {
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
try {
|
|
43
|
+
const params = new URLSearchParams({
|
|
44
|
+
grant_type: 'refresh_token',
|
|
45
|
+
refresh_token: refreshToken,
|
|
46
|
+
client_id: clientId,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const response = await fetch('https://github.com/login/oauth/access_token', {
|
|
50
|
+
method: 'POST',
|
|
51
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
52
|
+
body: params.toString(),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (!response.ok) return null;
|
|
56
|
+
|
|
57
|
+
const data = (await response.json()) as Record<string, unknown>;
|
|
58
|
+
if (!data.access_token) return null;
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
accessToken: data.access_token as string,
|
|
62
|
+
refreshToken: (data.refresh_token as string) ?? refreshToken,
|
|
63
|
+
};
|
|
64
|
+
} catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
32
67
|
}
|
package/src/plugin.ts
CHANGED
|
@@ -8,13 +8,13 @@ export class CopilotBridgePlugin implements BridgePlugin {
|
|
|
8
8
|
version = '2.0.0';
|
|
9
9
|
|
|
10
10
|
async authenticate(config: Record<string, string>): Promise<boolean> {
|
|
11
|
-
const token = getToken(config as CopilotConfig);
|
|
11
|
+
const token = await getToken(config as CopilotConfig);
|
|
12
12
|
if (!token) return false;
|
|
13
13
|
return validateToken(token);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
async listModels(config: Record<string, string>): Promise<ModelInfo[]> {
|
|
17
|
-
const token = getToken(config as CopilotConfig);
|
|
17
|
+
const token = await getToken(config as CopilotConfig);
|
|
18
18
|
if (!token) throw new Error('Missing COPILOT_TOKEN');
|
|
19
19
|
return COPILOT_MODELS.map((m) => ({
|
|
20
20
|
id: m.id,
|
|
@@ -24,7 +24,7 @@ export class CopilotBridgePlugin implements BridgePlugin {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
async createSession(config: Record<string, string>, model: string): Promise<BridgeSession> {
|
|
27
|
-
const token = getToken(config as CopilotConfig);
|
|
27
|
+
const token = await getToken(config as CopilotConfig);
|
|
28
28
|
if (!token) throw new Error('Missing COPILOT_TOKEN');
|
|
29
29
|
return new CopilotBridgeSession(token, model);
|
|
30
30
|
}
|
package/test/auth.test.ts
CHANGED
|
@@ -2,23 +2,23 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
|
2
2
|
import { getToken, validateToken } from '../src/auth.js';
|
|
3
3
|
|
|
4
4
|
describe('getToken', () => {
|
|
5
|
-
it('returns COPILOT_TOKEN when present', () => {
|
|
6
|
-
const result = getToken({ COPILOT_TOKEN: 'test-token' });
|
|
5
|
+
it('returns COPILOT_TOKEN when present', async () => {
|
|
6
|
+
const result = await getToken({ COPILOT_TOKEN: 'test-token' });
|
|
7
7
|
expect(result).toBe('test-token');
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
it('returns COPILOT_OAUTH_TOKEN when COPILOT_TOKEN is missing', () => {
|
|
11
|
-
const result = getToken({ COPILOT_OAUTH_TOKEN: 'oauth-token' });
|
|
10
|
+
it('returns COPILOT_OAUTH_TOKEN when COPILOT_TOKEN is missing', async () => {
|
|
11
|
+
const result = await getToken({ COPILOT_OAUTH_TOKEN: 'oauth-token' });
|
|
12
12
|
expect(result).toBe('oauth-token');
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
it('returns null when no token is present', () => {
|
|
16
|
-
const result = getToken({});
|
|
15
|
+
it('returns null when no token is present', async () => {
|
|
16
|
+
const result = await getToken({});
|
|
17
17
|
expect(result).toBeNull();
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
it('prefers COPILOT_TOKEN over COPILOT_OAUTH_TOKEN', () => {
|
|
21
|
-
const result = getToken({
|
|
20
|
+
it('prefers COPILOT_TOKEN over COPILOT_OAUTH_TOKEN', async () => {
|
|
21
|
+
const result = await getToken({
|
|
22
22
|
COPILOT_TOKEN: 'primary-token',
|
|
23
23
|
COPILOT_OAUTH_TOKEN: 'fallback-token',
|
|
24
24
|
});
|