@synergenius/flow-weaver 0.2.1 → 0.3.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 +260 -200
- package/dist/cli/commands/docs.d.ts +11 -0
- package/dist/cli/commands/docs.js +77 -0
- package/dist/cli/flow-weaver.mjs +1077 -543
- package/dist/cli/index.js +51 -0
- package/dist/diagram/geometry.d.ts +9 -4
- package/dist/diagram/geometry.js +219 -30
- package/dist/diagram/renderer.js +137 -116
- package/dist/docs/index.d.ts +54 -0
- package/dist/docs/index.js +256 -0
- package/dist/mcp/server.js +2 -0
- package/dist/mcp/tools-docs.d.ts +3 -0
- package/dist/mcp/tools-docs.js +62 -0
- package/dist/mcp/tools-editor.js +3 -1
- package/dist/mcp/tools-query.js +3 -1
- package/dist/mcp/workflow-executor.js +4 -2
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -3,290 +3,350 @@
|
|
|
3
3
|
[](./LICENSE)
|
|
4
4
|
[](https://nodejs.org)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
**Workflow compiler for AI agents.** LLMs create, validate, iterate, and test workflows programmatically. Humans review them visually. Compiled output is standalone TypeScript with no runtime dependencies.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Flow Weaver turns standard TypeScript functions into executable workflow graphs using JSDoc annotations. No YAML. No JSON configs. No drag-and-drop. Just TypeScript with full type safety, IDE autocomplete, and compile-time validation, in a format LLMs can read and write directly. Compiled output runs anywhere with no dependency on Flow Weaver.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Why Flow Weaver?
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
- [Quick Start](#quick-start)
|
|
14
|
-
- [API](#api)
|
|
15
|
-
- [Exports](#exports)
|
|
16
|
-
- [CLI Reference](#cli-reference)
|
|
17
|
-
- [STEP Port Architecture](#step-port-architecture)
|
|
18
|
-
- [Annotations](#annotations)
|
|
19
|
-
- [Deployment](#deployment)
|
|
20
|
-
- [MCP Integration](#mcp-integration)
|
|
21
|
-
- [API Documentation](#api-documentation)
|
|
22
|
-
- [Testing](#testing)
|
|
23
|
-
- [Development](#development)
|
|
24
|
-
- [License](#license)
|
|
12
|
+
**Agents generate code well. They don't generate reliable systems.**
|
|
25
13
|
|
|
26
|
-
|
|
14
|
+
With Flow Weaver, an agent builds a typed workflow graph instead of a monolithic script. Every connection is type-checked, every required input is enforced, every error path is explicit.
|
|
15
|
+
|
|
16
|
+
The development loop (steps 1-4 are fully autonomous):
|
|
17
|
+
|
|
18
|
+
1. **Agent creates**: scaffolds from templates or builds from scratch via 35+ MCP tools
|
|
19
|
+
2. **Compiler validates**: 15+ validation passes catch missing connections, type mismatches, unreachable paths
|
|
20
|
+
3. **Agent iterates**: validation errors include fix suggestions, the agent corrects and re-validates until clean
|
|
21
|
+
4. **Agent tests**: deterministic mock providers for reproducible testing without real API calls
|
|
22
|
+
5. **Human reviews**: visual editor renders the workflow as an interactive graph for final approval
|
|
23
|
+
|
|
24
|
+
The compiled code is yours. No runtime lock-in, no framework dependency.
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
### Install
|
|
27
29
|
|
|
28
30
|
```bash
|
|
29
31
|
npm install @synergenius/flow-weaver
|
|
30
32
|
```
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
### Define a workflow
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
Workflows are plain TypeScript. Annotations declare the graph structure:
|
|
35
37
|
|
|
36
38
|
```typescript
|
|
37
|
-
//
|
|
39
|
+
// data-pipeline.ts
|
|
38
40
|
|
|
39
41
|
/**
|
|
40
42
|
* @flowWeaver nodeType
|
|
41
|
-
* @input
|
|
42
|
-
* @
|
|
43
|
-
* @output
|
|
43
|
+
* @input rawData - string
|
|
44
|
+
* @output cleaned - string
|
|
45
|
+
* @output wordCount - number
|
|
44
46
|
*/
|
|
45
|
-
function
|
|
46
|
-
if (!execute) return { onSuccess: false, onFailure: false,
|
|
47
|
-
|
|
47
|
+
function processText(execute: boolean, rawData: string) {
|
|
48
|
+
if (!execute) return { onSuccess: false, onFailure: false, cleaned: '', wordCount: 0 };
|
|
49
|
+
const cleaned = rawData.trim().toLowerCase();
|
|
50
|
+
return { onSuccess: true, onFailure: false, cleaned, wordCount: cleaned.split(/\s+/).length };
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
/**
|
|
51
54
|
* @flowWeaver workflow
|
|
52
|
-
* @node
|
|
53
|
-
* @connect Start.
|
|
54
|
-
* @connect
|
|
55
|
-
* @connect
|
|
55
|
+
* @node processor processText
|
|
56
|
+
* @connect Start.rawData -> processor.rawData
|
|
57
|
+
* @connect processor.cleaned -> Exit.cleaned
|
|
58
|
+
* @connect processor.wordCount -> Exit.wordCount
|
|
56
59
|
*/
|
|
57
|
-
export async function
|
|
60
|
+
export async function dataPipeline(
|
|
58
61
|
execute: boolean,
|
|
59
|
-
params: {
|
|
60
|
-
): Promise<{ onSuccess: boolean; onFailure: boolean;
|
|
61
|
-
throw new Error('Not
|
|
62
|
+
params: { rawData: string }
|
|
63
|
+
): Promise<{ onSuccess: boolean; onFailure: boolean; cleaned: string; wordCount: number }> {
|
|
64
|
+
throw new Error('Not compiled');
|
|
62
65
|
}
|
|
63
66
|
```
|
|
64
67
|
|
|
65
|
-
Compile
|
|
68
|
+
### Compile and run
|
|
66
69
|
|
|
67
70
|
```bash
|
|
68
|
-
npx flow-weaver compile
|
|
71
|
+
npx flow-weaver compile data-pipeline.ts # generates executable code in-place
|
|
72
|
+
npx flow-weaver run data-pipeline.ts --params '{"rawData": "Hello World"}'
|
|
69
73
|
```
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
The compiler fills in the function body while preserving your code outside the generated markers.
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
import {
|
|
75
|
-
parseWorkflow, // Parse workflow file to AST
|
|
76
|
-
compileWorkflow, // Parse + generate in one step
|
|
77
|
-
validateWorkflow, // Validate AST
|
|
78
|
-
generateCode, // Generate code from AST
|
|
79
|
-
} from '@synergenius/flow-weaver';
|
|
77
|
+
## AI-Native Development with MCP
|
|
80
78
|
|
|
81
|
-
|
|
82
|
-
const { code } = await compileWorkflow('workflow.ts');
|
|
79
|
+
Flow Weaver includes an MCP server with 35+ tools for Claude Code (or any MCP-compatible agent):
|
|
83
80
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const code = generateCode(ast);
|
|
81
|
+
```bash
|
|
82
|
+
npx flow-weaver mcp-server # auto-registers with Claude Code
|
|
87
83
|
```
|
|
88
84
|
|
|
89
|
-
|
|
85
|
+
What an AI agent can do:
|
|
90
86
|
|
|
91
|
-
|
|
87
|
+
| Capability | MCP Tools |
|
|
88
|
+
|-----------|-----------|
|
|
89
|
+
| **Build** | `fw_scaffold`, `fw_modify`, `fw_modify_batch`, `fw_add_node`, `fw_connect` |
|
|
90
|
+
| **Validate** | `fw_validate` (with friendly error hints), `fw_doctor` |
|
|
91
|
+
| **Understand** | `fw_describe` (json/text/mermaid), `fw_query` (10 query types), `fw_diff` |
|
|
92
|
+
| **Test** | `fw_execute_workflow` (with trace), `fw_compile` |
|
|
93
|
+
| **Visualize** | `fw_diagram` (SVG), `fw_get_state`, `fw_focus_node` |
|
|
94
|
+
| **Deploy** | `fw_export` (Lambda, Vercel, Cloudflare, Inngest), `fw_compile --target inngest` |
|
|
95
|
+
| **Reuse** | `fw_list_patterns`, `fw_apply_pattern`, `fw_extract_pattern` |
|
|
96
|
+
| **Extend** | `fw_market_search`, `fw_market_install` |
|
|
92
97
|
|
|
93
|
-
|
|
94
|
-
|-------------|---------|
|
|
95
|
-
| `@synergenius/flow-weaver` | Main — parse, validate, compile, generate, AST types, builders, diff, JSDoc sync |
|
|
96
|
-
| `@synergenius/flow-weaver/runtime` | Execution context & errors for generated code |
|
|
97
|
-
| `@synergenius/flow-weaver/built-in-nodes` | Built-in workflow nodes (delay, waitForEvent, invokeWorkflow) |
|
|
98
|
-
| `@synergenius/flow-weaver/diagram` | Workflow diagram layout and rendering |
|
|
99
|
-
| `@synergenius/flow-weaver/describe` | Programmatic workflow description (structure, nodes, paths) |
|
|
98
|
+
The agent reads validation errors, fixes issues, and re-validates until the workflow compiles clean.
|
|
100
99
|
|
|
101
|
-
##
|
|
100
|
+
## Agent Workflow Templates
|
|
102
101
|
|
|
103
|
-
|
|
102
|
+
Built-in templates for AI agent workflows (LLM reasoning, tool calling, looping):
|
|
104
103
|
|
|
105
104
|
```bash
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
--watch # Recompile on changes
|
|
109
|
-
--dry-run # Preview without writing
|
|
110
|
-
--optimize # Optimize workflow compilation
|
|
111
|
-
--strict # Strict validation mode
|
|
112
|
-
--source-map # Generate source maps
|
|
113
|
-
--format esm|cjs|auto # Output module format
|
|
114
|
-
|
|
115
|
-
flow-weaver validate <file> # Validate without compiling
|
|
116
|
-
--verbose | --quiet | --json # Output format
|
|
117
|
-
--strict # Strict type checking
|
|
118
|
-
|
|
119
|
-
flow-weaver run <file> # Execute a workflow
|
|
120
|
-
--params '{"key":"val"}' # Input parameters (JSON)
|
|
121
|
-
--params-file params.json # Parameters from file
|
|
122
|
-
--production # Production mode
|
|
123
|
-
--trace # Include execution trace
|
|
124
|
-
--timeout 30000 # Execution timeout (ms)
|
|
125
|
-
|
|
126
|
-
flow-weaver dev <file> # Watch + compile + run
|
|
127
|
-
--params '{"key":"val"}' # Input parameters
|
|
128
|
-
--once # Run once then exit
|
|
129
|
-
|
|
130
|
-
flow-weaver watch <file> # Watch and recompile
|
|
131
|
-
flow-weaver describe <file> # Output structure
|
|
132
|
-
--format json|text|mermaid|paths # Output format
|
|
133
|
-
--node <id> # Focus on specific node
|
|
134
|
-
flow-weaver diagram <file> # Generate SVG diagram
|
|
135
|
-
--theme dark|light # Color theme (default: dark)
|
|
136
|
-
--width <pixels> # SVG width
|
|
137
|
-
--no-port-labels # Hide port data type labels
|
|
138
|
-
-o, --output <file> # Write to file (default: stdout)
|
|
139
|
-
flow-weaver diff <f1> <f2> # Semantic comparison
|
|
140
|
-
--format text|json|compact # Output format
|
|
141
|
-
```
|
|
105
|
+
# Scaffold a tool-calling agent with memory and error handling
|
|
106
|
+
npx flow-weaver create workflow ai-agent my-agent.ts --provider openai --model gpt-4o
|
|
142
107
|
|
|
143
|
-
|
|
108
|
+
# ReAct pattern (Thought -> Action -> Observation loop)
|
|
109
|
+
npx flow-weaver create workflow ai-react react-agent.ts
|
|
144
110
|
|
|
145
|
-
|
|
146
|
-
flow-weaver
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
flow-weaver create workflow
|
|
150
|
-
flow-weaver create node <name> <file> # Scaffold node type
|
|
151
|
-
flow-weaver templates # List available templates
|
|
152
|
-
flow-weaver doctor # Check project compatibility
|
|
153
|
-
flow-weaver grammar # Output annotation grammar (EBNF/railroad)
|
|
111
|
+
# RAG pipeline (Retrieve -> Augment -> Generate)
|
|
112
|
+
npx flow-weaver create workflow ai-rag rag-pipeline.ts
|
|
113
|
+
|
|
114
|
+
# Durable agent with per-step retries (compiles to Inngest)
|
|
115
|
+
npx flow-weaver create workflow ai-agent-durable durable-agent.ts
|
|
154
116
|
```
|
|
155
117
|
|
|
156
|
-
|
|
118
|
+
**12 workflow templates** cover common patterns:
|
|
157
119
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
120
|
+
| Template | What it builds |
|
|
121
|
+
|----------|---------------|
|
|
122
|
+
| `ai-agent` | Tool-calling agent with explicit loop and termination semantics |
|
|
123
|
+
| `ai-react` | ReAct agent (Thought -> Action -> Observation) |
|
|
124
|
+
| `ai-rag` | Retrieval-Augmented Generation pipeline |
|
|
125
|
+
| `ai-chat` | Stateful conversational AI with memory |
|
|
126
|
+
| `ai-agent-durable` | Durable agent pipeline with Inngest step-level retries |
|
|
127
|
+
| `ai-pipeline-durable` | Multi-step AI pipeline with durability |
|
|
128
|
+
| `sequential` | Linear data pipeline |
|
|
129
|
+
| `foreach` | Iteration over collections |
|
|
130
|
+
| `conditional` | Branching logic |
|
|
131
|
+
| `aggregator` | Multi-source aggregation |
|
|
132
|
+
| `webhook` | HTTP event handler |
|
|
133
|
+
| `error-handler` | Error recovery pattern |
|
|
170
134
|
|
|
171
|
-
|
|
135
|
+
**12 node templates** for common node types: `llm-call`, `tool-executor`, `conversation-memory`, `prompt-template`, `json-extractor`, `human-approval`, `agent-router`, `rag-retriever`, `validator`, `transformer`, `http`, `aggregator`.
|
|
172
136
|
|
|
173
|
-
|
|
174
|
-
flow-weaver pattern list <path> # List patterns in file
|
|
175
|
-
flow-weaver pattern apply <pat> <tgt> # Apply pattern to workflow
|
|
176
|
-
flow-weaver pattern extract <source> # Extract pattern from nodes
|
|
177
|
-
flow-weaver migrate <glob> # Migrate to current syntax
|
|
178
|
-
--dry-run # Preview changes
|
|
179
|
-
--diff # Show changes
|
|
180
|
-
flow-weaver changelog # Generate changelog from git
|
|
181
|
-
```
|
|
137
|
+
## Agent-Aware Validation
|
|
182
138
|
|
|
183
|
-
|
|
139
|
+
The validator understands AI agent patterns and enforces safety rules:
|
|
184
140
|
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
flow-weaver ui open-workflow <path> # Open workflow file
|
|
192
|
-
flow-weaver ui get-state # Get editor state
|
|
193
|
-
flow-weaver ui batch <json> # Batch editor commands
|
|
141
|
+
```
|
|
142
|
+
AGENT_LLM_MISSING_ERROR_HANDLER LLM node's onFailure is unconnected — add error handling
|
|
143
|
+
AGENT_UNGUARDED_TOOL_EXECUTOR Tool executor has no human-approval upstream — add a gate
|
|
144
|
+
AGENT_MISSING_MEMORY_IN_LOOP Agent loop has LLM but no memory — conversations will be stateless
|
|
145
|
+
AGENT_LLM_NO_FALLBACK LLM failure goes directly to Exit — add retry or fallback logic
|
|
146
|
+
AGENT_TOOL_NO_OUTPUT_HANDLING Tool executor outputs are all unconnected — results are discarded
|
|
194
147
|
```
|
|
195
148
|
|
|
196
|
-
|
|
149
|
+
Not generic lint rules. The validator identifies LLM, tool-executor, human-approval, and memory nodes by port signatures, annotations, and naming patterns, then applies agent-specific checks.
|
|
197
150
|
|
|
198
|
-
|
|
151
|
+
## Deterministic Agent Testing
|
|
199
152
|
|
|
200
|
-
|
|
201
|
-
function nodeName(
|
|
202
|
-
execute: boolean, // Control input
|
|
203
|
-
...inputs // Data inputs
|
|
204
|
-
): {
|
|
205
|
-
onSuccess: boolean; // Success control output
|
|
206
|
-
onFailure: boolean; // Failure control output
|
|
207
|
-
...outputs // Data outputs
|
|
208
|
-
}
|
|
209
|
-
```
|
|
153
|
+
Test LLM workflows without real API calls:
|
|
210
154
|
|
|
211
|
-
|
|
155
|
+
```typescript
|
|
156
|
+
import { createMockLlmProvider, createRecordingProvider, loadRecording } from '@synergenius/flow-weaver/testing';
|
|
212
157
|
|
|
213
|
-
|
|
158
|
+
// Mock: deterministic responses for CI
|
|
159
|
+
const mock = createMockLlmProvider([
|
|
160
|
+
{ content: 'I need to search for that.', toolCalls: [{ name: 'search', args: { q: 'test' } }] },
|
|
161
|
+
{ content: 'Based on the results, the answer is 42.' },
|
|
162
|
+
]);
|
|
214
163
|
|
|
215
|
-
|
|
164
|
+
// Record: capture real LLM calls, replay later
|
|
165
|
+
const recorder = createRecordingProvider(realProvider);
|
|
166
|
+
// ... run workflow ...
|
|
167
|
+
saveRecording(recorder.getRecording(), 'fixtures/agent-session.json');
|
|
216
168
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
* @flowWeaver nodeType
|
|
220
|
-
* @input value
|
|
221
|
-
* @output result
|
|
222
|
-
* @label Double
|
|
223
|
-
* @pullExecution execute
|
|
224
|
-
*/
|
|
169
|
+
// Replay: reproducible tests from recorded sessions
|
|
170
|
+
const replay = loadRecording('fixtures/agent-session.json');
|
|
225
171
|
```
|
|
226
172
|
|
|
227
|
-
|
|
173
|
+
Mock human approvals, fast-forward delays, and simulate external events. Configured via `globalThis.__fw_mock_config__`.
|
|
174
|
+
|
|
175
|
+
## Scoped Ports: Agent Loops Without Cycles
|
|
176
|
+
|
|
177
|
+
Most workflow engines either ban loops (DAG-only) or allow arbitrary cycles (hard to reason about). Flow Weaver uses **scoped ports** to express iteration without graph cycles:
|
|
228
178
|
|
|
229
179
|
```typescript
|
|
230
180
|
/**
|
|
231
181
|
* @flowWeaver workflow
|
|
232
|
-
* @node
|
|
233
|
-
* @
|
|
234
|
-
* @
|
|
235
|
-
* @
|
|
236
|
-
* @
|
|
182
|
+
* @node agent llmCall
|
|
183
|
+
* @node tools toolExecutor
|
|
184
|
+
* @node memory conversationMemory
|
|
185
|
+
* @scope agent, tools, memory // these nodes iterate together
|
|
186
|
+
* @connect agent.toolCalls -> tools.calls
|
|
187
|
+
* @connect tools.results -> memory.input
|
|
188
|
+
* @connect memory.history -> agent.context
|
|
237
189
|
*/
|
|
238
190
|
```
|
|
239
191
|
|
|
240
|
-
|
|
192
|
+
The scope's output ports become callback parameters, and input ports become return values. This enables:
|
|
193
|
+
- Agent reasoning loops (LLM -> tools -> memory -> LLM)
|
|
194
|
+
- ForEach over collections
|
|
195
|
+
- Map/reduce patterns
|
|
196
|
+
- Nested sub-workflows
|
|
241
197
|
|
|
242
|
-
|
|
198
|
+
All while keeping the graph acyclic and statically analyzable.
|
|
199
|
+
|
|
200
|
+
## Multi-Target Compilation
|
|
201
|
+
|
|
202
|
+
Same workflow source, multiple deployment targets:
|
|
243
203
|
|
|
244
204
|
```bash
|
|
245
|
-
|
|
205
|
+
# Plain TypeScript (default)
|
|
206
|
+
flow-weaver compile workflow.ts
|
|
207
|
+
|
|
208
|
+
# Inngest durable functions (per-node step.run, retries, cron)
|
|
209
|
+
flow-weaver compile workflow.ts --target inngest --retries 3 --cron "0 9 * * *"
|
|
210
|
+
|
|
211
|
+
# Serverless exports
|
|
212
|
+
flow-weaver export workflow.ts --target lambda --output deploy/
|
|
213
|
+
flow-weaver export workflow.ts --target vercel --output deploy/
|
|
214
|
+
flow-weaver export workflow.ts --target cloudflare --output deploy/
|
|
215
|
+
|
|
216
|
+
# HTTP server with OpenAPI docs
|
|
217
|
+
flow-weaver serve ./workflows --port 3000 --swagger
|
|
246
218
|
```
|
|
247
219
|
|
|
248
|
-
|
|
220
|
+
Inngest compilation wraps each node in `step.run()` for individual durability, parallelizes independent nodes with `Promise.all()`, and generates typed Zod event schemas.
|
|
221
|
+
|
|
222
|
+
## Visual Human-in-the-Loop
|
|
249
223
|
|
|
250
|
-
|
|
224
|
+
Workflows compile from code, but humans review them visually:
|
|
251
225
|
|
|
252
226
|
```bash
|
|
253
|
-
#
|
|
254
|
-
flow-weaver
|
|
227
|
+
# Generate SVG diagram
|
|
228
|
+
flow-weaver diagram workflow.ts -o workflow.svg --theme dark
|
|
255
229
|
|
|
256
|
-
#
|
|
257
|
-
flow-weaver
|
|
230
|
+
# Describe structure for quick review
|
|
231
|
+
flow-weaver describe workflow.ts --format text
|
|
258
232
|
|
|
259
|
-
#
|
|
260
|
-
flow-weaver
|
|
233
|
+
# Semantic diff between versions
|
|
234
|
+
flow-weaver diff workflow-v1.ts workflow-v2.ts
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Flow Weaver Studio is a visual editor with bidirectional sync: code changes update the canvas, canvas changes update the code. 80+ plugins handle rendering, state, minimap, undo/redo, and more.
|
|
238
|
+
|
|
239
|
+
## API
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import {
|
|
243
|
+
parseWorkflow, // Parse workflow file to AST
|
|
244
|
+
compileWorkflow, // Parse + validate + generate in one step
|
|
245
|
+
validateWorkflow, // Validate AST (returns errors and warnings)
|
|
246
|
+
generateCode, // Generate code from AST
|
|
247
|
+
generateInPlace, // Regenerate only the compiled markers in-place
|
|
248
|
+
} from '@synergenius/flow-weaver';
|
|
261
249
|
|
|
262
|
-
|
|
263
|
-
|
|
250
|
+
// Full compilation
|
|
251
|
+
const { code, ast, errors } = await compileWorkflow('workflow.ts');
|
|
252
|
+
|
|
253
|
+
// Step by step
|
|
254
|
+
const { ast } = await parseWorkflow('workflow.ts');
|
|
255
|
+
const { errors, warnings } = validateWorkflow(ast);
|
|
256
|
+
const code = generateCode(ast);
|
|
264
257
|
```
|
|
265
258
|
|
|
266
|
-
|
|
259
|
+
### Package Exports
|
|
267
260
|
|
|
268
|
-
|
|
261
|
+
| Import Path | Purpose |
|
|
262
|
+
|-------------|---------|
|
|
263
|
+
| `@synergenius/flow-weaver` | Parse, validate, compile, generate, AST types, builders, diff, patterns |
|
|
264
|
+
| `@synergenius/flow-weaver/runtime` | Execution context, errors, function registry for generated code |
|
|
265
|
+
| `@synergenius/flow-weaver/built-in-nodes` | delay, waitForEvent, invokeWorkflow |
|
|
266
|
+
| `@synergenius/flow-weaver/diagram` | SVG diagram layout and rendering |
|
|
267
|
+
| `@synergenius/flow-weaver/describe` | Programmatic workflow description |
|
|
268
|
+
| `@synergenius/flow-weaver/doc-metadata` | Documentation metadata extractors |
|
|
269
|
+
|
|
270
|
+
## CLI Reference
|
|
269
271
|
|
|
270
272
|
```bash
|
|
271
|
-
|
|
273
|
+
# Core
|
|
274
|
+
flow-weaver compile <file> # Compile to TypeScript or Inngest
|
|
275
|
+
flow-weaver validate <file> # Validate without compiling
|
|
276
|
+
flow-weaver run <file> # Execute a workflow
|
|
277
|
+
flow-weaver dev <file> # Watch + compile + run
|
|
278
|
+
flow-weaver describe <file> # Structure output (json/text/mermaid)
|
|
279
|
+
flow-weaver diagram <file> # Generate SVG diagram
|
|
280
|
+
flow-weaver diff <f1> <f2> # Semantic workflow comparison
|
|
281
|
+
|
|
282
|
+
# Setup
|
|
283
|
+
flow-weaver init [directory] # Create new project
|
|
284
|
+
flow-weaver create workflow <t> <f> # Scaffold from template
|
|
285
|
+
flow-weaver create node <name> <f> # Scaffold node type
|
|
286
|
+
flow-weaver templates # List available templates
|
|
287
|
+
flow-weaver doctor # Check project compatibility
|
|
288
|
+
flow-weaver grammar # Output annotation grammar (EBNF/railroad)
|
|
289
|
+
|
|
290
|
+
# Deploy
|
|
291
|
+
flow-weaver serve [directory] # HTTP server with Swagger UI
|
|
292
|
+
flow-weaver export <file> # Export to Lambda/Vercel/Cloudflare/Inngest
|
|
293
|
+
flow-weaver openapi <directory> # Generate OpenAPI spec
|
|
294
|
+
|
|
295
|
+
# Patterns
|
|
296
|
+
flow-weaver pattern list <path> # List reusable patterns
|
|
297
|
+
flow-weaver pattern apply <p> <t> # Apply pattern to workflow
|
|
298
|
+
flow-weaver pattern extract <src> # Extract pattern from nodes
|
|
299
|
+
|
|
300
|
+
# Docs
|
|
301
|
+
flow-weaver docs # List documentation topics
|
|
302
|
+
flow-weaver docs read <topic> # Read a topic
|
|
303
|
+
flow-weaver docs search <query> # Search documentation
|
|
304
|
+
|
|
305
|
+
# Marketplace
|
|
306
|
+
flow-weaver market search [query] # Search npm for packages
|
|
307
|
+
flow-weaver market install <pkg> # Install a package
|
|
308
|
+
flow-weaver market list # List installed packages
|
|
309
|
+
|
|
310
|
+
# IDE
|
|
311
|
+
flow-weaver mcp-server # Start MCP server for Claude Code
|
|
312
|
+
flow-weaver listen # Stream editor events
|
|
272
313
|
```
|
|
273
314
|
|
|
274
|
-
|
|
275
|
-
- **Editor** (13): check events, get state, focus/add/remove nodes, connect, batch, execute, undo/redo
|
|
276
|
-
- **Query** (6): describe, validate, compile, diff, query (10 query types), doctor
|
|
277
|
-
- **Template** (2): list templates, scaffold
|
|
278
|
-
- **Pattern** (7): list/apply/extract patterns, find workflows, modify, modify batch, migrate
|
|
279
|
-
- **Export** (1): export to serverless targets
|
|
315
|
+
## Built-in Nodes
|
|
280
316
|
|
|
281
|
-
|
|
317
|
+
| Node | Purpose |
|
|
318
|
+
|------|---------|
|
|
319
|
+
| `delay` | Sleep for a duration (ms, s, m, h, d). Mockable for fast testing. |
|
|
320
|
+
| `waitForEvent` | Wait for an external event with optional field matching and timeout. Maps to Inngest `step.waitForEvent()` for zero-cost durable pauses. |
|
|
321
|
+
| `invokeWorkflow` | Invoke another workflow by ID with payload and timeout. Maps to Inngest `step.invoke()`. |
|
|
282
322
|
|
|
283
|
-
|
|
323
|
+
## STEP Port Architecture
|
|
284
324
|
|
|
285
|
-
|
|
286
|
-
|
|
325
|
+
Every node follows a consistent contract:
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
function nodeName(
|
|
329
|
+
execute: boolean, // Control: should this node run?
|
|
330
|
+
...inputs // Data inputs (typed)
|
|
331
|
+
): {
|
|
332
|
+
onSuccess: boolean; // Success control output
|
|
333
|
+
onFailure: boolean; // Failure control output
|
|
334
|
+
...outputs // Data outputs (typed)
|
|
335
|
+
}
|
|
287
336
|
```
|
|
288
337
|
|
|
289
|
-
|
|
338
|
+
Expression nodes (`@expression`) skip the control flow boilerplate. Inputs and outputs map directly to the TypeScript signature.
|
|
339
|
+
|
|
340
|
+
## Marketplace
|
|
341
|
+
|
|
342
|
+
Distribute node types, workflows, and patterns as npm packages:
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
flow-weaver market init my-nodes # Scaffold a package
|
|
346
|
+
flow-weaver market pack # Validate and generate manifest
|
|
347
|
+
flow-weaver market publish # Publish to npm
|
|
348
|
+
flow-weaver market install flowweaver-pack-openai # Install
|
|
349
|
+
```
|
|
290
350
|
|
|
291
351
|
## Testing
|
|
292
352
|
|
|
@@ -299,7 +359,7 @@ npm run test:watch # Watch mode
|
|
|
299
359
|
|
|
300
360
|
```bash
|
|
301
361
|
npm run build # Build
|
|
302
|
-
npm run
|
|
362
|
+
npm run watch # Watch mode
|
|
303
363
|
npm run typecheck # Type check
|
|
304
364
|
npm run docs # Generate API docs
|
|
305
365
|
```
|
|
@@ -308,8 +368,8 @@ npm run docs # Generate API docs
|
|
|
308
368
|
|
|
309
369
|
Custom license based on the Elastic License 2.0. See [LICENSE](./LICENSE) for full terms.
|
|
310
370
|
|
|
311
|
-
- **Free to use
|
|
371
|
+
- **Free to use**: install, run, and compile workflows in any organization
|
|
312
372
|
- **Free to host internally** for organizations with 15 or fewer people
|
|
313
|
-
- **Commercial license required** to host internally for
|
|
314
|
-
- **External hosting prohibited**
|
|
315
|
-
- **Output is unrestricted
|
|
373
|
+
- **Commercial license required** to host internally for 16+ people (contact support@synergenius.pt)
|
|
374
|
+
- **External hosting prohibited** without a commercial license
|
|
375
|
+
- **Output is unrestricted**: compiled workflows, generated code, and deployment artifacts are yours
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface DocsCommandOptions {
|
|
2
|
+
compact?: boolean;
|
|
3
|
+
json?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export interface DocsSearchOptions {
|
|
6
|
+
json?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function docsListCommand(options: DocsCommandOptions): Promise<void>;
|
|
9
|
+
export declare function docsReadCommand(topic: string, options: DocsCommandOptions): Promise<void>;
|
|
10
|
+
export declare function docsSearchCommand(query: string, options: DocsSearchOptions): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=docs.d.ts.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { listTopics, readTopic, readTopicStructured, searchDocs } from '../../docs/index.js';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
export async function docsListCommand(options) {
|
|
4
|
+
const topics = listTopics();
|
|
5
|
+
if (topics.length === 0) {
|
|
6
|
+
logger.error('No documentation topics found.');
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
if (options.json) {
|
|
10
|
+
process.stdout.write(JSON.stringify({ topics }, null, 2) + '\n');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
logger.section('Flow Weaver Documentation');
|
|
14
|
+
logger.newline();
|
|
15
|
+
const maxSlug = Math.max(...topics.map((t) => t.slug.length));
|
|
16
|
+
for (const topic of topics) {
|
|
17
|
+
logger.log(` ${topic.slug.padEnd(maxSlug + 2)} ${topic.description}`);
|
|
18
|
+
}
|
|
19
|
+
logger.newline();
|
|
20
|
+
logger.log(' Usage: flow-weaver docs <topic>');
|
|
21
|
+
logger.log(' Search: flow-weaver docs search <query>');
|
|
22
|
+
logger.newline();
|
|
23
|
+
}
|
|
24
|
+
export async function docsReadCommand(topic, options) {
|
|
25
|
+
if (options.json) {
|
|
26
|
+
const structured = readTopicStructured(topic);
|
|
27
|
+
if (!structured) {
|
|
28
|
+
logger.error(`Unknown topic: "${topic}". Run "flow-weaver docs" to see available topics.`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
process.stdout.write(JSON.stringify(structured, null, 2) + '\n');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const doc = readTopic(topic, options.compact);
|
|
35
|
+
if (!doc) {
|
|
36
|
+
logger.error(`Unknown topic: "${topic}". Run "flow-weaver docs" to see available topics.`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
process.stdout.write(doc.content + '\n');
|
|
40
|
+
}
|
|
41
|
+
export async function docsSearchCommand(query, options) {
|
|
42
|
+
const results = searchDocs(query);
|
|
43
|
+
if (options.json) {
|
|
44
|
+
process.stdout.write(JSON.stringify({ query, results }, null, 2) + '\n');
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (results.length === 0) {
|
|
48
|
+
logger.log(`No results found for "${query}".`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
logger.section(`Search results for "${query}"`);
|
|
52
|
+
logger.newline();
|
|
53
|
+
// Deduplicate by topic+heading, show top results
|
|
54
|
+
const seen = new Set();
|
|
55
|
+
let shown = 0;
|
|
56
|
+
for (const result of results) {
|
|
57
|
+
const key = `${result.slug}:${result.heading}`;
|
|
58
|
+
if (seen.has(key))
|
|
59
|
+
continue;
|
|
60
|
+
seen.add(key);
|
|
61
|
+
logger.log(` [${result.slug}] ${result.heading}`);
|
|
62
|
+
if (result.excerpt) {
|
|
63
|
+
const excerptLines = result.excerpt.split('\n').slice(0, 2);
|
|
64
|
+
for (const line of excerptLines) {
|
|
65
|
+
logger.log(` ${line}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
logger.newline();
|
|
69
|
+
shown++;
|
|
70
|
+
if (shown >= 15)
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
logger.log(` ${results.length} matching section(s) across ${new Set(results.map((r) => r.slug)).size} topic(s).`);
|
|
74
|
+
logger.log(' Read a topic: flow-weaver docs <topic>');
|
|
75
|
+
logger.newline();
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=docs.js.map
|