@synergenius/flow-weaver 0.2.0 → 0.2.1

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.
@@ -12,6 +12,8 @@ export interface GrammarCollection {
12
12
  position: ISerializedGast[];
13
13
  scope: ISerializedGast[];
14
14
  path: ISerializedGast[];
15
+ map: ISerializedGast[];
16
+ triggerCancel: ISerializedGast[];
15
17
  }
16
18
  /**
17
19
  * Get all grammar productions as serialized GAST (Grammar AST).
@@ -10,6 +10,8 @@ import { getConnectGrammar } from './connect-parser.js';
10
10
  import { getPositionGrammar } from './position-parser.js';
11
11
  import { getScopeGrammar } from './scope-parser.js';
12
12
  import { getPathGrammar } from './path-parser.js';
13
+ import { getMapGrammar } from './map-parser.js';
14
+ import { getTriggerCancelGrammar } from './trigger-cancel-parser.js';
13
15
  export function serializedToEBNF(productions) {
14
16
  const lines = [];
15
17
  for (const prod of productions) {
@@ -72,7 +74,7 @@ function itemToEBNF(item) {
72
74
  if (pattern === 'BOTTOM\\b')
73
75
  return '"BOTTOM"';
74
76
  // Identifier pattern - use semantic name if available
75
- if (pattern === '[a-zA-Z_$][a-zA-Z0-9_$]*') {
77
+ if (pattern === '[a-zA-Z_$][a-zA-Z0-9_$]*' || pattern === '[a-zA-Z_$][a-zA-Z0-9_$\\/-]*') {
76
78
  const semanticName = item.terminalLabel || 'IDENTIFIER';
77
79
  return semanticName;
78
80
  }
@@ -126,6 +128,8 @@ export function getAllGrammars() {
126
128
  position: getPositionGrammar(),
127
129
  scope: getScopeGrammar(),
128
130
  path: getPathGrammar(),
131
+ map: getMapGrammar(),
132
+ triggerCancel: getTriggerCancelGrammar(),
129
133
  };
130
134
  }
131
135
  /**
@@ -142,6 +146,8 @@ export function generateGrammarDiagrams() {
142
146
  ...grammars.position,
143
147
  ...grammars.scope,
144
148
  ...grammars.path,
149
+ ...grammars.map,
150
+ ...grammars.triggerCancel,
145
151
  ];
146
152
  // createSyntaxDiagramsCode returns a complete HTML document
147
153
  const html = createSyntaxDiagramsCode(allProductions);
@@ -46,5 +46,9 @@ export declare function parseTimeoutLine(input: string, warnings: string[]): Tim
46
46
  * Parse a @throttle line and return structured result.
47
47
  * Returns null if the line is not a throttle declaration.
48
48
  */
49
+ /**
50
+ * Get serialized grammar productions for documentation/diagrams.
51
+ */
52
+ export declare function getTriggerCancelGrammar(): import("chevrotain").ISerializedGast[];
49
53
  export declare function parseThrottleLine(input: string, warnings: string[]): ThrottleParseResult | null;
50
54
  //# sourceMappingURL=trigger-cancel-parser.d.ts.map
