n8n-nodes-github-copilot 1.0.7 → 1.0.9

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.
@@ -1,9 +1,8 @@
1
- import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
1
+ import { ICredentialType, INodeProperties } from 'n8n-workflow';
2
2
  export declare class GitHubApi implements ICredentialType {
3
3
  name: string;
4
4
  displayName: string;
5
+ extends: string[];
5
6
  documentationUrl: string;
6
7
  properties: INodeProperties[];
7
- authenticate: IAuthenticateGeneric;
8
- test: ICredentialTestRequest;
9
8
  }
@@ -4,36 +4,47 @@ exports.GitHubApi = void 0;
4
4
  class GitHubApi {
5
5
  constructor() {
6
6
  this.name = 'gitHubApi';
7
- this.displayName = 'GitHub API';
8
- this.documentationUrl = 'https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token';
7
+ this.displayName = 'GitHub OAuth2 API';
8
+ this.extends = ['oAuth2Api'];
9
+ this.documentationUrl = 'https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps';
9
10
  this.properties = [
10
11
  {
11
- displayName: 'GitHub OAuth Token',
12
- name: 'oauthToken',
13
- type: 'string',
14
- typeOptions: {
15
- password: true,
16
- },
17
- default: '',
18
- required: true,
19
- description: 'GitHub OAuth Token (gho_...) for GitHub Copilot CLI. Generate via: gh auth login --web. Required for Copilot CLI access.',
12
+ displayName: 'Grant Type',
13
+ name: 'grantType',
14
+ type: 'hidden',
15
+ default: 'authorizationCode',
20
16
  },
21
- ];
22
- this.authenticate = {
23
- type: 'generic',
24
- properties: {
25
- headers: {
26
- Authorization: '=Bearer {{$credentials.oauthToken}}',
27
- },
17
+ {
18
+ displayName: 'Authorization URL',
19
+ name: 'authUrl',
20
+ type: 'hidden',
21
+ default: 'https://github.com/login/oauth/authorize',
22
+ },
23
+ {
24
+ displayName: 'Access Token URL',
25
+ name: 'accessTokenUrl',
26
+ type: 'hidden',
27
+ default: 'https://github.com/login/oauth/access_token',
28
+ },
29
+ {
30
+ displayName: 'Scope',
31
+ name: 'scope',
32
+ type: 'hidden',
33
+ default: 'copilot read:org repo user',
34
+ },
35
+ {
36
+ displayName: 'Auth URI Query Parameters',
37
+ name: 'authQueryParameters',
38
+ type: 'hidden',
39
+ default: '',
28
40
  },
29
- };
30
- this.test = {
31
- request: {
32
- baseURL: 'https://api.github.com',
33
- url: '/user',
34
- method: 'GET',
41
+ {
42
+ displayName: 'Authentication',
43
+ name: 'authentication',
44
+ type: 'hidden',
45
+ default: 'header',
35
46
  },
36
- };
47
+ ];
37
48
  }
38
49
  }
39
50
  exports.GitHubApi = GitHubApi;
@@ -0,0 +1,7 @@
1
+ import { ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class GitHubApiManual implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GitHubApiManual = void 0;
4
+ class GitHubApiManual {
5
+ constructor() {
6
+ this.name = 'gitHubApiManual';
7
+ this.displayName = 'GitHub API (Manual Token)';
8
+ this.documentationUrl = 'https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token';
9
+ this.properties = [
10
+ {
11
+ displayName: 'Access Token',
12
+ name: 'accessToken',
13
+ type: 'string',
14
+ typeOptions: { password: true },
15
+ required: true,
16
+ default: '',
17
+ placeholder: 'gho_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
18
+ description: 'GitHub Personal Access Token with Copilot permissions. Must start with "gho_" for OAuth or "ghp_" for classic.',
19
+ },
20
+ {
21
+ displayName: 'Token Type Info',
22
+ name: 'tokenInfo',
23
+ type: 'notice',
24
+ default: '',
25
+ displayOptions: {
26
+ show: {},
27
+ },
28
+ description: 'For GitHub Copilot CLI, OAuth tokens (gho_) are recommended. Create at: GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens',
29
+ },
30
+ ];
31
+ }
32
+ }
33
+ exports.GitHubApiManual = GitHubApiManual;
@@ -5,6 +5,45 @@ const n8n_workflow_1 = require("n8n-workflow");
5
5
  const child_process_1 = require("child_process");
6
6
  const util_1 = require("util");
7
7
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
8
+ function filterCopilotOutput(rawOutput) {
9
+ const lines = rawOutput.split('\n');
10
+ let startIndex = -1;
11
+ const endIndex = lines.length;
12
+ for (let i = 0; i < lines.length; i++) {
13
+ const line = lines[i].trim();
14
+ if (line.includes('# Explanation:') ||
15
+ line.includes('# Suggestion:') ||
16
+ line.includes('# Command:') ||
17
+ line.includes('# Code:') ||
18
+ (line.startsWith('•') && i > 5)) {
19
+ startIndex = i;
20
+ break;
21
+ }
22
+ }
23
+ if (startIndex === -1) {
24
+ for (let i = 0; i < lines.length; i++) {
25
+ const line = lines[i].trim();
26
+ if (line.includes('version ') && line.includes('(') && line.includes(')')) {
27
+ startIndex = i + 3;
28
+ break;
29
+ }
30
+ }
31
+ }
32
+ if (startIndex === -1) {
33
+ for (let i = 0; i < lines.length; i++) {
34
+ const line = lines[i].trim();
35
+ if (line.length > 10 && !line.includes('Welcome to') && !line.includes('powered by AI')) {
36
+ startIndex = i;
37
+ break;
38
+ }
39
+ }
40
+ }
41
+ if (startIndex >= 0) {
42
+ const filteredLines = lines.slice(startIndex, endIndex);
43
+ return filteredLines.join('\n').trim();
44
+ }
45
+ return rawOutput.trim();
46
+ }
8
47
  class GitHubCopilot {
9
48
  constructor() {
10
49
  this.description = {
@@ -23,7 +62,13 @@ class GitHubCopilot {
23
62
  credentials: [
24
63
  {
25
64
  name: 'gitHubApi',
26
- required: true,
65
+ displayName: 'GitHub API (OAuth2)',
66
+ required: false,
67
+ },
68
+ {
69
+ name: 'gitHubApiManual',
70
+ displayName: 'GitHub API (Manual Token)',
71
+ required: false,
27
72
  },
28
73
  ],
29
74
  properties: [
@@ -66,6 +111,13 @@ class GitHubCopilot {
66
111
  placeholder: 'Enter your request...',
67
112
  description: 'What you want GitHub Copilot to help with',
68
113
  },
114
+ {
115
+ displayName: 'Filter Output',
116
+ name: 'filterOutput',
117
+ type: 'boolean',
118
+ default: true,
119
+ description: 'Remove GitHub Copilot CLI header and footer, keeping only the useful response',
120
+ },
69
121
  {
70
122
  displayName: 'Language',
71
123
  name: 'language',
@@ -134,7 +186,24 @@ class GitHubCopilot {
134
186
  const operation = this.getNodeParameter('operation', i);
135
187
  const prompt = this.getNodeParameter('prompt', i);
136
188
  const context = this.getNodeParameter('context', i, '');
137
- const credentials = await this.getCredentials('gitHubApi');
189
+ let credentials;
190
+ let accessToken;
191
+ try {
192
+ credentials = await this.getCredentials('gitHubApi');
193
+ accessToken = credentials.accessToken;
194
+ }
195
+ catch (error) {
196
+ try {
197
+ credentials = await this.getCredentials('gitHubApiManual');
198
+ accessToken = credentials.accessToken;
199
+ }
200
+ catch (manualError) {
201
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No GitHub credentials found. Please configure either OAuth2 or Manual Token credentials.');
202
+ }
203
+ }
204
+ if (!accessToken) {
205
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'GitHub access token not found in credentials.');
206
+ }
138
207
  let command;
139
208
  let fullPrompt = prompt;
140
209
  if (context) {
@@ -178,7 +247,7 @@ class GitHubCopilot {
178
247
  const { stdout, stderr } = await execAsync(command, {
179
248
  env: {
180
249
  ...process.env,
181
- GH_TOKEN: credentials.oauthToken,
250
+ GH_TOKEN: accessToken,
182
251
  HOME: '/opt/n8n-source/packages/cli/bin',
183
252
  },
184
253
  timeout: 30000,
@@ -187,6 +256,11 @@ class GitHubCopilot {
187
256
  if (stderr && !stdout) {
188
257
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub Copilot CLI error: ${stderr}`);
189
258
  }
259
+ const filterOutput = this.getNodeParameter('filterOutput', i, true);
260
+ let processedOutput = stdout;
261
+ if (filterOutput) {
262
+ processedOutput = filterCopilotOutput(stdout);
263
+ }
190
264
  returnData.push({
191
265
  json: {
192
266
  operation,
@@ -194,6 +268,7 @@ class GitHubCopilot {
194
268
  context: context || undefined,
195
269
  language: operation === 'suggest' ? this.getNodeParameter('language', i) : undefined,
196
270
  commandType: operation === 'shell' ? this.getNodeParameter('commandType', i) : undefined,
271
+ output: processedOutput,
197
272
  cliRawOutput: stdout,
198
273
  timestamp: new Date().toISOString(),
199
274
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-github-copilot",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "n8n community node for GitHub Copilot CLI integration",
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/GitHubApi.credentials.js"
30
+ "dist/credentials/GitHubApi.credentials.js",
31
+ "dist/credentials/GitHubApiManual.credentials.js"
31
32
  ],
32
33
  "nodes": [
33
34
  "dist/nodes/GitHubCopilot/GitHubCopilot.node.js"