n8n-nodes-github-copilot 1.2.1 → 2.0.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.
|
@@ -59,53 +59,7 @@ class GitHubCopilot {
|
|
|
59
59
|
},
|
|
60
60
|
inputs: ["main"],
|
|
61
61
|
outputs: ["main"],
|
|
62
|
-
credentials: [
|
|
63
|
-
{
|
|
64
|
-
name: 'gitHubApi',
|
|
65
|
-
displayName: 'GitHub API (OAuth2)',
|
|
66
|
-
required: false,
|
|
67
|
-
displayOptions: {
|
|
68
|
-
show: {
|
|
69
|
-
authType: ['oauth2'],
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
name: 'gitHubApiManual',
|
|
75
|
-
displayName: 'GitHub API (Manual Token)',
|
|
76
|
-
required: false,
|
|
77
|
-
displayOptions: {
|
|
78
|
-
show: {
|
|
79
|
-
authType: ['manual'],
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
62
|
properties: [
|
|
85
|
-
{
|
|
86
|
-
displayName: 'Authentication Type',
|
|
87
|
-
name: 'authType',
|
|
88
|
-
type: 'options',
|
|
89
|
-
options: [
|
|
90
|
-
{
|
|
91
|
-
name: 'Local CLI Authentication',
|
|
92
|
-
value: 'local',
|
|
93
|
-
description: 'Use GitHub CLI local authentication (recommended)',
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
name: 'OAuth2 (Automatic)',
|
|
97
|
-
value: 'oauth2',
|
|
98
|
-
description: 'Use OAuth2 authentication configured in n8n',
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
name: 'Manual Token',
|
|
102
|
-
value: 'manual',
|
|
103
|
-
description: 'Use manually entered GitHub token',
|
|
104
|
-
},
|
|
105
|
-
],
|
|
106
|
-
default: 'local',
|
|
107
|
-
description: 'Choose how to authenticate with GitHub',
|
|
108
|
-
},
|
|
109
63
|
{
|
|
110
64
|
displayName: 'Operation',
|
|
111
65
|
name: 'operation',
|
|
@@ -145,6 +99,15 @@ class GitHubCopilot {
|
|
|
145
99
|
placeholder: 'Enter your request...',
|
|
146
100
|
description: 'What you want GitHub Copilot to help with',
|
|
147
101
|
},
|
|
102
|
+
{
|
|
103
|
+
displayName: 'GitHub Token (Optional)',
|
|
104
|
+
name: 'githubToken',
|
|
105
|
+
type: 'string',
|
|
106
|
+
typeOptions: { password: true },
|
|
107
|
+
default: '',
|
|
108
|
+
placeholder: 'gho_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
|
|
109
|
+
description: 'Optional GitHub Personal Access Token. If not provided, will use local GitHub CLI authentication. Create at: https://github.com/settings/tokens',
|
|
110
|
+
},
|
|
148
111
|
{
|
|
149
112
|
displayName: 'Filter Output',
|
|
150
113
|
name: 'filterOutput',
|
|
@@ -220,39 +183,9 @@ class GitHubCopilot {
|
|
|
220
183
|
const operation = this.getNodeParameter('operation', i);
|
|
221
184
|
const prompt = this.getNodeParameter('prompt', i);
|
|
222
185
|
const context = this.getNodeParameter('context', i, '');
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (authType === 'local') {
|
|
227
|
-
credentialType = 'Local CLI';
|
|
228
|
-
accessToken = undefined;
|
|
229
|
-
}
|
|
230
|
-
else if (authType === 'oauth2') {
|
|
231
|
-
const oauthCredentials = await this.getCredentials('gitHubApi');
|
|
232
|
-
console.log('OAuth2 credentials object:', JSON.stringify(oauthCredentials, null, 2));
|
|
233
|
-
const creds = oauthCredentials;
|
|
234
|
-
const oauthTokenData = creds === null || creds === void 0 ? void 0 : creds.oauthTokenData;
|
|
235
|
-
if ((oauthTokenData === null || oauthTokenData === void 0 ? void 0 : oauthTokenData.access_token) && typeof oauthTokenData.access_token === 'string') {
|
|
236
|
-
accessToken = oauthTokenData.access_token;
|
|
237
|
-
credentialType = 'OAuth2';
|
|
238
|
-
console.log('Using OAuth2 token from oauthTokenData.access_token:', accessToken.substring(0, 8) + '...');
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `OAuth2 token not found in oauthTokenData.access_token. Available fields: ${Object.keys(oauthCredentials || {}).join(', ')}. Please switch to Manual Token.`);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
const manualCredentials = await this.getCredentials('gitHubApiManual');
|
|
246
|
-
if ((manualCredentials === null || manualCredentials === void 0 ? void 0 : manualCredentials.accessToken) && typeof manualCredentials.accessToken === 'string') {
|
|
247
|
-
accessToken = manualCredentials.accessToken;
|
|
248
|
-
credentialType = 'Manual Token';
|
|
249
|
-
const tokenPrefix = accessToken.substring(0, 4);
|
|
250
|
-
console.log('Using manual token with prefix:', tokenPrefix + '...');
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Manual token credentials not found or invalid. Please configure Manual Token authentication or switch to OAuth2.');
|
|
254
|
-
}
|
|
255
|
-
}
|
|
186
|
+
const githubToken = this.getNodeParameter('githubToken', i, '');
|
|
187
|
+
const useToken = githubToken && githubToken.trim() !== '';
|
|
188
|
+
const authMethod = useToken ? 'Manual Token' : 'Local CLI';
|
|
256
189
|
let command;
|
|
257
190
|
let fullPrompt = prompt;
|
|
258
191
|
if (context) {
|
|
@@ -297,9 +230,8 @@ class GitHubCopilot {
|
|
|
297
230
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`);
|
|
298
231
|
}
|
|
299
232
|
console.log('Executing command:', command);
|
|
300
|
-
console.log('Auth
|
|
301
|
-
console.log('
|
|
302
|
-
console.log('Token type:', accessToken ? (accessToken.startsWith('gho_') ? 'OAuth' : accessToken.startsWith('ghp_') ? 'Classic' : 'Unknown') : 'Local CLI');
|
|
233
|
+
console.log('Auth method:', authMethod);
|
|
234
|
+
console.log('Using token:', useToken ? 'Yes (Manual)' : 'No (Local CLI)');
|
|
303
235
|
let stdout = '';
|
|
304
236
|
let stderr = '';
|
|
305
237
|
try {
|
|
@@ -307,9 +239,9 @@ class GitHubCopilot {
|
|
|
307
239
|
...process.env,
|
|
308
240
|
HOME: '/opt/n8n-source/packages/cli/bin',
|
|
309
241
|
};
|
|
310
|
-
if (
|
|
311
|
-
envVars.GH_TOKEN =
|
|
312
|
-
envVars.GITHUB_TOKEN =
|
|
242
|
+
if (useToken) {
|
|
243
|
+
envVars.GH_TOKEN = githubToken;
|
|
244
|
+
envVars.GITHUB_TOKEN = githubToken;
|
|
313
245
|
}
|
|
314
246
|
const result = await execAsync(command, {
|
|
315
247
|
env: envVars,
|
|
@@ -324,74 +256,27 @@ class GitHubCopilot {
|
|
|
324
256
|
stderr = err.stderr || err.message || String(execError);
|
|
325
257
|
stdout = err.stdout || '';
|
|
326
258
|
}
|
|
327
|
-
async function checkTokenPermissions(token) {
|
|
328
|
-
try {
|
|
329
|
-
const authCheckCommand = `/usr/bin/gh auth status`;
|
|
330
|
-
const apiCheckCommand = `/usr/bin/gh api user`;
|
|
331
|
-
const envVarsCheck = {
|
|
332
|
-
...process.env,
|
|
333
|
-
HOME: '/opt/n8n-source/packages/cli/bin',
|
|
334
|
-
GH_TOKEN: token,
|
|
335
|
-
GITHUB_TOKEN: token,
|
|
336
|
-
};
|
|
337
|
-
let permissionInfo = '';
|
|
338
|
-
try {
|
|
339
|
-
const authResult = await execAsync(authCheckCommand, { env: envVarsCheck, timeout: 10000 });
|
|
340
|
-
permissionInfo += `Auth Status: ${authResult.stdout.trim()}\n`;
|
|
341
|
-
}
|
|
342
|
-
catch (authError) {
|
|
343
|
-
const err = authError;
|
|
344
|
-
permissionInfo += `Auth Status Error: ${err.stderr || err.message}\n`;
|
|
345
|
-
}
|
|
346
|
-
try {
|
|
347
|
-
const apiResult = await execAsync(apiCheckCommand, { env: envVarsCheck, timeout: 10000 });
|
|
348
|
-
const userInfo = JSON.parse(apiResult.stdout);
|
|
349
|
-
permissionInfo += `User: ${userInfo.login} (${userInfo.name || 'no name'})\n`;
|
|
350
|
-
}
|
|
351
|
-
catch (apiError) {
|
|
352
|
-
const err = apiError;
|
|
353
|
-
permissionInfo += `API Access Error: ${err.stderr || err.message}\n`;
|
|
354
|
-
}
|
|
355
|
-
try {
|
|
356
|
-
await execAsync(`/usr/bin/gh api -H "Accept: application/vnd.github+json" /user`, { env: envVarsCheck, timeout: 10000 });
|
|
357
|
-
permissionInfo += `API Test: Success\n`;
|
|
358
|
-
}
|
|
359
|
-
catch (scopesError) {
|
|
360
|
-
const err = scopesError;
|
|
361
|
-
permissionInfo += `API Test Error: ${err.stderr || err.message}\n`;
|
|
362
|
-
}
|
|
363
|
-
return permissionInfo;
|
|
364
|
-
}
|
|
365
|
-
catch (error) {
|
|
366
|
-
return `Permission check failed: ${error}`;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
259
|
if (stderr) {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
debugTokenInfo = authType === 'local'
|
|
374
|
-
? ' [Local CLI - no token passed]'
|
|
375
|
-
: ` [Token used: ${accessToken || 'none'}]`;
|
|
376
|
-
if (authType === 'oauth2' && accessToken) {
|
|
377
|
-
permissionInfo = await checkTokenPermissions(accessToken);
|
|
378
|
-
debugTokenInfo += `\n\nToken Permissions Check:\n${permissionInfo}`;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
260
|
+
const debugInfo = useToken
|
|
261
|
+
? ` [Using manual token: ${githubToken.substring(0, 4)}...]`
|
|
262
|
+
: ' [Using local CLI authentication]';
|
|
381
263
|
if (stderr.includes('internal server error') || stderr.includes('code: 500')) {
|
|
382
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub Copilot service is temporarily unavailable (HTTP 500). This is a GitHub server issue. Please try again in a few moments.${
|
|
264
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub Copilot service is temporarily unavailable (HTTP 500). This is a GitHub server issue. Please try again in a few moments.${debugInfo} Error: ${stderr}`);
|
|
383
265
|
}
|
|
384
266
|
else if (stderr.includes('code: 400') || stderr.includes('Bad Request')) {
|
|
385
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub Copilot request failed (HTTP 400). The request is malformed or invalid.${
|
|
267
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub Copilot request failed (HTTP 400). The request is malformed or invalid.${debugInfo} Full error response: ${stderr}`);
|
|
386
268
|
}
|
|
387
269
|
else if (stderr.includes('401') || stderr.includes('Unauthorized') || stderr.includes('Bad credentials')) {
|
|
388
|
-
|
|
270
|
+
const tokenHelp = useToken
|
|
271
|
+
? ' Please check your token has the required scopes: repo, read:org, gist, admin:public_key. Create new token at: https://github.com/settings/tokens'
|
|
272
|
+
: ' Please run "gh auth login" on the server or provide a manual token.';
|
|
273
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub authentication failed (HTTP 401).${tokenHelp}${debugInfo} Full error response: ${stderr}`);
|
|
389
274
|
}
|
|
390
275
|
else if (stderr.includes('403') || stderr.includes('Forbidden')) {
|
|
391
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub Copilot access denied (HTTP 403). Please ensure your account has Copilot subscription.${
|
|
276
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub Copilot access denied (HTTP 403). Please ensure your account has Copilot subscription.${debugInfo} Full error response: ${stderr}`);
|
|
392
277
|
}
|
|
393
278
|
else if (!stdout) {
|
|
394
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub Copilot CLI error:${
|
|
279
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub Copilot CLI error:${debugInfo} Full error response: ${stderr}`);
|
|
395
280
|
}
|
|
396
281
|
}
|
|
397
282
|
const filterOutput = this.getNodeParameter('filterOutput', i, true);
|
|
@@ -404,9 +289,9 @@ class GitHubCopilot {
|
|
|
404
289
|
operation,
|
|
405
290
|
prompt: prompt,
|
|
406
291
|
context: context || undefined,
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
tokenPrefix:
|
|
292
|
+
authMethod: authMethod,
|
|
293
|
+
tokenUsed: useToken,
|
|
294
|
+
tokenPrefix: useToken ? githubToken.substring(0, 4) + '...' : 'none',
|
|
410
295
|
language: operation === 'suggest' ? this.getNodeParameter('language', i) : undefined,
|
|
411
296
|
commandType: operation === 'shell' ? this.getNodeParameter('commandType', i) : undefined,
|
|
412
297
|
output: processedOutput,
|
package/package.json
CHANGED