n8n-nodes-github-copilot 3.38.26 → 4.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.
- package/README.md +31 -52
- package/dist/nodes/GitHubCopilot/GitHubCopilot.node.js +86 -282
- package/dist/nodes/GitHubCopilotChatModel/GitHubCopilotChatModel.node.d.ts +2 -2
- package/dist/nodes/GitHubCopilotChatModel/GitHubCopilotChatModel.node.js +95 -31
- package/dist/nodes/GitHubCopilotSpeech/GitHubCopilotSpeech.node.d.ts +10 -4
- package/dist/nodes/GitHubCopilotSpeech/GitHubCopilotSpeech.node.js +8 -7
- package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.d.ts +6 -1
- package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.js +133 -0
- package/dist/package.json +2 -2
- package/dist/shared/models/GitHubCopilotModels.js +19 -2
- package/dist/shared/models/ModelVersionRequirements.js +5 -0
- package/dist/shared/utils/DynamicModelsManager.d.ts +9 -0
- package/dist/shared/utils/DynamicModelsManager.js +48 -6
- package/dist/shared/utils/FileChunkingApiUtils.d.ts +2 -2
- package/dist/shared/utils/FileChunkingApiUtils.js +15 -15
- package/dist/shared/utils/FileOptimizationUtils.d.ts +2 -2
- package/dist/shared/utils/FileOptimizationUtils.js +20 -20
- package/dist/shared/utils/GitHubCopilotApiUtils.js +6 -2
- package/dist/shared/utils/GitHubCopilotEndpoints.js +10 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,17 +4,19 @@
|
|
|
4
4
|