@@ -255,6 +255,12 @@ export function parseTimeoutLine(input, warnings) {
255
255
  * Parse a @throttle line and return structured result.
256
256
  * Returns null if the line is not a throttle declaration.
257
257
  */
258
+ /**
259
+ * Get serialized grammar productions for documentation/diagrams.
260
+ */
261
+ export function getTriggerCancelGrammar() {
262
+ return parserInstance.getSerializedGastProductions();
263
+ }
258
264
  export function parseThrottleLine(input, warnings) {
259
265
  const lexResult = JSDocLexer.tokenize(input);
260
266
  if (lexResult.errors.length > 0) {
@@ -42452,6 +42452,9 @@ function parseMapLine(input, warnings) {
42452
42452
  }
42453
42453
  return visitorInstance6.visit(cst);
42454
42454
  }
42455
+ function getMapGrammar() {
42456
+ return parserInstance6.getSerializedGastProductions();
42457
+ }
42455
42458
 
42456
42459
  // src/chevrotain-parser/path-parser.ts
42457
42460
  var PathParser = class extends CstParser {
@@ -42710,6 +42713,9 @@ function parseCancelOnLine(input, warnings) {
42710
42713
  }
42711
42714
  return visitorInstance8.visit(cst);
42712
42715
  }
42716
+ function getTriggerCancelGrammar() {
42717
+ return parserInstance8.getSerializedGastProductions();
42718
+ }
42713
42719
  function parseThrottleLine(input, warnings) {
42714
42720
  const lexResult = JSDocLexer.tokenize(input);
42715
42721
  if (lexResult.errors.length > 0) {
@@ -42784,7 +42790,7 @@ function itemToEBNF(item) {
42784
42790
  if (pattern === "minimized\\b") return '"minimized"';
42785
42791
  if (pattern === "TOP\\b") return '"TOP"';
42786
42792
  if (pattern === "BOTTOM\\b") return '"BOTTOM"';
42787
- if (pattern === "[a-zA-Z_$][a-zA-Z0-9_$]*") {
42793
+ if (pattern === "[a-zA-Z_$][a-zA-Z0-9_$]*" || pattern === "[a-zA-Z_$][a-zA-Z0-9_$\\/-]*") {
42788
42794
  const semanticName = item.terminalLabel || "IDENTIFIER";
42789
42795
  return semanticName;
42790
42796
  }
@@ -42828,7 +42834,9 @@ function getAllGrammars() {
42828
42834
  connect: getConnectGrammar(),
42829
42835
  position: getPositionGrammar(),
42830
42836
  scope: getScopeGrammar(),
42831
- path: getPathGrammar()
42837
+ path: getPathGrammar(),
42838
+ map: getMapGrammar(),
42839
+ triggerCancel: getTriggerCancelGrammar()
42832
42840
  };
42833
42841
  }
42834
42842
  function generateGrammarDiagrams() {
@@ -42839,7 +42847,9 @@ function generateGrammarDiagrams() {
42839
42847
  ...grammars.connect,
42840
42848
  ...grammars.position,
42841
42849
  ...grammars.scope,
42842
- ...grammars.path
42850
+ ...grammars.path,
42851
+ ...grammars.map,
42852
+ ...grammars.triggerCancel
42843
42853
  ];
42844
42854
  const html = createSyntaxDiagramsCode(allProductions);
42845
42855
  const ebnf = serializedToEBNF(allProductions);
@@ -51919,6 +51929,22 @@ function extractCyclePath(message) {
51919
51929
  return match2 ? match2[1] : null;
51920
51930
  }
51921
51931
  var errorMappers = {
51932
+ MISSING_WORKFLOW_NAME(error2) {
51933
+ return {
51934
+ title: "Missing Workflow Name",
51935
+ explanation: "The workflow annotation is missing or has no name. Every workflow needs a name in the @flowWeaver workflow block.",
51936
+ fix: "Add @flowWeaver workflow to the JSDoc block above your exported workflow function.",
51937
+ code: error2.code
51938
+ };
51939
+ },
51940
+ MISSING_FUNCTION_NAME(error2) {
51941
+ return {
51942
+ title: "Missing Function Name",
51943
+ explanation: "The compiler found a @flowWeaver workflow annotation but the function is anonymous or not exported.",
51944
+ fix: "Make sure your workflow is declared as `export function myWorkflowName(...)` \u2014 not anonymous or unexported.",
51945
+ code: error2.code
51946
+ };
51947
+ },
51922
51948
  MISSING_REQUIRED_INPUT(error2) {
51923
51949
  const quoted = extractQuoted(error2.message);
51924
51950
  const nodeName = quoted[0] || error2.node || "unknown";
@@ -52063,6 +52089,58 @@ var errorMappers = {
52063
52089
  code: error2.code
52064
52090
  };
52065
52091
  },
52092
+ RESERVED_INSTANCE_ID(error2) {
52093
+ const quoted = extractQuoted(error2.message);
52094
+ const instanceId = quoted[0] || error2.node || "unknown";
52095
+ return {
52096
+ title: "Reserved Instance ID",
52097
+ explanation: `Instance ID '${instanceId}' is reserved. 'Start' and 'Exit' are built-in nodes in every workflow.`,
52098
+ fix: `Choose a different instance ID, like 'startHandler' or 'exitProcessor'.`,
52099
+ code: error2.code
52100
+ };
52101
+ },
52102
+ INFERRED_NODE_TYPE(error2) {
52103
+ const quoted = extractQuoted(error2.message);
52104
+ const nodeTypeName = quoted[0] || error2.node || "unknown";
52105
+ return {
52106
+ title: "Inferred Node Type",
52107
+ explanation: `Node type '${nodeTypeName}' was auto-inferred from the function signature. It works, but you lose explicit control over port names, types, and ordering.`,
52108
+ fix: `Add /** @flowWeaver nodeType @expression */ above the function for explicit port control.`,
52109
+ code: error2.code
52110
+ };
52111
+ },
52112
+ UNDEFINED_NODE(error2) {
52113
+ const quoted = extractQuoted(error2.message);
52114
+ const nodeName = quoted[0] || error2.node || "unknown";
52115
+ return {
52116
+ title: "Undefined Node",
52117
+ explanation: `A connection references node '${nodeName}', but there's no @node annotation defining it.`,
52118
+ fix: `Add a @node annotation for '${nodeName}' in the workflow JSDoc, or remove the connections that reference it.`,
52119
+ code: error2.code
52120
+ };
52121
+ },
52122
+ TYPE_INCOMPATIBLE(error2) {
52123
+ const types2 = extractTypes(error2.message);
52124
+ const source = types2?.source || "unknown";
52125
+ const target = types2?.target || "unknown";
52126
+ return {
52127
+ title: "Type Incompatible",
52128
+ explanation: `Type mismatch: ${source} to ${target}. With @strictTypes enabled, this is an error instead of a warning.`,
52129
+ fix: `Add a conversion node between the ports, change one of the port types, or remove @strictTypes to allow implicit coercions.`,
52130
+ code: error2.code
52131
+ };
52132
+ },
52133
+ UNUSUAL_TYPE_COERCION(error2) {
52134
+ const types2 = extractTypes(error2.message);
52135
+ const source = types2?.source || "unknown";
52136
+ const target = types2?.target || "unknown";
52137
+ return {
52138
+ title: "Unusual Type Coercion",
52139
+ explanation: `Converting ${source} to ${target} is technically valid but semantically unusual and may produce unexpected behavior.`,
52140
+ fix: `Add an explicit conversion node if this is intentional, or use @strictTypes to enforce type safety.`,
52141
+ code: error2.code
52142
+ };
52143
+ },
52066
52144
  MULTIPLE_CONNECTIONS_TO_INPUT(error2) {
52067
52145
  const quoted = extractQuoted(error2.message);
52068
52146
  const portName = quoted[0] || "unknown";
@@ -92508,7 +92586,7 @@ function displayInstalledPackage(pkg) {
92508
92586
  }
92509
92587
 
92510
92588
  // src/cli/index.ts
92511
- var version2 = true ? "0.2.0" : "0.0.0-dev";
92589
+ var version2 = true ? "0.2.1" : "0.0.0-dev";
92512
92590
  var program2 = new Command();
92513
92591
  program2.name("flow-weaver").description("Flow Weaver Annotations - Compile and validate workflow files").version(version2, "-v, --version", "Output the current version");
92514
92592
  program2.configureOutput({
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Single source of truth for validation error code documentation.
3
+ *
4
+ * Every code the validator (src/validator.ts) and agent rules
5
+ * (src/validation/agent-rules.ts) can emit is listed here.
6
+ *
7
+ * The generate-docs script uses this to build the summary tables
8
+ * in docs/reference/error-codes.md.
9
+ */
10
+ export interface TValidationCodeDoc {
11
+ code: string;
12
+ severity: 'error' | 'warning';
13
+ title: string;
14
+ description: string;
15
+ category: 'structural' | 'naming' | 'connection' | 'type' | 'node-ref' | 'graph' | 'data-flow' | 'agent';
16
+ }
17
+ export declare const VALIDATION_CODES: TValidationCodeDoc[];
18
+ //# sourceMappingURL=error-codes.d.ts.map
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Single source of truth for validation error code documentation.
3
+ *
4
+ * Every code the validator (src/validator.ts) and agent rules
5
+ * (src/validation/agent-rules.ts) can emit is listed here.
6
+ *
7
+ * The generate-docs script uses this to build the summary tables
8
+ * in docs/reference/error-codes.md.
9
+ */
10
+ export const VALIDATION_CODES = [
11
+ // ── Structural ──────────────────────────────────────────────────────
12
+ {
13
+ code: 'MISSING_WORKFLOW_NAME',
14
+ severity: 'error',
15
+ title: 'Missing Workflow Name',
16
+ description: 'Workflow has no name',
17
+ category: 'structural',
18
+ },
19
+ {
20
+ code: 'MISSING_FUNCTION_NAME',
21
+ severity: 'error',
22
+ title: 'Missing Function Name',
23
+ description: 'Workflow has no function name',
24
+ category: 'structural',
25
+ },
26
+ {
27
+ code: 'DUPLICATE_NODE_NAME',
28
+ severity: 'error',
29
+ title: 'Duplicate Node Name',
30
+ description: 'Two node types share a function name',
31
+ category: 'structural',
32
+ },
33
+ {
34
+ code: 'MUTABLE_NODE_TYPE_BINDING',
35
+ severity: 'warning',
36
+ title: 'Mutable Node Binding',
37
+ description: 'Node type declared with let/var instead of const',
38
+ category: 'structural',
39
+ },
40
+ {
41
+ code: 'INFERRED_NODE_TYPE',
42
+ severity: 'warning',
43
+ title: 'Inferred Node Type',
44
+ description: 'Node type auto-inferred without explicit annotation',
45
+ category: 'structural',
46
+ },
47
+ {
48
+ code: 'ANNOTATION_SIGNATURE_MISMATCH',
49
+ severity: 'warning',
50
+ title: 'Optional Port Mismatch',
51
+ description: 'Port optionality differs between annotation and sig',
52
+ category: 'structural',
53
+ },
54
+ {
55
+ code: 'ANNOTATION_SIGNATURE_TYPE_MISMATCH',
56
+ severity: 'warning',
57
+ title: 'Annotation Type Mismatch',
58
+ description: 'Port type differs between annotation and signature',
59
+ category: 'structural',
60
+ },
61
+ // ── Naming ──────────────────────────────────────────────────────────
62
+ {
63
+ code: 'RESERVED_NODE_NAME',
64
+ severity: 'error',
65
+ title: 'Reserved Name Used',
66
+ description: 'Node type uses "Start" or "Exit"',
67
+ category: 'naming',
68
+ },
69
+ {
70
+ code: 'RESERVED_INSTANCE_ID',
71
+ severity: 'error',
72
+ title: 'Reserved Instance ID',
73
+ description: 'Instance ID is "Start" or "Exit"',
74
+ category: 'naming',
75
+ },
76
+ // ── Connection ──────────────────────────────────────────────────────
77
+ {
78
+ code: 'UNKNOWN_SOURCE_NODE',
79
+ severity: 'error',
80
+ title: 'Missing Source Node',
81
+ description: 'Connection from nonexistent node',
82
+ category: 'connection',
83
+ },
84
+ {
85
+ code: 'UNKNOWN_TARGET_NODE',
86
+ severity: 'error',
87
+ title: 'Missing Target Node',
88
+ description: 'Connection to nonexistent node',
89
+ category: 'connection',
90
+ },
91
+ {
92
+ code: 'UNKNOWN_SOURCE_PORT',
93
+ severity: 'error',
94
+ title: 'Unknown Output Port',
95
+ description: 'Connection from nonexistent output port',
96
+ category: 'connection',
97
+ },
98
+ {
99
+ code: 'UNKNOWN_TARGET_PORT',
100
+ severity: 'error',
101
+ title: 'Unknown Input Port',
102
+ description: 'Connection to nonexistent input port',
103
+ category: 'connection',
104
+ },
105
+ {
106
+ code: 'MULTIPLE_CONNECTIONS_TO_INPUT',
107
+ severity: 'error',
108
+ title: 'Multiple Input Connections',
109
+ description: 'Data input port has more than one source',
110
+ category: 'connection',
111
+ },
112
+ // ── Type ────────────────────────────────────────────────────────────
113
+ {
114
+ code: 'STEP_PORT_TYPE_MISMATCH',
115
+ severity: 'error',
116
+ title: 'Wrong Port Type',
117
+ description: 'STEP port connected to data port or vice versa',
118
+ category: 'type',
119
+ },
120
+ {
121
+ code: 'TYPE_INCOMPATIBLE',
122
+ severity: 'error',
123
+ title: 'Type Incompatible',
124
+ description: 'Type mismatch with @strictTypes enabled',
125
+ category: 'type',
126
+ },
127
+ {
128
+ code: 'OBJECT_TYPE_MISMATCH',
129
+ severity: 'warning',
130
+ title: 'Object Shape Mismatch',
131
+ description: 'OBJECT ports have different structural types',
132
+ category: 'type',
133
+ },
134
+ {
135
+ code: 'LOSSY_TYPE_COERCION',
136
+ severity: 'warning',
137
+ title: 'Lossy Type Conversion',
138
+ description: 'Type coercion may lose information',
139
+ category: 'type',
140
+ },
141
+ {
142
+ code: 'UNUSUAL_TYPE_COERCION',
143
+ severity: 'warning',
144
+ title: 'Unusual Type Coercion',
145
+ description: 'Type coercion is semantically unusual',
146
+ category: 'type',
147
+ },
148
+ {
149
+ code: 'TYPE_MISMATCH',
150
+ severity: 'warning',
151
+ title: 'Type Mismatch',
152
+ description: 'Incompatible types, runtime coercion attempted',
153
+ category: 'type',
154
+ },
155
+ // ── Node Reference ──────────────────────────────────────────────────
156
+ {
157
+ code: 'UNKNOWN_NODE_TYPE',
158
+ severity: 'error',
159
+ title: 'Unknown Node Type',
160
+ description: 'Instance references nonexistent node type',
161
+ category: 'node-ref',
162
+ },
163
+ {
164
+ code: 'UNDEFINED_NODE',
165
+ severity: 'error',
166
+ title: 'Undefined Node',
167
+ description: 'Connection references node with no instance',
168
+ category: 'node-ref',
169
+ },
170
+ {
171
+ code: 'MISSING_REQUIRED_INPUT',
172
+ severity: 'error',
173
+ title: 'Missing Required Input',
174
+ description: 'Required input has no connection/default/expression',
175
+ category: 'node-ref',
176
+ },
177
+ // ── Graph ───────────────────────────────────────────────────────────
178
+ {
179
+ code: 'CYCLE_DETECTED',
180
+ severity: 'error',
181
+ title: 'Circular Dependency Found',
182
+ description: 'Graph contains a loop',
183
+ category: 'graph',
184
+ },
185
+ {
186
+ code: 'INVALID_EXIT_PORT_TYPE',
187
+ severity: 'error',
188
+ title: 'Invalid Exit Port Type',
189
+ description: 'Exit onSuccess/onFailure is not STEP type',
190
+ category: 'graph',
191
+ },
192
+ // ── Data Flow ───────────────────────────────────────────────────────
193
+ {
194
+ code: 'UNUSED_NODE',
195
+ severity: 'warning',
196
+ title: 'Unused Node',
197
+ description: 'Node defined but not connected',
198
+ category: 'data-flow',
199
+ },
200
+ {
201
+ code: 'NO_START_CONNECTIONS',
202
+ severity: 'warning',
203
+ title: 'No Start Connections',
204
+ description: 'No connections from Start',
205
+ category: 'data-flow',
206
+ },
207
+ {
208
+ code: 'NO_EXIT_CONNECTIONS',
209
+ severity: 'warning',
210
+ title: 'No Exit Connections',
211
+ description: 'No connections to Exit',
212
+ category: 'data-flow',
213
+ },
214
+ {
215
+ code: 'UNUSED_OUTPUT_PORT',
216
+ severity: 'warning',
217
+ title: 'Unused Output Port',
218
+ description: 'Output port data is discarded',
219
+ category: 'data-flow',
220
+ },
221
+ {
222
+ code: 'UNREACHABLE_EXIT_PORT',
223
+ severity: 'warning',
224
+ title: 'Unreachable Exit Port',
225
+ description: 'Exit port has no incoming connection',
226
+ category: 'data-flow',
227
+ },
228
+ {
229
+ code: 'MULTIPLE_EXIT_CONNECTIONS',
230
+ severity: 'warning',
231
+ title: 'Multiple Exit Connections',
232
+ description: 'Exit port has multiple sources',
233
+ category: 'data-flow',
234
+ },
235
+ // ── Agent ───────────────────────────────────────────────────────────
236
+ {
237
+ code: 'AGENT_LLM_MISSING_ERROR_HANDLER',
238
+ severity: 'error',
239
+ title: 'LLM Missing Error Handler',
240
+ description: "LLM node's onFailure port is unconnected",
241
+ category: 'agent',
242
+ },
243
+ {
244
+ code: 'AGENT_UNGUARDED_TOOL_EXECUTOR',
245
+ severity: 'warning',
246
+ title: 'Unguarded Tool Executor',
247
+ description: 'Tool executor has no upstream human-approval gate',
248
+ category: 'agent',
249
+ },
250
+ {
251
+ code: 'AGENT_MISSING_MEMORY_IN_LOOP',
252
+ severity: 'warning',
253
+ title: 'No Memory in Agent Loop',
254
+ description: 'Loop has LLM but no conversation memory node',
255
+ category: 'agent',
256
+ },
257
+ {
258
+ code: 'AGENT_LLM_NO_FALLBACK',
259
+ severity: 'warning',
260
+ title: 'LLM Failure Goes to Exit',
261
+ description: 'LLM onFailure routes directly to Exit',
262
+ category: 'agent',
263
+ },
264
+ {
265
+ code: 'AGENT_TOOL_NO_OUTPUT_HANDLING',
266
+ severity: 'warning',
267
+ title: 'Tool Results Discarded',
268
+ description: 'Tool executor data outputs all unconnected',
269
+ category: 'agent',
270
+ },
271
+ ];
272
+ //# sourceMappingURL=error-codes.js.map
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Extractor for grammar rule documentation.
3
+ *
4
+ * Generates EBNF text and terminal definitions from the Chevrotain parsers
5
+ * so the jsdoc-grammar.md reference doc stays in sync with source code.
6
+ */
7
+ import { type GrammarCollection } from '../../chevrotain-parser/grammar-diagrams.js';
8
+ export interface TGrammarGroupDoc {
9
+ /** Grammar group name matching GrammarCollection keys */
10
+ name: keyof GrammarCollection;
11
+ /** EBNF text for this group */
12
+ ebnf: string;
13
+ }
14
+ export interface TTerminalDoc {
15
+ name: string;
16
+ pattern: string;
17
+ description: string;
18
+ }
19
+ /**
20
+ * Extract EBNF for all grammar groups.
21
+ */
22
+ export declare function extractGrammarEBNF(): TGrammarGroupDoc[];
23
+ /**
24
+ * Extract terminal pattern definitions for the Terminals section of docs.
25
+ *
26
+ * These are the key token patterns from tokens.ts that users need to know.
27
+ */
28
+ export declare function extractTerminals(): TTerminalDoc[];
29
+ //# sourceMappingURL=grammar-rules.d.ts.map
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Extractor for grammar rule documentation.
3
+ *
4
+ * Generates EBNF text and terminal definitions from the Chevrotain parsers
5
+ * so the jsdoc-grammar.md reference doc stays in sync with source code.
6
+ */
7
+ import { getAllGrammars, serializedToEBNF, } from '../../chevrotain-parser/grammar-diagrams.js';
8
+ /**
9
+ * Extract EBNF for all grammar groups.
10
+ */
11
+ export function extractGrammarEBNF() {
12
+ const grammars = getAllGrammars();
13
+ const groups = [];
14
+ for (const [name, productions] of Object.entries(grammars)) {
15
+ const ebnf = serializedToEBNF(productions);
16
+ if (ebnf.trim()) {
17
+ groups.push({ name: name, ebnf });
18
+ }
19
+ }
20
+ return groups;
21
+ }
22
+ /**
23
+ * Extract terminal pattern definitions for the Terminals section of docs.
24
+ *
25
+ * These are the key token patterns from tokens.ts that users need to know.
26
+ */
27
+ export function extractTerminals() {
28
+ return [
29
+ {
30
+ name: 'IDENTIFIER',
31
+ pattern: '[a-zA-Z_$] [a-zA-Z0-9_$\\/-]*',
32
+ description: 'IDENTIFIER supports `/` and `-` to accommodate npm package naming conventions (e.g., `npm/react-window/areEqual`).',
33
+ },
34
+ {
35
+ name: 'INTEGER',
36
+ pattern: '"-"? [0-9]+',
37
+ description: 'Signed integer literal.',
38
+ },
39
+ {
40
+ name: 'STRING',
41
+ pattern: `'"' { any character except '"' or '\\', or escape sequence } '"'`,
42
+ description: 'Double-quoted string with escape sequences.',
43
+ },
44
+ {
45
+ name: 'TEXT',
46
+ pattern: 'any characters to end of line',
47
+ description: 'Free-form text to end of line (used in descriptions).',
48
+ },
49
+ ];
50
+ }
51
+ //# sourceMappingURL=grammar-rules.js.map
@@ -1,5 +1,10 @@
1
1
  export { extractMcpTools, MCP_TOOLS } from './extractors/mcp-tools.js';
2
2
  export { extractCliCommands, CLI_COMMANDS } from './extractors/cli-commands.js';
3
3
  export { PLUGIN_DEFINITION_FIELDS, PLUGIN_CAPABILITIES, PLUGIN_COMPONENT_CONFIG_FIELDS, PLUGIN_COMPONENT_AREAS, PLUGIN_UI_KIT_COMPONENTS, } from './extractors/plugin-api.js';
4
+ export { ALL_ANNOTATIONS, PORT_MODIFIERS, NODE_MODIFIERS, } from './extractors/annotations.js';
5
+ export { VALIDATION_CODES } from './extractors/error-codes.js';
6
+ export type { TValidationCodeDoc } from './extractors/error-codes.js';
7
+ export { extractGrammarEBNF, extractTerminals } from './extractors/grammar-rules.js';
8
+ export type { TGrammarGroupDoc, TTerminalDoc } from './extractors/grammar-rules.js';
4
9
  export type { TMcpToolDoc, TMcpToolParam, TPluginApiFieldDoc, TCliCommandDoc, TCliOptionDoc } from './types.js';
5
10
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,7 @@
1
1
  export { extractMcpTools, MCP_TOOLS } from './extractors/mcp-tools.js';
2
2
  export { extractCliCommands, CLI_COMMANDS } from './extractors/cli-commands.js';
3
3
  export { PLUGIN_DEFINITION_FIELDS, PLUGIN_CAPABILITIES, PLUGIN_COMPONENT_CONFIG_FIELDS, PLUGIN_COMPONENT_AREAS, PLUGIN_UI_KIT_COMPONENTS, } from './extractors/plugin-api.js';
4
+ export { ALL_ANNOTATIONS, PORT_MODIFIERS, NODE_MODIFIERS, } from './extractors/annotations.js';
5
+ export { VALIDATION_CODES } from './extractors/error-codes.js';
6
+ export { extractGrammarEBNF, extractTerminals } from './extractors/grammar-rules.js';
4
7
  //# sourceMappingURL=index.js.map
@@ -24,6 +24,22 @@ function extractCyclePath(message) {
24
24
  return match ? match[1] : null;
25
25
  }
26
26
  const errorMappers = {
27
+ MISSING_WORKFLOW_NAME(error) {
28
+ return {
29
+ title: 'Missing Workflow Name',
30
+ explanation: 'The workflow annotation is missing or has no name. Every workflow needs a name in the @flowWeaver workflow block.',
31
+ fix: 'Add @flowWeaver workflow to the JSDoc block above your exported workflow function.',
32
+ code: error.code,
33
+ };
34
+ },
35
+ MISSING_FUNCTION_NAME(error) {
36
+ return {
37
+ title: 'Missing Function Name',
38
+ explanation: 'The compiler found a @flowWeaver workflow annotation but the function is anonymous or not exported.',
39
+ fix: 'Make sure your workflow is declared as `export function myWorkflowName(...)` — not anonymous or unexported.',
40
+ code: error.code,
41
+ };
42
+ },
27
43
  MISSING_REQUIRED_INPUT(error) {
28
44
  const quoted = extractQuoted(error.message);
29
45
  const nodeName = quoted[0] || error.node || 'unknown';
@@ -170,6 +186,58 @@ const errorMappers = {
170
186
  code: error.code,
171
187
  };
172
188
  },
189
+ RESERVED_INSTANCE_ID(error) {
190
+ const quoted = extractQuoted(error.message);
191
+ const instanceId = quoted[0] || error.node || 'unknown';
192
+ return {
193
+ title: 'Reserved Instance ID',
194
+ explanation: `Instance ID '${instanceId}' is reserved. 'Start' and 'Exit' are built-in nodes in every workflow.`,
195
+ fix: `Choose a different instance ID, like 'startHandler' or 'exitProcessor'.`,
196
+ code: error.code,
197
+ };
198
+ },
199
+ INFERRED_NODE_TYPE(error) {
200
+ const quoted = extractQuoted(error.message);
201
+ const nodeTypeName = quoted[0] || error.node || 'unknown';
202
+ return {
203
+ title: 'Inferred Node Type',
204
+ explanation: `Node type '${nodeTypeName}' was auto-inferred from the function signature. It works, but you lose explicit control over port names, types, and ordering.`,
205
+ fix: `Add /** @flowWeaver nodeType @expression */ above the function for explicit port control.`,
206
+ code: error.code,
207
+ };
208
+ },
209
+ UNDEFINED_NODE(error) {
210
+ const quoted = extractQuoted(error.message);
211
+ const nodeName = quoted[0] || error.node || 'unknown';
212
+ return {
213
+ title: 'Undefined Node',
214
+ explanation: `A connection references node '${nodeName}', but there's no @node annotation defining it.`,
215
+ fix: `Add a @node annotation for '${nodeName}' in the workflow JSDoc, or remove the connections that reference it.`,
216
+ code: error.code,
217
+ };
218
+ },
219
+ TYPE_INCOMPATIBLE(error) {
220
+ const types = extractTypes(error.message);
221
+ const source = types?.source || 'unknown';
222
+ const target = types?.target || 'unknown';
223
+ return {
224
+ title: 'Type Incompatible',
225
+ explanation: `Type mismatch: ${source} to ${target}. With @strictTypes enabled, this is an error instead of a warning.`,
226
+ fix: `Add a conversion node between the ports, change one of the port types, or remove @strictTypes to allow implicit coercions.`,
227
+ code: error.code,
228
+ };
229
+ },
230
+ UNUSUAL_TYPE_COERCION(error) {
231
+ const types = extractTypes(error.message);
232
+ const source = types?.source || 'unknown';
233
+ const target = types?.target || 'unknown';
234
+ return {
235
+ title: 'Unusual Type Coercion',
236
+ explanation: `Converting ${source} to ${target} is technically valid but semantically unusual and may produce unexpected behavior.`,
237
+ fix: `Add an explicit conversion node if this is intentional, or use @strictTypes to enforce type safety.`,
238
+ code: error.code,
239
+ };
240
+ },
173
241
  MULTIPLE_CONNECTIONS_TO_INPUT(error) {
174
242
  const quoted = extractQuoted(error.message);
175
243
  const portName = quoted[0] || 'unknown';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synergenius/flow-weaver",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "TypeScript annotation-based workflow compiler for Flow Weaver",
5
5
  "private": false,
6
6
  "type": "module",
@@ -26,6 +26,10 @@
26
26
  "./describe": {
27
27
  "types": "./dist/cli/commands/describe.d.ts",
28
28
  "default": "./dist/cli/commands/describe.js"
29
+ },
30
+ "./doc-metadata": {
31
+ "types": "./dist/doc-metadata/index.d.ts",
32
+ "default": "./dist/doc-metadata/index.js"
29
33
  }
30
34
  },
31
35
  "bin": {
@@ -34,12 +38,15 @@
34
38
  "files": [
35
39
  "dist",
36
40
  "!dist/**/*.map",
41
+ "docs/reference",
37
42
  "README.md",
38
43
  "LICENSE"
39
44
  ],
40
45
  "scripts": {
41
46
  "build": "rimraf dist .tsbuildinfo && tsc -p tsconfig.build.json && npm run build:cli",
42
- "postbuild": "npx tsx scripts/postbuild.ts",
47
+ "postbuild": "npx tsx scripts/postbuild.ts && npm run generate:docs",
48
+ "generate:docs": "tsx scripts/generate-docs.ts",
49
+ "generate:docs:check": "tsx scripts/generate-docs.ts --check",
43
50
  "build:cli": "npx tsx scripts/build-cli.ts",
44
51
  "watch": "tsc -p tsconfig.build.json --watch --preserveWatchOutput --incremental",
45
52
  "test": "vitest run",