@synergenius/flow-weaver 0.15.2 → 0.16.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/dist/cli/commands/compile.js +158 -149
- package/dist/cli/commands/dev.js +14 -11
- package/dist/cli/commands/diff.js +6 -1
- package/dist/cli/commands/doctor.js +16 -25
- package/dist/cli/commands/export.js +2 -0
- package/dist/cli/commands/grammar.js +3 -1
- package/dist/cli/commands/init.js +18 -28
- package/dist/cli/commands/market.js +14 -6
- package/dist/cli/commands/migrate.js +3 -2
- package/dist/cli/commands/openapi.js +4 -1
- package/dist/cli/commands/run.js +44 -16
- package/dist/cli/commands/status.js +5 -3
- package/dist/cli/commands/strip.js +3 -1
- package/dist/cli/commands/templates.js +1 -1
- package/dist/cli/commands/validate.js +27 -24
- package/dist/cli/env-setup.d.ts +5 -0
- package/dist/cli/env-setup.js +12 -0
- package/dist/cli/flow-weaver.mjs +762 -794
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +254 -508
- package/dist/cli/utils/logger.d.ts +14 -0
- package/dist/cli/utils/logger.js +96 -16
- package/dist/generated-version.d.ts +1 -1
- package/dist/generated-version.js +1 -1
- package/dist/mcp/workflow-executor.js +7 -1
- package/package.json +2 -1
package/dist/cli/index.js
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* Note: Shebang is added by build script (scripts/build-cli.ts) to the CJS bundle.
|
|
6
6
|
* Do not add #!/usr/bin/env node here - it will cause duplicate shebangs.
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
// Must be imported first: sets up env vars before picocolors reads them
|
|
9
|
+
import './env-setup.js';
|
|
10
|
+
import { Command, Option } from 'commander';
|
|
9
11
|
import { compileCommand } from './commands/compile.js';
|
|
10
12
|
import { createWorkflowCommand, createNodeCommand } from './commands/create.js';
|
|
11
13
|
import { describeCommand } from './commands/describe.js';
|
|
@@ -45,9 +47,24 @@ const program = new Command();
|
|
|
45
47
|
program
|
|
46
48
|
.name('flow-weaver')
|
|
47
49
|
.description('Flow Weaver Annotations - Compile and validate workflow files')
|
|
48
|
-
.
|
|
50
|
+
.option('-v, --version', 'Output the current version')
|
|
51
|
+
.option('--no-color', 'Disable colors')
|
|
52
|
+
.option('--color', 'Force colors')
|
|
53
|
+
.on('option:version', () => {
|
|
54
|
+
logger.banner(version);
|
|
55
|
+
process.exit(0);
|
|
56
|
+
})
|
|
57
|
+
.configureHelp({
|
|
58
|
+
sortSubcommands: false,
|
|
59
|
+
subcommandTerm: (cmd) => cmd.name() + (cmd.usage() ? ' ' + cmd.usage() : ''),
|
|
60
|
+
});
|
|
61
|
+
// Track whether our action handler already printed the error,
|
|
62
|
+
// so Commander's own error handling doesn't duplicate it.
|
|
63
|
+
let actionErrorHandled = false;
|
|
49
64
|
program.configureOutput({
|
|
50
65
|
writeErr: (str) => {
|
|
66
|
+
if (actionErrorHandled)
|
|
67
|
+
return;
|
|
51
68
|
const trimmed = str.replace(/^error:\s*/i, '').trimEnd();
|
|
52
69
|
if (trimmed) {
|
|
53
70
|
logger.error(trimmed);
|
|
@@ -55,6 +72,22 @@ program.configureOutput({
|
|
|
55
72
|
},
|
|
56
73
|
writeOut: (str) => process.stdout.write(str),
|
|
57
74
|
});
|
|
75
|
+
/**
|
|
76
|
+
* Wraps a command action with centralized error handling.
|
|
77
|
+
* Catches errors, prints them once, sets the flag to prevent Commander duplication.
|
|
78
|
+
*/
|
|
79
|
+
function wrapAction(fn) {
|
|
80
|
+
return async (...args) => {
|
|
81
|
+
try {
|
|
82
|
+
await fn(...args);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
actionErrorHandled = true;
|
|
86
|
+
logger.error(getErrorMessage(error));
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
58
91
|
// Compile command
|
|
59
92
|
program
|
|
60
93
|
.command('compile <input>')
|
|
@@ -64,8 +97,8 @@ program
|
|
|
64
97
|
.option('-s, --source-map', 'Generate source maps', false)
|
|
65
98
|
.option('--verbose', 'Verbose output', false)
|
|
66
99
|
.option('--dry-run', 'Preview compilation without writing files', false)
|
|
67
|
-
.option('-w, --workflow
|
|
68
|
-
.
|
|
100
|
+
.option('-w, --workflow <name>', 'Specific workflow name to compile')
|
|
101
|
+
.addOption(new Option('-f, --format <format>', 'Module format').choices(['esm', 'cjs', 'auto']).default('auto'))
|
|
69
102
|
.option('--strict', 'Treat type coercion warnings as errors', false)
|
|
70
103
|
.option('--inline-runtime', 'Force inline runtime even when @synergenius/flow-weaver package is installed', false)
|
|
71
104
|
.option('--clean', 'Omit redundant @param/@returns annotations from compiled output', false)
|
|
@@ -76,15 +109,11 @@ program
|
|
|
76
109
|
.option('--typed-events', 'Generate Zod event schemas from workflow @param annotations')
|
|
77
110
|
.option('--retries <n>', 'Number of retries per function (Inngest target only)', parseInt)
|
|
78
111
|
.option('--timeout <duration>', 'Function timeout (e.g. "30m", "1h")')
|
|
79
|
-
.action(async (input, options) => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
});
|
|
112
|
+
.action(wrapAction(async (input, options) => {
|
|
113
|
+
if (options.workflow)
|
|
114
|
+
options.workflowName = options.workflow;
|
|
115
|
+
await compileCommand(input, options);
|
|
116
|
+
}));
|
|
88
117
|
// Strip command
|
|
89
118
|
program
|
|
90
119
|
.command('strip <input>')
|
|
@@ -92,73 +121,55 @@ program
|
|
|
92
121
|
.option('-o, --output <path>', 'Output directory (default: in-place)')
|
|
93
122
|
.option('--dry-run', 'Preview without writing', false)
|
|
94
123
|
.option('--verbose', 'Verbose output', false)
|
|
95
|
-
.action(async (input, options) => {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
101
|
-
process.exit(1);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
124
|
+
.action(wrapAction(async (input, options) => {
|
|
125
|
+
await stripCommand(input, options);
|
|
126
|
+
}));
|
|
104
127
|
// Describe command
|
|
105
128
|
program
|
|
106
129
|
.command('describe <input>')
|
|
107
130
|
.description('Output workflow structure in LLM-friendly formats (JSON, text, mermaid)')
|
|
108
|
-
.
|
|
131
|
+
.addOption(new Option('-f, --format <format>', 'Output format').choices(['json', 'text', 'mermaid', 'paths', 'ascii', 'ascii-compact']).default('json'))
|
|
109
132
|
.option('-n, --node <id>', 'Focus on a specific node')
|
|
110
133
|
.option('--compile', 'Also update runtime markers in the source file')
|
|
111
|
-
.option('-w, --workflow
|
|
112
|
-
.action(async (input, options) => {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
118
|
-
process.exit(1);
|
|
119
|
-
}
|
|
120
|
-
});
|
|
134
|
+
.option('-w, --workflow <name>', 'Specific workflow name to describe')
|
|
135
|
+
.action(wrapAction(async (input, options) => {
|
|
136
|
+
if (options.workflow)
|
|
137
|
+
options.workflowName = options.workflow;
|
|
138
|
+
await describeCommand(input, options);
|
|
139
|
+
}));
|
|
121
140
|
// Diagram command
|
|
122
141
|
program
|
|
123
142
|
.command('diagram <input>')
|
|
124
143
|
.description('Generate SVG or interactive HTML diagram of a workflow')
|
|
125
|
-
.option('-t, --theme <theme>', 'Color theme: dark
|
|
126
|
-
.option('
|
|
144
|
+
.option('-t, --theme <theme>', 'Color theme: dark, light', 'dark')
|
|
145
|
+
.option('--width <pixels>', 'SVG width in pixels')
|
|
127
146
|
.option('-p, --padding <pixels>', 'Canvas padding in pixels')
|
|
128
147
|
.option('--no-port-labels', 'Hide data type labels on ports')
|
|
129
|
-
.option('--workflow
|
|
130
|
-
.
|
|
148
|
+
.option('-w, --workflow <name>', 'Specific workflow to render')
|
|
149
|
+
.addOption(new Option('-f, --format <format>', 'Output format').choices(['svg', 'html', 'ascii', 'ascii-compact', 'text']).default('svg'))
|
|
131
150
|
.option('-o, --output <file>', 'Write output to file instead of stdout')
|
|
132
|
-
.action(async (input, options) => {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
});
|
|
151
|
+
.action(wrapAction(async (input, options) => {
|
|
152
|
+
if (options.width)
|
|
153
|
+
options.width = Number(options.width);
|
|
154
|
+
if (options.padding)
|
|
155
|
+
options.padding = Number(options.padding);
|
|
156
|
+
options.showPortLabels = options.portLabels;
|
|
157
|
+
if (options.workflow)
|
|
158
|
+
options.workflowName = options.workflow;
|
|
159
|
+
await diagramCommand(input, options);
|
|
160
|
+
}));
|
|
146
161
|
// Diff command
|
|
147
162
|
program
|
|
148
163
|
.command('diff <file1> <file2>')
|
|
149
164
|
.description('Compare two workflow files semantically')
|
|
150
|
-
.
|
|
151
|
-
.option('-w, --workflow
|
|
165
|
+
.addOption(new Option('-f, --format <format>', 'Output format').choices(['text', 'json', 'compact']).default('text'))
|
|
166
|
+
.option('-w, --workflow <name>', 'Specific workflow name to compare')
|
|
152
167
|
.option('--exit-zero', 'Exit 0 even when differences are found', false)
|
|
153
|
-
.action(async (file1, file2, options) => {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
159
|
-
process.exit(1);
|
|
160
|
-
}
|
|
161
|
-
});
|
|
168
|
+
.action(wrapAction(async (file1, file2, options) => {
|
|
169
|
+
if (options.workflow)
|
|
170
|
+
options.workflowName = options.workflow;
|
|
171
|
+
await diffCommand(file1, file2, options);
|
|
172
|
+
}));
|
|
162
173
|
// Validate command
|
|
163
174
|
program
|
|
164
175
|
.command('validate <input>')
|
|
@@ -166,37 +177,27 @@ program
|
|
|
166
177
|
.option('--verbose', 'Verbose output', false)
|
|
167
178
|
.option('-q, --quiet', 'Suppress warnings', false)
|
|
168
179
|
.option('--json', 'Output results as JSON', false)
|
|
169
|
-
.option('-w, --workflow
|
|
180
|
+
.option('-w, --workflow <name>', 'Specific workflow name to validate')
|
|
170
181
|
.option('--strict', 'Treat type coercion warnings as errors', false)
|
|
171
|
-
.action(async (input, options) => {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
177
|
-
process.exit(1);
|
|
178
|
-
}
|
|
179
|
-
});
|
|
182
|
+
.action(wrapAction(async (input, options) => {
|
|
183
|
+
if (options.workflow)
|
|
184
|
+
options.workflowName = options.workflow;
|
|
185
|
+
await validateCommand(input, options);
|
|
186
|
+
}));
|
|
180
187
|
// Doctor command
|
|
181
188
|
program
|
|
182
189
|
.command('doctor')
|
|
183
190
|
.description('Check project environment and configuration for flow-weaver compatibility')
|
|
184
191
|
.option('--json', 'Output results as JSON', false)
|
|
185
|
-
.action(async (options) => {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
catch (error) {
|
|
190
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
191
|
-
process.exit(1);
|
|
192
|
-
}
|
|
193
|
-
});
|
|
192
|
+
.action(wrapAction(async (options) => {
|
|
193
|
+
await doctorCommand(options);
|
|
194
|
+
}));
|
|
194
195
|
// Init command
|
|
195
196
|
program
|
|
196
197
|
.command('init [directory]')
|
|
197
198
|
.description('Create a new flow-weaver project')
|
|
198
199
|
.option('-n, --name <name>', 'Project name (defaults to directory name)')
|
|
199
|
-
.option('-t, --template <template>', 'Workflow template (default:
|
|
200
|
+
.option('-t, --template <template>', 'Workflow template (default: sequential)')
|
|
200
201
|
.option('-f, --format <format>', 'Module format: esm or cjs (default: esm)')
|
|
201
202
|
.option('-y, --yes', 'Skip prompts and use defaults', false)
|
|
202
203
|
.option('--install', 'Run npm install after scaffolding')
|
|
@@ -205,15 +206,9 @@ program
|
|
|
205
206
|
.option('--no-git', 'Skip git init')
|
|
206
207
|
.option('--force', 'Overwrite existing files', false)
|
|
207
208
|
.option('--json', 'Output results as JSON', false)
|
|
208
|
-
.action(async (directory, options) => {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
catch (error) {
|
|
213
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
214
|
-
process.exit(1);
|
|
215
|
-
}
|
|
216
|
-
});
|
|
209
|
+
.action(wrapAction(async (directory, options) => {
|
|
210
|
+
await initCommand(directory, options);
|
|
211
|
+
}));
|
|
217
212
|
// Watch command
|
|
218
213
|
program
|
|
219
214
|
.command('watch <input>')
|
|
@@ -222,17 +217,13 @@ program
|
|
|
222
217
|
.option('-p, --production', 'Generate production code (no debug events)', false)
|
|
223
218
|
.option('-s, --source-map', 'Generate source maps', false)
|
|
224
219
|
.option('--verbose', 'Verbose output', false)
|
|
225
|
-
.option('-w, --workflow
|
|
226
|
-
.option('-f, --format <format>', 'Module format: esm, cjs, or auto
|
|
227
|
-
.action(async (input, options) => {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
233
|
-
process.exit(1);
|
|
234
|
-
}
|
|
235
|
-
});
|
|
220
|
+
.option('-w, --workflow <name>', 'Specific workflow name to compile')
|
|
221
|
+
.option('-f, --format <format>', 'Module format: esm, cjs, or auto', 'auto')
|
|
222
|
+
.action(wrapAction(async (input, options) => {
|
|
223
|
+
if (options.workflow)
|
|
224
|
+
options.workflowName = options.workflow;
|
|
225
|
+
await watchCommand(input, options);
|
|
226
|
+
}));
|
|
236
227
|
// Dev command (watch + compile + run)
|
|
237
228
|
program
|
|
238
229
|
.command('dev <input>')
|
|
@@ -241,36 +232,24 @@ program
|
|
|
241
232
|
.option('--params-file <path>', 'Path to JSON file with input parameters')
|
|
242
233
|
.option('-w, --workflow <name>', 'Specific workflow name to run')
|
|
243
234
|
.option('-p, --production', 'Run in production mode (no trace events)', false)
|
|
244
|
-
.option('-f, --format <format>', 'Module format: esm, cjs, or auto
|
|
235
|
+
.option('-f, --format <format>', 'Module format: esm, cjs, or auto', 'auto')
|
|
245
236
|
.option('--clean', 'Omit redundant @param/@returns annotations', false)
|
|
246
237
|
.option('--once', 'Run once then exit', false)
|
|
247
238
|
.option('--json', 'Output result as JSON', false)
|
|
248
239
|
.option('--target <target>', 'Compilation target: typescript or inngest (default: typescript)')
|
|
249
240
|
.option('--framework <framework>', 'Framework for serve handler (inngest target only)', 'express')
|
|
250
241
|
.option('--port <port>', 'Port for dev server (inngest target only)', (v) => parseInt(v, 10), 3000)
|
|
251
|
-
.action(async (input, options) => {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
catch (error) {
|
|
256
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
257
|
-
process.exit(1);
|
|
258
|
-
}
|
|
259
|
-
});
|
|
242
|
+
.action(wrapAction(async (input, options) => {
|
|
243
|
+
await devCommand(input, options);
|
|
244
|
+
}));
|
|
260
245
|
// Listen command
|
|
261
246
|
program
|
|
262
247
|
.command('listen')
|
|
263
248
|
.description('Connect to Studio and stream integration events as JSON lines')
|
|
264
249
|
.option('-s, --server <url>', 'Studio URL', DEFAULT_SERVER_URL)
|
|
265
|
-
.action(async (options) => {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
catch (error) {
|
|
270
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
271
|
-
process.exit(1);
|
|
272
|
-
}
|
|
273
|
-
});
|
|
250
|
+
.action(wrapAction(async (options) => {
|
|
251
|
+
await listenCommand(options);
|
|
252
|
+
}));
|
|
274
253
|
// Tunnel command
|
|
275
254
|
program
|
|
276
255
|
.command('tunnel')
|
|
@@ -278,30 +257,18 @@ program
|
|
|
278
257
|
.requiredOption('-k, --key <apiKey>', 'API key for cloud authentication (fw_xxxx)')
|
|
279
258
|
.option('-c, --cloud <url>', 'Cloud server URL', 'https://flowweaver.dev')
|
|
280
259
|
.option('-d, --dir <path>', 'Project directory', process.cwd())
|
|
281
|
-
.action(async (options) => {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
catch (error) {
|
|
286
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
287
|
-
process.exit(1);
|
|
288
|
-
}
|
|
289
|
-
});
|
|
260
|
+
.action(wrapAction(async (options) => {
|
|
261
|
+
await tunnelCommand(options);
|
|
262
|
+
}));
|
|
290
263
|
// MCP server command
|
|
291
264
|
program
|
|
292
265
|
.command('mcp-server')
|
|
293
266
|
.description('Start MCP server for Claude Code integration')
|
|
294
267
|
.option('-s, --server <url>', 'Studio URL', DEFAULT_SERVER_URL)
|
|
295
268
|
.option('--stdio', 'Run in MCP stdio mode (skip interactive registration)')
|
|
296
|
-
.action(async (options) => {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
catch (error) {
|
|
301
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
302
|
-
process.exit(1);
|
|
303
|
-
}
|
|
304
|
-
});
|
|
269
|
+
.action(wrapAction(async (options) => {
|
|
270
|
+
await mcpServerCommand(options);
|
|
271
|
+
}));
|
|
305
272
|
// MCP setup command
|
|
306
273
|
program
|
|
307
274
|
.command('mcp-setup')
|
|
@@ -309,82 +276,46 @@ program
|
|
|
309
276
|
.option('--tool <tools...>', 'Specific tools to configure (claude, cursor, vscode, windsurf, codex, openclaw)')
|
|
310
277
|
.option('--all', 'Configure all detected tools without prompting')
|
|
311
278
|
.option('--list', 'List detected tools without configuring')
|
|
312
|
-
.action(async (options) => {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
catch (error) {
|
|
317
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
318
|
-
process.exit(1);
|
|
319
|
-
}
|
|
320
|
-
});
|
|
279
|
+
.action(wrapAction(async (options) => {
|
|
280
|
+
await mcpSetupCommand(options);
|
|
281
|
+
}));
|
|
321
282
|
// UI command group (send commands to Studio)
|
|
322
283
|
const uiCmd = program.command('ui').description('Send commands to Studio');
|
|
323
284
|
uiCmd
|
|
324
285
|
.command('focus-node <nodeId>')
|
|
325
286
|
.description('Select and center a node in Studio')
|
|
326
287
|
.option('-s, --server <url>', 'Studio URL', DEFAULT_SERVER_URL)
|
|
327
|
-
.action(async (nodeId, options) => {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
}
|
|
331
|
-
catch (error) {
|
|
332
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
333
|
-
process.exit(1);
|
|
334
|
-
}
|
|
335
|
-
});
|
|
288
|
+
.action(wrapAction(async (nodeId, options) => {
|
|
289
|
+
await uiFocusNode(nodeId, options);
|
|
290
|
+
}));
|
|
336
291
|
uiCmd
|
|
337
292
|
.command('add-node <nodeTypeName>')
|
|
338
293
|
.description('Add a node at viewport center')
|
|
339
294
|
.option('-s, --server <url>', 'Studio URL', DEFAULT_SERVER_URL)
|
|
340
|
-
.action(async (nodeTypeName, options) => {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
344
|
-
catch (error) {
|
|
345
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
346
|
-
process.exit(1);
|
|
347
|
-
}
|
|
348
|
-
});
|
|
295
|
+
.action(wrapAction(async (nodeTypeName, options) => {
|
|
296
|
+
await uiAddNode(nodeTypeName, options);
|
|
297
|
+
}));
|
|
349
298
|
uiCmd
|
|
350
299
|
.command('open-workflow <filePath>')
|
|
351
300
|
.description('Open a workflow file in Studio')
|
|
352
301
|
.option('-s, --server <url>', 'Studio URL', DEFAULT_SERVER_URL)
|
|
353
|
-
.action(async (filePath, options) => {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
catch (error) {
|
|
358
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
359
|
-
process.exit(1);
|
|
360
|
-
}
|
|
361
|
-
});
|
|
302
|
+
.action(wrapAction(async (filePath, options) => {
|
|
303
|
+
await uiOpenWorkflow(filePath, options);
|
|
304
|
+
}));
|
|
362
305
|
uiCmd
|
|
363
306
|
.command('get-state')
|
|
364
307
|
.description('Return current workflow state from Studio')
|
|
365
308
|
.option('-s, --server <url>', 'Studio URL', DEFAULT_SERVER_URL)
|
|
366
|
-
.action(async (options) => {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}
|
|
370
|
-
catch (error) {
|
|
371
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
372
|
-
process.exit(1);
|
|
373
|
-
}
|
|
374
|
-
});
|
|
309
|
+
.action(wrapAction(async (options) => {
|
|
310
|
+
await uiGetState(options);
|
|
311
|
+
}));
|
|
375
312
|
uiCmd
|
|
376
313
|
.command('batch <json>')
|
|
377
314
|
.description('Execute a batch of commands with auto-snapshot rollback')
|
|
378
315
|
.option('-s, --server <url>', 'Studio URL', DEFAULT_SERVER_URL)
|
|
379
|
-
.action(async (json, options) => {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
}
|
|
383
|
-
catch (error) {
|
|
384
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
385
|
-
process.exit(1);
|
|
386
|
-
}
|
|
387
|
-
});
|
|
316
|
+
.action(wrapAction(async (json, options) => {
|
|
317
|
+
await uiBatch(json, options);
|
|
318
|
+
}));
|
|
388
319
|
// Create command (with subcommands)
|
|
389
320
|
const createCmd = program.command('create').description('Create workflows or nodes from templates');
|
|
390
321
|
createCmd
|
|
@@ -400,91 +331,55 @@ createCmd
|
|
|
400
331
|
.option('--nodes <names>', 'Comma-separated node function names (e.g., "fetch,parse,store")')
|
|
401
332
|
.option('--input <name>', 'Custom input port name (default: "data")')
|
|
402
333
|
.option('--output <name>', 'Custom output port name (default: "result")')
|
|
403
|
-
.action(async (template, file, options) => {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
}
|
|
407
|
-
catch (error) {
|
|
408
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
409
|
-
process.exit(1);
|
|
410
|
-
}
|
|
411
|
-
});
|
|
334
|
+
.action(wrapAction(async (template, file, options) => {
|
|
335
|
+
await createWorkflowCommand(template, file, options);
|
|
336
|
+
}));
|
|
412
337
|
createCmd
|
|
413
338
|
.command('node <name> <file>')
|
|
414
|
-
.description('Create a node type
|
|
339
|
+
.description('Create a node type from a template')
|
|
415
340
|
.option('-l, --line <number>', 'Insert at specific line number', parseInt)
|
|
416
|
-
.option('-t, --template <template>', 'Node template to use', '
|
|
341
|
+
.option('-t, --template <template>', 'Node template to use', 'transformer')
|
|
417
342
|
.option('-p, --preview', 'Preview generated code without writing', false)
|
|
418
343
|
.option('--strategy <strategy>', 'Template strategy (e.g. mock, callback, webhook)')
|
|
419
344
|
.option('--config <json>', 'Additional configuration (JSON)')
|
|
420
|
-
.action(async (name, file, options) => {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
}
|
|
424
|
-
catch (error) {
|
|
425
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
426
|
-
process.exit(1);
|
|
427
|
-
}
|
|
428
|
-
});
|
|
345
|
+
.action(wrapAction(async (name, file, options) => {
|
|
346
|
+
await createNodeCommand(name, file, options);
|
|
347
|
+
}));
|
|
429
348
|
// Templates command
|
|
430
349
|
program
|
|
431
350
|
.command('templates')
|
|
432
351
|
.description('List available templates')
|
|
433
352
|
.option('--json', 'Output as JSON', false)
|
|
434
|
-
.action(async (options) => {
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
}
|
|
438
|
-
catch (error) {
|
|
439
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
440
|
-
process.exit(1);
|
|
441
|
-
}
|
|
442
|
-
});
|
|
353
|
+
.action(wrapAction(async (options) => {
|
|
354
|
+
await templatesCommand(options);
|
|
355
|
+
}));
|
|
443
356
|
// Grammar command
|
|
444
357
|
program
|
|
445
358
|
.command('grammar')
|
|
446
359
|
.description('Output JSDoc annotation grammar (@input, @output, @connect, @node, @scope) as HTML railroad diagrams or EBNF text')
|
|
447
|
-
.
|
|
360
|
+
.addOption(new Option('-f, --format <format>', 'Output format').choices(['html', 'ebnf']))
|
|
448
361
|
.option('-o, --output <path>', 'Write output to file instead of stdout')
|
|
449
|
-
.action(async (options) => {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
}
|
|
453
|
-
catch (error) {
|
|
454
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
455
|
-
process.exit(1);
|
|
456
|
-
}
|
|
457
|
-
});
|
|
362
|
+
.action(wrapAction(async (options) => {
|
|
363
|
+
await grammarCommand(options);
|
|
364
|
+
}));
|
|
458
365
|
// Pattern command (with subcommands)
|
|
459
366
|
const patternCmd = program.command('pattern').description('Work with reusable workflow patterns');
|
|
460
367
|
patternCmd
|
|
461
368
|
.command('list <path>')
|
|
462
369
|
.description('List patterns in a file or directory')
|
|
463
370
|
.option('--json', 'Output as JSON', false)
|
|
464
|
-
.action(async (inputPath, options) => {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
}
|
|
468
|
-
catch (error) {
|
|
469
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
470
|
-
process.exit(1);
|
|
471
|
-
}
|
|
472
|
-
});
|
|
371
|
+
.action(wrapAction(async (inputPath, options) => {
|
|
372
|
+
await patternListCommand(inputPath, options);
|
|
373
|
+
}));
|
|
473
374
|
patternCmd
|
|
474
375
|
.command('apply <pattern-file> <target-file>')
|
|
475
376
|
.description('Apply a pattern to a workflow file')
|
|
476
377
|
.option('-p, --preview', 'Preview changes without writing', false)
|
|
477
378
|
.option('--prefix <prefix>', 'Prefix for node instance IDs')
|
|
478
379
|
.option('-n, --name <name>', 'Specific pattern name to apply')
|
|
479
|
-
.action(async (patternFile, targetFile, options) => {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
}
|
|
483
|
-
catch (error) {
|
|
484
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
485
|
-
process.exit(1);
|
|
486
|
-
}
|
|
487
|
-
});
|
|
380
|
+
.action(wrapAction(async (patternFile, targetFile, options) => {
|
|
381
|
+
await patternApplyCommand(patternFile, targetFile, options);
|
|
382
|
+
}));
|
|
488
383
|
patternCmd
|
|
489
384
|
.command('extract <source-file>')
|
|
490
385
|
.description('Extract a pattern from workflow nodes')
|
|
@@ -492,15 +387,9 @@ patternCmd
|
|
|
492
387
|
.requiredOption('-o, --output <file>', 'Output pattern file')
|
|
493
388
|
.option('-n, --name <name>', 'Pattern name')
|
|
494
389
|
.option('-p, --preview', 'Preview pattern without writing', false)
|
|
495
|
-
.action(async (sourceFile, options) => {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
}
|
|
499
|
-
catch (error) {
|
|
500
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
501
|
-
process.exit(1);
|
|
502
|
-
}
|
|
503
|
-
});
|
|
390
|
+
.action(wrapAction(async (sourceFile, options) => {
|
|
391
|
+
await patternExtractCommand(sourceFile, options);
|
|
392
|
+
}));
|
|
504
393
|
// Run command
|
|
505
394
|
program
|
|
506
395
|
.command('run <input>')
|
|
@@ -519,15 +408,9 @@ program
|
|
|
519
408
|
.option('--checkpoint', 'Enable checkpointing to disk after each node')
|
|
520
409
|
.option('--resume [file]', 'Resume from a checkpoint file (auto-detects latest if no file)')
|
|
521
410
|
.option('-b, --breakpoint <nodeIds...>', 'Set initial breakpoints (repeatable)')
|
|
522
|
-
.action(async (input, options) => {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
}
|
|
526
|
-
catch (error) {
|
|
527
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
528
|
-
process.exit(1);
|
|
529
|
-
}
|
|
530
|
-
});
|
|
411
|
+
.action(wrapAction(async (input, options) => {
|
|
412
|
+
await runCommand(input, options);
|
|
413
|
+
}));
|
|
531
414
|
// Serve command
|
|
532
415
|
program
|
|
533
416
|
.command('serve [directory]')
|
|
@@ -539,28 +422,22 @@ program
|
|
|
539
422
|
.option('--precompile', 'Precompile all workflows on startup', false)
|
|
540
423
|
.option('--cors <origin>', 'CORS origin', '*')
|
|
541
424
|
.option('--swagger', 'Enable Swagger UI at /docs', false)
|
|
542
|
-
.action(async (directory, options) => {
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
}
|
|
554
|
-
catch (error) {
|
|
555
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
556
|
-
process.exit(1);
|
|
557
|
-
}
|
|
558
|
-
});
|
|
425
|
+
.action(wrapAction(async (directory, options) => {
|
|
426
|
+
await serveCommand(directory, {
|
|
427
|
+
port: parseInt(options.port, 10),
|
|
428
|
+
host: options.host,
|
|
429
|
+
watch: options.watch,
|
|
430
|
+
production: options.production,
|
|
431
|
+
precompile: options.precompile,
|
|
432
|
+
cors: options.cors,
|
|
433
|
+
swagger: options.swagger,
|
|
434
|
+
});
|
|
435
|
+
}));
|
|
559
436
|
// Export command
|
|
560
437
|
program
|
|
561
438
|
.command('export <input>')
|
|
562
439
|
.description('Export workflow as serverless function')
|
|
563
|
-
.requiredOption('-t, --target <target>', 'Target platform (
|
|
440
|
+
.requiredOption('-t, --target <target>', 'Target platform (install target packs via marketplace)')
|
|
564
441
|
.requiredOption('-o, --output <path>', 'Output directory')
|
|
565
442
|
.option('-w, --workflow <name>', 'Specific workflow name to export')
|
|
566
443
|
.option('-p, --production', 'Production mode', true)
|
|
@@ -569,15 +446,9 @@ program
|
|
|
569
446
|
.option('--workflows <names>', 'Comma-separated list of workflows to export (used with --multi)')
|
|
570
447
|
.option('--docs', 'Include API documentation routes (/docs and /openapi.json)', false)
|
|
571
448
|
.option('--durable-steps', 'Use deep generator with per-node Inngest steps for durability (inngest target only)', false)
|
|
572
|
-
.action(async (input, options) => {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
}
|
|
576
|
-
catch (error) {
|
|
577
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
578
|
-
process.exit(1);
|
|
579
|
-
}
|
|
580
|
-
});
|
|
449
|
+
.action(wrapAction(async (input, options) => {
|
|
450
|
+
await exportCommand(input, options);
|
|
451
|
+
}));
|
|
581
452
|
// OpenAPI command
|
|
582
453
|
program
|
|
583
454
|
.command('openapi <directory>')
|
|
@@ -586,17 +457,11 @@ program
|
|
|
586
457
|
.option('--title <title>', 'API title', 'Flow Weaver API')
|
|
587
458
|
.option('--version <version>', 'API version', '1.0.0')
|
|
588
459
|
.option('--description <desc>', 'API description')
|
|
589
|
-
.option('-f, --format <format>', 'Output format: json
|
|
460
|
+
.option('-f, --format <format>', 'Output format: json, yaml', 'json')
|
|
590
461
|
.option('--server <url>', 'Server URL')
|
|
591
|
-
.action(async (directory, options) => {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
}
|
|
595
|
-
catch (error) {
|
|
596
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
597
|
-
process.exit(1);
|
|
598
|
-
}
|
|
599
|
-
});
|
|
462
|
+
.action(wrapAction(async (directory, options) => {
|
|
463
|
+
await openapiCommand(directory, options);
|
|
464
|
+
}));
|
|
600
465
|
// Plugin command group
|
|
601
466
|
const pluginCmd = program.command('plugin').description('Scaffold and manage external plugins');
|
|
602
467
|
pluginCmd
|
|
@@ -606,60 +471,40 @@ pluginCmd
|
|
|
606
471
|
.option('--no-system', 'Skip generating a system module')
|
|
607
472
|
.option('-p, --preview', 'Preview generated files without writing', false)
|
|
608
473
|
.option('--force', 'Overwrite existing files', false)
|
|
609
|
-
.action(async (name, options) => {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
613
|
-
catch (error) {
|
|
614
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
615
|
-
process.exit(1);
|
|
616
|
-
}
|
|
617
|
-
});
|
|
474
|
+
.action(wrapAction(async (name, options) => {
|
|
475
|
+
await pluginInitCommand(name, options);
|
|
476
|
+
}));
|
|
618
477
|
// Migrate command
|
|
619
478
|
program
|
|
620
479
|
.command('migrate <glob>')
|
|
621
480
|
.description('Migrate workflow files to current syntax via parse → regenerate round-trip')
|
|
622
481
|
.option('--dry-run', 'Preview changes without writing files', false)
|
|
623
482
|
.option('--diff', 'Show semantic diff before/after', false)
|
|
624
|
-
.action(async (glob, options) => {
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
}
|
|
628
|
-
catch (error) {
|
|
629
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
630
|
-
process.exit(1);
|
|
631
|
-
}
|
|
632
|
-
});
|
|
483
|
+
.action(wrapAction(async (glob, options) => {
|
|
484
|
+
await migrateCommand(glob, options);
|
|
485
|
+
}));
|
|
633
486
|
// Status command
|
|
634
487
|
program
|
|
635
488
|
.command('status <input>')
|
|
636
489
|
.description('Report implementation progress for stub workflows')
|
|
637
|
-
.option('-w, --workflow
|
|
490
|
+
.option('-w, --workflow <name>', 'Specific workflow name')
|
|
638
491
|
.option('--json', 'Output as JSON', false)
|
|
639
|
-
.action(async (input, options) => {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
645
|
-
process.exit(1);
|
|
646
|
-
}
|
|
647
|
-
});
|
|
492
|
+
.action(wrapAction(async (input, options) => {
|
|
493
|
+
if (options.workflow)
|
|
494
|
+
options.workflowName = options.workflow;
|
|
495
|
+
await statusCommand(input, options);
|
|
496
|
+
}));
|
|
648
497
|
// Implement command
|
|
649
498
|
program
|
|
650
499
|
.command('implement <input> <node>')
|
|
651
500
|
.description('Replace a stub node with a real function skeleton')
|
|
652
|
-
.option('-w, --workflow
|
|
501
|
+
.option('-w, --workflow <name>', 'Specific workflow name')
|
|
653
502
|
.option('-p, --preview', 'Preview the generated code without writing', false)
|
|
654
|
-
.action(async (input, node, options) => {
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
660
|
-
process.exit(1);
|
|
661
|
-
}
|
|
662
|
-
});
|
|
503
|
+
.action(wrapAction(async (input, node, options) => {
|
|
504
|
+
if (options.workflow)
|
|
505
|
+
options.workflowName = options.workflow;
|
|
506
|
+
await implementCommand(input, node, options);
|
|
507
|
+
}));
|
|
663
508
|
// Changelog command
|
|
664
509
|
program
|
|
665
510
|
.command('changelog')
|
|
@@ -667,43 +512,31 @@ program
|
|
|
667
512
|
.option('--last-tag', 'From last git tag to HEAD', false)
|
|
668
513
|
.option('--since <date>', 'Date-based range (e.g., "2024-01-01")')
|
|
669
514
|
.option('-r, --range <range>', 'Custom git range (e.g., "v0.1.0..HEAD")')
|
|
670
|
-
.action(async (options) => {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
}
|
|
674
|
-
catch (error) {
|
|
675
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
676
|
-
process.exit(1);
|
|
677
|
-
}
|
|
678
|
-
});
|
|
515
|
+
.action(wrapAction(async (options) => {
|
|
516
|
+
await changelogCommand(options);
|
|
517
|
+
}));
|
|
679
518
|
// Docs command: flow-weaver docs [topic] | flow-weaver docs search <query>
|
|
680
519
|
program
|
|
681
520
|
.command('docs [args...]')
|
|
682
521
|
.description('Browse reference documentation')
|
|
683
522
|
.option('--json', 'Output as JSON', false)
|
|
684
523
|
.option('--compact', 'Return compact LLM-friendly version', false)
|
|
685
|
-
.action(async (args, options) => {
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
process.exit(1);
|
|
695
|
-
}
|
|
696
|
-
await docsSearchCommand(query, options);
|
|
697
|
-
}
|
|
698
|
-
else {
|
|
699
|
-
await docsReadCommand(args[0], options);
|
|
524
|
+
.action(wrapAction(async (args, options) => {
|
|
525
|
+
if (args.length === 0 || args[0] === 'list') {
|
|
526
|
+
await docsListCommand(options);
|
|
527
|
+
}
|
|
528
|
+
else if (args[0] === 'search') {
|
|
529
|
+
const query = args.slice(1).join(' ');
|
|
530
|
+
if (!query) {
|
|
531
|
+
logger.error('Usage: flow-weaver docs search <query>');
|
|
532
|
+
process.exit(1);
|
|
700
533
|
}
|
|
534
|
+
await docsSearchCommand(query, options);
|
|
701
535
|
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
process.exit(1);
|
|
536
|
+
else {
|
|
537
|
+
await docsReadCommand(args[0], options);
|
|
705
538
|
}
|
|
706
|
-
});
|
|
539
|
+
}));
|
|
707
540
|
// Context command: generate LLM context bundles
|
|
708
541
|
program
|
|
709
542
|
.command('context [preset]')
|
|
@@ -714,15 +547,9 @@ program
|
|
|
714
547
|
.option('--no-grammar', 'Omit EBNF grammar section')
|
|
715
548
|
.option('-o, --output <path>', 'Write to file instead of stdout')
|
|
716
549
|
.option('--list', 'List available presets and exit')
|
|
717
|
-
.action(async (preset, options) => {
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
}
|
|
721
|
-
catch (error) {
|
|
722
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
723
|
-
process.exit(1);
|
|
724
|
-
}
|
|
725
|
-
});
|
|
550
|
+
.action(wrapAction(async (preset, options) => {
|
|
551
|
+
await contextCommand(preset, options);
|
|
552
|
+
}));
|
|
726
553
|
// Marketplace command group
|
|
727
554
|
const marketCmd = program.command('market').description('Discover, install, and publish marketplace packages');
|
|
728
555
|
marketCmd
|
|
@@ -731,158 +558,77 @@ marketCmd
|
|
|
731
558
|
.option('-d, --description <desc>', 'Package description')
|
|
732
559
|
.option('-a, --author <author>', 'Author name')
|
|
733
560
|
.option('-y, --yes', 'Skip prompts and use defaults', false)
|
|
734
|
-
.action(async (name, options) => {
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
}
|
|
738
|
-
catch (error) {
|
|
739
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
740
|
-
process.exit(1);
|
|
741
|
-
}
|
|
742
|
-
});
|
|
561
|
+
.action(wrapAction(async (name, options) => {
|
|
562
|
+
await marketInitCommand(name, options);
|
|
563
|
+
}));
|
|
743
564
|
marketCmd
|
|
744
565
|
.command('pack [directory]')
|
|
745
566
|
.description('Validate and generate flowweaver.manifest.json')
|
|
746
567
|
.option('--json', 'Output results as JSON', false)
|
|
747
568
|
.option('--verbose', 'Show parse warnings', false)
|
|
748
|
-
.action(async (directory, options) => {
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
}
|
|
752
|
-
catch (error) {
|
|
753
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
754
|
-
process.exit(1);
|
|
755
|
-
}
|
|
756
|
-
});
|
|
569
|
+
.action(wrapAction(async (directory, options) => {
|
|
570
|
+
await marketPackCommand(directory, options);
|
|
571
|
+
}));
|
|
757
572
|
marketCmd
|
|
758
573
|
.command('publish [directory]')
|
|
759
574
|
.description('Pack and publish to npm')
|
|
760
575
|
.option('--dry-run', 'Preview without publishing', false)
|
|
761
576
|
.option('--tag <tag>', 'npm dist-tag')
|
|
762
|
-
.action(async (directory, options) => {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
}
|
|
766
|
-
catch (error) {
|
|
767
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
768
|
-
process.exit(1);
|
|
769
|
-
}
|
|
770
|
-
});
|
|
577
|
+
.action(wrapAction(async (directory, options) => {
|
|
578
|
+
await marketPublishCommand(directory, options);
|
|
579
|
+
}));
|
|
771
580
|
marketCmd
|
|
772
581
|
.command('install <package>')
|
|
773
582
|
.description('Install a marketplace package')
|
|
774
583
|
.option('--json', 'Output results as JSON', false)
|
|
775
|
-
.action(async (packageSpec, options) => {
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
}
|
|
779
|
-
catch (error) {
|
|
780
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
781
|
-
process.exit(1);
|
|
782
|
-
}
|
|
783
|
-
});
|
|
584
|
+
.action(wrapAction(async (packageSpec, options) => {
|
|
585
|
+
await marketInstallCommand(packageSpec, options);
|
|
586
|
+
}));
|
|
784
587
|
marketCmd
|
|
785
588
|
.command('search [query]')
|
|
786
589
|
.description('Search npm for marketplace packages')
|
|
787
590
|
.option('-l, --limit <number>', 'Max results', '20')
|
|
788
591
|
.option('-r, --registry <url>', 'Custom registry search URL (e.g., private npm registry)')
|
|
789
592
|
.option('--json', 'Output as JSON', false)
|
|
790
|
-
.action(async (query, options) => {
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
}
|
|
794
|
-
catch (error) {
|
|
795
|
-
logger.error(`Command failed: ${getErrorMessage(error)}`);
|
|
796
|
-
process.exit(1);
|
|
797
|
-
}
|
|
798
|
-
});
|
|
593
|
+
.action(wrapAction(async (query, options) => {
|
|
594
|
+
await marketSearchCommand(query, { ...options, limit: parseInt(options.limit, 10) });
|
|
595
|
+
}));
|
|
799
596
|
marketCmd
|
|
800
597
|
.command('list')
|
|
801
598
|
.description('List installed marketplace packages')
|
|
802
599
|
.option('--json', 'Output as JSON', false)
|
|
803
|
-
.action(async (options) => {
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
logger.log(' $ flow-weaver describe workflow.ts');
|
|
820
|
-
logger.log(' $ flow-weaver describe workflow.ts --format mermaid');
|
|
821
|
-
logger.log(' $ flow-weaver describe workflow.ts --node validator');
|
|
822
|
-
logger.log(' $ flow-weaver diagram workflow.ts');
|
|
823
|
-
logger.log(' $ flow-weaver diagram workflow.ts --theme light -o diagram.svg');
|
|
824
|
-
logger.log(' $ flow-weaver diagram workflow.ts --format html -o diagram.html');
|
|
825
|
-
logger.log(' $ flow-weaver diff workflow-v1.ts workflow-v2.ts');
|
|
826
|
-
logger.log(' $ flow-weaver diff workflow-v1.ts workflow-v2.ts --format json');
|
|
827
|
-
logger.log(" $ flow-weaver validate '**/*.ts'");
|
|
828
|
-
logger.log(" $ flow-weaver watch 'src/**/*.ts' -o dist");
|
|
829
|
-
logger.log(' $ flow-weaver create workflow simple my-workflow.ts');
|
|
830
|
-
logger.log(' $ flow-weaver create workflow ai-agent agent.ts --provider openai --model gpt-4o');
|
|
831
|
-
logger.log(' $ flow-weaver create node myProcessor my-workflow.ts');
|
|
832
|
-
logger.log(' $ flow-weaver templates');
|
|
833
|
-
logger.log(' $ flow-weaver pattern list ./patterns');
|
|
834
|
-
logger.log(' $ flow-weaver pattern apply pattern.ts workflow.ts');
|
|
835
|
-
logger.log(' $ flow-weaver pattern extract workflow.ts --nodes a,b -o extracted.ts');
|
|
836
|
-
logger.log(' $ flow-weaver init my-project');
|
|
837
|
-
logger.log(' $ flow-weaver init --template ai-agent -y');
|
|
838
|
-
logger.log(' $ flow-weaver init my-project --format cjs');
|
|
839
|
-
logger.log(' $ flow-weaver doctor');
|
|
840
|
-
logger.log(' $ flow-weaver doctor --json');
|
|
841
|
-
logger.newline();
|
|
842
|
-
logger.section('Plugin Commands');
|
|
843
|
-
logger.log(' $ flow-weaver plugin init my-plugin');
|
|
844
|
-
logger.log(' $ flow-weaver plugin init my-plugin --area sidebar --no-system');
|
|
845
|
-
logger.log(' $ flow-weaver plugin init my-plugin --preview');
|
|
846
|
-
logger.newline();
|
|
847
|
-
logger.section('Deployment Commands');
|
|
848
|
-
logger.log(' $ flow-weaver run workflow.ts --params \'{"a": 5}\'');
|
|
849
|
-
logger.log(' $ flow-weaver serve ./workflows --port 8080');
|
|
850
|
-
logger.log(' $ flow-weaver export workflow.ts --target vercel --output api/');
|
|
851
|
-
logger.log(' $ flow-weaver export workflows.ts --target lambda --output dist/ --multi');
|
|
852
|
-
logger.log(' $ flow-weaver export workflows.ts --target lambda --output dist/ --multi --docs');
|
|
853
|
-
logger.log(' $ flow-weaver export workflow.ts --target inngest --output dist/ --durable-steps');
|
|
854
|
-
logger.log(' $ flow-weaver compile workflow.ts --target inngest');
|
|
855
|
-
logger.log(' $ flow-weaver openapi ./workflows --output api-spec.json');
|
|
856
|
-
logger.newline();
|
|
857
|
-
logger.section('Marketplace Commands');
|
|
858
|
-
logger.log(' $ flow-weaver market init openai');
|
|
859
|
-
logger.log(' $ flow-weaver market pack');
|
|
860
|
-
logger.log(' $ flow-weaver market publish');
|
|
861
|
-
logger.log(' $ flow-weaver market publish --dry-run');
|
|
862
|
-
logger.log(' $ flow-weaver market install flowweaver-pack-openai');
|
|
863
|
-
logger.log(' $ flow-weaver market search openai');
|
|
864
|
-
logger.log(' $ flow-weaver market list');
|
|
865
|
-
logger.newline();
|
|
866
|
-
logger.section('Documentation');
|
|
867
|
-
logger.log(' $ flow-weaver docs');
|
|
868
|
-
logger.log(' $ flow-weaver docs read error-codes');
|
|
869
|
-
logger.log(' $ flow-weaver docs read scaffold --compact');
|
|
870
|
-
logger.log(' $ flow-weaver docs search "missing workflow"');
|
|
871
|
-
logger.log(' $ flow-weaver docs read error-codes --json');
|
|
872
|
-
logger.newline();
|
|
873
|
-
logger.section('Migration & Changelog');
|
|
874
|
-
logger.log(" $ flow-weaver migrate '**/*.ts'");
|
|
875
|
-
logger.log(" $ flow-weaver migrate '**/*.ts' --dry-run");
|
|
876
|
-
logger.log(" $ flow-weaver migrate 'src/**/*.ts' --diff");
|
|
877
|
-
logger.log(' $ flow-weaver changelog --last-tag');
|
|
878
|
-
logger.log(' $ flow-weaver changelog --range v0.1.0..HEAD');
|
|
879
|
-
logger.log(' $ flow-weaver changelog --since 2024-01-01');
|
|
880
|
-
logger.newline();
|
|
881
|
-
});
|
|
882
|
-
// Parse arguments
|
|
883
|
-
program.parse(process.argv);
|
|
884
|
-
// Show help if no command specified
|
|
600
|
+
.action(wrapAction(async (options) => {
|
|
601
|
+
await marketListCommand(options);
|
|
602
|
+
}));
|
|
603
|
+
// Concise examples appended to --help
|
|
604
|
+
program.addHelpText('after', `
|
|
605
|
+
Examples:
|
|
606
|
+
|
|
607
|
+
$ flow-weaver compile my-workflow.ts
|
|
608
|
+
$ flow-weaver validate 'src/**/*.ts'
|
|
609
|
+
$ flow-weaver run workflow.ts --params '{"a": 5}'
|
|
610
|
+
$ flow-weaver describe workflow.ts --format ascii-compact
|
|
611
|
+
$ flow-weaver init my-project
|
|
612
|
+
|
|
613
|
+
Run flow-weaver <command> --help for detailed usage.
|
|
614
|
+
`);
|
|
615
|
+
// Show concise welcome when no command specified (before parse to avoid Commander error handling)
|
|
885
616
|
if (!process.argv.slice(2).length) {
|
|
886
|
-
|
|
617
|
+
logger.banner(version);
|
|
618
|
+
console.log();
|
|
619
|
+
console.log(' Usage: flow-weaver <command> [options]');
|
|
620
|
+
console.log();
|
|
621
|
+
console.log(' Get started:');
|
|
622
|
+
console.log(' init [dir] Create a new project');
|
|
623
|
+
console.log(' compile <input> Compile workflow files');
|
|
624
|
+
console.log(' validate <input> Validate without compiling');
|
|
625
|
+
console.log(' run <input> Execute a workflow');
|
|
626
|
+
console.log(' doctor Check project environment');
|
|
627
|
+
console.log();
|
|
628
|
+
console.log(' Run ' + logger.highlight('flow-weaver --help') + ' for all commands.');
|
|
629
|
+
console.log();
|
|
630
|
+
process.exit(0);
|
|
887
631
|
}
|
|
632
|
+
// Parse arguments
|
|
633
|
+
program.parse(process.argv);
|
|
888
634
|
//# sourceMappingURL=index.js.map
|