@lokascript/domain-flow 2.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.
- package/README.md +120 -0
- package/dist/index.cjs +2251 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +643 -0
- package/dist/index.d.ts +643 -0
- package/dist/index.js +2169 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -0
- package/src/__test__/flow-domain.test.ts +696 -0
- package/src/__test__/hateoas-commands.test.ts +520 -0
- package/src/__test__/htmx-generator.test.ts +100 -0
- package/src/__test__/mcp-workflow-server.test.ts +317 -0
- package/src/__test__/pipeline-parser.test.ts +188 -0
- package/src/__test__/route-extractor.test.ts +94 -0
- package/src/generators/flow-generator.ts +338 -0
- package/src/generators/flow-renderer.ts +262 -0
- package/src/generators/htmx-generator.ts +129 -0
- package/src/generators/route-extractor.ts +105 -0
- package/src/generators/workflow-generator.ts +129 -0
- package/src/index.ts +210 -0
- package/src/parser/pipeline-parser.ts +151 -0
- package/src/profiles/index.ts +186 -0
- package/src/runtime/mcp-workflow-server.ts +409 -0
- package/src/runtime/workflow-executor.ts +171 -0
- package/src/schemas/hateoas-schemas.ts +152 -0
- package/src/schemas/index.ts +320 -0
- package/src/siren-agent.d.ts +14 -0
- package/src/tokenizers/index.ts +592 -0
- package/src/types.ts +108 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
import * as _lokascript_framework from '@lokascript/framework';
|
|
2
|
+
import { PatternGenLanguageProfile, CodeGenerator, SemanticNode, MultilingualDSL, LanguageTokenizer } from '@lokascript/framework';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* HATEOAS Command Schemas
|
|
6
|
+
*
|
|
7
|
+
* Defines 4 HATEOAS-aware FlowScript commands: enter, follow, perform, capture.
|
|
8
|
+
* These compile to siren-grail workflow steps instead of vanilla JS.
|
|
9
|
+
*/
|
|
10
|
+
declare const enterSchema: _lokascript_framework.CommandSchema;
|
|
11
|
+
declare const followSchema: _lokascript_framework.CommandSchema;
|
|
12
|
+
declare const performSchema: _lokascript_framework.CommandSchema;
|
|
13
|
+
declare const captureSchema: _lokascript_framework.CommandSchema;
|
|
14
|
+
declare const hateoasSchemas: _lokascript_framework.CommandSchema[];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* FlowScript Command Schemas
|
|
18
|
+
*
|
|
19
|
+
* Defines the semantic structure of data flow commands using the framework's
|
|
20
|
+
* defineCommand/defineRole helpers. Each schema specifies roles (source, destination,
|
|
21
|
+
* style, duration, etc.) and per-language marker overrides for 8 languages.
|
|
22
|
+
*/
|
|
23
|
+
declare const fetchSchema: _lokascript_framework.CommandSchema;
|
|
24
|
+
declare const pollSchema: _lokascript_framework.CommandSchema;
|
|
25
|
+
declare const streamSchema: _lokascript_framework.CommandSchema;
|
|
26
|
+
declare const submitSchema: _lokascript_framework.CommandSchema;
|
|
27
|
+
declare const transformSchema: _lokascript_framework.CommandSchema;
|
|
28
|
+
|
|
29
|
+
declare const allSchemas: _lokascript_framework.CommandSchema[];
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* FlowScript Language Profiles
|
|
33
|
+
*
|
|
34
|
+
* Pattern generation profiles for 8 supported languages.
|
|
35
|
+
* Covers SVO (EN, ES, ZH, FR), SOV (JA, KO, TR), and VSO (AR) word orders.
|
|
36
|
+
*
|
|
37
|
+
* Role markers are specified via markerOverride on each schema role.
|
|
38
|
+
* Profile roleMarkers are used only when positional defaults need overriding.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
declare const englishProfile: PatternGenLanguageProfile;
|
|
42
|
+
declare const spanishProfile: PatternGenLanguageProfile;
|
|
43
|
+
declare const japaneseProfile: PatternGenLanguageProfile;
|
|
44
|
+
declare const arabicProfile: PatternGenLanguageProfile;
|
|
45
|
+
declare const koreanProfile: PatternGenLanguageProfile;
|
|
46
|
+
declare const chineseProfile: PatternGenLanguageProfile;
|
|
47
|
+
declare const turkishProfile: PatternGenLanguageProfile;
|
|
48
|
+
declare const frenchProfile: PatternGenLanguageProfile;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* FlowScript Domain Types
|
|
52
|
+
*
|
|
53
|
+
* Output types for the FlowScript code generator. FlowSpec captures the
|
|
54
|
+
* semantic intent of a data flow command — URL, method, response format,
|
|
55
|
+
* target element, polling interval — ready for compilation to vanilla JS,
|
|
56
|
+
* HTMX attributes, or route descriptors.
|
|
57
|
+
*/
|
|
58
|
+
type FlowAction = 'fetch' | 'poll' | 'stream' | 'submit' | 'transform' | 'enter' | 'follow' | 'perform' | 'capture';
|
|
59
|
+
/**
|
|
60
|
+
* Structured data flow specification.
|
|
61
|
+
*
|
|
62
|
+
* Output of domain-flow's code generator. Can be used to:
|
|
63
|
+
* - Generate vanilla JS (fetch, EventSource, setInterval)
|
|
64
|
+
* - Generate HTMX attributes (hx-get, hx-trigger, hx-target)
|
|
65
|
+
* - Extract route descriptors for server-bridge
|
|
66
|
+
*/
|
|
67
|
+
interface FlowSpec {
|
|
68
|
+
/** The command that produced this spec */
|
|
69
|
+
action: FlowAction;
|
|
70
|
+
/** URL for source commands (fetch, poll, stream, submit destination) */
|
|
71
|
+
url?: string;
|
|
72
|
+
/** HTTP method inferred from command type */
|
|
73
|
+
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
74
|
+
/** Response format */
|
|
75
|
+
responseFormat?: 'json' | 'html' | 'text' | 'sse';
|
|
76
|
+
/** Target CSS selector for DOM insertion */
|
|
77
|
+
target?: string;
|
|
78
|
+
/** Polling interval in milliseconds (poll command) */
|
|
79
|
+
intervalMs?: number;
|
|
80
|
+
/** Form selector (submit command) */
|
|
81
|
+
formSelector?: string;
|
|
82
|
+
/** Transform function or format string (transform command) */
|
|
83
|
+
transformFn?: string;
|
|
84
|
+
/** Link relation name (follow command) */
|
|
85
|
+
linkRel?: string;
|
|
86
|
+
/** Action name (perform command) */
|
|
87
|
+
actionName?: string;
|
|
88
|
+
/** Data source selector or inline data (perform command) */
|
|
89
|
+
dataSource?: string;
|
|
90
|
+
/** Variable name for captured data (capture command) */
|
|
91
|
+
captureAs?: string;
|
|
92
|
+
/** Property path to capture (capture command) */
|
|
93
|
+
capturePath?: string;
|
|
94
|
+
/** Metadata for debugging */
|
|
95
|
+
metadata: {
|
|
96
|
+
/** Language the command was written in */
|
|
97
|
+
sourceLanguage: string;
|
|
98
|
+
/** Raw role values extracted from the parsed command */
|
|
99
|
+
roles: Record<string, string | undefined>;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/** A single step in a HATEOAS workflow */
|
|
103
|
+
type WorkflowStep = {
|
|
104
|
+
type: 'navigate';
|
|
105
|
+
rel: string;
|
|
106
|
+
capture?: Record<string, string>;
|
|
107
|
+
} | {
|
|
108
|
+
type: 'action';
|
|
109
|
+
action: string;
|
|
110
|
+
data?: Record<string, unknown>;
|
|
111
|
+
dataSource?: string;
|
|
112
|
+
capture?: Record<string, string>;
|
|
113
|
+
} | {
|
|
114
|
+
type: 'stop';
|
|
115
|
+
result?: string;
|
|
116
|
+
reason?: string;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* A complete HATEOAS workflow specification.
|
|
120
|
+
*
|
|
121
|
+
* Compiles to siren-grail's compileWorkflow() step format.
|
|
122
|
+
* Can also drive an MCP server with dynamic tools.
|
|
123
|
+
*/
|
|
124
|
+
interface WorkflowSpec {
|
|
125
|
+
/** API entry point URL */
|
|
126
|
+
entryPoint: string;
|
|
127
|
+
/** Ordered workflow steps */
|
|
128
|
+
steps: WorkflowStep[];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* FlowScript Code Generator
|
|
133
|
+
*
|
|
134
|
+
* Transforms semantic AST nodes into either:
|
|
135
|
+
* 1. Vanilla JavaScript strings (primary output via CodeGenerator interface)
|
|
136
|
+
* 2. Structured FlowSpec JSON (via toFlowSpec helper)
|
|
137
|
+
*/
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Parse a duration string to milliseconds.
|
|
141
|
+
* Supports: 500ms, 5s, 1m, 1h, plain number (treated as ms)
|
|
142
|
+
*/
|
|
143
|
+
declare function parseDuration(duration: string): number;
|
|
144
|
+
/**
|
|
145
|
+
* Extract a structured FlowSpec from a parsed SemanticNode.
|
|
146
|
+
*/
|
|
147
|
+
declare function toFlowSpec(node: SemanticNode, language: string): FlowSpec;
|
|
148
|
+
/**
|
|
149
|
+
* FlowScript code generator implementation.
|
|
150
|
+
* Returns vanilla JavaScript — ready to execute in a browser.
|
|
151
|
+
*/
|
|
152
|
+
declare const flowCodeGenerator: CodeGenerator;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* FlowScript Natural Language Renderer
|
|
156
|
+
*
|
|
157
|
+
* Renders a SemanticNode back into natural-language FlowScript syntax
|
|
158
|
+
* for a target language. Inverse of the parser — used by translate().
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Render a FlowScript SemanticNode to natural-language text in the target language.
|
|
163
|
+
*/
|
|
164
|
+
declare function renderFlow(node: SemanticNode, language: string): string;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* HTMX Attribute Generator
|
|
168
|
+
*
|
|
169
|
+
* Transforms a FlowSpec into HTMX-compatible HTML attributes.
|
|
170
|
+
* Maps fetch → hx-get, poll → hx-get + hx-trigger, submit → hx-post.
|
|
171
|
+
* Stream (SSE) has no direct HTMX equivalent — returns null with a note.
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
interface HTMXAttributes {
|
|
175
|
+
/** Generated HTMX attribute map */
|
|
176
|
+
attrs: Record<string, string>;
|
|
177
|
+
/** Notes about limitations or warnings */
|
|
178
|
+
notes: string[];
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Generate HTMX attributes from a FlowSpec.
|
|
182
|
+
*
|
|
183
|
+
* @returns HTMXAttributes with attr map and notes, or null if the command
|
|
184
|
+
* has no HTMX equivalent (e.g., transform)
|
|
185
|
+
*/
|
|
186
|
+
declare function generateHTMX(spec: FlowSpec): HTMXAttributes | null;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Route Extractor
|
|
190
|
+
*
|
|
191
|
+
* Extracts server route descriptors from parsed FlowScript commands.
|
|
192
|
+
* Each fetch/poll/stream/submit URL becomes a RouteDescriptor that can
|
|
193
|
+
* be fed into server-bridge for server-side code generation.
|
|
194
|
+
*/
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Lightweight route descriptor — compatible with server-bridge's RouteDescriptor
|
|
198
|
+
* but self-contained to avoid a hard dependency on the server-bridge package.
|
|
199
|
+
*/
|
|
200
|
+
interface FlowRouteDescriptor {
|
|
201
|
+
/** URL path (e.g., /api/users, /api/user/{id}) */
|
|
202
|
+
path: string;
|
|
203
|
+
/** HTTP method */
|
|
204
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
205
|
+
/** Expected response format */
|
|
206
|
+
responseFormat: 'json' | 'html' | 'text' | 'sse';
|
|
207
|
+
/** Path parameters extracted from URL (e.g., ['id'] from /api/user/{id}) */
|
|
208
|
+
pathParams: string[];
|
|
209
|
+
/** Suggested handler function name */
|
|
210
|
+
handlerName: string;
|
|
211
|
+
/** Source command that produced this route */
|
|
212
|
+
sourceCommand: string;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Extract route descriptors from a FlowSpec.
|
|
216
|
+
* Returns null for commands without URLs (e.g., transform).
|
|
217
|
+
*/
|
|
218
|
+
declare function extractRoute(spec: FlowSpec): FlowRouteDescriptor | null;
|
|
219
|
+
/**
|
|
220
|
+
* Extract multiple route descriptors from an array of FlowSpecs.
|
|
221
|
+
* Filters out nulls (commands without URLs).
|
|
222
|
+
*/
|
|
223
|
+
declare function extractRoutes(specs: FlowSpec[]): FlowRouteDescriptor[];
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Pipeline Parser
|
|
227
|
+
*
|
|
228
|
+
* Wraps the framework's single-command DSL parser to handle multi-step
|
|
229
|
+
* data flow pipelines. Splits input on arrow delimiters (→ / ->), parses
|
|
230
|
+
* each step individually, and assembles a PipelineParseResult.
|
|
231
|
+
*/
|
|
232
|
+
|
|
233
|
+
interface PipelineStep {
|
|
234
|
+
/** The semantic node from parsing a single command */
|
|
235
|
+
node: SemanticNode;
|
|
236
|
+
}
|
|
237
|
+
interface PipelineParseResult {
|
|
238
|
+
/** Ordered pipeline steps */
|
|
239
|
+
steps: PipelineStep[];
|
|
240
|
+
/** Parse errors for any failed steps */
|
|
241
|
+
errors: string[];
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Parse a multi-step FlowScript pipeline into ordered steps.
|
|
245
|
+
*
|
|
246
|
+
* Splits input on arrow delimiters (→ / ->), parses each segment
|
|
247
|
+
* via the DSL, and returns the steps in order.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```
|
|
251
|
+
* // Single-line arrow chain
|
|
252
|
+
* parseFlowPipeline(dsl, 'fetch /api/users as json → transform data with uppercase → into #list', 'en')
|
|
253
|
+
*
|
|
254
|
+
* // Multi-line (newline-separated, each line is a step)
|
|
255
|
+
* parseFlowPipeline(dsl, 'fetch /api/users as json\ntransform data with uppercase', 'en')
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
declare function parseFlowPipeline(dsl: MultilingualDSL, input: string, language: string): PipelineParseResult;
|
|
259
|
+
/**
|
|
260
|
+
* Compile a pipeline to a single JS code block.
|
|
261
|
+
*
|
|
262
|
+
* For linear pipelines (no branching), each step's output feeds into the next
|
|
263
|
+
* via Promise chaining. The first step must be a source (fetch/poll/stream),
|
|
264
|
+
* middle steps can be transforms, and the last step can include a destination.
|
|
265
|
+
*/
|
|
266
|
+
declare function compilePipeline(dsl: MultilingualDSL, input: string, language: string): {
|
|
267
|
+
ok: boolean;
|
|
268
|
+
code?: string;
|
|
269
|
+
errors: string[];
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* FlowScript Tokenizers
|
|
274
|
+
*
|
|
275
|
+
* Language-specific tokenizers for data flow commands (4 languages).
|
|
276
|
+
* Created via the framework's createSimpleTokenizer factory.
|
|
277
|
+
*
|
|
278
|
+
* Custom extractors handle:
|
|
279
|
+
* - CSS selectors (#id, .class)
|
|
280
|
+
* - URL paths (/api/users, /api/user/{id})
|
|
281
|
+
* - Duration literals (5s, 30s, 1m, 500ms)
|
|
282
|
+
* - Latin extended identifiers (diacritics in Spanish)
|
|
283
|
+
*/
|
|
284
|
+
|
|
285
|
+
declare const EnglishFlowTokenizer: LanguageTokenizer;
|
|
286
|
+
declare const SpanishFlowTokenizer: LanguageTokenizer;
|
|
287
|
+
declare const JapaneseFlowTokenizer: LanguageTokenizer;
|
|
288
|
+
declare const ArabicFlowTokenizer: LanguageTokenizer;
|
|
289
|
+
declare const KoreanFlowTokenizer: LanguageTokenizer;
|
|
290
|
+
declare const ChineseFlowTokenizer: LanguageTokenizer;
|
|
291
|
+
declare const TurkishFlowTokenizer: LanguageTokenizer;
|
|
292
|
+
declare const FrenchFlowTokenizer: LanguageTokenizer;
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Workflow Generator — HATEOAS compilation target
|
|
296
|
+
*
|
|
297
|
+
* Converts a sequence of parsed FlowSpec objects into a WorkflowSpec
|
|
298
|
+
* compatible with siren-grail's compileWorkflow() step format.
|
|
299
|
+
*
|
|
300
|
+
* This is the bridge between FlowScript's natural-language parsing
|
|
301
|
+
* and siren-grail's workflow execution engine.
|
|
302
|
+
*/
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Convert an ordered array of FlowSpecs (from parsed HATEOAS commands)
|
|
306
|
+
* into a WorkflowSpec ready for siren-grail execution.
|
|
307
|
+
*
|
|
308
|
+
* The first 'enter' command provides the entry point URL.
|
|
309
|
+
* Subsequent follow/perform/capture commands become workflow steps.
|
|
310
|
+
*
|
|
311
|
+
* @throws Error if no 'enter' command is found in the specs
|
|
312
|
+
*/
|
|
313
|
+
declare function toWorkflowSpec(specs: FlowSpec[]): WorkflowSpec;
|
|
314
|
+
/**
|
|
315
|
+
* Convert a WorkflowSpec to siren-grail's compileWorkflow() step format.
|
|
316
|
+
*
|
|
317
|
+
* This produces a plain JSON array compatible with:
|
|
318
|
+
* import { compileWorkflow } from 'siren-agent/workflow';
|
|
319
|
+
* const decide = compileWorkflow(steps);
|
|
320
|
+
*/
|
|
321
|
+
declare function toSirenGrailSteps(spec: WorkflowSpec): Array<Record<string, unknown>>;
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Workflow Executor — siren-grail adapter
|
|
325
|
+
*
|
|
326
|
+
* Thin adapter that takes a WorkflowSpec (from FlowScript parsing)
|
|
327
|
+
* and executes it against a Siren API using siren-grail's OODAAgent
|
|
328
|
+
* and compileWorkflow().
|
|
329
|
+
*
|
|
330
|
+
* This bridges FlowScript's natural-language parsing to siren-grail's
|
|
331
|
+
* HATEOAS agent runtime.
|
|
332
|
+
*
|
|
333
|
+
* @example
|
|
334
|
+
* ```typescript
|
|
335
|
+
* import { executeWorkflow } from '@lokascript/domain-flow/runtime';
|
|
336
|
+
* import { createFlowDSL, toFlowSpec } from '@lokascript/domain-flow';
|
|
337
|
+
* import { toWorkflowSpec } from '@lokascript/domain-flow/generators/workflow-generator';
|
|
338
|
+
*
|
|
339
|
+
* const flow = createFlowDSL();
|
|
340
|
+
* const specs = [
|
|
341
|
+
* toFlowSpec(flow.parse('enter /api', 'en'), 'en'),
|
|
342
|
+
* toFlowSpec(flow.parse('follow orders', 'en'), 'en'),
|
|
343
|
+
* toFlowSpec(flow.parse('perform createOrder with #checkout', 'en'), 'en'),
|
|
344
|
+
* toFlowSpec(flow.parse('capture as orderId', 'en'), 'en'),
|
|
345
|
+
* ];
|
|
346
|
+
*
|
|
347
|
+
* const workflow = toWorkflowSpec(specs);
|
|
348
|
+
* const result = await executeWorkflow(workflow, { verbose: true });
|
|
349
|
+
* ```
|
|
350
|
+
*/
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Result from a workflow execution.
|
|
354
|
+
* Maps to siren-grail's OODAResult.
|
|
355
|
+
*/
|
|
356
|
+
interface WorkflowResult {
|
|
357
|
+
status: 'stopped' | 'error' | 'maxSteps';
|
|
358
|
+
reason: string;
|
|
359
|
+
result?: unknown;
|
|
360
|
+
steps: number;
|
|
361
|
+
history: Array<Record<string, unknown>>;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Options for workflow execution.
|
|
365
|
+
*/
|
|
366
|
+
interface ExecuteWorkflowOptions {
|
|
367
|
+
/** Maximum OODA steps before stopping (default: 50) */
|
|
368
|
+
maxSteps?: number;
|
|
369
|
+
/** HTTP headers to send with all requests */
|
|
370
|
+
headers?: Record<string, string>;
|
|
371
|
+
/** Enable verbose logging (default: false) */
|
|
372
|
+
verbose?: boolean;
|
|
373
|
+
/** Timeout per request in ms (default: 30000) */
|
|
374
|
+
timeout?: number;
|
|
375
|
+
/** Enable auto-pursuit on 409 Conflict responses */
|
|
376
|
+
autoPursue?: boolean;
|
|
377
|
+
/** Callback on each entity navigation */
|
|
378
|
+
onEntity?: (entity: unknown, url: string) => void;
|
|
379
|
+
/** Callback on each decision */
|
|
380
|
+
onDecision?: (decision: unknown) => void;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Convert a WorkflowSpec to siren-grail's step format.
|
|
384
|
+
*
|
|
385
|
+
* This is a pure-data transformation — no siren-grail dependency required.
|
|
386
|
+
* The step types map 1:1:
|
|
387
|
+
* WorkflowStep.navigate → { type: 'navigate', rel }
|
|
388
|
+
* WorkflowStep.action → { type: 'action', action, data?, dataSource? }
|
|
389
|
+
* WorkflowStep.stop → { type: 'stop', result?, reason? }
|
|
390
|
+
*/
|
|
391
|
+
declare function toSirenSteps(steps: WorkflowStep[]): Array<Record<string, unknown>>;
|
|
392
|
+
/**
|
|
393
|
+
* Execute a WorkflowSpec against a Siren API using siren-grail.
|
|
394
|
+
*
|
|
395
|
+
* Requires `siren-agent` to be installed as a peer dependency.
|
|
396
|
+
* Dynamically imports it to avoid hard dependency.
|
|
397
|
+
*
|
|
398
|
+
* @param spec - The compiled WorkflowSpec from toWorkflowSpec()
|
|
399
|
+
* @param options - Execution options (headers, timeout, etc.)
|
|
400
|
+
* @returns The execution result with status, history, and captured values
|
|
401
|
+
*
|
|
402
|
+
* @throws Error if siren-agent is not installed
|
|
403
|
+
*/
|
|
404
|
+
declare function executeWorkflow(spec: WorkflowSpec, options?: ExecuteWorkflowOptions): Promise<WorkflowResult>;
|
|
405
|
+
/**
|
|
406
|
+
* Create a reusable workflow executor bound to specific options.
|
|
407
|
+
*
|
|
408
|
+
* Useful when executing multiple workflows against the same API
|
|
409
|
+
* with shared headers/auth.
|
|
410
|
+
*/
|
|
411
|
+
declare function createWorkflowExecutor(defaultOptions?: ExecuteWorkflowOptions): {
|
|
412
|
+
execute(spec: WorkflowSpec, overrides?: ExecuteWorkflowOptions): Promise<WorkflowResult>;
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* MCP Workflow Server — HATEOAS → MCP tool bridge
|
|
417
|
+
*
|
|
418
|
+
* An MCP server that wraps a Siren API, exposing current entity affordances
|
|
419
|
+
* (actions and links) as dynamic MCP tools. As the agent navigates through
|
|
420
|
+
* hypermedia states, tools appear and disappear — `tools/list_changed` fires
|
|
421
|
+
* on every state transition.
|
|
422
|
+
*
|
|
423
|
+
* This is the novel contribution: MCP's tool protocol becomes a first-class
|
|
424
|
+
* HATEOAS mechanism. External LLM clients (Claude Code, Cursor, etc.) see
|
|
425
|
+
* affordance-driven tool sets without needing to understand Siren.
|
|
426
|
+
*
|
|
427
|
+
* Tool naming convention:
|
|
428
|
+
* action__{name} — Execute a Siren action
|
|
429
|
+
* navigate__{rel} — Follow a Siren link
|
|
430
|
+
* resolve__{name} — Resolve a 409 prerequisite action
|
|
431
|
+
*
|
|
432
|
+
* @example
|
|
433
|
+
* ```typescript
|
|
434
|
+
* import { createMcpWorkflowServer } from '@lokascript/domain-flow/runtime';
|
|
435
|
+
*
|
|
436
|
+
* const server = createMcpWorkflowServer({
|
|
437
|
+
* entryPoint: 'http://api.example.com/',
|
|
438
|
+
* name: 'order-api',
|
|
439
|
+
* version: '1.0.0',
|
|
440
|
+
* });
|
|
441
|
+
*
|
|
442
|
+
* await server.start(); // Connects to API, builds initial tools, listens on stdio
|
|
443
|
+
* ```
|
|
444
|
+
*/
|
|
445
|
+
|
|
446
|
+
/** Siren entity structure (subset for our needs) */
|
|
447
|
+
interface SirenEntity {
|
|
448
|
+
class?: string[];
|
|
449
|
+
properties?: Record<string, unknown>;
|
|
450
|
+
entities?: Array<Record<string, unknown>>;
|
|
451
|
+
actions?: SirenAction[];
|
|
452
|
+
links?: SirenLink[];
|
|
453
|
+
}
|
|
454
|
+
interface SirenAction {
|
|
455
|
+
name: string;
|
|
456
|
+
title?: string;
|
|
457
|
+
href: string;
|
|
458
|
+
method?: string;
|
|
459
|
+
type?: string;
|
|
460
|
+
fields?: SirenField[];
|
|
461
|
+
}
|
|
462
|
+
interface SirenField {
|
|
463
|
+
name: string;
|
|
464
|
+
type?: string;
|
|
465
|
+
value?: unknown;
|
|
466
|
+
title?: string;
|
|
467
|
+
}
|
|
468
|
+
interface SirenLink {
|
|
469
|
+
rel: string[];
|
|
470
|
+
href: string;
|
|
471
|
+
title?: string;
|
|
472
|
+
type?: string;
|
|
473
|
+
}
|
|
474
|
+
/** MCP tool definition */
|
|
475
|
+
interface McpTool {
|
|
476
|
+
name: string;
|
|
477
|
+
description: string;
|
|
478
|
+
inputSchema: {
|
|
479
|
+
type: 'object';
|
|
480
|
+
properties: Record<string, unknown>;
|
|
481
|
+
required?: string[];
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
/** Configuration for the MCP workflow server */
|
|
485
|
+
interface McpWorkflowServerConfig {
|
|
486
|
+
/** API entry point URL */
|
|
487
|
+
entryPoint: string;
|
|
488
|
+
/** Server name for MCP identification */
|
|
489
|
+
name?: string;
|
|
490
|
+
/** Server version */
|
|
491
|
+
version?: string;
|
|
492
|
+
/** HTTP headers (e.g., auth) for all API requests */
|
|
493
|
+
headers?: Record<string, string>;
|
|
494
|
+
/** Enable verbose logging */
|
|
495
|
+
verbose?: boolean;
|
|
496
|
+
/** Optional pre-compiled WorkflowSpec to auto-execute */
|
|
497
|
+
workflow?: WorkflowSpec;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Convert Siren actions to MCP tool definitions.
|
|
501
|
+
*
|
|
502
|
+
* Each action becomes an `action__{name}` tool with input schema
|
|
503
|
+
* generated from the action's fields.
|
|
504
|
+
*/
|
|
505
|
+
declare function actionsToTools(actions: SirenAction[]): McpTool[];
|
|
506
|
+
/**
|
|
507
|
+
* Convert Siren links to MCP tool definitions.
|
|
508
|
+
*
|
|
509
|
+
* Each link becomes a `navigate__{rel}` tool with no required inputs.
|
|
510
|
+
*/
|
|
511
|
+
declare function linksToTools(links: SirenLink[]): McpTool[];
|
|
512
|
+
/**
|
|
513
|
+
* Build the complete tool set from a Siren entity.
|
|
514
|
+
*/
|
|
515
|
+
declare function entityToTools(entity: SirenEntity): McpTool[];
|
|
516
|
+
/**
|
|
517
|
+
* MCP Workflow Server state machine.
|
|
518
|
+
*
|
|
519
|
+
* Manages the Siren agent state and translates between MCP tool
|
|
520
|
+
* calls and Siren API interactions. Transport (stdio, SSE, etc.)
|
|
521
|
+
* is handled externally.
|
|
522
|
+
*
|
|
523
|
+
* The server lifecycle:
|
|
524
|
+
* 1. initialize() — fetch entry point, build initial tool set
|
|
525
|
+
* 2. listTools() — return current affordance-derived tools
|
|
526
|
+
* 3. callTool(name, args) — execute action or navigate, rebuild tools
|
|
527
|
+
* 4. On each state change, emit tools/list_changed notification
|
|
528
|
+
*/
|
|
529
|
+
declare class McpWorkflowServer {
|
|
530
|
+
private config;
|
|
531
|
+
private currentEntity;
|
|
532
|
+
private currentUrl;
|
|
533
|
+
private currentTools;
|
|
534
|
+
private toolChangeListeners;
|
|
535
|
+
constructor(config: McpWorkflowServerConfig);
|
|
536
|
+
/**
|
|
537
|
+
* Register a listener for tool list changes (maps to tools/list_changed).
|
|
538
|
+
*/
|
|
539
|
+
onToolsChanged(listener: () => void): void;
|
|
540
|
+
/**
|
|
541
|
+
* Initialize the server by fetching the entry point entity.
|
|
542
|
+
*/
|
|
543
|
+
initialize(): Promise<void>;
|
|
544
|
+
/**
|
|
545
|
+
* Get the current list of available MCP tools.
|
|
546
|
+
*/
|
|
547
|
+
listTools(): McpTool[];
|
|
548
|
+
/**
|
|
549
|
+
* Get the current entity as an MCP resource.
|
|
550
|
+
*/
|
|
551
|
+
getCurrentEntity(): SirenEntity | null;
|
|
552
|
+
/**
|
|
553
|
+
* Get the current URL.
|
|
554
|
+
*/
|
|
555
|
+
getCurrentUrl(): string;
|
|
556
|
+
/**
|
|
557
|
+
* Call a tool (action or navigation).
|
|
558
|
+
*
|
|
559
|
+
* Returns the result text and triggers tools/list_changed if the
|
|
560
|
+
* entity state changed.
|
|
561
|
+
*/
|
|
562
|
+
callTool(name: string, args: Record<string, unknown>): Promise<{
|
|
563
|
+
content: string;
|
|
564
|
+
isError?: boolean;
|
|
565
|
+
}>;
|
|
566
|
+
/**
|
|
567
|
+
* Get MCP server capabilities for the initialize response.
|
|
568
|
+
*/
|
|
569
|
+
getCapabilities(): {
|
|
570
|
+
tools: {
|
|
571
|
+
listChanged: boolean;
|
|
572
|
+
};
|
|
573
|
+
resources: {};
|
|
574
|
+
};
|
|
575
|
+
/**
|
|
576
|
+
* Get MCP server info for the initialize response.
|
|
577
|
+
*/
|
|
578
|
+
getServerInfo(): {
|
|
579
|
+
name: string;
|
|
580
|
+
version: string;
|
|
581
|
+
};
|
|
582
|
+
private fetchEntity;
|
|
583
|
+
private executeAction;
|
|
584
|
+
private updateState;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Create a new MCP workflow server instance.
|
|
588
|
+
*/
|
|
589
|
+
declare function createMcpWorkflowServer(config: McpWorkflowServerConfig): McpWorkflowServer;
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* @lokascript/domain-flow — Declarative Reactive Data Flow DSL
|
|
593
|
+
*
|
|
594
|
+
* A multilingual data flow domain built on @lokascript/framework.
|
|
595
|
+
* Parses data flow commands written in 8 languages, compiling to
|
|
596
|
+
* vanilla JS (fetch, EventSource, setInterval) or HTMX attributes.
|
|
597
|
+
*
|
|
598
|
+
* @example
|
|
599
|
+
* ```typescript
|
|
600
|
+
* import { createFlowDSL } from '@lokascript/domain-flow';
|
|
601
|
+
*
|
|
602
|
+
* const flow = createFlowDSL();
|
|
603
|
+
*
|
|
604
|
+
* // English (SVO)
|
|
605
|
+
* flow.compile('fetch /api/users as json into #user-list', 'en');
|
|
606
|
+
* // → { ok: true, code: "fetch('/api/users').then(r => r.json())..." }
|
|
607
|
+
*
|
|
608
|
+
* // Spanish (SVO)
|
|
609
|
+
* flow.compile('obtener /api/users como json en #user-list', 'es');
|
|
610
|
+
*
|
|
611
|
+
* // Japanese (SOV)
|
|
612
|
+
* flow.compile('/api/users json で 取得', 'ja');
|
|
613
|
+
*
|
|
614
|
+
* // Arabic (VSO)
|
|
615
|
+
* flow.compile('جلب /api/users ك json في #user-list', 'ar');
|
|
616
|
+
*
|
|
617
|
+
* // Korean (SOV)
|
|
618
|
+
* flow.compile('/api/users json 로 가져오기', 'ko');
|
|
619
|
+
*
|
|
620
|
+
* // Chinese (SVO)
|
|
621
|
+
* flow.compile('获取 /api/users 以 json 到 #user-list', 'zh');
|
|
622
|
+
*
|
|
623
|
+
* // Turkish (SOV)
|
|
624
|
+
* flow.compile('/api/users json olarak getir', 'tr');
|
|
625
|
+
*
|
|
626
|
+
* // French (SVO)
|
|
627
|
+
* flow.compile('récupérer /api/users comme json dans #user-list', 'fr');
|
|
628
|
+
* ```
|
|
629
|
+
*/
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Create a multilingual FlowScript DSL instance with all 8 supported languages.
|
|
633
|
+
*/
|
|
634
|
+
declare function createFlowDSL(): MultilingualDSL;
|
|
635
|
+
|
|
636
|
+
/** HTML attribute and script-type patterns for AOT scanning */
|
|
637
|
+
declare const flowScanConfig: {
|
|
638
|
+
attributes: readonly ["data-flow", "_flow"];
|
|
639
|
+
scriptTypes: readonly ["text/flowscript"];
|
|
640
|
+
defaultLanguage: string;
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
export { ArabicFlowTokenizer, ChineseFlowTokenizer, EnglishFlowTokenizer, type ExecuteWorkflowOptions, type FlowAction, type FlowRouteDescriptor, type FlowSpec, FrenchFlowTokenizer, type HTMXAttributes, JapaneseFlowTokenizer, KoreanFlowTokenizer, McpWorkflowServer, type McpWorkflowServerConfig, type PipelineParseResult, type PipelineStep, SpanishFlowTokenizer, TurkishFlowTokenizer, type WorkflowResult, type WorkflowSpec, type WorkflowStep, actionsToTools, allSchemas, arabicProfile, captureSchema, chineseProfile, compilePipeline, createFlowDSL, createMcpWorkflowServer, createWorkflowExecutor, englishProfile, enterSchema, entityToTools, executeWorkflow, extractRoute, extractRoutes, fetchSchema, flowCodeGenerator, flowScanConfig, followSchema, frenchProfile, generateHTMX, hateoasSchemas, japaneseProfile, koreanProfile, linksToTools, parseDuration, parseFlowPipeline, performSchema, pollSchema, renderFlow, spanishProfile, streamSchema, submitSchema, toFlowSpec, toSirenGrailSteps, toSirenSteps, toWorkflowSpec, transformSchema, turkishProfile };
|