|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
Este é um **community node** para [n8n](https://n8n.io/) que integra o **GitHub Copilot**
|
|
7
|
+
Este é um **community node** para [n8n](https://n8n.io/) que integra o **GitHub Copilot** através do novo **GitHub Copilot CLI** em modo programático e da **API oficial do GitHub Copilot**, permitindo acesso direto aos modelos avançados de IA como GPT-5, Claude Sonnet 4.5, Gemini 2.5 Pro e muito mais usando seus créditos existentes do Copilot.
|
|
8
8
|
|
|
9
9
|
## 🚀 Nodes Disponíveis
|
|
10
10
|
|
|
11
|
-
### 1. GitHub Copilot (
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
11
|
+
### 1. GitHub Copilot CLI (Novo! ⭐ Modo Programático)
|
|
12
|
+
- **Modo Programático**: Execute qualquer tarefa ou consulta do Copilot diretamente via `copilot -p "prompt"`
|
|
13
|
+
- **Agentic Capabilities**: Copilot pode planejar e executar tarefas complexas automaticamente
|
|
14
|
+
- **Tool Approval**: Controle fino sobre quais ferramentas o Copilot pode usar (shell, write, MCP servers)
|
|
15
|
+
- **Múltiplos Modelos**: Claude Sonnet 4.5 (padrão), Claude Sonnet 4, GPT-5
|
|
16
|
+
- **Integração GitHub**: Trabalhe com repositórios, issues, PRs diretamente da CLI
|
|
17
|
+
- **MCP Support**: Suporte nativo para Model Context Protocol servers
|
|
16
18
|
|
|
17
|
-
### 2. GitHub Copilot Chat API
|
|
19
|
+
### 2. GitHub Copilot Chat API
|
|
18
20
|
- **Chat Completion**: Conversas diretas com modelos avançados de IA
|
|
19
21
|
- **Análise de Imagens**: Processamento de imagens com modelos de visão
|
|
20
22
|
- **Modelos Disponíveis**: GPT-5, GPT-5 Mini, Claude Opus 4.1, Gemini 2.5 Pro, Grok Code Fast 1, GPT-4.1 Copilot
|
|
@@ -22,8 +24,9 @@ Este é um **community node** para [n8n](https://n8n.io/) que integra o **GitHub
|
|
|
22
24
|
|
|
23
25
|
## 🎯 Funcionalidades
|
|
24
26
|
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
27
|
+
- **Novo Copilot CLI**: Agente conversacional com modo programático
|
|
28
|
+
- **API oficial**: Acesso direto aos modelos via API
|
|
29
|
+
- **Modelos Premium**: GPT-5, Claude Sonnet 4.5, Gemini através de sua assinatura
|
|
27
30
|
|
|
28
31
|
## 📋 Pré-requisitos
|
|
29
32
|
|
|
@@ -33,71 +36,47 @@ Você precisa ter uma assinatura ativa do GitHub Copilot:
|
|
|
33
36
|
- **GitHub Copilot Business**: $19/usuário/mês
|
|
34
37
|
- **GitHub Copilot Enterprise**: $39/usuário/mês
|
|
35
38
|
|
|
36
|
-
### 2. GitHub CLI
|
|
37
|
-
O node usa o GitHub CLI (`gh`
|
|
39
|
+
### 2. Novo GitHub Copilot CLI
|
|
40
|
+
O node agora usa o **novo GitHub Copilot CLI standalone** (não mais a extensão `gh copilot` que foi depreciada):
|
|
38
41
|
|
|
39
42
|
#### Linux/Ubuntu:
|
|
40
43
|
```bash
|
|
41
|
-
#
|
|
42
|
-
curl -fsSL https://
|
|
43
|
-
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
|
|
44
|
-
sudo apt update
|
|
45
|
-
sudo apt install gh
|
|
44
|
+
# Via install script
|
|
45
|
+
curl -fsSL https://gh.io/copilot-install | bash
|
|
46
46
|
|
|
47
|
-
#
|
|
48
|
-
|
|
47
|
+
# Ou via npm
|
|
48
|
+
npm install -g @github/copilot
|
|
49
49
|
|
|
50
|
-
# Autenticar
|
|
51
|
-
|
|
50
|
+
# Autenticar (primeira vez)
|
|
51
|
+
copilot
|
|
52
|
+
# Use o comando /login quando solicitado
|
|
52
53
|
```
|
|
53
54
|
|
|
54
55
|
#### macOS:
|
|
55
56
|
```bash
|
|
56
57
|
# Usando Homebrew
|
|
57
|
-
brew install
|
|
58
|
+
brew install copilot-cli
|
|
58
59
|
|
|
59
|
-
#
|
|
60
|
-
|
|
60
|
+
# Ou via npm
|
|
61
|
+
npm install -g @github/copilot
|
|
61
62
|
|
|
62
63
|
# Autenticar
|
|
63
|
-
|
|
64
|
+
copilot
|
|
64
65
|
```
|
|
65
66
|
|
|
66
67
|
#### Windows:
|
|
67
68
|
```powershell
|
|
68
|
-
# Usando
|
|
69
|
-
|
|
69
|
+
# Usando npm
|
|
70
|
+
npm install -g @github/copilot
|
|
70
71
|
|
|
71
|
-
# Ou
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
# Instalar extensão Copilot
|
|
75
|
-
gh extension install github/gh-copilot
|
|
72
|
+
# Ou via WinGet
|
|
73
|
+
winget install GitHub.Copilot
|
|
76
74
|
|
|
77
75
|
# Autenticar
|
|
78
|
-
|
|
76
|
+
copilot
|
|
79
77
|
```
|
|
80
78
|
|
|
81
|
-
|
|
82
|
-
Crie um Personal Access Token no GitHub com as seguintes permissões:
|
|
83
|
-
- `read:user`
|
|
84
|
-
- `user:email`
|
|
85
|
-
- Acesso ao GitHub Copilot (incluído automaticamente se você tem assinatura)
|
|
86
|
-
|
|
87
|
-
## 🚀 Instalação
|
|
88
|
-
|
|
89
|
-
### Opção 1: Via npm (Recomendado)
|
|
90
|
-
```bash
|
|
91
|
-
npm install n8n-nodes-github-copilot
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### Opção 2: Via Interface do n8n
|
|
95
|
-
1. Vá para **Settings > Community Nodes**
|
|
96
|
-
2. Clique em **Install a community node**
|
|
97
|
-
3. Digite: `n8n-nodes-github-copilot`
|
|
98
|
-
4. Clique em **Install**
|
|
99
|
-
|
|
100
|
-
### Opção 3: Instalação Manual
|
|
79
|
+
**⚠️ IMPORTANTE**: O antigo `gh copilot` (extensão do GitHub CLI) foi depreciado. Este node agora usa o novo `copilot` CLI standalone.
|
|
101
80
|
1. Clone este repositório
|
|
102
81
|
2. Execute `npm run build`
|
|
103
82
|
3. Copie a pasta `dist` para o diretório de nodes do n8n
|
|
@@ -5,57 +5,18 @@ 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
|
-
}
|
|
47
8
|
class GitHubCopilot {
|
|
48
9
|
constructor() {
|
|
49
10
|
this.description = {
|
|
50
|
-
displayName: 'GitHub Copilot',
|
|
11
|
+
displayName: 'GitHub Copilot CLI',
|
|
51
12
|
name: 'gitHubCopilot',
|
|
52
13
|
icon: 'file:../../shared/icons/copilot.svg',
|
|
53
14
|
group: ['transform'],
|
|
54
|
-
version:
|
|
55
|
-
subtitle: '',
|
|
56
|
-
description: 'Interact with GitHub Copilot
|
|
15
|
+
version: 2,
|
|
16
|
+
subtitle: '={{$parameter["operation"]}}',
|
|
17
|
+
description: 'Interact with GitHub Copilot CLI in programmatic mode',
|
|
57
18
|
defaults: {
|
|
58
|
-
name: 'GitHub Copilot',
|
|
19
|
+
name: 'GitHub Copilot CLI',
|
|
59
20
|
},
|
|
60
21
|
inputs: ['main'],
|
|
61
22
|
outputs: ['main'],
|
|
@@ -76,7 +37,7 @@ class GitHubCopilot {
|
|
|
76
37
|
name: 'useCredential',
|
|
77
38
|
type: 'boolean',
|
|
78
39
|
default: false,
|
|
79
|
-
description: 'Use GitHub
|
|
40
|
+
description: 'Use GitHub token (GH_TOKEN/GITHUB_TOKEN) instead of local copilot CLI authentication',
|
|
80
41
|
},
|
|
81
42
|
{
|
|
82
43
|
displayName: 'Operation',
|
|
@@ -85,166 +46,59 @@ class GitHubCopilot {
|
|
|
85
46
|
noDataExpression: true,
|
|
86
47
|
options: [
|
|
87
48
|
{
|
|
88
|
-
name: '
|
|
89
|
-
value: '
|
|
90
|
-
description: '
|
|
91
|
-
action: '
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
name: 'Explain',
|
|
95
|
-
value: 'explain',
|
|
96
|
-
description: 'Explain code or commands using GitHub Copilot',
|
|
97
|
-
action: 'Explain code or commands',
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
name: 'Shell',
|
|
101
|
-
value: 'shell',
|
|
102
|
-
description: 'Get shell command suggestions from GitHub Copilot',
|
|
103
|
-
action: 'Get shell command suggestions',
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
name: 'Revise',
|
|
107
|
-
value: 'revise',
|
|
108
|
-
description: 'Revise and improve existing code or commands',
|
|
109
|
-
action: 'Revise code or commands',
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
name: 'Rate Response',
|
|
113
|
-
value: 'rating',
|
|
114
|
-
description: 'Rate a previous GitHub Copilot response',
|
|
115
|
-
action: 'Rate response',
|
|
49
|
+
name: 'Query',
|
|
50
|
+
value: 'query',
|
|
51
|
+
description: 'Ask GitHub Copilot any question or task in programmatic mode',
|
|
52
|
+
action: 'Query Copilot in programmatic mode',
|
|
116
53
|
},
|
|
117
54
|
],
|
|
118
|
-
default: '
|
|
55
|
+
default: 'query',
|
|
119
56
|
},
|
|
120
57
|
{
|
|
121
58
|
displayName: 'Prompt',
|
|
122
59
|
name: 'prompt',
|
|
123
60
|
type: 'string',
|
|
124
61
|
typeOptions: {
|
|
125
|
-
rows:
|
|
62
|
+
rows: 5,
|
|
126
63
|
},
|
|
127
64
|
required: true,
|
|
128
65
|
default: '',
|
|
129
|
-
placeholder: '
|
|
130
|
-
description: '
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
displayName: 'Filter Output',
|
|
134
|
-
name: 'filterOutput',
|
|
135
|
-
type: 'boolean',
|
|
136
|
-
default: true,
|
|
137
|
-
description: 'Remove GitHub Copilot CLI header and footer, keeping only the useful response',
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
displayName: 'Language',
|
|
141
|
-
name: 'language',
|
|
142
|
-
type: 'options',
|
|
143
|
-
displayOptions: {
|
|
144
|
-
show: {
|
|
145
|
-
operation: ['suggest'],
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
options: [
|
|
149
|
-
{ name: 'JavaScript', value: 'javascript' },
|
|
150
|
-
{ name: 'TypeScript', value: 'typescript' },
|
|
151
|
-
{ name: 'Python', value: 'python' },
|
|
152
|
-
{ name: 'Java', value: 'java' },
|
|
153
|
-
{ name: 'C#', value: 'csharp' },
|
|
154
|
-
{ name: 'C++', value: 'cpp' },
|
|
155
|
-
{ name: 'Go', value: 'go' },
|
|
156
|
-
{ name: 'Rust', value: 'rust' },
|
|
157
|
-
{ name: 'PHP', value: 'php' },
|
|
158
|
-
{ name: 'Ruby', value: 'ruby' },
|
|
159
|
-
{ name: 'Shell', value: 'shell' },
|
|
160
|
-
{ name: 'SQL', value: 'sql' },
|
|
161
|
-
{ name: 'Other', value: 'other' },
|
|
162
|
-
],
|
|
163
|
-
default: 'javascript',
|
|
164
|
-
description: 'Programming language for code suggestions',
|
|
66
|
+
placeholder: 'Example: Show me this week\'s commits and summarize them',
|
|
67
|
+
description: 'Your query or task for GitHub Copilot CLI. Will be executed with: copilot -p "your prompt"',
|
|
165
68
|
},
|
|
166
69
|
{
|
|
167
|
-
displayName: '
|
|
168
|
-
name: '
|
|
70
|
+
displayName: 'Tool Approval',
|
|
71
|
+
name: 'toolApproval',
|
|
169
72
|
type: 'options',
|
|
170
|
-
displayOptions: {
|
|
171
|
-
show: {
|
|
172
|
-
operation: ['shell'],
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
73
|
options: [
|
|
176
|
-
{ name: '
|
|
177
|
-
{ name: '
|
|
178
|
-
{ name: '
|
|
179
|
-
{ name: '
|
|
180
|
-
{ name: '
|
|
74
|
+
{ name: 'Allow All Tools (Unsafe)', value: 'allow-all' },
|
|
75
|
+
{ name: 'Allow Shell Commands Only', value: 'shell-only' },
|
|
76
|
+
{ name: 'Allow Write Operations Only', value: 'write-only' },
|
|
77
|
+
{ name: 'Manual Approval Required', value: 'manual' },
|
|
78
|
+
{ name: 'Custom (Advanced)', value: 'custom' },
|
|
181
79
|
],
|
|
182
|
-
default: '
|
|
183
|
-
description: '
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
displayName: 'Additional Context',
|
|
187
|
-
name: 'context',
|
|
188
|
-
type: 'string',
|
|
189
|
-
typeOptions: {
|
|
190
|
-
rows: 2,
|
|
191
|
-
},
|
|
192
|
-
default: '',
|
|
193
|
-
placeholder: 'Any additional context or constraints...',
|
|
194
|
-
description: 'Optional additional context to provide better suggestions',
|
|
80
|
+
default: 'manual',
|
|
81
|
+
description: 'Which tools Copilot can use without asking. WARNING: "Allow All" is dangerous - Copilot can execute ANY command!',
|
|
195
82
|
},
|
|
196
83
|
{
|
|
197
|
-
displayName: '
|
|
198
|
-
name: '
|
|
84
|
+
displayName: 'Allowed Tools',
|
|
85
|
+
name: 'allowedTools',
|
|
199
86
|
type: 'string',
|
|
200
|
-
typeOptions: {
|
|
201
|
-
rows: 4,
|
|
202
|
-
},
|
|
203
|
-
required: true,
|
|
204
|
-
default: '',
|
|
205
|
-
placeholder: 'Enter the original code or command to revise...',
|
|
206
|
-
description: 'The original code or command that you want to improve',
|
|
207
|
-
displayOptions: {
|
|
208
|
-
show: {
|
|
209
|
-
operation: ['revise'],
|
|
210
|
-
},
|
|
211
|
-
},
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
displayName: 'Rating',
|
|
215
|
-
name: 'rating',
|
|
216
|
-
type: 'options',
|
|
217
|
-
options: [
|
|
218
|
-
{ name: 'Very Good', value: 'very-good' },
|
|
219
|
-
{ name: 'Good', value: 'good' },
|
|
220
|
-
{ name: 'Fair', value: 'fair' },
|
|
221
|
-
{ name: 'Poor', value: 'poor' },
|
|
222
|
-
],
|
|
223
|
-
required: true,
|
|
224
|
-
default: 'good',
|
|
225
|
-
description: 'Rate the GitHub Copilot response',
|
|
226
87
|
displayOptions: {
|
|
227
88
|
show: {
|
|
228
|
-
|
|
89
|
+
toolApproval: ['custom'],
|
|
229
90
|
},
|
|
230
91
|
},
|
|
92
|
+
default: '',
|
|
93
|
+
placeholder: '--allow-tool \'shell(git)\' --allow-tool \'write\'',
|
|
94
|
+
description: 'Custom tool approval flags (space-separated). Example: --allow-tool \'shell(git)\' --deny-tool \'shell(rm)\'',
|
|
231
95
|
},
|
|
232
96
|
{
|
|
233
|
-
displayName: '
|
|
234
|
-
name: '
|
|
235
|
-
type: '
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
},
|
|
239
|
-
required: true,
|
|
240
|
-
default: '',
|
|
241
|
-
placeholder: 'Enter the GitHub Copilot response you want to rate...',
|
|
242
|
-
description: 'The GitHub Copilot response that you want to rate',
|
|
243
|
-
displayOptions: {
|
|
244
|
-
show: {
|
|
245
|
-
operation: ['rating'],
|
|
246
|
-
},
|
|
247
|
-
},
|
|
97
|
+
displayName: 'Timeout (seconds)',
|
|
98
|
+
name: 'timeout',
|
|
99
|
+
type: 'number',
|
|
100
|
+
default: 60,
|
|
101
|
+
description: 'Maximum execution time in seconds',
|
|
248
102
|
},
|
|
249
103
|
],
|
|
250
104
|
};
|
|
@@ -252,105 +106,73 @@ class GitHubCopilot {
|
|
|
252
106
|
async execute() {
|
|
253
107
|
const items = this.getInputData();
|
|
254
108
|
const returnData = [];
|
|
109
|
+
let copilotVersion = 'unknown';
|
|
110
|
+
try {
|
|
111
|
+
const versionResult = await execAsync('copilot --version', { timeout: 5000 });
|
|
112
|
+
copilotVersion = versionResult.stdout.trim();
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
copilotVersion = 'not installed';
|
|
116
|
+
}
|
|
255
117
|
for (let i = 0; i < items.length; i++) {
|
|
256
118
|
try {
|
|
257
119
|
const operation = this.getNodeParameter('operation', i);
|
|
258
120
|
const prompt = this.getNodeParameter('prompt', i);
|
|
259
|
-
const
|
|
121
|
+
const toolApproval = this.getNodeParameter('toolApproval', i);
|
|
122
|
+
const timeout = this.getNodeParameter('timeout', i, 60);
|
|
260
123
|
const useCredential = this.getNodeParameter('useCredential', i, false);
|
|
261
124
|
let githubToken = '';
|
|
262
|
-
let authMethod = 'Local CLI';
|
|
125
|
+
let authMethod = 'Local Copilot CLI';
|
|
263
126
|
if (useCredential) {
|
|
264
127
|
try {
|
|
265
128
|
const credentials = await this.getCredentials('githubCopilotApi');
|
|
266
129
|
const token = credentials.token;
|
|
267
130
|
if (token) {
|
|
268
131
|
githubToken = token;
|
|
269
|
-
authMethod = 'GitHub
|
|
132
|
+
authMethod = 'GitHub Token (GH_TOKEN)';
|
|
270
133
|
}
|
|
271
134
|
}
|
|
272
135
|
catch {
|
|
273
136
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'GitHub Copilot credential is not configured. Please configure it or use Local CLI authentication.');
|
|
274
137
|
}
|
|
275
138
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
fullPrompt = `${prompt}\n\nAdditional context: ${context}`;
|
|
281
|
-
}
|
|
282
|
-
switch (operation) {
|
|
283
|
-
case 'suggest': {
|
|
284
|
-
const language = this.getNodeParameter('language', i);
|
|
285
|
-
if (language !== 'other') {
|
|
286
|
-
fullPrompt = `[${language}] ${fullPrompt}`;
|
|
287
|
-
}
|
|
288
|
-
const escapedSuggestPrompt = fullPrompt.replace(/'/g, "'\"'\"'");
|
|
289
|
-
command = `gh copilot suggest '${escapedSuggestPrompt}'`;
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
292
|
-
case 'explain': {
|
|
293
|
-
const escapedExplainPrompt = fullPrompt.replace(/'/g, "'\"'\"'");
|
|
294
|
-
command = `gh copilot explain '${escapedExplainPrompt}'`;
|
|
139
|
+
let toolFlags = '';
|
|
140
|
+
switch (toolApproval) {
|
|
141
|
+
case 'allow-all':
|
|
142
|
+
toolFlags = '--allow-all-tools';
|
|
295
143
|
break;
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const commandType = this.getNodeParameter('commandType', i);
|
|
299
|
-
let shellPrompt = fullPrompt;
|
|
300
|
-
switch (commandType) {
|
|
301
|
-
case 'git':
|
|
302
|
-
shellPrompt = `git: ${fullPrompt}`;
|
|
303
|
-
break;
|
|
304
|
-
case 'docker':
|
|
305
|
-
shellPrompt = `docker: ${fullPrompt}`;
|
|
306
|
-
break;
|
|
307
|
-
case 'npm':
|
|
308
|
-
shellPrompt = `npm/yarn: ${fullPrompt}`;
|
|
309
|
-
break;
|
|
310
|
-
case 'file':
|
|
311
|
-
shellPrompt = `file operations: ${fullPrompt}`;
|
|
312
|
-
break;
|
|
313
|
-
default:
|
|
314
|
-
shellPrompt = fullPrompt;
|
|
315
|
-
}
|
|
316
|
-
const escapedShellPrompt = shellPrompt.replace(/'/g, "'\"'\"'");
|
|
317
|
-
command = `gh copilot suggest '${escapedShellPrompt}' --type shell`;
|
|
144
|
+
case 'shell-only':
|
|
145
|
+
toolFlags = '--allow-tool \'shell\'';
|
|
318
146
|
break;
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const originalCode = this.getNodeParameter('originalCode', i);
|
|
322
|
-
const revisePrompt = `${fullPrompt}\n\nOriginal code/command:\n${originalCode}`;
|
|
323
|
-
const escapedRevisePrompt = revisePrompt.replace(/'/g, "'\"'\"'");
|
|
324
|
-
command = `gh copilot revise '${escapedRevisePrompt}'`;
|
|
147
|
+
case 'write-only':
|
|
148
|
+
toolFlags = '--allow-tool \'write\'';
|
|
325
149
|
break;
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
const rating = this.getNodeParameter('rating', i);
|
|
329
|
-
const responseToRate = this.getNodeParameter('responseToRate', i);
|
|
330
|
-
const escapedResponseToRate = responseToRate.replace(/'/g, "'\"'\"'");
|
|
331
|
-
command = `gh copilot rate '${escapedResponseToRate}' --rating ${rating}`;
|
|
150
|
+
case 'custom':
|
|
151
|
+
toolFlags = this.getNodeParameter('allowedTools', i, '');
|
|
332
152
|
break;
|
|
333
|
-
|
|
153
|
+
case 'manual':
|
|
334
154
|
default:
|
|
335
|
-
|
|
155
|
+
toolFlags = '';
|
|
156
|
+
break;
|
|
336
157
|
}
|
|
158
|
+
const escapedPrompt = prompt.replace(/'/g, "'\"'\"'");
|
|
159
|
+
const command = `copilot -p '${escapedPrompt}' ${toolFlags}`.trim();
|
|
337
160
|
console.log('Executing command:', command);
|
|
338
161
|
console.log('Auth method:', authMethod);
|
|
339
|
-
console.log('Using token:', useToken ? 'Yes (Manual)' : 'No (Local CLI)');
|
|
340
162
|
let stdout = '';
|
|
341
163
|
let stderr = '';
|
|
342
164
|
try {
|
|
343
165
|
const envVars = {
|
|
344
166
|
...process.env,
|
|
345
167
|
};
|
|
346
|
-
if (
|
|
168
|
+
if (githubToken) {
|
|
347
169
|
envVars.GH_TOKEN = githubToken;
|
|
348
170
|
envVars.GITHUB_TOKEN = githubToken;
|
|
349
171
|
}
|
|
350
172
|
const result = await execAsync(command, {
|
|
351
173
|
env: envVars,
|
|
352
|
-
timeout:
|
|
353
|
-
maxBuffer: 1024 * 1024,
|
|
174
|
+
timeout: timeout * 1000,
|
|
175
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
354
176
|
});
|
|
355
177
|
stdout = result.stdout;
|
|
356
178
|
stderr = result.stderr;
|
|
@@ -359,53 +181,34 @@ class GitHubCopilot {
|
|
|
359
181
|
const err = execError;
|
|
360
182
|
stderr = err.stderr || err.message || String(execError);
|
|
361
183
|
stdout = err.stdout || '';
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const debugInfo = useToken
|
|
365
|
-
? ` [Using manual token: ${githubToken.substring(0, 4)}...]`
|
|
366
|
-
: ' [Using local CLI authentication]';
|
|
367
|
-
if (stderr.includes('internal server error') || stderr.includes('code: 500')) {
|
|
368
|
-
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}`);
|
|
369
|
-
}
|
|
370
|
-
else if (stderr.includes('code: 400') || stderr.includes('Bad Request')) {
|
|
371
|
-
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}`);
|
|
184
|
+
if (err.code === 'ETIMEDOUT') {
|
|
185
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Command timed out after ${timeout} seconds. Try increasing the timeout or simplifying the task.`);
|
|
372
186
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
187
|
+
}
|
|
188
|
+
if (stderr && !stdout) {
|
|
189
|
+
if (stderr.includes('command not found: copilot') || stderr.includes('\'copilot\' is not recognized')) {
|
|
190
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'GitHub Copilot CLI not found. Please install it:\n' +
|
|
191
|
+
'- npm: npm install -g @github/copilot\n' +
|
|
192
|
+
'- brew: brew install copilot-cli\n' +
|
|
193
|
+
'- See: https://github.com/github/copilot-cli');
|
|
380
194
|
}
|
|
381
|
-
else if (stderr.includes('
|
|
382
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(),
|
|
195
|
+
else if (stderr.includes('not logged in') || stderr.includes('authentication required')) {
|
|
196
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Not authenticated with GitHub Copilot CLI. Please run: copilot (and use /login command)\n' +
|
|
197
|
+
'Or provide a GitHub token via credential.');
|
|
383
198
|
}
|
|
384
|
-
else
|
|
385
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `
|
|
199
|
+
else {
|
|
200
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Copilot CLI error: ${stderr}`);
|
|
386
201
|
}
|
|
387
202
|
}
|
|
388
|
-
const filterOutput = this.getNodeParameter('filterOutput', i, true);
|
|
389
|
-
let processedOutput = stdout;
|
|
390
|
-
if (filterOutput) {
|
|
391
|
-
processedOutput = filterCopilotOutput(stdout);
|
|
392
|
-
}
|
|
393
203
|
returnData.push({
|
|
394
204
|
json: {
|
|
395
205
|
operation,
|
|
396
|
-
prompt
|
|
397
|
-
|
|
398
|
-
authMethod
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
commandType: operation === 'shell' ? this.getNodeParameter('commandType', i) : undefined,
|
|
403
|
-
originalCode: operation === 'revise' ? this.getNodeParameter('originalCode', i) : undefined,
|
|
404
|
-
rating: operation === 'rating' ? this.getNodeParameter('rating', i) : undefined,
|
|
405
|
-
responseToRate: operation === 'rating' ? this.getNodeParameter('responseToRate', i) : undefined,
|
|
406
|
-
output: processedOutput,
|
|
407
|
-
cliRawOutput: stdout,
|
|
408
|
-
cliStderr: stderr || undefined,
|
|
206
|
+
prompt,
|
|
207
|
+
toolApproval,
|
|
208
|
+
authMethod,
|
|
209
|
+
copilotVersion,
|
|
210
|
+
output: stdout,
|
|
211
|
+
stderr: stderr || undefined,
|
|
409
212
|
timestamp: new Date().toISOString(),
|
|
410
213
|
},
|
|
411
214
|
pairedItem: { item: i },
|
|
@@ -416,7 +219,8 @@ class GitHubCopilot {
|
|
|
416
219
|
returnData.push({
|
|
417
220
|
json: {
|
|
418
221
|
error: error instanceof Error ? error.message : String(error),
|
|
419
|
-
operation:
|
|
222
|
+
operation: 'query',
|
|
223
|
+
copilotVersion,
|
|
420
224
|
prompt: this.getNodeParameter('prompt', i, ''),
|
|
421
225
|
timestamp: new Date().toISOString(),
|
|
422
226
|
},
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { INodeType, INodeTypeDescription,
|
|
1
|
+
import { ISupplyDataFunctions, INodeType, INodeTypeDescription, SupplyData } from 'n8n-workflow';
|
|
2
2
|
export declare class GitHubCopilotChatModel implements INodeType {
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
4
|
methods: {
|
|
5
5
|
loadOptions: {
|
|
6
|
-
getAvailableModels(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
6
|
+
getAvailableModels(this: import("n8n-workflow").ILoadOptionsFunctions): Promise<import("n8n-workflow").INodePropertyOptions[]>;
|
|
7
7
|
};
|
|
8
8
|
};
|
|
9
9
|
supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData>;
|