n8n-nodes-github-copilot 3.38.35 → 4.0.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/README.md +31 -52
- package/dist/nodes/GitHubCopilot/GitHubCopilot.node.js +90 -282
- package/dist/package.json +2 -2
- 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,77 @@ class GitHubCopilot {
|
|
|
252
106
|
async execute() {
|
|
253
107
|
const items = this.getInputData();
|
|
254
108
|
const returnData = [];
|
|
109
|
+
let copilotVersionInfo = { version: 'unknown', commit: 'unknown' };
|
|
110
|
+
try {
|
|
111
|
+
const versionResult = await execAsync('copilot --version', { timeout: 5000 });
|
|
112
|
+
const versionOutput = versionResult.stdout.trim();
|
|
113
|
+
const lines = versionOutput.split('\n');
|
|
114
|
+
copilotVersionInfo.version = lines[0] || 'unknown';
|
|
115
|
+
const commitLine = lines.find(l => l.startsWith('Commit:'));
|
|
116
|
+
copilotVersionInfo.commit = commitLine ? commitLine.replace('Commit:', '').trim() : 'unknown';
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
copilotVersionInfo = { version: 'not installed', commit: 'unknown' };
|
|
120
|
+
}
|
|
255
121
|
for (let i = 0; i < items.length; i++) {
|
|
256
122
|
try {
|
|
257
123
|
const operation = this.getNodeParameter('operation', i);
|
|
258
124
|
const prompt = this.getNodeParameter('prompt', i);
|
|
259
|
-
const
|
|
125
|
+
const toolApproval = this.getNodeParameter('toolApproval', i);
|
|
126
|
+
const timeout = this.getNodeParameter('timeout', i, 60);
|
|
260
127
|
const useCredential = this.getNodeParameter('useCredential', i, false);
|
|
261
128
|
let githubToken = '';
|
|
262
|
-
let authMethod = 'Local CLI';
|
|
129
|
+
let authMethod = 'Local Copilot CLI';
|
|
263
130
|
if (useCredential) {
|
|
264
131
|
try {
|
|
265
132
|
const credentials = await this.getCredentials('githubCopilotApi');
|
|
266
133
|
const token = credentials.token;
|
|
267
134
|
if (token) {
|
|
268
135
|
githubToken = token;
|
|
269
|
-
authMethod = 'GitHub
|
|
136
|
+
authMethod = 'GitHub Token (GH_TOKEN)';
|
|
270
137
|
}
|
|
271
138
|
}
|
|
272
139
|
catch {
|
|
273
140
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'GitHub Copilot credential is not configured. Please configure it or use Local CLI authentication.');
|
|
274
141
|
}
|
|
275
142
|
}
|
|
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}'`;
|
|
143
|
+
let toolFlags = '';
|
|
144
|
+
switch (toolApproval) {
|
|
145
|
+
case 'allow-all':
|
|
146
|
+
toolFlags = '--allow-all-tools';
|
|
295
147
|
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`;
|
|
148
|
+
case 'shell-only':
|
|
149
|
+
toolFlags = '--allow-tool \'shell\'';
|
|
318
150
|
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}'`;
|
|
151
|
+
case 'write-only':
|
|
152
|
+
toolFlags = '--allow-tool \'write\'';
|
|
325
153
|
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}`;
|
|
154
|
+
case 'custom':
|
|
155
|
+
toolFlags = this.getNodeParameter('allowedTools', i, '');
|
|
332
156
|
break;
|
|
333
|
-
|
|
157
|
+
case 'manual':
|
|
334
158
|
default:
|
|
335
|
-
|
|
159
|
+
toolFlags = '';
|
|
160
|
+
break;
|
|
336
161
|
}
|
|
162
|
+
const escapedPrompt = prompt.replace(/'/g, "'\"'\"'");
|
|
163
|
+
const command = `copilot -p '${escapedPrompt}' ${toolFlags}`.trim();
|
|
337
164
|
console.log('Executing command:', command);
|
|
338
165
|
console.log('Auth method:', authMethod);
|
|
339
|
-
console.log('Using token:', useToken ? 'Yes (Manual)' : 'No (Local CLI)');
|
|
340
166
|
let stdout = '';
|
|
341
167
|
let stderr = '';
|
|
342
168
|
try {
|
|
343
169
|
const envVars = {
|
|
344
170
|
...process.env,
|
|
345
171
|
};
|
|
346
|
-
if (
|
|
172
|
+
if (githubToken) {
|
|
347
173
|
envVars.GH_TOKEN = githubToken;
|
|
348
174
|
envVars.GITHUB_TOKEN = githubToken;
|
|
349
175
|
}
|
|
350
176
|
const result = await execAsync(command, {
|
|
351
177
|
env: envVars,
|
|
352
|
-
timeout:
|
|
353
|
-
maxBuffer: 1024 * 1024,
|
|
178
|
+
timeout: timeout * 1000,
|
|
179
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
354
180
|
});
|
|
355
181
|
stdout = result.stdout;
|
|
356
182
|
stderr = result.stderr;
|
|
@@ -359,53 +185,34 @@ class GitHubCopilot {
|
|
|
359
185
|
const err = execError;
|
|
360
186
|
stderr = err.stderr || err.message || String(execError);
|
|
361
187
|
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}`);
|
|
188
|
+
if (err.code === 'ETIMEDOUT') {
|
|
189
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Command timed out after ${timeout} seconds. Try increasing the timeout or simplifying the task.`);
|
|
372
190
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
191
|
+
}
|
|
192
|
+
if (stderr && !stdout) {
|
|
193
|
+
if (stderr.includes('command not found: copilot') || stderr.includes('\'copilot\' is not recognized')) {
|
|
194
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'GitHub Copilot CLI not found. Please install it:\n' +
|
|
195
|
+
'- npm: npm install -g @github/copilot\n' +
|
|
196
|
+
'- brew: brew install copilot-cli\n' +
|
|
197
|
+
'- See: https://github.com/github/copilot-cli');
|
|
380
198
|
}
|
|
381
|
-
else if (stderr.includes('
|
|
382
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(),
|
|
199
|
+
else if (stderr.includes('not logged in') || stderr.includes('authentication required')) {
|
|
200
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Not authenticated with GitHub Copilot CLI. Please run: copilot (and use /login command)\n' +
|
|
201
|
+
'Or provide a GitHub token via credential.');
|
|
383
202
|
}
|
|
384
|
-
else
|
|
385
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `
|
|
203
|
+
else {
|
|
204
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Copilot CLI error: ${stderr}`);
|
|
386
205
|
}
|
|
387
206
|
}
|
|
388
|
-
const filterOutput = this.getNodeParameter('filterOutput', i, true);
|
|
389
|
-
let processedOutput = stdout;
|
|
390
|
-
if (filterOutput) {
|
|
391
|
-
processedOutput = filterCopilotOutput(stdout);
|
|
392
|
-
}
|
|
393
207
|
returnData.push({
|
|
394
208
|
json: {
|
|
395
209
|
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,
|
|
210
|
+
prompt,
|
|
211
|
+
toolApproval,
|
|
212
|
+
authMethod,
|
|
213
|
+
copilotVersion: copilotVersionInfo,
|
|
214
|
+
output: stdout,
|
|
215
|
+
stderr: stderr || undefined,
|
|
409
216
|
timestamp: new Date().toISOString(),
|
|
410
217
|
},
|
|
411
218
|
pairedItem: { item: i },
|
|
@@ -416,7 +223,8 @@ class GitHubCopilot {
|
|
|
416
223
|
returnData.push({
|
|
417
224
|
json: {
|
|
418
225
|
error: error instanceof Error ? error.message : String(error),
|
|
419
|
-
operation:
|
|
226
|
+
operation: 'query',
|
|
227
|
+
copilotVersion: copilotVersionInfo,
|
|
420
228
|
prompt: this.getNodeParameter('prompt', i, ''),
|
|
421
229
|
timestamp: new Date().toISOString(),
|
|
422
230
|
},
|
package/dist/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-github-copilot",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "n8n community node for GitHub Copilot with CLI
|
|
3
|
+
"version": "4.0.1",
|
|
4
|
+
"description": "n8n community node for GitHub Copilot with NEW CLI programmatic mode, Chat API access, and AI Chat Model for workflows - access GPT-5, Claude Sonnet 4.5, Gemini and more using your Copilot subscription",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/sufficit/n8n-nodes-github-copilot",
|
|
7
7
|
"author": {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-github-copilot",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "n8n community node for GitHub Copilot with CLI
|
|
3
|
+
"version": "4.0.1",
|
|
4
|
+
"description": "n8n community node for GitHub Copilot with NEW CLI programmatic mode, Chat API access, and AI Chat Model for workflows - access GPT-5, Claude Sonnet 4.5, Gemini and more using your Copilot subscription",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/sufficit/n8n-nodes-github-copilot",
|
|
7
7
|
"author": {
|