@mudlab/create-workflow 1.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 +78 -0
- package/bin/create.js +84 -0
- package/package.json +31 -0
- package/template/.env.example +11 -0
- package/template/CLAUDE.md +947 -0
- package/template/README.md +49 -0
- package/template/assets/.gitkeep +3 -0
- package/template/directives/.gitkeep +12 -0
- package/template/execution/push_workflow.js +396 -0
- package/template/execution/tools/.gitkeep +18 -0
- package/template/execution/tools_directives/.gitkeep +12 -0
- package/template/execution/workflows/.gitkeep +10 -0
- package/template/package.json +12 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# My Mudlab Workflows
|
|
2
|
+
|
|
3
|
+
Automated workflows powered by [Mudlab](https://mudlab.io).
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
1. Copy `.env.example` to `.env` and add your API keys:
|
|
8
|
+
```bash
|
|
9
|
+
cp .env.example .env
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
2. Edit `.env` with your Mudlab API key and any integration keys you need.
|
|
13
|
+
|
|
14
|
+
## Creating Workflows
|
|
15
|
+
|
|
16
|
+
1. **Add a tool** in `execution/tools/my_tool.js`
|
|
17
|
+
2. **Add a workflow** in `execution/workflows/my_workflow.json`
|
|
18
|
+
3. **Add a directive** in `directives/my_workflow.md`
|
|
19
|
+
|
|
20
|
+
See `CLAUDE.md` for detailed documentation on the 3-layer architecture.
|
|
21
|
+
|
|
22
|
+
## Push to Mudlab
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Single workflow
|
|
26
|
+
node execution/push_workflow.js execution/workflows/my_workflow.json
|
|
27
|
+
|
|
28
|
+
# All workflows
|
|
29
|
+
npm run push:all
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Directory Structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
├── CLAUDE.md # AI orchestrator instructions
|
|
36
|
+
├── directives/ # Workflow documentation (SOPs)
|
|
37
|
+
├── execution/
|
|
38
|
+
│ ├── push_workflow.js # Push script
|
|
39
|
+
│ ├── tools/ # Node.js tool functions
|
|
40
|
+
│ ├── tools_directives/ # AI usage instructions
|
|
41
|
+
│ └── workflows/ # Workflow packages (JSON)
|
|
42
|
+
├── assets/ # Static assets
|
|
43
|
+
└── .tmp/ # Temp files (gitignored)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Learn More
|
|
47
|
+
|
|
48
|
+
- [Mudlab Documentation](https://mudlab.io/docs)
|
|
49
|
+
- See `CLAUDE.md` for the complete 3-layer architecture guide
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Workflow Directives
|
|
2
|
+
|
|
3
|
+
Place your workflow directive markdown files here.
|
|
4
|
+
|
|
5
|
+
Each workflow needs a directive file that documents:
|
|
6
|
+
- What the workflow does
|
|
7
|
+
- Workflow scope (what it IS and IS NOT for)
|
|
8
|
+
- Trigger format (webhook URL and payload)
|
|
9
|
+
- Input/output specifications
|
|
10
|
+
- Example usage
|
|
11
|
+
|
|
12
|
+
See CLAUDE.md for the full directive structure template.
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Push Workflow to Mudlab
|
|
5
|
+
*
|
|
6
|
+
* Takes one or more workflow packages (tools + workflow definition) and pushes
|
|
7
|
+
* everything to the Mudlab API. Automatically handles create vs update
|
|
8
|
+
* based on existing IDs, and writes returned IDs back to the JSON files.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* Single: node execution/push_workflow.js execution/workflows/my_workflow.json
|
|
12
|
+
* Bulk: node execution/push_workflow.js execution/workflows/*.json
|
|
13
|
+
*
|
|
14
|
+
* When multiple files are provided, they are pushed in a single bulk API call
|
|
15
|
+
* for better performance.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
const path = require('path');
|
|
20
|
+
|
|
21
|
+
// Load environment variables from .env
|
|
22
|
+
function loadEnv() {
|
|
23
|
+
const envPath = path.join(process.cwd(), '.env');
|
|
24
|
+
if (fs.existsSync(envPath)) {
|
|
25
|
+
const envContent = fs.readFileSync(envPath, 'utf-8');
|
|
26
|
+
for (const line of envContent.split('\n')) {
|
|
27
|
+
const trimmed = line.trim();
|
|
28
|
+
if (trimmed && !trimmed.startsWith('#')) {
|
|
29
|
+
const [key, ...valueParts] = trimmed.split('=');
|
|
30
|
+
const value = valueParts.join('=').replace(/^["']|["']$/g, '');
|
|
31
|
+
process.env[key] = value;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
loadEnv();
|
|
38
|
+
|
|
39
|
+
const MUDLAB_API_URL = process.env.MUDLAB_API_URL || 'http://localhost:3000';
|
|
40
|
+
const MUDLAB_API_KEY = process.env.MUDLAB_API_KEY;
|
|
41
|
+
|
|
42
|
+
function getHeaders() {
|
|
43
|
+
return {
|
|
44
|
+
'Content-Type': 'application/json',
|
|
45
|
+
...(MUDLAB_API_KEY && { 'X-API-Key': MUDLAB_API_KEY })
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Write IDs back to the workflow JSON file
|
|
52
|
+
*/
|
|
53
|
+
function updateWorkflowFile(workflowPath, workflowId, toolIds) {
|
|
54
|
+
const workflowPackage = JSON.parse(fs.readFileSync(workflowPath, 'utf-8'));
|
|
55
|
+
|
|
56
|
+
// Update workflow ID
|
|
57
|
+
workflowPackage.id = workflowId;
|
|
58
|
+
|
|
59
|
+
// Update tool IDs
|
|
60
|
+
for (const tool of workflowPackage.tools) {
|
|
61
|
+
if (toolIds[tool.tool_id]) {
|
|
62
|
+
tool.id = toolIds[tool.tool_id];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
fs.writeFileSync(workflowPath, JSON.stringify(workflowPackage, null, 2) + '\n');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function savePushLog(workflowResult, toolResults) {
|
|
70
|
+
const tmpDir = path.join(process.cwd(), '.tmp');
|
|
71
|
+
if (!fs.existsSync(tmpDir)) {
|
|
72
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const logPath = path.join(tmpDir, 'pushed_workflows.json');
|
|
76
|
+
let log = [];
|
|
77
|
+
if (fs.existsSync(logPath)) {
|
|
78
|
+
log = JSON.parse(fs.readFileSync(logPath, 'utf-8'));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
log.push({
|
|
82
|
+
pushed_at: new Date().toISOString(),
|
|
83
|
+
workflow: workflowResult,
|
|
84
|
+
tools: toolResults
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
fs.writeFileSync(logPath, JSON.stringify(log, null, 2));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Prepare a single workflow payload from package and directive
|
|
92
|
+
*/
|
|
93
|
+
function prepareWorkflowPayload(workflowPackage, directivePath) {
|
|
94
|
+
// Read directive
|
|
95
|
+
const directive = fs.readFileSync(directivePath, 'utf-8');
|
|
96
|
+
|
|
97
|
+
// Prepare tools with code and directives loaded from files
|
|
98
|
+
const tools = workflowPackage.tools.map(tool => {
|
|
99
|
+
let code = tool.code;
|
|
100
|
+
if (tool.code_file) {
|
|
101
|
+
const codePath = path.join(process.cwd(), tool.code_file);
|
|
102
|
+
if (!fs.existsSync(codePath)) {
|
|
103
|
+
throw new Error(`Tool code file not found: ${tool.code_file}`);
|
|
104
|
+
}
|
|
105
|
+
code = fs.readFileSync(codePath, 'utf-8');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Read tool directive from file if specified
|
|
109
|
+
let toolDirective = tool.directive || null;
|
|
110
|
+
if (tool.directive_file) {
|
|
111
|
+
const toolDirectivePath = path.join(process.cwd(), tool.directive_file);
|
|
112
|
+
if (fs.existsSync(toolDirectivePath)) {
|
|
113
|
+
toolDirective = fs.readFileSync(toolDirectivePath, 'utf-8');
|
|
114
|
+
console.log(` 📝 Loaded directive for ${tool.tool_id} (${toolDirective.length} chars)`);
|
|
115
|
+
} else {
|
|
116
|
+
console.log(` ⚠️ Directive file not found: ${tool.directive_file}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
id: tool.id || null,
|
|
122
|
+
tool_id: tool.tool_id,
|
|
123
|
+
name: tool.name,
|
|
124
|
+
description: tool.description,
|
|
125
|
+
directive: toolDirective,
|
|
126
|
+
running_message: tool.running_message,
|
|
127
|
+
code: code,
|
|
128
|
+
inputs: tool.inputs,
|
|
129
|
+
outputs: tool.outputs
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Debug: show tools with directives
|
|
134
|
+
for (const tool of tools) {
|
|
135
|
+
if (tool.directive) {
|
|
136
|
+
console.log(` 📤 Sending directive for ${tool.tool_id}: "${tool.directive.substring(0, 50)}..."`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
id: workflowPackage.id || null,
|
|
142
|
+
name: workflowPackage.name,
|
|
143
|
+
description: workflowPackage.description,
|
|
144
|
+
directive: directive,
|
|
145
|
+
running_message: workflowPackage.running_message,
|
|
146
|
+
success_message: workflowPackage.success_message,
|
|
147
|
+
client_id: workflowPackage.client_id,
|
|
148
|
+
steps: workflowPackage.steps,
|
|
149
|
+
tools: tools
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Push workflow(s) to the API
|
|
155
|
+
* @param {Array|Object} payloads - Single payload or array of payloads
|
|
156
|
+
* @returns {Object} API response (normalized)
|
|
157
|
+
*
|
|
158
|
+
* Bulk response format:
|
|
159
|
+
* {
|
|
160
|
+
* success: boolean, // true only if ALL succeeded
|
|
161
|
+
* results: [...], // all results (success and failure)
|
|
162
|
+
* summary: { total, succeeded, failed },
|
|
163
|
+
* workflows: [...], // convenience: only successes
|
|
164
|
+
* errors: [{ workflow_name, error, details }, ...] // convenience: only failures
|
|
165
|
+
* }
|
|
166
|
+
*/
|
|
167
|
+
async function pushToApi(payloads) {
|
|
168
|
+
const isBulk = Array.isArray(payloads) && payloads.length > 1;
|
|
169
|
+
const body = isBulk ? payloads : (Array.isArray(payloads) ? payloads[0] : payloads);
|
|
170
|
+
|
|
171
|
+
const response = await fetch(`${MUDLAB_API_URL}/api/push-workflow`, {
|
|
172
|
+
method: 'POST',
|
|
173
|
+
headers: getHeaders(),
|
|
174
|
+
body: JSON.stringify(body)
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// Handle different status codes
|
|
178
|
+
// 200 = all succeeded, 207 = partial success, 400/500 = error
|
|
179
|
+
if (!response.ok && response.status !== 207) {
|
|
180
|
+
const error = await response.text();
|
|
181
|
+
throw new Error(`Push failed (${response.status}): ${error}`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const result = await response.json();
|
|
185
|
+
|
|
186
|
+
// Normalize response format
|
|
187
|
+
// Single: { success, workflow, tools }
|
|
188
|
+
// Bulk: { success, results, summary, workflows, errors }
|
|
189
|
+
if (isBulk) {
|
|
190
|
+
return { isBulk: true, ...result };
|
|
191
|
+
} else {
|
|
192
|
+
// Normalize single response to match bulk format
|
|
193
|
+
return {
|
|
194
|
+
isBulk: false,
|
|
195
|
+
results: [result],
|
|
196
|
+
summary: { total: 1, succeeded: result.success ? 1 : 0, failed: result.success ? 0 : 1 },
|
|
197
|
+
workflows: result.success ? [result] : [],
|
|
198
|
+
errors: result.success ? [] : [{ workflow_name: result.workflow?.name || 'Unknown', error: result.error, details: result.details }]
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Process a single workflow result and update its JSON file
|
|
205
|
+
*/
|
|
206
|
+
function processWorkflowResult(result, workflowPath, workflowPackage) {
|
|
207
|
+
const workflowData = result.workflow;
|
|
208
|
+
// Tools are now nested inside workflow object
|
|
209
|
+
const toolResults = workflowData.tools || [];
|
|
210
|
+
const toolIdMap = {};
|
|
211
|
+
|
|
212
|
+
// Log tool results
|
|
213
|
+
console.log('🔧 Tools:\n');
|
|
214
|
+
for (const tool of toolResults) {
|
|
215
|
+
toolIdMap[tool.tool_id] = tool.id;
|
|
216
|
+
const action = tool.created ? 'Created' : 'Updated';
|
|
217
|
+
const toolDef = workflowPackage.tools.find(t => t.tool_id === tool.tool_id);
|
|
218
|
+
const toolName = tool.name || toolDef?.name || tool.tool_id;
|
|
219
|
+
const hasDirective = toolDef?.directive_file ? ' [has directive]' : '';
|
|
220
|
+
console.log(` ✓ ${toolName} (${action})${hasDirective}`);
|
|
221
|
+
console.log(` ID: ${tool.id}`);
|
|
222
|
+
console.log(` Version: ${tool.version}\n`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Log workflow result
|
|
226
|
+
const workflowAction = workflowData.created ? 'Created' : 'Updated';
|
|
227
|
+
console.log(`📋 Workflow: ${workflowPackage.name} (${workflowAction})`);
|
|
228
|
+
console.log(` ID: ${workflowData.id}`);
|
|
229
|
+
console.log(` Status: ${workflowData.status}`);
|
|
230
|
+
console.log(` Steps: ${workflowData.steps_count || workflowPackage.steps.length}\n`);
|
|
231
|
+
|
|
232
|
+
// Write IDs back to the JSON file
|
|
233
|
+
console.log('💾 Updating workflow file with IDs...');
|
|
234
|
+
updateWorkflowFile(workflowPath, workflowData.id, toolIdMap);
|
|
235
|
+
console.log(` ✓ ${workflowPath}\n`);
|
|
236
|
+
|
|
237
|
+
// Save push log
|
|
238
|
+
savePushLog(workflowData, toolResults);
|
|
239
|
+
|
|
240
|
+
return { workflowData, toolIdMap };
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async function main() {
|
|
244
|
+
const args = process.argv.slice(2);
|
|
245
|
+
|
|
246
|
+
if (args.length === 0) {
|
|
247
|
+
console.error('Usage: node push_workflow.js <workflow-package.json> [workflow2.json ...]');
|
|
248
|
+
console.error(' node push_workflow.js execution/workflows/*.json');
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Validate all files exist first
|
|
253
|
+
const workflowPaths = [];
|
|
254
|
+
for (const arg of args) {
|
|
255
|
+
if (!fs.existsSync(arg)) {
|
|
256
|
+
console.error(`Workflow package not found: ${arg}`);
|
|
257
|
+
process.exit(1);
|
|
258
|
+
}
|
|
259
|
+
workflowPaths.push(arg);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!MUDLAB_API_KEY) {
|
|
263
|
+
console.warn('Warning: MUDLAB_API_KEY not set. API calls may fail.');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const isBulk = workflowPaths.length > 1;
|
|
267
|
+
|
|
268
|
+
if (isBulk) {
|
|
269
|
+
console.log(`\n📦 Pushing ${workflowPaths.length} workflow packages (bulk mode)`);
|
|
270
|
+
} else {
|
|
271
|
+
console.log(`\n📦 Pushing workflow package: ${workflowPaths[0]}`);
|
|
272
|
+
}
|
|
273
|
+
console.log(` API: ${MUDLAB_API_URL}\n`);
|
|
274
|
+
|
|
275
|
+
// Prepare all payloads
|
|
276
|
+
const payloads = [];
|
|
277
|
+
const workflowPackages = [];
|
|
278
|
+
|
|
279
|
+
for (const workflowPath of workflowPaths) {
|
|
280
|
+
console.log(`📄 Preparing: ${workflowPath}`);
|
|
281
|
+
const workflowPackage = JSON.parse(fs.readFileSync(workflowPath, 'utf-8'));
|
|
282
|
+
workflowPackages.push(workflowPackage);
|
|
283
|
+
|
|
284
|
+
// Validate directive file exists
|
|
285
|
+
if (!workflowPackage.directive_file) {
|
|
286
|
+
console.error(` Missing required field: directive_file in ${workflowPath}`);
|
|
287
|
+
process.exit(1);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const directivePath = path.join(process.cwd(), workflowPackage.directive_file);
|
|
291
|
+
if (!fs.existsSync(directivePath)) {
|
|
292
|
+
console.error(` Directive file not found: ${workflowPackage.directive_file}`);
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
console.log(` Directive: ${workflowPackage.directive_file}`);
|
|
297
|
+
const payload = prepareWorkflowPayload(workflowPackage, directivePath);
|
|
298
|
+
payloads.push(payload);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
console.log('\n🔗 Pushing workflow(s) and tools...\n');
|
|
302
|
+
|
|
303
|
+
try {
|
|
304
|
+
const response = await pushToApi(payloads);
|
|
305
|
+
const { results, summary, errors } = response;
|
|
306
|
+
|
|
307
|
+
// Process each result
|
|
308
|
+
const allToolIds = {};
|
|
309
|
+
const allWorkflowIds = [];
|
|
310
|
+
|
|
311
|
+
for (let i = 0; i < results.length; i++) {
|
|
312
|
+
const result = results[i];
|
|
313
|
+
const workflowPath = workflowPaths[i];
|
|
314
|
+
const workflowPackage = workflowPackages[i];
|
|
315
|
+
|
|
316
|
+
if (isBulk) {
|
|
317
|
+
console.log('─'.repeat(50));
|
|
318
|
+
console.log(`\n[${i + 1}/${results.length}] ${workflowPackage.name}\n`);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (!result.success) {
|
|
322
|
+
console.error(` ✗ Failed: ${result.error || 'Unknown error'}`);
|
|
323
|
+
if (result.details) {
|
|
324
|
+
console.error(` Details: ${result.details}`);
|
|
325
|
+
}
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const { workflowData, toolIdMap } = processWorkflowResult(result, workflowPath, workflowPackage);
|
|
330
|
+
Object.assign(allToolIds, toolIdMap);
|
|
331
|
+
allWorkflowIds.push({ name: workflowPackage.name, id: workflowData.id });
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Summary
|
|
335
|
+
console.log('─'.repeat(50));
|
|
336
|
+
|
|
337
|
+
if (isBulk) {
|
|
338
|
+
console.log(`\n📊 Bulk Push Summary:`);
|
|
339
|
+
console.log(` Total: ${summary.total}`);
|
|
340
|
+
console.log(` Succeeded: ${summary.succeeded}`);
|
|
341
|
+
console.log(` Failed: ${summary.failed}`);
|
|
342
|
+
|
|
343
|
+
if (summary.failed > 0 && errors && errors.length > 0) {
|
|
344
|
+
console.log(`\n❌ Failed Workflows:\n`);
|
|
345
|
+
for (const err of errors) {
|
|
346
|
+
console.log(` ${err.workflow_name}:`);
|
|
347
|
+
console.log(` Error: ${err.error}`);
|
|
348
|
+
if (err.details) {
|
|
349
|
+
console.log(` Details: ${err.details}`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
console.log('');
|
|
353
|
+
} else if (summary.failed === 0) {
|
|
354
|
+
console.log(`\n✅ All workflows pushed successfully!\n`);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (allWorkflowIds.length > 0) {
|
|
358
|
+
console.log('Workflow UUIDs:');
|
|
359
|
+
for (const { name, id } of allWorkflowIds) {
|
|
360
|
+
console.log(` ${name}: ${id}`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
} else {
|
|
364
|
+
if (summary.failed > 0) {
|
|
365
|
+
console.log('\n❌ Workflow push failed.\n');
|
|
366
|
+
} else {
|
|
367
|
+
console.log('\n✅ Workflow pushed successfully!\n');
|
|
368
|
+
console.log('Tool UUIDs:');
|
|
369
|
+
for (const [toolId, uuid] of Object.entries(allToolIds)) {
|
|
370
|
+
console.log(` ${toolId}: ${uuid}`);
|
|
371
|
+
}
|
|
372
|
+
const workflowId = allWorkflowIds[0]?.id;
|
|
373
|
+
console.log(`\nWorkflow UUID: ${workflowId}`);
|
|
374
|
+
console.log(`\nTo run this workflow:`);
|
|
375
|
+
console.log(` POST ${MUDLAB_API_URL}/api/run`);
|
|
376
|
+
console.log(` Body: { "workflow_id": "${workflowId}", "input": { ... } }`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
console.log(`\nPush log saved to: .tmp/pushed_workflows.json\n`);
|
|
381
|
+
|
|
382
|
+
// Exit with error if any failed
|
|
383
|
+
if (summary.failed > 0) {
|
|
384
|
+
process.exit(1);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
} catch (error) {
|
|
388
|
+
console.error(` ✗ Push failed: ${error.message}`);
|
|
389
|
+
process.exit(1);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
main().catch(error => {
|
|
394
|
+
console.error('Fatal error:', error.message);
|
|
395
|
+
process.exit(1);
|
|
396
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Tools
|
|
2
|
+
|
|
3
|
+
Place your Node.js tool files here.
|
|
4
|
+
|
|
5
|
+
Each tool is a module that exports a `run` function:
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
async function run({ input, env, context }) {
|
|
9
|
+
// Your logic here
|
|
10
|
+
return {
|
|
11
|
+
action: "completed",
|
|
12
|
+
message: "Human-readable success message",
|
|
13
|
+
// ... other output fields
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = { run };
|
|
18
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Tool Directives
|
|
2
|
+
|
|
3
|
+
Place your tool directive markdown files here.
|
|
4
|
+
|
|
5
|
+
Each tool directive provides AI usage instructions:
|
|
6
|
+
- Input constraints and validation rules
|
|
7
|
+
- Output details
|
|
8
|
+
- Formatting requirements
|
|
9
|
+
- Best practices
|
|
10
|
+
- Common mistakes to avoid
|
|
11
|
+
|
|
12
|
+
These are injected into the AI's context when the tool is used.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Workflow Packages
|
|
2
|
+
|
|
3
|
+
Place your workflow JSON package files here.
|
|
4
|
+
|
|
5
|
+
Each workflow package defines:
|
|
6
|
+
- Workflow metadata (name, description, messages)
|
|
7
|
+
- Tools used by the workflow
|
|
8
|
+
- Steps that execute the tools in order
|
|
9
|
+
|
|
10
|
+
Run `node execution/push_workflow.js execution/workflows/your_workflow.json` to push.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "my-mudlab-workflows",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Mudlab workflow automation project",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"push": "node execution/push_workflow.js",
|
|
7
|
+
"push:all": "node execution/push_workflow.js execution/workflows/*.json"
|
|
8
|
+
},
|
|
9
|
+
"keywords": ["mudlab", "workflow", "automation"],
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"dependencies": {}
|
|
12
|
+
}
|