n8n-nodes-github-copilot 3.26.0 → 3.27.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.
@@ -0,0 +1,9 @@
1
+ import { ICredentialType, INodeProperties, ICredentialTestRequest, IAuthenticateGeneric } from 'n8n-workflow';
2
+ export declare class GitHubCopilotOAuth2Api implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ authenticate: IAuthenticateGeneric;
8
+ test: ICredentialTestRequest;
9
+ }
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GitHubCopilotOAuth2Api = void 0;
4
+ const GitHubCopilotEndpoints_1 = require("../shared/utils/GitHubCopilotEndpoints");
5
+ class GitHubCopilotOAuth2Api {
6
+ constructor() {
7
+ this.name = 'githubCopilotOAuth2Api';
8
+ this.displayName = 'GitHub Copilot Token (with OAuth Helper)';
9
+ this.documentationUrl = 'https://docs.github.com/en/copilot/github-copilot-chat/copilot-chat-in-ides/using-github-copilot-chat-in-your-ide';
10
+ this.properties = [
11
+ {
12
+ displayName: '🔐 GitHub Copilot Authentication',
13
+ name: 'notice',
14
+ type: 'notice',
15
+ default: '',
16
+ description: 'Choose between manual token input or guided Device Flow OAuth. For automated setup, use the provided authentication script.',
17
+ },
18
+ {
19
+ displayName: 'Authentication Method',
20
+ name: 'authMethod',
21
+ type: 'options',
22
+ options: [
23
+ {
24
+ name: 'Manual Token (Recommended)',
25
+ value: 'manual',
26
+ description: 'Enter your GitHub CLI token manually',
27
+ },
28
+ {
29
+ name: 'Device Flow OAuth (Experimental)',
30
+ value: 'deviceFlow',
31
+ description: 'Use Device Flow OAuth to obtain token automatically',
32
+ },
33
+ ],
34
+ default: 'manual',
35
+ },
36
+ {
37
+ displayName: 'GitHub CLI Token',
38
+ name: 'token',
39
+ type: 'string',
40
+ typeOptions: {
41
+ password: true,
42
+ },
43
+ default: '',
44
+ required: true,
45
+ displayOptions: {
46
+ show: {
47
+ authMethod: ['manual'],
48
+ },
49
+ },
50
+ description: '⚠️ REQUIRED: Token generated by GitHub CLI that starts with "gho_". Get it by running the authenticate.js script or: gh auth login && gh auth token',
51
+ placeholder: 'gho_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
52
+ },
53
+ {
54
+ displayName: 'Device Flow Instructions',
55
+ name: 'deviceFlowInstructions',
56
+ type: 'notice',
57
+ default: '',
58
+ displayOptions: {
59
+ show: {
60
+ authMethod: ['deviceFlow'],
61
+ },
62
+ },
63
+ description: `🚧 EXPERIMENTAL: Device Flow OAuth is under development.
64
+
65
+ For now, please:
66
+ 1. Run the authenticate.js script in the project root
67
+ 2. Copy the generated token to the Manual Token field above
68
+ 3. Switch Authentication Method to "Manual Token"
69
+
70
+ The script will guide you through GitHub Device Flow OAuth and generate the correct token format.`,
71
+ },
72
+ {
73
+ displayName: 'Client ID',
74
+ name: 'clientId',
75
+ type: 'string',
76
+ default: '01ab8ac9400c4e429b23',
77
+ displayOptions: {
78
+ show: {
79
+ authMethod: ['deviceFlow'],
80
+ },
81
+ },
82
+ description: 'GitHub OAuth App Client ID (VS Code default)',
83
+ },
84
+ {
85
+ displayName: 'Scopes',
86
+ name: 'scopes',
87
+ type: 'string',
88
+ default: 'repo user:email',
89
+ displayOptions: {
90
+ show: {
91
+ authMethod: ['deviceFlow'],
92
+ },
93
+ },
94
+ description: 'OAuth scopes required for GitHub Copilot access',
95
+ },
96
+ ];
97
+ this.authenticate = {
98
+ type: 'generic',
99
+ properties: {
100
+ headers: {
101
+ 'Authorization': '=Bearer {{$credentials.token}}',
102
+ 'Accept': 'application/json',
103
+ 'Content-Type': 'application/json',
104
+ 'User-Agent': 'GitHub-Copilot-Chat/1.0.0 VSCode/1.85.0',
105
+ 'Editor-Version': 'vscode/1.85.0',
106
+ 'Editor-Plugin-Version': 'copilot-chat/0.12.0',
107
+ 'X-GitHub-Api-Version': '2025-04-01',
108
+ },
109
+ },
110
+ };
111
+ this.test = {
112
+ request: {
113
+ baseURL: GitHubCopilotEndpoints_1.GITHUB_COPILOT_API.BASE_URL,
114
+ url: GitHubCopilotEndpoints_1.GITHUB_COPILOT_API.ENDPOINTS.MODELS,
115
+ method: 'GET',
116
+ },
117
+ };
118
+ }
119
+ }
120
+ exports.GitHubCopilotOAuth2Api = GitHubCopilotOAuth2Api;
@@ -66,6 +66,17 @@ class GitHubCopilot {
66
66
  displayOptions: {
67
67
  show: {
68
68
  useCredential: [true],
69
+ credentialType: ['githubCopilotApi'],
70
+ },
71
+ },
72
+ },
73
+ {
74
+ name: 'githubCopilotOAuth2Api',
75
+ required: false,
76
+ displayOptions: {
77
+ show: {
78
+ useCredential: [true],
79
+ credentialType: ['githubCopilotOAuth2Api'],
69
80
  },
70
81
  },
71
82
  },
