@synergenius/flow-weaver 0.2.1 → 0.4.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 +261 -200
- package/dist/annotation-generator.js +36 -0
- package/dist/api/generate-in-place.js +39 -0
- package/dist/api/generate.js +11 -1
- package/dist/api/manipulation/nodes.js +22 -0
- package/dist/ast/types.d.ts +27 -1
- package/dist/built-in-nodes/index.d.ts +1 -0
- package/dist/built-in-nodes/index.js +1 -0
- package/dist/built-in-nodes/invoke-workflow.js +12 -1
- package/dist/built-in-nodes/mock-types.d.ts +2 -0
- package/dist/built-in-nodes/wait-for-agent.d.ts +13 -0
- package/dist/built-in-nodes/wait-for-agent.js +26 -0
- package/dist/chevrotain-parser/fan-parser.d.ts +38 -0
- package/dist/chevrotain-parser/fan-parser.js +149 -0
- package/dist/chevrotain-parser/grammar-diagrams.d.ts +1 -0
- package/dist/chevrotain-parser/grammar-diagrams.js +3 -0
- package/dist/chevrotain-parser/index.d.ts +3 -1
- package/dist/chevrotain-parser/index.js +3 -1
- package/dist/chevrotain-parser/tokens.d.ts +2 -0
- package/dist/chevrotain-parser/tokens.js +10 -0
- package/dist/cli/commands/diagram.d.ts +2 -1
- package/dist/cli/commands/diagram.js +9 -6
- package/dist/cli/commands/docs.d.ts +11 -0
- package/dist/cli/commands/docs.js +77 -0
- package/dist/cli/commands/run.js +59 -1
- package/dist/cli/flow-weaver.mjs +2447 -594
- package/dist/cli/index.js +40 -2
- package/dist/diagram/geometry.d.ts +9 -4
- package/dist/diagram/geometry.js +262 -31
- package/dist/diagram/html-viewer.d.ts +12 -0
- package/dist/diagram/html-viewer.js +399 -0
- package/dist/diagram/index.d.ts +12 -0
- package/dist/diagram/index.js +22 -0
- package/dist/diagram/renderer.js +137 -116
- package/dist/diagram/types.d.ts +1 -0
- package/dist/doc-metadata/extractors/annotations.js +282 -1
- package/dist/doc-metadata/types.d.ts +6 -0
- package/dist/docs/index.d.ts +54 -0
- package/dist/docs/index.js +256 -0
- package/dist/generator/control-flow.d.ts +13 -0
- package/dist/generator/control-flow.js +74 -0
- package/dist/generator/inngest.js +23 -0
- package/dist/generator/unified.js +122 -2
- package/dist/jsdoc-parser.d.ts +24 -0
- package/dist/jsdoc-parser.js +41 -1
- package/dist/mcp/agent-channel.d.ts +35 -0
- package/dist/mcp/agent-channel.js +61 -0
- package/dist/mcp/run-registry.d.ts +29 -0
- package/dist/mcp/run-registry.js +24 -0
- package/dist/mcp/server.js +2 -0
- package/dist/mcp/tools-diagram.d.ts +1 -1
- package/dist/mcp/tools-diagram.js +15 -7
- package/dist/mcp/tools-docs.d.ts +3 -0
- package/dist/mcp/tools-docs.js +62 -0
- package/dist/mcp/tools-editor.js +77 -3
- package/dist/mcp/tools-query.js +3 -1
- package/dist/mcp/workflow-executor.d.ts +28 -0
- package/dist/mcp/workflow-executor.js +66 -3
- package/dist/parser.d.ts +8 -0
- package/dist/parser.js +100 -0
- package/dist/runtime/ExecutionContext.d.ts +2 -0
- package/dist/runtime/ExecutionContext.js +2 -0
- package/dist/runtime/events.d.ts +1 -1
- package/dist/sugar-optimizer.js +28 -3
- package/dist/validator.d.ts +8 -0
- package/dist/validator.js +92 -0
- package/docs/reference/advanced-annotations.md +431 -0
- package/docs/reference/built-in-nodes.md +225 -0
- package/docs/reference/cli-reference.md +882 -0
- package/docs/reference/compilation.md +351 -0
- package/docs/reference/concepts.md +400 -0
- package/docs/reference/debugging.md +255 -0
- package/docs/reference/deployment.md +207 -0
- package/docs/reference/error-codes.md +686 -0
- package/docs/reference/export-interface.md +229 -0
- package/docs/reference/iterative-development.md +186 -0
- package/docs/reference/jsdoc-grammar.md +471 -0
- package/docs/reference/marketplace.md +205 -0
- package/docs/reference/node-conversion.md +308 -0
- package/docs/reference/patterns.md +161 -0
- package/docs/reference/scaffold.md +160 -0
- package/docs/reference/tutorial.md +519 -0
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -1,292 +1,353 @@
|
|
|
1
1
|
# @synergenius/flow-weaver
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@synergenius/flow-weaver)
|
|
3
4
|
[](./LICENSE)
|
|
4
5
|
[](https://nodejs.org)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
**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
8
|
|
|
8
|
-
|
|
9
|
+
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
10
|
|
|
10
|
-
##
|
|
11
|
+
## Why Flow Weaver?
|
|
11
12
|
|
|
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)
|
|
13
|
+
**Agents generate code well. They don't generate reliable systems.**
|
|
25
14
|
|
|
26
|
-
|
|
15
|
+
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.
|
|
16
|
+
|
|
17
|
+
The development loop (steps 1-4 are fully autonomous):
|
|
18
|
+
|
|
19
|
+
1. **Agent creates**: scaffolds from templates or builds from scratch via 35+ MCP tools
|
|
20
|
+
2. **Compiler validates**: 15+ validation passes catch missing connections, type mismatches, unreachable paths
|
|
21
|
+
3. **Agent iterates**: validation errors include fix suggestions, the agent corrects and re-validates until clean
|
|
22
|
+
4. **Agent tests**: deterministic mock providers for reproducible testing without real API calls
|
|
23
|
+
5. **Human reviews**: visual editor renders the workflow as an interactive graph for final approval
|
|
24
|
+
|
|
25
|
+
The compiled code is yours. No runtime lock-in, no framework dependency.
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
### Install
|
|
27
30
|
|
|
28
31
|
```bash
|
|
29
32
|
npm install @synergenius/flow-weaver
|
|
30
33
|
```
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
### Define a workflow
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
Workflows are plain TypeScript. Annotations declare the graph structure:
|
|
35
38
|
|
|
36
39
|
```typescript
|
|
37
|
-
//
|
|
40
|
+
// data-pipeline.ts
|
|
38
41
|
|
|
39
42
|
/**
|
|
40
43
|
* @flowWeaver nodeType
|
|
41
|
-
* @input
|
|
42
|
-
* @
|
|
43
|
-
* @output
|
|
44
|
+
* @input rawData - string
|
|
45
|
+
* @output cleaned - string
|
|
46
|
+
* @output wordCount - number
|
|
44
47
|
*/
|
|
45
|
-
function
|
|
46
|
-
if (!execute) return { onSuccess: false, onFailure: false,
|
|
47
|
-
|
|
48
|
+
function processText(execute: boolean, rawData: string) {
|
|
49
|
+
if (!execute) return { onSuccess: false, onFailure: false, cleaned: '', wordCount: 0 };
|
|
50
|
+
const cleaned = rawData.trim().toLowerCase();
|
|
51
|
+
return { onSuccess: true, onFailure: false, cleaned, wordCount: cleaned.split(/\s+/).length };
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
/**
|
|
51
55
|
* @flowWeaver workflow
|
|
52
|
-
* @node
|
|
53
|
-
* @connect Start.
|
|
54
|
-
* @connect
|
|
55
|
-
* @connect
|
|
56
|
+
* @node processor processText
|
|
57
|
+
* @connect Start.rawData -> processor.rawData
|
|
58
|
+
* @connect processor.cleaned -> Exit.cleaned
|
|
59
|
+
* @connect processor.wordCount -> Exit.wordCount
|
|
56
60
|
*/
|
|
57
|
-
export async function
|
|
61
|
+
export async function dataPipeline(
|
|
58
62
|
execute: boolean,
|
|
59
|
-
params: {
|
|
60
|
-
): Promise<{ onSuccess: boolean; onFailure: boolean;
|
|
61
|
-
throw new Error('Not
|
|
63
|
+
params: { rawData: string }
|
|
64
|
+
): Promise<{ onSuccess: boolean; onFailure: boolean; cleaned: string; wordCount: number }> {
|
|
65
|
+
throw new Error('Not compiled');
|
|
62
66
|
}
|
|
63
67
|
```
|
|
64
68
|
|
|
65
|
-
Compile
|
|
69
|
+
### Compile and run
|
|
66
70
|
|
|
67
71
|
```bash
|
|
68
|
-
npx flow-weaver compile
|
|
72
|
+
npx flow-weaver compile data-pipeline.ts # generates executable code in-place
|
|
73
|
+
npx flow-weaver run data-pipeline.ts --params '{"rawData": "Hello World"}'
|
|
69
74
|
```
|
|
70
75
|
|
|
71
|
-
|
|
76
|
+
The compiler fills in the function body while preserving your code outside the generated markers.
|
|
72
77
|
|
|
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';
|
|
78
|
+
## AI-Native Development with MCP
|
|
80
79
|
|
|
81
|
-
|
|
82
|
-
const { code } = await compileWorkflow('workflow.ts');
|
|
80
|
+
Flow Weaver includes an MCP server with 35+ tools for Claude Code (or any MCP-compatible agent):
|
|
83
81
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const code = generateCode(ast);
|
|
82
|
+
```bash
|
|
83
|
+
npx flow-weaver mcp-server # auto-registers with Claude Code
|
|
87
84
|
```
|
|
88
85
|
|
|
89
|
-
|
|
86
|
+
What an AI agent can do:
|
|
90
87
|
|
|
91
|
-
|
|
88
|
+
| Capability | MCP Tools |
|
|
89
|
+
|-----------|-----------|
|
|
90
|
+
| **Build** | `fw_scaffold`, `fw_modify`, `fw_modify_batch`, `fw_add_node`, `fw_connect` |
|
|
91
|
+
| **Validate** | `fw_validate` (with friendly error hints), `fw_doctor` |
|
|
92
|
+
| **Understand** | `fw_describe` (json/text/mermaid), `fw_query` (10 query types), `fw_diff` |
|
|
93
|
+
| **Test** | `fw_execute_workflow` (with trace), `fw_compile` |
|
|
94
|
+
| **Visualize** | `fw_diagram` (SVG), `fw_get_state`, `fw_focus_node` |
|
|
95
|
+
| **Deploy** | `fw_export` (Lambda, Vercel, Cloudflare, Inngest), `fw_compile --target inngest` |
|
|
96
|
+
| **Reuse** | `fw_list_patterns`, `fw_apply_pattern`, `fw_extract_pattern` |
|
|
97
|
+
| **Extend** | `fw_market_search`, `fw_market_install` |
|
|
92
98
|
|
|
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) |
|
|
99
|
+
The agent reads validation errors, fixes issues, and re-validates until the workflow compiles clean.
|
|
100
100
|
|
|
101
|
-
##
|
|
101
|
+
## Agent Workflow Templates
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
Built-in templates for AI agent workflows (LLM reasoning, tool calling, looping):
|
|
104
104
|
|
|
105
105
|
```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
|
-
```
|
|
106
|
+
# Scaffold a tool-calling agent with memory and error handling
|
|
107
|
+
npx flow-weaver create workflow ai-agent my-agent.ts --provider openai --model gpt-4o
|
|
142
108
|
|
|
143
|
-
|
|
109
|
+
# ReAct pattern (Thought -> Action -> Observation loop)
|
|
110
|
+
npx flow-weaver create workflow ai-react react-agent.ts
|
|
144
111
|
|
|
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)
|
|
112
|
+
# RAG pipeline (Retrieve -> Augment -> Generate)
|
|
113
|
+
npx flow-weaver create workflow ai-rag rag-pipeline.ts
|
|
114
|
+
|
|
115
|
+
# Durable agent with per-step retries (compiles to Inngest)
|
|
116
|
+
npx flow-weaver create workflow ai-agent-durable durable-agent.ts
|
|
154
117
|
```
|
|
155
118
|
|
|
156
|
-
|
|
119
|
+
**12 workflow templates** cover common patterns:
|
|
157
120
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
121
|
+
| Template | What it builds |
|
|
122
|
+
|----------|---------------|
|
|
123
|
+
| `ai-agent` | Tool-calling agent with explicit loop and termination semantics |
|
|
124
|
+
| `ai-react` | ReAct agent (Thought -> Action -> Observation) |
|
|
125
|
+
| `ai-rag` | Retrieval-Augmented Generation pipeline |
|
|
126
|
+
| `ai-chat` | Stateful conversational AI with memory |
|
|
127
|
+
| `ai-agent-durable` | Durable agent pipeline with Inngest step-level retries |
|
|
128
|
+
| `ai-pipeline-durable` | Multi-step AI pipeline with durability |
|
|
129
|
+
| `sequential` | Linear data pipeline |
|
|
130
|
+
| `foreach` | Iteration over collections |
|
|
131
|
+
| `conditional` | Branching logic |
|
|
132
|
+
| `aggregator` | Multi-source aggregation |
|
|
133
|
+
| `webhook` | HTTP event handler |
|
|
134
|
+
| `error-handler` | Error recovery pattern |
|
|
170
135
|
|
|
171
|
-
|
|
136
|
+
**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
137
|
|
|
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
|
-
```
|
|
138
|
+
## Agent-Aware Validation
|
|
182
139
|
|
|
183
|
-
|
|
140
|
+
The validator understands AI agent patterns and enforces safety rules:
|
|
184
141
|
|
|
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
|
|
142
|
+
```
|
|
143
|
+
AGENT_LLM_MISSING_ERROR_HANDLER LLM node's onFailure is unconnected — add error handling
|
|
144
|
+
AGENT_UNGUARDED_TOOL_EXECUTOR Tool executor has no human-approval upstream — add a gate
|
|
145
|
+
AGENT_MISSING_MEMORY_IN_LOOP Agent loop has LLM but no memory — conversations will be stateless
|
|
146
|
+
AGENT_LLM_NO_FALLBACK LLM failure goes directly to Exit — add retry or fallback logic
|
|
147
|
+
AGENT_TOOL_NO_OUTPUT_HANDLING Tool executor outputs are all unconnected — results are discarded
|
|
194
148
|
```
|
|
195
149
|
|
|
196
|
-
|
|
150
|
+
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
151
|
|
|
198
|
-
|
|
152
|
+
## Deterministic Agent Testing
|
|
199
153
|
|
|
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
|
-
```
|
|
154
|
+
Test LLM workflows without real API calls:
|
|
210
155
|
|
|
211
|
-
|
|
156
|
+
```typescript
|
|
157
|
+
import { createMockLlmProvider, createRecordingProvider, loadRecording } from '@synergenius/flow-weaver/testing';
|
|
212
158
|
|
|
213
|
-
|
|
159
|
+
// Mock: deterministic responses for CI
|
|
160
|
+
const mock = createMockLlmProvider([
|
|
161
|
+
{ content: 'I need to search for that.', toolCalls: [{ name: 'search', args: { q: 'test' } }] },
|
|
162
|
+
{ content: 'Based on the results, the answer is 42.' },
|
|
163
|
+
]);
|
|
214
164
|
|
|
215
|
-
|
|
165
|
+
// Record: capture real LLM calls, replay later
|
|
166
|
+
const recorder = createRecordingProvider(realProvider);
|
|
167
|
+
// ... run workflow ...
|
|
168
|
+
saveRecording(recorder.getRecording(), 'fixtures/agent-session.json');
|
|
216
169
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
* @flowWeaver nodeType
|
|
220
|
-
* @input value
|
|
221
|
-
* @output result
|
|
222
|
-
* @label Double
|
|
223
|
-
* @pullExecution execute
|
|
224
|
-
*/
|
|
170
|
+
// Replay: reproducible tests from recorded sessions
|
|
171
|
+
const replay = loadRecording('fixtures/agent-session.json');
|
|
225
172
|
```
|
|
226
173
|
|
|
227
|
-
|
|
174
|
+
Mock human approvals, fast-forward delays, and simulate external events. Configured via `globalThis.__fw_mock_config__`.
|
|
175
|
+
|
|
176
|
+
## Scoped Ports: Agent Loops Without Cycles
|
|
177
|
+
|
|
178
|
+
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
179
|
|
|
229
180
|
```typescript
|
|
230
181
|
/**
|
|
231
182
|
* @flowWeaver workflow
|
|
232
|
-
* @node
|
|
233
|
-
* @
|
|
234
|
-
* @
|
|
235
|
-
* @
|
|
236
|
-
* @
|
|
183
|
+
* @node agent llmCall
|
|
184
|
+
* @node tools toolExecutor
|
|
185
|
+
* @node memory conversationMemory
|
|
186
|
+
* @scope agent, tools, memory // these nodes iterate together
|
|
187
|
+
* @connect agent.toolCalls -> tools.calls
|
|
188
|
+
* @connect tools.results -> memory.input
|
|
189
|
+
* @connect memory.history -> agent.context
|
|
237
190
|
*/
|
|
238
191
|
```
|
|
239
192
|
|
|
240
|
-
|
|
193
|
+
The scope's output ports become callback parameters, and input ports become return values. This enables:
|
|
194
|
+
- Agent reasoning loops (LLM -> tools -> memory -> LLM)
|
|
195
|
+
- ForEach over collections
|
|
196
|
+
- Map/reduce patterns
|
|
197
|
+
- Nested sub-workflows
|
|
241
198
|
|
|
242
|
-
|
|
199
|
+
All while keeping the graph acyclic and statically analyzable.
|
|
200
|
+
|
|
201
|
+
## Multi-Target Compilation
|
|
202
|
+
|
|
203
|
+
Same workflow source, multiple deployment targets:
|
|
243
204
|
|
|
244
205
|
```bash
|
|
245
|
-
|
|
206
|
+
# Plain TypeScript (default)
|
|
207
|
+
flow-weaver compile workflow.ts
|
|
208
|
+
|
|
209
|
+
# Inngest durable functions (per-node step.run, retries, cron)
|
|
210
|
+
flow-weaver compile workflow.ts --target inngest --retries 3 --cron "0 9 * * *"
|
|
211
|
+
|
|
212
|
+
# Serverless exports
|
|
213
|
+
flow-weaver export workflow.ts --target lambda --output deploy/
|
|
214
|
+
flow-weaver export workflow.ts --target vercel --output deploy/
|
|
215
|
+
flow-weaver export workflow.ts --target cloudflare --output deploy/
|
|
216
|
+
|
|
217
|
+
# HTTP server with OpenAPI docs
|
|
218
|
+
flow-weaver serve ./workflows --port 3000 --swagger
|
|
246
219
|
```
|
|
247
220
|
|
|
248
|
-
|
|
221
|
+
Inngest compilation wraps each node in `step.run()` for individual durability, parallelizes independent nodes with `Promise.all()`, and generates typed Zod event schemas.
|
|
222
|
+
|
|
223
|
+
## Visual Human-in-the-Loop
|
|
249
224
|
|
|
250
|
-
|
|
225
|
+
Workflows compile from code, but humans review them visually:
|
|
251
226
|
|
|
252
227
|
```bash
|
|
253
|
-
#
|
|
254
|
-
flow-weaver
|
|
228
|
+
# Generate SVG diagram
|
|
229
|
+
flow-weaver diagram workflow.ts -o workflow.svg --theme dark
|
|
255
230
|
|
|
256
|
-
#
|
|
257
|
-
flow-weaver
|
|
231
|
+
# Describe structure for quick review
|
|
232
|
+
flow-weaver describe workflow.ts --format text
|
|
258
233
|
|
|
259
|
-
#
|
|
260
|
-
flow-weaver
|
|
234
|
+
# Semantic diff between versions
|
|
235
|
+
flow-weaver diff workflow-v1.ts workflow-v2.ts
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
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.
|
|
239
|
+
|
|
240
|
+
## API
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import {
|
|
244
|
+
parseWorkflow, // Parse workflow file to AST
|
|
245
|
+
compileWorkflow, // Parse + validate + generate in one step
|
|
246
|
+
validateWorkflow, // Validate AST (returns errors and warnings)
|
|
247
|
+
generateCode, // Generate code from AST
|
|
248
|
+
generateInPlace, // Regenerate only the compiled markers in-place
|
|
249
|
+
} from '@synergenius/flow-weaver';
|
|
261
250
|
|
|
262
|
-
|
|
263
|
-
|
|
251
|
+
// Full compilation
|
|
252
|
+
const { code, ast, errors } = await compileWorkflow('workflow.ts');
|
|
253
|
+
|
|
254
|
+
// Step by step
|
|
255
|
+
const { ast } = await parseWorkflow('workflow.ts');
|
|
256
|
+
const { errors, warnings } = validateWorkflow(ast);
|
|
257
|
+
const code = generateCode(ast);
|
|
264
258
|
```
|
|
265
259
|
|
|
266
|
-
|
|
260
|
+
### Package Exports
|
|
267
261
|
|
|
268
|
-
|
|
262
|
+
| Import Path | Purpose |
|
|
263
|
+
|-------------|---------|
|
|
264
|
+
| `@synergenius/flow-weaver` | Parse, validate, compile, generate, AST types, builders, diff, patterns |
|
|
265
|
+
| `@synergenius/flow-weaver/runtime` | Execution context, errors, function registry for generated code |
|
|
266
|
+
| `@synergenius/flow-weaver/built-in-nodes` | delay, waitForEvent, invokeWorkflow |
|
|
267
|
+
| `@synergenius/flow-weaver/diagram` | SVG diagram layout and rendering |
|
|
268
|
+
| `@synergenius/flow-weaver/describe` | Programmatic workflow description |
|
|
269
|
+
| `@synergenius/flow-weaver/doc-metadata` | Documentation metadata extractors |
|
|
270
|
+
|
|
271
|
+
## CLI Reference
|
|
269
272
|
|
|
270
273
|
```bash
|
|
271
|
-
|
|
274
|
+
# Core
|
|
275
|
+
flow-weaver compile <file> # Compile to TypeScript or Inngest
|
|
276
|
+
flow-weaver validate <file> # Validate without compiling
|
|
277
|
+
flow-weaver run <file> # Execute a workflow
|
|
278
|
+
flow-weaver dev <file> # Watch + compile + run
|
|
279
|
+
flow-weaver describe <file> # Structure output (json/text/mermaid)
|
|
280
|
+
flow-weaver diagram <file> # Generate SVG diagram
|
|
281
|
+
flow-weaver diff <f1> <f2> # Semantic workflow comparison
|
|
282
|
+
|
|
283
|
+
# Setup
|
|
284
|
+
flow-weaver init [directory] # Create new project
|
|
285
|
+
flow-weaver create workflow <t> <f> # Scaffold from template
|
|
286
|
+
flow-weaver create node <name> <f> # Scaffold node type
|
|
287
|
+
flow-weaver templates # List available templates
|
|
288
|
+
flow-weaver doctor # Check project compatibility
|
|
289
|
+
flow-weaver grammar # Output annotation grammar (EBNF/railroad)
|
|
290
|
+
|
|
291
|
+
# Deploy
|
|
292
|
+
flow-weaver serve [directory] # HTTP server with Swagger UI
|
|
293
|
+
flow-weaver export <file> # Export to Lambda/Vercel/Cloudflare/Inngest
|
|
294
|
+
flow-weaver openapi <directory> # Generate OpenAPI spec
|
|
295
|
+
|
|
296
|
+
# Patterns
|
|
297
|
+
flow-weaver pattern list <path> # List reusable patterns
|
|
298
|
+
flow-weaver pattern apply <p> <t> # Apply pattern to workflow
|
|
299
|
+
flow-weaver pattern extract <src> # Extract pattern from nodes
|
|
300
|
+
|
|
301
|
+
# Docs
|
|
302
|
+
flow-weaver docs # List documentation topics
|
|
303
|
+
flow-weaver docs read <topic> # Read a topic
|
|
304
|
+
flow-weaver docs search <query> # Search documentation
|
|
305
|
+
|
|
306
|
+
# Marketplace
|
|
307
|
+
flow-weaver market search [query] # Search npm for packages
|
|
308
|
+
flow-weaver market install <pkg> # Install a package
|
|
309
|
+
flow-weaver market list # List installed packages
|
|
310
|
+
|
|
311
|
+
# IDE
|
|
312
|
+
flow-weaver mcp-server # Start MCP server for Claude Code
|
|
313
|
+
flow-weaver listen # Stream editor events
|
|
272
314
|
```
|
|
273
315
|
|
|
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
|
|
316
|
+
## Built-in Nodes
|
|
280
317
|
|
|
281
|
-
|
|
318
|
+
| Node | Purpose |
|
|
319
|
+
|------|---------|
|
|
320
|
+
| `delay` | Sleep for a duration (ms, s, m, h, d). Mockable for fast testing. |
|
|
321
|
+
| `waitForEvent` | Wait for an external event with optional field matching and timeout. Maps to Inngest `step.waitForEvent()` for zero-cost durable pauses. |
|
|
322
|
+
| `invokeWorkflow` | Invoke another workflow by ID with payload and timeout. Maps to Inngest `step.invoke()`. |
|
|
282
323
|
|
|
283
|
-
|
|
324
|
+
## STEP Port Architecture
|
|
284
325
|
|
|
285
|
-
|
|
286
|
-
|
|
326
|
+
Every node follows a consistent contract:
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
function nodeName(
|
|
330
|
+
execute: boolean, // Control: should this node run?
|
|
331
|
+
...inputs // Data inputs (typed)
|
|
332
|
+
): {
|
|
333
|
+
onSuccess: boolean; // Success control output
|
|
334
|
+
onFailure: boolean; // Failure control output
|
|
335
|
+
...outputs // Data outputs (typed)
|
|
336
|
+
}
|
|
287
337
|
```
|
|
288
338
|
|
|
289
|
-
|
|
339
|
+
Expression nodes (`@expression`) skip the control flow boilerplate. Inputs and outputs map directly to the TypeScript signature.
|
|
340
|
+
|
|
341
|
+
## Marketplace
|
|
342
|
+
|
|
343
|
+
Distribute node types, workflows, and patterns as npm packages:
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
flow-weaver market init my-nodes # Scaffold a package
|
|
347
|
+
flow-weaver market pack # Validate and generate manifest
|
|
348
|
+
flow-weaver market publish # Publish to npm
|
|
349
|
+
flow-weaver market install flowweaver-pack-openai # Install
|
|
350
|
+
```
|
|
290
351
|
|
|
291
352
|
## Testing
|
|
292
353
|
|
|
@@ -299,7 +360,7 @@ npm run test:watch # Watch mode
|
|
|
299
360
|
|
|
300
361
|
```bash
|
|
301
362
|
npm run build # Build
|
|
302
|
-
npm run
|
|
363
|
+
npm run watch # Watch mode
|
|
303
364
|
npm run typecheck # Type check
|
|
304
365
|
npm run docs # Generate API docs
|
|
305
366
|
```
|
|
@@ -308,8 +369,8 @@ npm run docs # Generate API docs
|
|
|
308
369
|
|
|
309
370
|
Custom license based on the Elastic License 2.0. See [LICENSE](./LICENSE) for full terms.
|
|
310
371
|
|
|
311
|
-
- **Free to use
|
|
372
|
+
- **Free to use**: install, run, and compile workflows in any organization
|
|
312
373
|
- **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
|
|
374
|
+
- **Commercial license required** to host internally for 16+ people (contact support@synergenius.pt)
|
|
375
|
+
- **External hosting prohibited** without a commercial license
|
|
376
|
+
- **Output is unrestricted**: compiled workflows, generated code, and deployment artifacts are yours
|
|
@@ -247,6 +247,16 @@ export class AnnotationGenerator {
|
|
|
247
247
|
const stepsStr = macro.steps.map(s => s.route ? `${s.node}:${s.route}` : s.node).join(' -> ');
|
|
248
248
|
lines.push(` * @path ${stepsStr}`);
|
|
249
249
|
}
|
|
250
|
+
else if (macro.type === 'fanOut') {
|
|
251
|
+
const src = `${macro.source.node}.${macro.source.port}`;
|
|
252
|
+
const tgts = macro.targets.map(t => t.port ? `${t.node}.${t.port}` : t.node).join(', ');
|
|
253
|
+
lines.push(` * @fanOut ${src} -> ${tgts}`);
|
|
254
|
+
}
|
|
255
|
+
else if (macro.type === 'fanIn') {
|
|
256
|
+
const srcs = macro.sources.map(s => s.port ? `${s.node}.${s.port}` : s.node).join(', ');
|
|
257
|
+
const tgt = `${macro.target.node}.${macro.target.port}`;
|
|
258
|
+
lines.push(` * @fanIn ${srcs} -> ${tgt}`);
|
|
259
|
+
}
|
|
250
260
|
}
|
|
251
261
|
}
|
|
252
262
|
// Add node positions (if they exist)
|
|
@@ -456,6 +466,32 @@ function isConnectionCoveredByMacroStatic(conn, macros) {
|
|
|
456
466
|
return true;
|
|
457
467
|
}
|
|
458
468
|
}
|
|
469
|
+
else if (macro.type === 'fanOut') {
|
|
470
|
+
if (conn.from.scope || conn.to.scope)
|
|
471
|
+
continue;
|
|
472
|
+
// Check if connection matches the fan-out pattern
|
|
473
|
+
if (conn.from.node === macro.source.node && conn.from.port === macro.source.port) {
|
|
474
|
+
for (const target of macro.targets) {
|
|
475
|
+
const targetPort = target.port ?? macro.source.port;
|
|
476
|
+
if (conn.to.node === target.node && conn.to.port === targetPort) {
|
|
477
|
+
return true;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
else if (macro.type === 'fanIn') {
|
|
483
|
+
if (conn.from.scope || conn.to.scope)
|
|
484
|
+
continue;
|
|
485
|
+
// Check if connection matches the fan-in pattern
|
|
486
|
+
if (conn.to.node === macro.target.node && conn.to.port === macro.target.port) {
|
|
487
|
+
for (const source of macro.sources) {
|
|
488
|
+
const sourcePort = source.port ?? macro.target.port;
|
|
489
|
+
if (conn.from.node === source.node && conn.from.port === sourcePort) {
|
|
490
|
+
return true;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
459
495
|
}
|
|
460
496
|
return false;
|
|
461
497
|
}
|