flow-lang 0.1.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.
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "fs";
3
+ import { config as loadDotenv } from "dotenv";
4
+ import { Command } from "commander";
5
+ import chalk from "chalk";
6
+ import { tokenize } from "../lexer/index.js";
7
+ import { parse } from "../parser/index.js";
8
+ import { analyze } from "../analyzer/index.js";
9
+ import { execute, toDisplay, flowValueToJson, HTTPAPIConnector, WebhookConnector, PluginStubConnector, AnthropicConnector, OpenAIConnector, createMockConnector, } from "../runtime/index.js";
10
+ import { formatErrors } from "../errors/index.js";
11
+ function runPipeline(filePath) {
12
+ let source;
13
+ try {
14
+ source = readFileSync(filePath, "utf-8");
15
+ }
16
+ catch {
17
+ console.error(chalk.red(`Error: Could not read file "${filePath}"`));
18
+ return { success: false, errors: [] };
19
+ }
20
+ // Tokenize
21
+ let tokens;
22
+ try {
23
+ tokens = tokenize(source, filePath);
24
+ }
25
+ catch (err) {
26
+ const message = err instanceof Error ? err.message : String(err);
27
+ console.error(chalk.red(`Lexer error: ${message}`));
28
+ return { success: false, errors: [] };
29
+ }
30
+ // Parse
31
+ const { program, errors: parseErrors } = parse(tokens, source, filePath);
32
+ // Analyze
33
+ const analysisErrors = analyze(program, source, filePath);
34
+ const allErrors = [...parseErrors, ...analysisErrors];
35
+ if (allErrors.length > 0) {
36
+ return { success: false, errors: allErrors, program, source };
37
+ }
38
+ return { success: true, errors: [], program, source };
39
+ }
40
+ // ============================================================
41
+ // Output helpers
42
+ // ============================================================
43
+ function printErrors(errors) {
44
+ console.error(formatErrors(errors));
45
+ const errorCount = errors.filter(e => e.severity === "error").length;
46
+ const warnCount = errors.filter(e => e.severity === "warning").length;
47
+ const parts = [];
48
+ if (errorCount > 0)
49
+ parts.push(chalk.red(`${errorCount} error${errorCount !== 1 ? "s" : ""}`));
50
+ if (warnCount > 0)
51
+ parts.push(chalk.yellow(`${warnCount} warning${warnCount !== 1 ? "s" : ""}`));
52
+ console.error("\n" + parts.join(", ") + " found.");
53
+ }
54
+ function printLog(log, verbose) {
55
+ if (!verbose)
56
+ return;
57
+ if (log.length === 0)
58
+ return;
59
+ console.log(chalk.gray("\n--- Execution Log ---"));
60
+ for (const entry of log) {
61
+ const stepLabel = entry.step ? chalk.cyan(`[${entry.step}]`) + " " : "";
62
+ const resultColor = entry.result === "success" ? chalk.green : entry.result === "failure" ? chalk.red : chalk.yellow;
63
+ const resultLabel = resultColor(entry.result);
64
+ let detail = "";
65
+ if (entry.details["message"]) {
66
+ detail = ` ${entry.details["message"]}`;
67
+ }
68
+ console.log(chalk.gray(` ${stepLabel}${entry.action} ${resultLabel}${detail}`));
69
+ }
70
+ console.log(chalk.gray("--- End Log ---"));
71
+ }
72
+ function buildConnectors(declarations) {
73
+ const connectors = new Map();
74
+ for (const decl of declarations) {
75
+ switch (decl.serviceType) {
76
+ case "api":
77
+ connectors.set(decl.name, new HTTPAPIConnector(decl.target));
78
+ break;
79
+ case "webhook":
80
+ connectors.set(decl.name, new WebhookConnector(decl.target));
81
+ break;
82
+ case "plugin":
83
+ connectors.set(decl.name, new PluginStubConnector());
84
+ break;
85
+ case "ai":
86
+ if (decl.target.startsWith("anthropic/")) {
87
+ connectors.set(decl.name, new AnthropicConnector(decl.target, process.env.ANTHROPIC_API_KEY));
88
+ }
89
+ else if (decl.target.startsWith("openai/")) {
90
+ connectors.set(decl.name, new OpenAIConnector(decl.target, process.env.OPENAI_API_KEY));
91
+ }
92
+ else {
93
+ connectors.set(decl.name, createMockConnector("ai"));
94
+ }
95
+ break;
96
+ }
97
+ }
98
+ return connectors;
99
+ }
100
+ // ============================================================
101
+ // Commands
102
+ // ============================================================
103
+ function checkCommand(filePath) {
104
+ const { success, errors } = runPipeline(filePath);
105
+ if (!success && errors.length === 0) {
106
+ process.exitCode = 1;
107
+ return;
108
+ }
109
+ if (errors.length > 0) {
110
+ printErrors(errors);
111
+ process.exitCode = 1;
112
+ return;
113
+ }
114
+ console.log(chalk.green(`No errors found in ${filePath}`));
115
+ }
116
+ async function runCommand(filePath, options) {
117
+ // Load .env file into process.env
118
+ loadDotenv();
119
+ const pipeline = runPipeline(filePath);
120
+ if (!pipeline.success) {
121
+ if (pipeline.errors.length > 0)
122
+ printErrors(pipeline.errors);
123
+ process.exitCode = 1;
124
+ return;
125
+ }
126
+ // Parse input
127
+ let input = {};
128
+ if (options.input) {
129
+ try {
130
+ input = JSON.parse(options.input);
131
+ }
132
+ catch {
133
+ console.error(chalk.red(`Error: Invalid JSON input: ${options.input}`));
134
+ process.exitCode = 1;
135
+ return;
136
+ }
137
+ }
138
+ // Build connectors: real by default, mock with --mock flag
139
+ let connectors;
140
+ if (!options.mock && pipeline.program.services) {
141
+ connectors = buildConnectors(pipeline.program.services.declarations);
142
+ }
143
+ // Execute
144
+ const result = await execute(pipeline.program, pipeline.source, {
145
+ input,
146
+ connectors,
147
+ envVars: process.env,
148
+ verbose: options.verbose,
149
+ strictEnv: options.strictEnv,
150
+ });
151
+ // Print log
152
+ printLog(result.log, options.verbose ?? false);
153
+ // Print result
154
+ switch (result.result.status) {
155
+ case "completed": {
156
+ console.log(chalk.green("\nWorkflow completed successfully."));
157
+ const keys = Object.keys(result.result.outputs);
158
+ if (keys.length > 0) {
159
+ console.log(chalk.white("\nOutputs:"));
160
+ for (const [key, value] of Object.entries(result.result.outputs)) {
161
+ console.log(` ${chalk.cyan(key)}: ${toDisplay(value)}`);
162
+ }
163
+ }
164
+ break;
165
+ }
166
+ case "rejected":
167
+ console.log(chalk.red(`\nWorkflow rejected: ${result.result.message}`));
168
+ process.exitCode = 1;
169
+ break;
170
+ case "error":
171
+ console.error(chalk.red(`\nRuntime error:`));
172
+ console.error(formatErrors([result.result.error]));
173
+ process.exitCode = 1;
174
+ break;
175
+ }
176
+ }
177
+ async function testCommand(filePath, options) {
178
+ const pipeline = runPipeline(filePath);
179
+ if (!pipeline.success) {
180
+ if (pipeline.errors.length > 0)
181
+ printErrors(pipeline.errors);
182
+ process.exitCode = 1;
183
+ return;
184
+ }
185
+ console.log(chalk.blue(`Testing ${filePath} with mock services...\n`));
186
+ const result = await execute(pipeline.program, pipeline.source, {
187
+ input: {},
188
+ envVars: { API_KEY: "mock-api-key", SECRET: "mock-secret" },
189
+ verbose: options.verbose,
190
+ });
191
+ printLog(result.log, options.verbose ?? false);
192
+ switch (result.result.status) {
193
+ case "completed": {
194
+ console.log(chalk.green("\nTest passed — workflow completed successfully."));
195
+ const keys = Object.keys(result.result.outputs);
196
+ if (keys.length > 0) {
197
+ console.log(chalk.white("\nOutputs:"));
198
+ for (const [key, value] of Object.entries(result.result.outputs)) {
199
+ console.log(` ${chalk.cyan(key)}: ${JSON.stringify(flowValueToJson(value))}`);
200
+ }
201
+ }
202
+ break;
203
+ }
204
+ case "rejected":
205
+ console.log(chalk.yellow(`\nTest result — workflow rejected: ${result.result.message}`));
206
+ break;
207
+ case "error":
208
+ console.log(chalk.red(`\nTest failed — runtime error:`));
209
+ console.error(formatErrors([result.result.error]));
210
+ process.exitCode = 1;
211
+ break;
212
+ }
213
+ }
214
+ // ============================================================
215
+ // CLI setup
216
+ // ============================================================
217
+ const program = new Command();
218
+ program
219
+ .name("flow")
220
+ .description("Flow — a language for AI agent and workflow orchestration")
221
+ .version("0.1.0");
222
+ program
223
+ .command("check <file>")
224
+ .description("Check a .flow file for errors without running it")
225
+ .action(checkCommand);
226
+ program
227
+ .command("run <file>")
228
+ .description("Execute a .flow file")
229
+ .option("--input <json>", "JSON string with input data for the workflow")
230
+ .option("--verbose", "Show detailed execution log")
231
+ .option("--strict-env", "Error on missing environment variables instead of using empty")
232
+ .option("--mock", "Use mock services instead of real HTTP calls")
233
+ .action(runCommand);
234
+ program
235
+ .command("test <file>")
236
+ .description("Test a .flow file with mock services")
237
+ .option("--dry-run", "Use mock services (default)")
238
+ .option("--verbose", "Show detailed execution log")
239
+ .action(testCommand);
240
+ program.parse();
241
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { FlowError } from "../types/index.js";
2
+ /**
3
+ * Compute the Levenshtein edit distance between two strings.
4
+ * Used for "did you mean?" suggestions.
5
+ */
6
+ export declare function levenshtein(a: string, b: string): number;
7
+ /**
8
+ * Find the closest match to `target` from a list of `candidates`.
9
+ * Returns null if no candidate is close enough (threshold: 60% of target length, minimum 3).
10
+ */
11
+ export declare function findClosestMatch(target: string, candidates: readonly string[]): string | null;
12
+ /**
13
+ * Format a FlowError into the standard user-facing error message.
14
+ *
15
+ * Output format:
16
+ *
17
+ * Error in <file>, line <n>:
18
+ *
19
+ * <the offending source line>
20
+ *
21
+ * <plain English explanation>
22
+ *
23
+ * <suggestion>
24
+ *
25
+ * <hint>
26
+ */
27
+ export declare function formatError(error: FlowError): string;
28
+ /**
29
+ * Format multiple errors into a single output string.
30
+ */
31
+ export declare function formatErrors(errors: readonly FlowError[]): string;
32
+ /**
33
+ * Create a FlowError with all required fields.
34
+ */
35
+ export declare function createError(file: string, line: number, column: number, message: string, source: string, options?: {
36
+ suggestion?: string;
37
+ hint?: string;
38
+ severity?: FlowError["severity"];
39
+ }): FlowError;
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAwBxD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAoB7F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CA2BpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAGjE;AAED;;GAEG;AACH,wBAAgB,WAAW,CACvB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAA;CAAE,GACnF,SAAS,CAcX"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Compute the Levenshtein edit distance between two strings.
3
+ * Used for "did you mean?" suggestions.
4
+ */
5
+ export function levenshtein(a, b) {
6
+ const aLower = a.toLowerCase();
7
+ const bLower = b.toLowerCase();
8
+ const aLen = aLower.length;
9
+ const bLen = bLower.length;
10
+ // Previous and current row of distances
11
+ let prev = Array.from({ length: bLen + 1 }, (_, i) => i);
12
+ let curr = new Array(bLen + 1);
13
+ for (let i = 1; i <= aLen; i++) {
14
+ curr[0] = i;
15
+ for (let j = 1; j <= bLen; j++) {
16
+ const cost = aLower[i - 1] === bLower[j - 1] ? 0 : 1;
17
+ curr[j] = Math.min((prev[j] ?? 0) + 1, // deletion
18
+ (curr[j - 1] ?? 0) + 1, // insertion
19
+ (prev[j - 1] ?? 0) + cost // substitution
20
+ );
21
+ }
22
+ [prev, curr] = [curr, prev];
23
+ }
24
+ return prev[bLen] ?? aLen;
25
+ }
26
+ /**
27
+ * Find the closest match to `target` from a list of `candidates`.
28
+ * Returns null if no candidate is close enough (threshold: 60% of target length, minimum 3).
29
+ */
30
+ export function findClosestMatch(target, candidates) {
31
+ if (candidates.length === 0)
32
+ return null;
33
+ const maxDistance = Math.max(3, Math.floor(target.length * 0.6));
34
+ let bestMatch = null;
35
+ let bestDistance = Infinity;
36
+ for (const candidate of candidates) {
37
+ const distance = levenshtein(target, candidate);
38
+ if (distance < bestDistance) {
39
+ bestDistance = distance;
40
+ bestMatch = candidate;
41
+ }
42
+ }
43
+ if (bestDistance <= maxDistance && bestMatch !== null) {
44
+ return bestMatch;
45
+ }
46
+ return null;
47
+ }
48
+ /**
49
+ * Format a FlowError into the standard user-facing error message.
50
+ *
51
+ * Output format:
52
+ *
53
+ * Error in <file>, line <n>:
54
+ *
55
+ * <the offending source line>
56
+ *
57
+ * <plain English explanation>
58
+ *
59
+ * <suggestion>
60
+ *
61
+ * <hint>
62
+ */
63
+ export function formatError(error) {
64
+ const label = error.severity === "warning" ? "Warning" : "Error";
65
+ const lines = [];
66
+ lines.push(`${label} in ${error.file}, line ${error.line}:`);
67
+ lines.push("");
68
+ if (error.sourceLine) {
69
+ lines.push(` ${error.sourceLine.trimEnd()}`);
70
+ lines.push("");
71
+ }
72
+ lines.push(` ${error.message}`);
73
+ if (error.suggestion) {
74
+ lines.push("");
75
+ lines.push(` ${error.suggestion}`);
76
+ }
77
+ if (error.hint) {
78
+ lines.push("");
79
+ for (const hintLine of error.hint.split("\n")) {
80
+ lines.push(` ${hintLine}`);
81
+ }
82
+ }
83
+ return lines.join("\n");
84
+ }
85
+ /**
86
+ * Format multiple errors into a single output string.
87
+ */
88
+ export function formatErrors(errors) {
89
+ if (errors.length === 0)
90
+ return "";
91
+ return errors.map(formatError).join("\n\n");
92
+ }
93
+ /**
94
+ * Create a FlowError with all required fields.
95
+ */
96
+ export function createError(file, line, column, message, source, options) {
97
+ const sourceLines = source.split("\n");
98
+ const sourceLine = sourceLines[line - 1] ?? "";
99
+ return {
100
+ severity: options?.severity ?? "error",
101
+ file,
102
+ line,
103
+ column,
104
+ message,
105
+ sourceLine,
106
+ suggestion: options?.suggestion ?? null,
107
+ hint: options?.hint ?? null,
108
+ };
109
+ }
110
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Token, FlowError } from "../types/index.js";
2
+ export declare class LexerError extends Error {
3
+ readonly flowError: FlowError;
4
+ constructor(flowError: FlowError);
5
+ }
6
+ export declare function tokenize(source: string, fileName?: string): Token[];
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lexer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAa,SAAS,EAAE,MAAM,mBAAmB,CAAC;AA4EhE,qBAAa,UAAW,SAAQ,KAAK;IACjC,SAAgB,SAAS,EAAE,SAAS,CAAC;gBAEzB,SAAS,EAAE,SAAS;CAKnC;AAMD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAkB,GAAG,KAAK,EAAE,CAkc9E"}