blyuecode 0.1.7 → 0.1.8
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/core/agent.js +2 -2
- package/dist/core/n8n.js +85 -0
- package/dist/core/tools.js +101 -8
- package/package.json +1 -1
package/dist/core/agent.js
CHANGED
|
@@ -11,8 +11,8 @@ export class Agent {
|
|
|
11
11
|
{
|
|
12
12
|
role: 'system',
|
|
13
13
|
content: 'You are BLYUE, a coding assistant running in a terminal. ' +
|
|
14
|
-
'Use tools to read, write,
|
|
15
|
-
'
|
|
14
|
+
'Use tools to read, write, run commands, and manage n8n workflows. ' +
|
|
15
|
+
'Always explain what you are doing. Be concise.',
|
|
16
16
|
},
|
|
17
17
|
];
|
|
18
18
|
async *run(userInput) {
|
package/dist/core/n8n.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const BASE = process.env.N8N_URL || '';
|
|
2
|
+
const KEY = process.env.N8N_API_KEY || '';
|
|
3
|
+
function headers() {
|
|
4
|
+
return {
|
|
5
|
+
'X-N8N-API-KEY': KEY,
|
|
6
|
+
'Content-Type': 'application/json',
|
|
7
|
+
Accept: 'application/json',
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function ensureConfig() {
|
|
11
|
+
if (!BASE)
|
|
12
|
+
throw new Error('N8N_URL not set. Add to ~/.blyue/.env');
|
|
13
|
+
if (!KEY)
|
|
14
|
+
throw new Error('N8N_API_KEY not set. Add to ~/.blyue/.env');
|
|
15
|
+
}
|
|
16
|
+
export async function n8nListWorkflows() {
|
|
17
|
+
ensureConfig();
|
|
18
|
+
const res = await fetch(`${BASE}/api/v1/workflows`, { headers: headers() });
|
|
19
|
+
if (!res.ok)
|
|
20
|
+
throw new Error(`n8n API ${res.status}: ${await res.text()}`);
|
|
21
|
+
const json = await res.json();
|
|
22
|
+
return (json.data || []).map((w) => ({
|
|
23
|
+
id: w.id,
|
|
24
|
+
name: w.name,
|
|
25
|
+
active: w.active,
|
|
26
|
+
updatedAt: w.updatedAt,
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
export async function n8nTriggerWorkflow(workflowId, data = {}) {
|
|
30
|
+
ensureConfig();
|
|
31
|
+
const res = await fetch(`${BASE}/webhook/${workflowId}`, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: { 'Content-Type': 'application/json' },
|
|
34
|
+
body: JSON.stringify(data),
|
|
35
|
+
});
|
|
36
|
+
return await res.text();
|
|
37
|
+
}
|
|
38
|
+
export async function n8nListExecutions(workflowId, limit = 10) {
|
|
39
|
+
ensureConfig();
|
|
40
|
+
const url = new URL(`${BASE}/api/v1/executions`);
|
|
41
|
+
url.searchParams.set('limit', String(limit));
|
|
42
|
+
if (workflowId)
|
|
43
|
+
url.searchParams.set('workflowId', workflowId);
|
|
44
|
+
const res = await fetch(url.toString(), { headers: headers() });
|
|
45
|
+
if (!res.ok)
|
|
46
|
+
throw new Error(`n8n API ${res.status}: ${await res.text()}`);
|
|
47
|
+
const json = await res.json();
|
|
48
|
+
return (json.data || []).map((e) => ({
|
|
49
|
+
id: e.id,
|
|
50
|
+
status: e.finished
|
|
51
|
+
? 'success'
|
|
52
|
+
: e.stoppedAt
|
|
53
|
+
? 'failed'
|
|
54
|
+
: 'running',
|
|
55
|
+
startedAt: e.startedAt,
|
|
56
|
+
workflowId: e.workflowId,
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
export async function n8nGetWorkflow(id) {
|
|
60
|
+
ensureConfig();
|
|
61
|
+
const res = await fetch(`${BASE}/api/v1/workflows/${id}`, { headers: headers() });
|
|
62
|
+
if (!res.ok)
|
|
63
|
+
throw new Error(`n8n API ${res.status}: ${await res.text()}`);
|
|
64
|
+
return await res.json();
|
|
65
|
+
}
|
|
66
|
+
export async function n8nActivateWorkflow(id) {
|
|
67
|
+
ensureConfig();
|
|
68
|
+
const res = await fetch(`${BASE}/api/v1/workflows/${id}/activate`, {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers: headers(),
|
|
71
|
+
});
|
|
72
|
+
if (!res.ok)
|
|
73
|
+
throw new Error(`n8n API ${res.status}: ${await res.text()}`);
|
|
74
|
+
return 'activated';
|
|
75
|
+
}
|
|
76
|
+
export async function n8nDeactivateWorkflow(id) {
|
|
77
|
+
ensureConfig();
|
|
78
|
+
const res = await fetch(`${BASE}/api/v1/workflows/${id}/deactivate`, {
|
|
79
|
+
method: 'POST',
|
|
80
|
+
headers: headers(),
|
|
81
|
+
});
|
|
82
|
+
if (!res.ok)
|
|
83
|
+
throw new Error(`n8n API ${res.status}: ${await res.text()}`);
|
|
84
|
+
return 'deactivated';
|
|
85
|
+
}
|
package/dist/core/tools.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import { exec } from 'child_process';
|
|
3
3
|
import { promisify } from 'util';
|
|
4
|
+
import { n8nListWorkflows, n8nTriggerWorkflow, n8nListExecutions, n8nGetWorkflow, n8nActivateWorkflow, n8nDeactivateWorkflow, } from './n8n.js';
|
|
4
5
|
const execAsync = promisify(exec);
|
|
6
|
+
// ─────────────────────────────────────────────
|
|
7
|
+
// Tool definitions
|
|
8
|
+
// ─────────────────────────────────────────────
|
|
5
9
|
export const toolDefs = [
|
|
10
|
+
// ───── File ops ─────
|
|
6
11
|
{
|
|
7
12
|
type: 'function',
|
|
8
13
|
function: {
|
|
@@ -10,9 +15,7 @@ export const toolDefs = [
|
|
|
10
15
|
description: 'Read a file from disk',
|
|
11
16
|
parameters: {
|
|
12
17
|
type: 'object',
|
|
13
|
-
properties: {
|
|
14
|
-
path: { type: 'string', description: 'File path' },
|
|
15
|
-
},
|
|
18
|
+
properties: { path: { type: 'string' } },
|
|
16
19
|
required: ['path'],
|
|
17
20
|
},
|
|
18
21
|
},
|
|
@@ -39,9 +42,7 @@ export const toolDefs = [
|
|
|
39
42
|
description: 'List files in a directory',
|
|
40
43
|
parameters: {
|
|
41
44
|
type: 'object',
|
|
42
|
-
properties: {
|
|
43
|
-
path: { type: 'string', description: 'Directory path (default: .)' },
|
|
44
|
-
},
|
|
45
|
+
properties: { path: { type: 'string' } },
|
|
45
46
|
},
|
|
46
47
|
},
|
|
47
48
|
},
|
|
@@ -50,19 +51,98 @@ export const toolDefs = [
|
|
|
50
51
|
function: {
|
|
51
52
|
name: 'run_command',
|
|
52
53
|
description: 'Run a shell command. Use carefully.',
|
|
54
|
+
parameters: {
|
|
55
|
+
type: 'object',
|
|
56
|
+
properties: { command: { type: 'string' } },
|
|
57
|
+
required: ['command'],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
// ───── n8n ─────
|
|
62
|
+
{
|
|
63
|
+
type: 'function',
|
|
64
|
+
function: {
|
|
65
|
+
name: 'n8n_list_workflows',
|
|
66
|
+
description: 'List all n8n workflows. Returns id, name, active status, updatedAt.',
|
|
67
|
+
parameters: { type: 'object', properties: {} },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'function',
|
|
72
|
+
function: {
|
|
73
|
+
name: 'n8n_get_workflow',
|
|
74
|
+
description: 'Get details of a specific n8n workflow by ID',
|
|
75
|
+
parameters: {
|
|
76
|
+
type: 'object',
|
|
77
|
+
properties: { id: { type: 'string' } },
|
|
78
|
+
required: ['id'],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: 'function',
|
|
84
|
+
function: {
|
|
85
|
+
name: 'n8n_trigger_workflow',
|
|
86
|
+
description: 'Trigger an n8n workflow via its webhook URL',
|
|
53
87
|
parameters: {
|
|
54
88
|
type: 'object',
|
|
55
89
|
properties: {
|
|
56
|
-
|
|
90
|
+
workflowId: { type: 'string' },
|
|
91
|
+
data: {
|
|
92
|
+
type: 'object',
|
|
93
|
+
description: 'JSON payload to send to the webhook',
|
|
94
|
+
},
|
|
57
95
|
},
|
|
58
|
-
required: ['
|
|
96
|
+
required: ['workflowId'],
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
type: 'function',
|
|
102
|
+
function: {
|
|
103
|
+
name: 'n8n_list_executions',
|
|
104
|
+
description: 'List recent n8n executions (runs)',
|
|
105
|
+
parameters: {
|
|
106
|
+
type: 'object',
|
|
107
|
+
properties: {
|
|
108
|
+
workflowId: { type: 'string', description: 'Filter by workflow ID' },
|
|
109
|
+
limit: { type: 'number', description: 'Max results (default 10)' },
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
type: 'function',
|
|
116
|
+
function: {
|
|
117
|
+
name: 'n8n_activate_workflow',
|
|
118
|
+
description: 'Activate an n8n workflow so it runs on its trigger',
|
|
119
|
+
parameters: {
|
|
120
|
+
type: 'object',
|
|
121
|
+
properties: { id: { type: 'string' } },
|
|
122
|
+
required: ['id'],
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
type: 'function',
|
|
128
|
+
function: {
|
|
129
|
+
name: 'n8n_deactivate_workflow',
|
|
130
|
+
description: 'Deactivate an n8n workflow',
|
|
131
|
+
parameters: {
|
|
132
|
+
type: 'object',
|
|
133
|
+
properties: { id: { type: 'string' } },
|
|
134
|
+
required: ['id'],
|
|
59
135
|
},
|
|
60
136
|
},
|
|
61
137
|
},
|
|
62
138
|
];
|
|
139
|
+
// ─────────────────────────────────────────────
|
|
140
|
+
// Tool execution
|
|
141
|
+
// ─────────────────────────────────────────────
|
|
63
142
|
export async function executeTool(name, args) {
|
|
64
143
|
try {
|
|
65
144
|
switch (name) {
|
|
145
|
+
// ───── File ops ─────
|
|
66
146
|
case 'read_file':
|
|
67
147
|
return await fs.readFile(args.path, 'utf8');
|
|
68
148
|
case 'write_file':
|
|
@@ -82,6 +162,19 @@ export async function executeTool(name, args) {
|
|
|
82
162
|
});
|
|
83
163
|
return 'stdout:\n' + stdout + '\nstderr:\n' + stderr;
|
|
84
164
|
}
|
|
165
|
+
// ───── n8n ─────
|
|
166
|
+
case 'n8n_list_workflows':
|
|
167
|
+
return JSON.stringify(await n8nListWorkflows(), null, 2);
|
|
168
|
+
case 'n8n_get_workflow':
|
|
169
|
+
return JSON.stringify(await n8nGetWorkflow(args.id), null, 2);
|
|
170
|
+
case 'n8n_trigger_workflow':
|
|
171
|
+
return await n8nTriggerWorkflow(args.workflowId, args.data || {});
|
|
172
|
+
case 'n8n_list_executions':
|
|
173
|
+
return JSON.stringify(await n8nListExecutions(args.workflowId, args.limit ?? 10), null, 2);
|
|
174
|
+
case 'n8n_activate_workflow':
|
|
175
|
+
return await n8nActivateWorkflow(args.id);
|
|
176
|
+
case 'n8n_deactivate_workflow':
|
|
177
|
+
return await n8nDeactivateWorkflow(args.id);
|
|
85
178
|
default:
|
|
86
179
|
return 'Unknown tool: ' + name;
|
|
87
180
|
}
|