@@ -78,6 +89,30 @@ class GitHubCopilot {
78
89
  default: false,
79
90
  description: 'Use GitHub Copilot API credential instead of local GitHub CLI authentication',
80
91
  },
92
+ {
93
+ displayName: 'Credential Type',
94
+ name: 'credentialType',
95
+ type: 'options',
96
+ options: [
97
+ {
98
+ name: 'GitHub Copilot API (Manual Token)',
99
+ value: 'githubCopilotApi',
100
+ description: 'Use manual GitHub CLI token',
101
+ },
102
+ {
103
+ name: 'GitHub Copilot OAuth2 (with Helper)',
104
+ value: 'githubCopilotOAuth2Api',
105
+ description: 'Use OAuth2 credential with helper script',
106
+ },
107
+ ],
108
+ default: 'githubCopilotApi',
109
+ description: 'Type of credential to use for GitHub Copilot authentication',
110
+ displayOptions: {
111
+ show: {
112
+ useCredential: [true],
113
+ },
114
+ },
115
+ },
81
116
  {
82
117
  displayName: 'Operation',
83
118
  name: 'operation',
@@ -250,6 +285,7 @@ class GitHubCopilot {
250
285
  };
251
286
  }
252
287
  async execute() {
288
+ var _a;
253
289
  const items = this.getInputData();
254
290
  const returnData = [];
255
291
  for (let i = 0; i < items.length; i++) {
@@ -262,10 +298,15 @@ class GitHubCopilot {
262
298
  let authMethod = 'Local CLI';
263
299
  if (useCredential) {
264
300
  try {
265
- const credentials = await this.getCredentials('githubCopilotApi');
266
- if (credentials && credentials.token) {
267
- githubToken = credentials.token;
268
- authMethod = 'GitHub Copilot Credential';
301
+ const credentialType = this.getNodeParameter('credentialType', i, 'githubCopilotApi');
302
+ const credentials = await this.getCredentials(credentialType);
303
+ const token = (credentials.accessToken ||
304
+ credentials.access_token ||
305
+ ((_a = credentials.oauthTokenData) === null || _a === void 0 ? void 0 : _a.access_token) ||
306
+ credentials.token);
307
+ if (token) {
308
+ githubToken = token;
309
+ authMethod = `GitHub Copilot ${credentialType === 'githubCopilotOAuth2Api' ? 'OAuth2' : 'API'} Credential`;
269
310
  }
270
311
  }
271
312
  catch (error) {
@@ -25,6 +25,20 @@ class GitHubCopilotChatAPI {
25
25
  {
26
26
  name: 'githubCopilotApi',
27
27
  required: true,
28
+ displayOptions: {
29
+ show: {
30
+ credentialType: ['githubCopilotApi'],
31
+ },
32
+ },
33
+ },
34
+ {
35
+ name: 'githubCopilotOAuth2Api',
36
+ required: true,
37
+ displayOptions: {
38
+ show: {
39
+ credentialType: ['githubCopilotOAuth2Api'],
40
+ },
41
+ },
28
42
  },
29
43
  ],
30
44
  properties: nodeProperties_1.nodeProperties,
@@ -3,6 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.nodeProperties = void 0;
4
4
  const GitHubCopilotModels_1 = require("../../shared/models/GitHubCopilotModels");
5
5
  exports.nodeProperties = [
6
+ {
7
+ displayName: 'Credential Type',
8
+ name: 'credentialType',
9
+ type: 'options',
10
+ options: [
11
+ {
12
+ name: 'GitHub Copilot API (Manual Token)',
13
+ value: 'githubCopilotApi',
14
+ description: 'Use manual GitHub CLI token',
15
+ },
16
+ {
17
+ name: 'GitHub Copilot OAuth2 (with Helper)',
18
+ value: 'githubCopilotOAuth2Api',
19
+ description: 'Use OAuth2 credential with helper script',
20
+ },
21
+ ],
22
+ default: 'githubCopilotApi',
23
+ description: 'Type of credential to use for GitHub Copilot authentication',
24
+ },
6
25
  {
7
26
  displayName: 'Operation',
8
27
  name: 'operation',
@@ -37,9 +37,42 @@ class GitHubCopilotChatModel {
37
37
  {
38
38
  name: 'githubCopilotApi',
39
39
  required: true,
40
+ displayOptions: {
41
+ show: {
42
+ credentialType: ['githubCopilotApi'],
43
+ },
44
+ },
45
+ },
46
+ {
47
+ name: 'githubCopilotOAuth2Api',
48
+ required: true,
49
+ displayOptions: {
50
+ show: {
51
+ credentialType: ['githubCopilotOAuth2Api'],
52
+ },
53
+ },
40
54
  },
41
55
  ],
42
56
  properties: [
57
+ {
58
+ displayName: 'Credential Type',
59
+ name: 'credentialType',
60
+ type: 'options',
61
+ options: [
62
+ {
63
+ name: 'GitHub Copilot API (Manual Token)',
64
+ value: 'githubCopilotApi',
65
+ description: 'Use manual GitHub CLI token',
66
+ },
67
+ {
68
+ name: 'GitHub Copilot OAuth2 (with Helper)',
69
+ value: 'githubCopilotOAuth2Api',
70
+ description: 'Use OAuth2 credential with helper script',
71
+ },
72
+ ],
73
+ default: 'githubCopilotApi',
74
+ description: 'Type of credential to use for GitHub Copilot authentication',
75
+ },
43
76
  {
44
77
  displayName: 'Model',
45
78
  name: 'model',
@@ -128,7 +161,8 @@ class GitHubCopilotChatModel {
128
161
  const model = this.getNodeParameter('model', itemIndex);
129
162
  const options = this.getNodeParameter('options', itemIndex, {});
130
163
  const modelInfo = GitHubCopilotModels_1.GitHubCopilotModelsManager.getModelByValue(model);
131
- const credentials = await this.getCredentials('githubCopilotApi');
164
+ const credentialType = this.getNodeParameter('credentialType', 0, 'githubCopilotApi');
165
+ const credentials = await this.getCredentials(credentialType);
132
166
  const token = (credentials.accessToken ||
133
167
  credentials.access_token ||
134
168
  ((_a = credentials.oauthTokenData) === null || _a === void 0 ? void 0 : _a.access_token) ||
@@ -325,9 +325,42 @@ class GitHubCopilotTest {
325
325
  {
326
326
  name: 'githubCopilotApi',
327
327
  required: true,
328
+ displayOptions: {
329
+ show: {
330
+ credentialType: ['githubCopilotApi'],
331
+ },
332
+ },
333
+ },
334
+ {
335
+ name: 'githubCopilotOAuth2Api',
336
+ required: true,
337
+ displayOptions: {
338
+ show: {
339
+ credentialType: ['githubCopilotOAuth2Api'],
340
+ },
341
+ },
328
342
  },
329
343
  ],
330
344
  properties: [
345
+ {
346
+ displayName: 'Credential Type',
347
+ name: 'credentialType',
348
+ type: 'options',
349
+ options: [
350
+ {
351
+ name: 'GitHub Copilot API (Manual Token)',
352
+ value: 'githubCopilotApi',
353
+ description: 'Use manual GitHub CLI token',
354
+ },
355
+ {
356
+ name: 'GitHub Copilot OAuth2 (with Helper)',
357
+ value: 'githubCopilotOAuth2Api',
358
+ description: 'Use OAuth2 credential with helper script',
359
+ },
360
+ ],
361
+ default: 'githubCopilotApi',
362
+ description: 'Type of credential to use for GitHub Copilot authentication',
363
+ },
331
364
  {
332
365
  displayName: 'Test Function',
333
366
  name: 'testFunction',
@@ -397,6 +430,7 @@ class GitHubCopilotTest {
397
430
  };
398
431
  }
399
432
  async execute() {
433
+ var _a;
400
434
  const items = this.getInputData();
401
435
  const returnData = [];
402
436
  for (let i = 0; i < items.length; i++) {
@@ -408,11 +442,15 @@ class GitHubCopilotTest {
408
442
  const testsPerModel = testFunction === 'consolidatedTest'
409
443
  ? this.getNodeParameter('testsPerModel', i)
410
444
  : 5;
411
- const credentials = await this.getCredentials('githubCopilotApi', i);
412
- if (!(credentials === null || credentials === void 0 ? void 0 : credentials.token)) {
445
+ const credentialType = this.getNodeParameter('credentialType', i, 'githubCopilotApi');
446
+ const credentials = await this.getCredentials(credentialType, i);
447
+ const token = (credentials.accessToken ||
448
+ credentials.access_token ||
449
+ ((_a = credentials.oauthTokenData) === null || _a === void 0 ? void 0 : _a.access_token) ||
450
+ credentials.token);
451
+ if (!token) {
413
452
  throw new Error(GitHubCopilotEndpoints_1.GITHUB_COPILOT_API.ERRORS.CREDENTIALS_REQUIRED);
414
453
  }
415
- const token = credentials.token;
416
454
  if (!GitHubCopilotEndpoints_1.GitHubCopilotEndpoints.validateToken(token)) {
417
455
  throw new Error(GitHubCopilotEndpoints_1.GITHUB_COPILOT_API.ERRORS.INVALID_TOKEN);
418
456
  }
@@ -12,20 +12,27 @@ exports.truncateToTokenLimit = truncateToTokenLimit;
12
12
  const GitHubCopilotEndpoints_1 = require("./GitHubCopilotEndpoints");
13
13
  async function makeGitHubCopilotRequest(context, endpoint, body, hasMedia = false) {
14
14
  var _a;
15
- const credentials = await context.getCredentials('githubCopilotApi');
16
- console.log('🔍 OAuth2 Credentials Debug:', Object.keys(credentials));
15
+ let credentialType = 'githubCopilotApi';
16
+ try {
17
+ credentialType = context.getNodeParameter('credentialType', 0, 'githubCopilotApi');
18
+ }
19
+ catch (error) {
20
+ console.log('🔍 No credentialType parameter found, using default: githubCopilotApi');
21
+ }
22
+ const credentials = await context.getCredentials(credentialType);
23
+ console.log(`🔍 ${credentialType} Credentials Debug:`, Object.keys(credentials));
17
24
  const token = (credentials.accessToken ||
18
25
  credentials.access_token ||
19
26
  ((_a = credentials.oauthTokenData) === null || _a === void 0 ? void 0 : _a.access_token) ||
20
27
  credentials.token);
21
28
  if (!token) {
22
- console.error('❌ Available OAuth2 credential properties:', Object.keys(credentials));
23
- console.error('❌ Full OAuth2 credential object:', JSON.stringify(credentials, null, 2));
24
- throw new Error('GitHub Copilot: No access token found in OAuth2 credentials. Available properties: ' + Object.keys(credentials).join(', '));
29
+ console.error(`❌ Available ${credentialType} credential properties:`, Object.keys(credentials));
30
+ console.error(`❌ Full ${credentialType} credential object:`, JSON.stringify(credentials, null, 2));
31
+ throw new Error(`GitHub Copilot: No access token found in ${credentialType} credentials. Available properties: ` + Object.keys(credentials).join(', '));
25
32
  }
26
33
  const tokenPrefix = token.substring(0, Math.min(4, token.indexOf('_') + 1)) || token.substring(0, 4);
27
34
  const tokenSuffix = token.substring(Math.max(0, token.length - 5));
28
- console.log(`🔍 GitHub Copilot OAuth2 Debug: Using token ${tokenPrefix}...${tokenSuffix}`);
35
+ console.log(`🔍 GitHub Copilot ${credentialType} Debug: Using token ${tokenPrefix}...${tokenSuffix}`);
29
36
  if (!token.startsWith('gho_') && !token.startsWith('ghu_') && !token.startsWith('github_pat_')) {
30
37
  console.warn(`⚠️ Unexpected token format: ${tokenPrefix}...${tokenSuffix}. Trying API call anyway.`);
31
38
  }
@@ -51,7 +58,7 @@ async function makeGitHubCopilotRequest(context, endpoint, body, hasMedia = fals
51
58
  const tokenInfo = `${tokenPrefix}...${tokenSuffix}`;
52
59
  console.error(`❌ GitHub Copilot API Error: ${response.status} ${response.statusText}`);
53
60
  console.error(`❌ Error details: ${errorText}`);
54
- console.error(`❌ Used credential type: githubCopilotApi`);
61
+ console.error(`❌ Used credential type: ${credentialType}`);
55
62
  console.error(`❌ Token format used: ${tokenInfo}`);
56
63
  const enhancedError = `GitHub Copilot API error: ${response.status} ${response.statusText}. ${errorText} [Token used: ${tokenInfo}]`;
57
64
  throw new Error(enhancedError);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-github-copilot",
3
- "version": "3.26.0",
3
+ "version": "3.27.0",
4
4
  "description": "n8n community node for GitHub Copilot with CLI integration, Chat API access, and AI Chat Model for workflows - access GPT-5, Claude, Gemini and more using your Copilot subscription",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/sufficit/n8n-nodes-github-copilot",
@@ -27,7 +27,8 @@
27
27
  "n8n": {
28
28
  "n8nNodesApiVersion": 1,
29
29
  "credentials": [
30
- "dist/credentials/GitHubCopilotApi.credentials.js"
30
+ "dist/credentials/GitHubCopilotApi.credentials.js",
31
+ "dist/credentials/GitHubCopilotOAuth2Api.credentials.js"
31
32
  ],
32
33
  "nodes": [
33
34
  "dist/nodes/GitHubCopilot/GitHubCopilot.node.js",