n8n-nodes-github-copilot 3.27.6 → 3.28.1
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/dist/credentials/GitHubCopilotApi.credentials.d.ts +1 -1
- package/dist/credentials/GitHubCopilotApi.credentials.js +19 -19
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.backup.d.ts +1 -1
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.backup.js +71 -71
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.d.ts +1 -1
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.js +67 -67
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.oauth.d.ts +1 -1
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.oauth.js +38 -38
- package/dist/nodes/GitHubCopilot/GitHubCopilot.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilot/GitHubCopilot.node.js +188 -181
- package/dist/nodes/GitHubCopilotChatAPI/GitHubCopilotChatAPI.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatAPI/GitHubCopilotChatAPI.node.js +38 -38
- package/dist/nodes/GitHubCopilotChatAPI/nodeProperties.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatAPI/nodeProperties.js +97 -97
- package/dist/nodes/GitHubCopilotChatAPI/utils/imageProcessor.d.ts +2 -2
- package/dist/nodes/GitHubCopilotChatAPI/utils/imageProcessor.js +16 -15
- package/dist/nodes/GitHubCopilotChatAPI/utils/index.d.ts +3 -3
- package/dist/nodes/GitHubCopilotChatAPI/utils/mediaDetection.d.ts +3 -3
- package/dist/nodes/GitHubCopilotChatAPI/utils/mediaDetection.js +20 -26
- package/dist/nodes/GitHubCopilotChatAPI/utils/modelCapabilities.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatAPI/utils/modelCapabilities.js +24 -24
- package/dist/nodes/GitHubCopilotChatAPI/utils/types.d.ts +4 -4
- package/dist/nodes/GitHubCopilotChatModel/GitHubCopilotChatModel.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatModel/GitHubCopilotChatModel.node.js +86 -82
- package/dist/nodes/GitHubCopilotOpenAI/GitHubCopilotOpenAI.node.d.ts +5 -0
- package/dist/nodes/GitHubCopilotOpenAI/GitHubCopilotOpenAI.node.js +142 -0
- package/dist/nodes/GitHubCopilotOpenAI/nodeProperties.d.ts +2 -0
- package/dist/nodes/GitHubCopilotOpenAI/nodeProperties.js +326 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/index.d.ts +2 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/index.js +24 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/openaiCompat.d.ts +95 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/openaiCompat.js +175 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/types.d.ts +101 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/types.js +2 -0
- package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.js +96 -94
- package/package.json +77 -74
|
@@ -6,16 +6,16 @@ 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
8
|
function filterCopilotOutput(rawOutput) {
|
|
9
|
-
const lines = rawOutput.split(
|
|
9
|
+
const lines = rawOutput.split("\n");
|
|
10
10
|
let startIndex = -1;
|
|
11
11
|
const endIndex = lines.length;
|
|
12
12
|
for (let i = 0; i < lines.length; i++) {
|
|
13
13
|
const line = lines[i].trim();
|
|
14
|
-
if (line.includes(
|
|
15
|
-
line.includes(
|
|
16
|
-
line.includes(
|
|
17
|
-
line.includes(
|
|
18
|
-
(line.startsWith(
|
|
14
|
+
if (line.includes("# Explanation:") ||
|
|
15
|
+
line.includes("# Suggestion:") ||
|
|
16
|
+
line.includes("# Command:") ||
|
|
17
|
+
line.includes("# Code:") ||
|
|
18
|
+
(line.startsWith("•") && i > 5)) {
|
|
19
19
|
startIndex = i;
|
|
20
20
|
break;
|
|
21
21
|
}
|
|
@@ -23,7 +23,7 @@ function filterCopilotOutput(rawOutput) {
|
|
|
23
23
|
if (startIndex === -1) {
|
|
24
24
|
for (let i = 0; i < lines.length; i++) {
|
|
25
25
|
const line = lines[i].trim();
|
|
26
|
-
if (line.includes(
|
|
26
|
+
if (line.includes("version ") && line.includes("(") && line.includes(")")) {
|
|
27
27
|
startIndex = i + 3;
|
|
28
28
|
break;
|
|
29
29
|
}
|
|
@@ -32,7 +32,7 @@ function filterCopilotOutput(rawOutput) {
|
|
|
32
32
|
if (startIndex === -1) {
|
|
33
33
|
for (let i = 0; i < lines.length; i++) {
|
|
34
34
|
const line = lines[i].trim();
|
|
35
|
-
if (line.length > 10 && !line.includes(
|
|
35
|
+
if (line.length > 10 && !line.includes("Welcome to") && !line.includes("powered by AI")) {
|
|
36
36
|
startIndex = i;
|
|
37
37
|
break;
|
|
38
38
|
}
|
|
@@ -40,73 +40,73 @@ function filterCopilotOutput(rawOutput) {
|
|
|
40
40
|
}
|
|
41
41
|
if (startIndex >= 0) {
|
|
42
42
|
const filteredLines = lines.slice(startIndex, endIndex);
|
|
43
|
-
return filteredLines.join(
|
|
43
|
+
return filteredLines.join("\n").trim();
|
|
44
44
|
}
|
|
45
45
|
return rawOutput.trim();
|
|
46
46
|
}
|
|
47
47
|
class GitHubCopilot {
|
|
48
48
|
constructor() {
|
|
49
49
|
this.description = {
|
|
50
|
-
displayName:
|
|
51
|
-
name:
|
|
52
|
-
icon:
|
|
53
|
-
group: [
|
|
50
|
+
displayName: "GitHub Copilot",
|
|
51
|
+
name: "gitHubCopilot",
|
|
52
|
+
icon: "file:../../shared/icons/copilot.svg",
|
|
53
|
+
group: ["transform"],
|
|
54
54
|
version: 1,
|
|
55
|
-
subtitle:
|
|
56
|
-
description:
|
|
55
|
+
subtitle: "={{$parameter[\"operation\"]}}",
|
|
56
|
+
description: "Use GitHub Copilot CLI for AI-powered code suggestions and explanations",
|
|
57
57
|
defaults: {
|
|
58
|
-
name:
|
|
58
|
+
name: "GitHub Copilot",
|
|
59
59
|
},
|
|
60
60
|
inputs: ["main"],
|
|
61
61
|
outputs: ["main"],
|
|
62
62
|
credentials: [
|
|
63
63
|
{
|
|
64
|
-
name:
|
|
64
|
+
name: "githubCopilotApi",
|
|
65
65
|
required: false,
|
|
66
66
|
displayOptions: {
|
|
67
67
|
show: {
|
|
68
68
|
useCredential: [true],
|
|
69
|
-
credentialType: [
|
|
69
|
+
credentialType: ["githubCopilotApi"],
|
|
70
70
|
},
|
|
71
71
|
},
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
|
-
name:
|
|
74
|
+
name: "githubCopilotOAuth2Api",
|
|
75
75
|
required: false,
|
|
76
76
|
displayOptions: {
|
|
77
77
|
show: {
|
|
78
78
|
useCredential: [true],
|
|
79
|
-
credentialType: [
|
|
79
|
+
credentialType: ["githubCopilotOAuth2Api"],
|
|
80
80
|
},
|
|
81
81
|
},
|
|
82
82
|
},
|
|
83
83
|
],
|
|
84
84
|
properties: [
|
|
85
85
|
{
|
|
86
|
-
displayName:
|
|
87
|
-
name:
|
|
88
|
-
type:
|
|
86
|
+
displayName: "Authentication Method",
|
|
87
|
+
name: "useCredential",
|
|
88
|
+
type: "boolean",
|
|
89
89
|
default: false,
|
|
90
|
-
description:
|
|
90
|
+
description: "Use GitHub Copilot API credential instead of local GitHub CLI authentication",
|
|
91
91
|
},
|
|
92
92
|
{
|
|
93
|
-
displayName:
|
|
94
|
-
name:
|
|
95
|
-
type:
|
|
93
|
+
displayName: "Credential Type",
|
|
94
|
+
name: "credentialType",
|
|
95
|
+
type: "options",
|
|
96
96
|
options: [
|
|
97
97
|
{
|
|
98
|
-
name:
|
|
99
|
-
value:
|
|
100
|
-
description:
|
|
98
|
+
name: "GitHub Copilot API (Manual Token)",
|
|
99
|
+
value: "githubCopilotApi",
|
|
100
|
+
description: "Use manual GitHub CLI token",
|
|
101
101
|
},
|
|
102
102
|
{
|
|
103
|
-
name:
|
|
104
|
-
value:
|
|
105
|
-
description:
|
|
103
|
+
name: "GitHub Copilot OAuth2 (with Helper)",
|
|
104
|
+
value: "githubCopilotOAuth2Api",
|
|
105
|
+
description: "Use OAuth2 credential with helper script",
|
|
106
106
|
},
|
|
107
107
|
],
|
|
108
|
-
default:
|
|
109
|
-
description:
|
|
108
|
+
default: "githubCopilotApi",
|
|
109
|
+
description: "Type of credential to use for GitHub Copilot authentication",
|
|
110
110
|
displayOptions: {
|
|
111
111
|
show: {
|
|
112
112
|
useCredential: [true],
|
|
@@ -114,170 +114,170 @@ class GitHubCopilot {
|
|
|
114
114
|
},
|
|
115
115
|
},
|
|
116
116
|
{
|
|
117
|
-
displayName:
|
|
118
|
-
name:
|
|
119
|
-
type:
|
|
117
|
+
displayName: "Operation",
|
|
118
|
+
name: "operation",
|
|
119
|
+
type: "options",
|
|
120
120
|
noDataExpression: true,
|
|
121
121
|
options: [
|
|
122
122
|
{
|
|
123
|
-
name:
|
|
124
|
-
value:
|
|
125
|
-
description:
|
|
126
|
-
action:
|
|
123
|
+
name: "Suggest",
|
|
124
|
+
value: "suggest",
|
|
125
|
+
description: "Get code suggestions from GitHub Copilot",
|
|
126
|
+
action: "Get code suggestions",
|
|
127
127
|
},
|
|
128
128
|
{
|
|
129
|
-
name:
|
|
130
|
-
value:
|
|
131
|
-
description:
|
|
132
|
-
action:
|
|
129
|
+
name: "Explain",
|
|
130
|
+
value: "explain",
|
|
131
|
+
description: "Explain code or commands using GitHub Copilot",
|
|
132
|
+
action: "Explain code or commands",
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
|
-
name:
|
|
136
|
-
value:
|
|
137
|
-
description:
|
|
138
|
-
action:
|
|
135
|
+
name: "Shell",
|
|
136
|
+
value: "shell",
|
|
137
|
+
description: "Get shell command suggestions from GitHub Copilot",
|
|
138
|
+
action: "Get shell command suggestions",
|
|
139
139
|
},
|
|
140
140
|
{
|
|
141
|
-
name:
|
|
142
|
-
value:
|
|
143
|
-
description:
|
|
144
|
-
action:
|
|
141
|
+
name: "Revise",
|
|
142
|
+
value: "revise",
|
|
143
|
+
description: "Revise and improve existing code or commands",
|
|
144
|
+
action: "Revise code or commands",
|
|
145
145
|
},
|
|
146
146
|
{
|
|
147
|
-
name:
|
|
148
|
-
value:
|
|
149
|
-
description:
|
|
150
|
-
action:
|
|
147
|
+
name: "Rate Response",
|
|
148
|
+
value: "rating",
|
|
149
|
+
description: "Rate a previous GitHub Copilot response",
|
|
150
|
+
action: "Rate response",
|
|
151
151
|
},
|
|
152
152
|
],
|
|
153
|
-
default:
|
|
153
|
+
default: "suggest",
|
|
154
154
|
},
|
|
155
155
|
{
|
|
156
|
-
displayName:
|
|
157
|
-
name:
|
|
158
|
-
type:
|
|
156
|
+
displayName: "Prompt",
|
|
157
|
+
name: "prompt",
|
|
158
|
+
type: "string",
|
|
159
159
|
typeOptions: {
|
|
160
160
|
rows: 3,
|
|
161
161
|
},
|
|
162
162
|
required: true,
|
|
163
|
-
default:
|
|
164
|
-
placeholder:
|
|
165
|
-
description:
|
|
163
|
+
default: "",
|
|
164
|
+
placeholder: "Enter your request...",
|
|
165
|
+
description: "What you want GitHub Copilot to help with",
|
|
166
166
|
},
|
|
167
167
|
{
|
|
168
|
-
displayName:
|
|
169
|
-
name:
|
|
170
|
-
type:
|
|
168
|
+
displayName: "Filter Output",
|
|
169
|
+
name: "filterOutput",
|
|
170
|
+
type: "boolean",
|
|
171
171
|
default: true,
|
|
172
|
-
description:
|
|
172
|
+
description: "Remove GitHub Copilot CLI header and footer, keeping only the useful response",
|
|
173
173
|
},
|
|
174
174
|
{
|
|
175
|
-
displayName:
|
|
176
|
-
name:
|
|
177
|
-
type:
|
|
175
|
+
displayName: "Language",
|
|
176
|
+
name: "language",
|
|
177
|
+
type: "options",
|
|
178
178
|
displayOptions: {
|
|
179
179
|
show: {
|
|
180
|
-
operation: [
|
|
180
|
+
operation: ["suggest"],
|
|
181
181
|
},
|
|
182
182
|
},
|
|
183
183
|
options: [
|
|
184
|
-
{ name:
|
|
185
|
-
{ name:
|
|
186
|
-
{ name:
|
|
187
|
-
{ name:
|
|
188
|
-
{ name:
|
|
189
|
-
{ name:
|
|
190
|
-
{ name:
|
|
191
|
-
{ name:
|
|
192
|
-
{ name:
|
|
193
|
-
{ name:
|
|
194
|
-
{ name:
|
|
195
|
-
{ name:
|
|
196
|
-
{ name:
|
|
184
|
+
{ name: "JavaScript", value: "javascript" },
|
|
185
|
+
{ name: "TypeScript", value: "typescript" },
|
|
186
|
+
{ name: "Python", value: "python" },
|
|
187
|
+
{ name: "Java", value: "java" },
|
|
188
|
+
{ name: "C#", value: "csharp" },
|
|
189
|
+
{ name: "C++", value: "cpp" },
|
|
190
|
+
{ name: "Go", value: "go" },
|
|
191
|
+
{ name: "Rust", value: "rust" },
|
|
192
|
+
{ name: "PHP", value: "php" },
|
|
193
|
+
{ name: "Ruby", value: "ruby" },
|
|
194
|
+
{ name: "Shell", value: "shell" },
|
|
195
|
+
{ name: "SQL", value: "sql" },
|
|
196
|
+
{ name: "Other", value: "other" },
|
|
197
197
|
],
|
|
198
|
-
default:
|
|
199
|
-
description:
|
|
198
|
+
default: "javascript",
|
|
199
|
+
description: "Programming language for code suggestions",
|
|
200
200
|
},
|
|
201
201
|
{
|
|
202
|
-
displayName:
|
|
203
|
-
name:
|
|
204
|
-
type:
|
|
202
|
+
displayName: "Command Type",
|
|
203
|
+
name: "commandType",
|
|
204
|
+
type: "options",
|
|
205
205
|
displayOptions: {
|
|
206
206
|
show: {
|
|
207
|
-
operation: [
|
|
207
|
+
operation: ["shell"],
|
|
208
208
|
},
|
|
209
209
|
},
|
|
210
210
|
options: [
|
|
211
|
-
{ name:
|
|
212
|
-
{ name:
|
|
213
|
-
{ name:
|
|
214
|
-
{ name:
|
|
215
|
-
{ name:
|
|
211
|
+
{ name: "General", value: "general" },
|
|
212
|
+
{ name: "Git", value: "git" },
|
|
213
|
+
{ name: "Docker", value: "docker" },
|
|
214
|
+
{ name: "npm/yarn", value: "npm" },
|
|
215
|
+
{ name: "File Operations", value: "file" },
|
|
216
216
|
],
|
|
217
|
-
default:
|
|
218
|
-
description:
|
|
217
|
+
default: "general",
|
|
218
|
+
description: "Type of shell commands to suggest",
|
|
219
219
|
},
|
|
220
220
|
{
|
|
221
|
-
displayName:
|
|
222
|
-
name:
|
|
223
|
-
type:
|
|
221
|
+
displayName: "Additional Context",
|
|
222
|
+
name: "context",
|
|
223
|
+
type: "string",
|
|
224
224
|
typeOptions: {
|
|
225
225
|
rows: 2,
|
|
226
226
|
},
|
|
227
|
-
default:
|
|
228
|
-
placeholder:
|
|
229
|
-
description:
|
|
227
|
+
default: "",
|
|
228
|
+
placeholder: "Any additional context or constraints...",
|
|
229
|
+
description: "Optional additional context to provide better suggestions",
|
|
230
230
|
},
|
|
231
231
|
{
|
|
232
|
-
displayName:
|
|
233
|
-
name:
|
|
234
|
-
type:
|
|
232
|
+
displayName: "Original Code/Command",
|
|
233
|
+
name: "originalCode",
|
|
234
|
+
type: "string",
|
|
235
235
|
typeOptions: {
|
|
236
236
|
rows: 4,
|
|
237
237
|
},
|
|
238
238
|
required: true,
|
|
239
|
-
default:
|
|
240
|
-
placeholder:
|
|
241
|
-
description:
|
|
239
|
+
default: "",
|
|
240
|
+
placeholder: "Enter the original code or command to revise...",
|
|
241
|
+
description: "The original code or command that you want to improve",
|
|
242
242
|
displayOptions: {
|
|
243
243
|
show: {
|
|
244
|
-
operation: [
|
|
244
|
+
operation: ["revise"],
|
|
245
245
|
},
|
|
246
246
|
},
|
|
247
247
|
},
|
|
248
248
|
{
|
|
249
|
-
displayName:
|
|
250
|
-
name:
|
|
251
|
-
type:
|
|
249
|
+
displayName: "Rating",
|
|
250
|
+
name: "rating",
|
|
251
|
+
type: "options",
|
|
252
252
|
options: [
|
|
253
|
-
{ name:
|
|
254
|
-
{ name:
|
|
255
|
-
{ name:
|
|
256
|
-
{ name:
|
|
253
|
+
{ name: "Very Good", value: "very-good" },
|
|
254
|
+
{ name: "Good", value: "good" },
|
|
255
|
+
{ name: "Fair", value: "fair" },
|
|
256
|
+
{ name: "Poor", value: "poor" },
|
|
257
257
|
],
|
|
258
258
|
required: true,
|
|
259
|
-
default:
|
|
260
|
-
description:
|
|
259
|
+
default: "good",
|
|
260
|
+
description: "Rate the GitHub Copilot response",
|
|
261
261
|
displayOptions: {
|
|
262
262
|
show: {
|
|
263
|
-
operation: [
|
|
263
|
+
operation: ["rating"],
|
|
264
264
|
},
|
|
265
265
|
},
|
|
266
266
|
},
|
|
267
267
|
{
|
|
268
|
-
displayName:
|
|
269
|
-
name:
|
|
270
|
-
type:
|
|
268
|
+
displayName: "Response to Rate",
|
|
269
|
+
name: "responseToRate",
|
|
270
|
+
type: "string",
|
|
271
271
|
typeOptions: {
|
|
272
272
|
rows: 3,
|
|
273
273
|
},
|
|
274
274
|
required: true,
|
|
275
|
-
default:
|
|
276
|
-
placeholder:
|
|
277
|
-
description:
|
|
275
|
+
default: "",
|
|
276
|
+
placeholder: "Enter the GitHub Copilot response you want to rate...",
|
|
277
|
+
description: "The GitHub Copilot response that you want to rate",
|
|
278
278
|
displayOptions: {
|
|
279
279
|
show: {
|
|
280
|
-
operation: [
|
|
280
|
+
operation: ["rating"],
|
|
281
281
|
},
|
|
282
282
|
},
|
|
283
283
|
},
|
|
@@ -290,15 +290,15 @@ class GitHubCopilot {
|
|
|
290
290
|
const returnData = [];
|
|
291
291
|
for (let i = 0; i < items.length; i++) {
|
|
292
292
|
try {
|
|
293
|
-
const operation = this.getNodeParameter(
|
|
294
|
-
const prompt = this.getNodeParameter(
|
|
295
|
-
const context = this.getNodeParameter(
|
|
296
|
-
const useCredential = this.getNodeParameter(
|
|
297
|
-
let githubToken =
|
|
298
|
-
let authMethod =
|
|
293
|
+
const operation = this.getNodeParameter("operation", i);
|
|
294
|
+
const prompt = this.getNodeParameter("prompt", i);
|
|
295
|
+
const context = this.getNodeParameter("context", i, "");
|
|
296
|
+
const useCredential = this.getNodeParameter("useCredential", i, false);
|
|
297
|
+
let githubToken = "";
|
|
298
|
+
let authMethod = "Local CLI";
|
|
299
299
|
if (useCredential) {
|
|
300
300
|
try {
|
|
301
|
-
const credentialType = this.getNodeParameter(
|
|
301
|
+
const credentialType = this.getNodeParameter("credentialType", i, "githubCopilotApi");
|
|
302
302
|
const credentials = await this.getCredentials(credentialType);
|
|
303
303
|
const token = (credentials.accessToken ||
|
|
304
304
|
credentials.access_token ||
|
|
@@ -306,74 +306,79 @@ class GitHubCopilot {
|
|
|
306
306
|
credentials.token);
|
|
307
307
|
if (token) {
|
|
308
308
|
githubToken = token;
|
|
309
|
-
authMethod = `GitHub Copilot ${credentialType ===
|
|
309
|
+
authMethod = `GitHub Copilot ${credentialType === "githubCopilotOAuth2Api" ? "OAuth2" : "API"} Credential`;
|
|
310
310
|
}
|
|
311
311
|
}
|
|
312
312
|
catch (error) {
|
|
313
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(),
|
|
313
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), "GitHub Copilot credential is not configured. Please configure it or use Local CLI authentication.");
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
|
-
const useToken = githubToken && githubToken.trim() !==
|
|
316
|
+
const useToken = githubToken && githubToken.trim() !== "";
|
|
317
317
|
let command;
|
|
318
318
|
let fullPrompt = prompt;
|
|
319
319
|
if (context) {
|
|
320
320
|
fullPrompt = `${prompt}\n\nAdditional context: ${context}`;
|
|
321
321
|
}
|
|
322
322
|
switch (operation) {
|
|
323
|
-
case
|
|
324
|
-
const language = this.getNodeParameter(
|
|
325
|
-
if (language !==
|
|
323
|
+
case "suggest": {
|
|
324
|
+
const language = this.getNodeParameter("language", i);
|
|
325
|
+
if (language !== "other") {
|
|
326
326
|
fullPrompt = `[${language}] ${fullPrompt}`;
|
|
327
327
|
}
|
|
328
|
-
const escapedSuggestPrompt = fullPrompt.replace(/'/g,
|
|
328
|
+
const escapedSuggestPrompt = fullPrompt.replace(/'/g, "'\"'\"'");
|
|
329
329
|
command = `gh copilot suggest '${escapedSuggestPrompt}'`;
|
|
330
330
|
break;
|
|
331
|
-
|
|
332
|
-
|
|
331
|
+
}
|
|
332
|
+
case "explain": {
|
|
333
|
+
const escapedExplainPrompt = fullPrompt.replace(/'/g, "'\"'\"'");
|
|
333
334
|
command = `gh copilot explain '${escapedExplainPrompt}'`;
|
|
334
335
|
break;
|
|
335
|
-
|
|
336
|
-
|
|
336
|
+
}
|
|
337
|
+
case "shell": {
|
|
338
|
+
const commandType = this.getNodeParameter("commandType", i);
|
|
337
339
|
let shellPrompt = fullPrompt;
|
|
338
340
|
switch (commandType) {
|
|
339
|
-
case
|
|
341
|
+
case "git":
|
|
340
342
|
shellPrompt = `git: ${fullPrompt}`;
|
|
341
343
|
break;
|
|
342
|
-
case
|
|
344
|
+
case "docker":
|
|
343
345
|
shellPrompt = `docker: ${fullPrompt}`;
|
|
344
346
|
break;
|
|
345
|
-
case
|
|
347
|
+
case "npm":
|
|
346
348
|
shellPrompt = `npm/yarn: ${fullPrompt}`;
|
|
347
349
|
break;
|
|
348
|
-
case
|
|
350
|
+
case "file":
|
|
349
351
|
shellPrompt = `file operations: ${fullPrompt}`;
|
|
350
352
|
break;
|
|
351
353
|
default:
|
|
352
354
|
shellPrompt = fullPrompt;
|
|
353
355
|
}
|
|
354
|
-
const escapedShellPrompt = shellPrompt.replace(/'/g,
|
|
356
|
+
const escapedShellPrompt = shellPrompt.replace(/'/g, "'\"'\"'");
|
|
355
357
|
command = `gh copilot suggest '${escapedShellPrompt}' --type shell`;
|
|
356
358
|
break;
|
|
357
|
-
|
|
358
|
-
|
|
359
|
+
}
|
|
360
|
+
case "revise": {
|
|
361
|
+
const originalCode = this.getNodeParameter("originalCode", i);
|
|
359
362
|
const revisePrompt = `${fullPrompt}\n\nOriginal code/command:\n${originalCode}`;
|
|
360
|
-
const escapedRevisePrompt = revisePrompt.replace(/'/g,
|
|
363
|
+
const escapedRevisePrompt = revisePrompt.replace(/'/g, "'\"'\"'");
|
|
361
364
|
command = `gh copilot revise '${escapedRevisePrompt}'`;
|
|
362
365
|
break;
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
const
|
|
366
|
-
const
|
|
366
|
+
}
|
|
367
|
+
case "rating": {
|
|
368
|
+
const rating = this.getNodeParameter("rating", i);
|
|
369
|
+
const responseToRate = this.getNodeParameter("responseToRate", i);
|
|
370
|
+
const escapedResponseToRate = responseToRate.replace(/'/g, "'\"'\"'");
|
|
367
371
|
command = `gh copilot rate '${escapedResponseToRate}' --rating ${rating}`;
|
|
368
372
|
break;
|
|
373
|
+
}
|
|
369
374
|
default:
|
|
370
375
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`);
|
|
371
376
|
}
|
|
372
|
-
console.log(
|
|
373
|
-
console.log(
|
|
374
|
-
console.log(
|
|
375
|
-
let stdout =
|
|
376
|
-
let stderr =
|
|
377
|
+
console.log("Executing command:", command);
|
|
378
|
+
console.log("Auth method:", authMethod);
|
|
379
|
+
console.log("Using token:", useToken ? "Yes (Manual)" : "No (Local CLI)");
|
|
380
|
+
let stdout = "";
|
|
381
|
+
let stderr = "";
|
|
377
382
|
try {
|
|
378
383
|
const envVars = {
|
|
379
384
|
...process.env,
|
|
@@ -393,32 +398,34 @@ class GitHubCopilot {
|
|
|
393
398
|
catch (execError) {
|
|
394
399
|
const err = execError;
|
|
395
400
|
stderr = err.stderr || err.message || String(execError);
|
|
396
|
-
stdout = err.stdout ||
|
|
401
|
+
stdout = err.stdout || "";
|
|
397
402
|
}
|
|
398
403
|
if (stderr) {
|
|
399
404
|
const debugInfo = useToken
|
|
400
405
|
? ` [Using manual token: ${githubToken.substring(0, 4)}...]`
|
|
401
|
-
:
|
|
402
|
-
if (stderr.includes(
|
|
406
|
+
: " [Using local CLI authentication]";
|
|
407
|
+
if (stderr.includes("internal server error") || stderr.includes("code: 500")) {
|
|
403
408
|
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}`);
|
|
404
409
|
}
|
|
405
|
-
else if (stderr.includes(
|
|
410
|
+
else if (stderr.includes("code: 400") || stderr.includes("Bad Request")) {
|
|
406
411
|
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}`);
|
|
407
412
|
}
|
|
408
|
-
else if (stderr.includes(
|
|
413
|
+
else if (stderr.includes("401") ||
|
|
414
|
+
stderr.includes("Unauthorized") ||
|
|
415
|
+
stderr.includes("Bad credentials")) {
|
|
409
416
|
const tokenHelp = useToken
|
|
410
|
-
?
|
|
411
|
-
:
|
|
417
|
+
? " IMPORTANT: Only tokens generated by \"gh auth token\" command work with Copilot. Personal Access Tokens from GitHub website DO NOT work. Try: run \"gh auth login\" first, then use \"gh auth token\" to get a working token."
|
|
418
|
+
: " Please run \"gh auth login\" on the server first, or provide a token generated by \"gh auth token\" command.";
|
|
412
419
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub authentication failed (HTTP 401).${tokenHelp}${debugInfo} Full error response: ${stderr}`);
|
|
413
420
|
}
|
|
414
|
-
else if (stderr.includes(
|
|
421
|
+
else if (stderr.includes("403") || stderr.includes("Forbidden")) {
|
|
415
422
|
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}`);
|
|
416
423
|
}
|
|
417
424
|
else if (!stdout) {
|
|
418
425
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `GitHub Copilot CLI error:${debugInfo} Full error response: ${stderr}`);
|
|
419
426
|
}
|
|
420
427
|
}
|
|
421
|
-
const filterOutput = this.getNodeParameter(
|
|
428
|
+
const filterOutput = this.getNodeParameter("filterOutput", i, true);
|
|
422
429
|
let processedOutput = stdout;
|
|
423
430
|
if (filterOutput) {
|
|
424
431
|
processedOutput = filterCopilotOutput(stdout);
|
|
@@ -430,12 +437,12 @@ class GitHubCopilot {
|
|
|
430
437
|
context: context || undefined,
|
|
431
438
|
authMethod: authMethod,
|
|
432
439
|
tokenUsed: useToken,
|
|
433
|
-
tokenPrefix: useToken ? githubToken.substring(0, 4) +
|
|
434
|
-
language: operation ===
|
|
435
|
-
commandType: operation ===
|
|
436
|
-
originalCode: operation ===
|
|
437
|
-
rating: operation ===
|
|
438
|
-
responseToRate: operation ===
|
|
440
|
+
tokenPrefix: useToken ? githubToken.substring(0, 4) + "..." : "none",
|
|
441
|
+
language: operation === "suggest" ? this.getNodeParameter("language", i) : undefined,
|
|
442
|
+
commandType: operation === "shell" ? this.getNodeParameter("commandType", i) : undefined,
|
|
443
|
+
originalCode: operation === "revise" ? this.getNodeParameter("originalCode", i) : undefined,
|
|
444
|
+
rating: operation === "rating" ? this.getNodeParameter("rating", i) : undefined,
|
|
445
|
+
responseToRate: operation === "rating" ? this.getNodeParameter("responseToRate", i) : undefined,
|
|
439
446
|
output: processedOutput,
|
|
440
447
|
cliRawOutput: stdout,
|
|
441
448
|
cliStderr: stderr || undefined,
|
|
@@ -449,8 +456,8 @@ class GitHubCopilot {
|
|
|
449
456
|
returnData.push({
|
|
450
457
|
json: {
|
|
451
458
|
error: error instanceof Error ? error.message : String(error),
|
|
452
|
-
operation: this.getNodeParameter(
|
|
453
|
-
prompt: this.getNodeParameter(
|
|
459
|
+
operation: this.getNodeParameter("operation", i, "unknown"),
|
|
460
|
+
prompt: this.getNodeParameter("prompt", i, ""),
|
|
454
461
|
timestamp: new Date().toISOString(),
|
|
455
462
|
},
|
|
456
463
|
pairedItem: { item: i },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from
|
|
1
|
+
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from "n8n-workflow";
|
|
2
2
|
export declare class GitHubCopilotChatAPI implements INodeType {
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
4
|
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|