@styx-api/core 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.
- package/dist/index.cjs +7947 -0
- package/dist/index.d.cts +1143 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +1143 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +7877 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +55 -0
- package/src/backend/backend.ts +95 -0
- package/src/backend/boutiques/boutiques.ts +1049 -0
- package/src/backend/boutiques/index.ts +1 -0
- package/src/backend/code-builder.ts +49 -0
- package/src/backend/collect-field-info.ts +50 -0
- package/src/backend/collect-named-types.ts +103 -0
- package/src/backend/collect-output-fields.ts +222 -0
- package/src/backend/find-doc.ts +38 -0
- package/src/backend/find-struct-node.ts +66 -0
- package/src/backend/index.ts +39 -0
- package/src/backend/python/arg-builder.ts +454 -0
- package/src/backend/python/emit.ts +638 -0
- package/src/backend/python/index.ts +9 -0
- package/src/backend/python/outputs-emit.ts +430 -0
- package/src/backend/python/packaging.ts +173 -0
- package/src/backend/python/python.ts +558 -0
- package/src/backend/python/snippet.ts +84 -0
- package/src/backend/python/typemap.ts +131 -0
- package/src/backend/python/types.ts +8 -0
- package/src/backend/python/validate-emit.ts +356 -0
- package/src/backend/resolve-field-binding.ts +41 -0
- package/src/backend/resolve-output-tokens.ts +80 -0
- package/src/backend/schema/index.ts +2 -0
- package/src/backend/schema/jsonschema.ts +303 -0
- package/src/backend/scope.ts +50 -0
- package/src/backend/sig-entries.ts +97 -0
- package/src/backend/snippet-core.ts +185 -0
- package/src/backend/string-case.ts +30 -0
- package/src/backend/styxdefs-compat.ts +21 -0
- package/src/backend/type-keys.ts +52 -0
- package/src/backend/typescript/arg-builder.ts +420 -0
- package/src/backend/typescript/emit.ts +450 -0
- package/src/backend/typescript/index.ts +10 -0
- package/src/backend/typescript/outputs-emit.ts +389 -0
- package/src/backend/typescript/packaging.ts +130 -0
- package/src/backend/typescript/snippet.ts +60 -0
- package/src/backend/typescript/typemap.ts +47 -0
- package/src/backend/typescript/types.ts +8 -0
- package/src/backend/typescript/typescript.ts +507 -0
- package/src/backend/typescript/validate-emit.ts +341 -0
- package/src/backend/union-variants.ts +42 -0
- package/src/backend/validate-walk.ts +111 -0
- package/src/bindings/binding.ts +77 -0
- package/src/bindings/format.ts +176 -0
- package/src/bindings/index.ts +16 -0
- package/src/bindings/output-gate.ts +50 -0
- package/src/bindings/resolved-output.ts +56 -0
- package/src/bindings/types.ts +16 -0
- package/src/frontend/argdump/index.ts +1 -0
- package/src/frontend/argdump/parser.ts +914 -0
- package/src/frontend/boutiques/destruct-template.ts +50 -0
- package/src/frontend/boutiques/index.ts +1 -0
- package/src/frontend/boutiques/parser.ts +676 -0
- package/src/frontend/boutiques/split-command.ts +69 -0
- package/src/frontend/detect-format.ts +42 -0
- package/src/frontend/frontend.ts +31 -0
- package/src/frontend/index.ts +9 -0
- package/src/frontend/workbench/index.ts +1 -0
- package/src/frontend/workbench/parser.ts +351 -0
- package/src/index.ts +41 -0
- package/src/ir/builders.ts +69 -0
- package/src/ir/format.ts +157 -0
- package/src/ir/index.ts +32 -0
- package/src/ir/meta.ts +91 -0
- package/src/ir/node.ts +95 -0
- package/src/ir/passes/canonicalize.ts +108 -0
- package/src/ir/passes/flatten.ts +73 -0
- package/src/ir/passes/index.ts +7 -0
- package/src/ir/passes/pass.ts +86 -0
- package/src/ir/passes/pipeline.ts +21 -0
- package/src/ir/passes/remove-empty.ts +76 -0
- package/src/ir/passes/simplify.ts +179 -0
- package/src/ir/types.ts +15 -0
- package/src/manifest/context.ts +36 -0
- package/src/manifest/index.ts +3 -0
- package/src/manifest/types.ts +15 -0
- package/src/solver/assign-access.ts +218 -0
- package/src/solver/index.ts +4 -0
- package/src/solver/resolve-outputs.ts +233 -0
- package/src/solver/solver.ts +319 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,1143 @@
|
|
|
1
|
+
//#region src/frontend/detect-format.d.ts
|
|
2
|
+
type FormatName = "boutiques" | "argdump" | "workbench";
|
|
3
|
+
/**
|
|
4
|
+
* Auto-detect the format of a JSON descriptor source string.
|
|
5
|
+
* Returns null if the format cannot be determined.
|
|
6
|
+
*/
|
|
7
|
+
declare function detectFormat(source: string): FormatName | null;
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/ir/types.d.ts
|
|
10
|
+
/** Scalar type kinds for terminal nodes */
|
|
11
|
+
type ScalarKind = "int" | "float" | "str" | "path";
|
|
12
|
+
/** Media type identifier (MIME type) */
|
|
13
|
+
type MediaTypeIdentifier = string;
|
|
14
|
+
/** Human-facing documentation metadata */
|
|
15
|
+
interface Documentation {
|
|
16
|
+
title?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
authors?: string[];
|
|
19
|
+
literature?: string[];
|
|
20
|
+
urls?: string[];
|
|
21
|
+
comment?: string;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/ir/meta.d.ts
|
|
25
|
+
/**
|
|
26
|
+
* Opaque, name-based reference to an IR node by its `NodeMeta.name`.
|
|
27
|
+
*
|
|
28
|
+
* Resolved post-solve against the binding registry, not within IR passes.
|
|
29
|
+
* Names survive optimization (pointers don't), so token refs stay valid even
|
|
30
|
+
* after passes rewrite the tree. See `memory/design_outputs.md`.
|
|
31
|
+
*/
|
|
32
|
+
interface NodeRef {
|
|
33
|
+
kind: "node-ref";
|
|
34
|
+
name: string;
|
|
35
|
+
}
|
|
36
|
+
/** Construct a NodeRef from a node name. */
|
|
37
|
+
declare function nodeRef(name: string): NodeRef;
|
|
38
|
+
/** Output token: literal text or a parameter reference. */
|
|
39
|
+
type OutputToken = {
|
|
40
|
+
kind: "literal";
|
|
41
|
+
value: string;
|
|
42
|
+
} | {
|
|
43
|
+
kind: "ref";
|
|
44
|
+
target: NodeRef;
|
|
45
|
+
stripExtensions?: string[];
|
|
46
|
+
fallback?: string;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Specification for a file the tool produces. Lives on `NodeMeta.outputs` of
|
|
50
|
+
* the struct node (root sequence or subcommand sequence) that declared it.
|
|
51
|
+
* Per-output gating is derived downstream from the scope's binding gate and
|
|
52
|
+
* each ref binding's gate, so no host node or `optional` flag is stored.
|
|
53
|
+
*/
|
|
54
|
+
interface Output {
|
|
55
|
+
name?: string;
|
|
56
|
+
doc?: Documentation;
|
|
57
|
+
tokens: OutputToken[];
|
|
58
|
+
mediaTypes?: MediaTypeIdentifier[];
|
|
59
|
+
}
|
|
60
|
+
/** Metadata attached to any IR node. */
|
|
61
|
+
interface NodeMeta {
|
|
62
|
+
/** Name identifier for this node (used by solver for binding names). */
|
|
63
|
+
name?: string;
|
|
64
|
+
/**
|
|
65
|
+
* The discriminator (`@type`) tag for this node when it is a union arm (a
|
|
66
|
+
* Boutiques sub-command). Kept separate from `name`: a single-field
|
|
67
|
+
* sub-command collapses onto its inner field, whose `name` then wins, so the
|
|
68
|
+
* tag would otherwise become the inner field's id - e.g. two distinct
|
|
69
|
+
* sub-commands `VariousString`/`VariousFile` both wrapping an `obj` field
|
|
70
|
+
* would collide on `@type: "obj"` (and the second arm would be unreachable).
|
|
71
|
+
* `mergeMeta` preserves this through the collapse and the solver prefers it
|
|
72
|
+
* for the variant tag, so distinct sub-commands keep distinct, reachable
|
|
73
|
+
* `@type`s.
|
|
74
|
+
*/
|
|
75
|
+
variantTag?: string;
|
|
76
|
+
doc?: Documentation;
|
|
77
|
+
defaultValue?: string | number | boolean;
|
|
78
|
+
/** Files produced when this node is active. See `Output`. */
|
|
79
|
+
outputs?: Output[];
|
|
80
|
+
}
|
|
81
|
+
/** Application-level metadata for the root node. */
|
|
82
|
+
interface AppMeta {
|
|
83
|
+
id?: string;
|
|
84
|
+
version?: string;
|
|
85
|
+
doc?: Documentation;
|
|
86
|
+
container?: {
|
|
87
|
+
image: string;
|
|
88
|
+
type?: "docker" | "singularity";
|
|
89
|
+
};
|
|
90
|
+
stdout?: StreamOutput;
|
|
91
|
+
stderr?: StreamOutput;
|
|
92
|
+
}
|
|
93
|
+
interface StreamOutput {
|
|
94
|
+
name: string;
|
|
95
|
+
doc?: Documentation;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Produce a usable name for an Output. Frontends may leave `Output.name`
|
|
99
|
+
* unset; downstream code (resolver, validator, backends) needs a stable
|
|
100
|
+
* identifier for diagnostics and field naming. Falls back to `output_<index>`
|
|
101
|
+
* keyed by the output's position in tree-walk order.
|
|
102
|
+
*/
|
|
103
|
+
declare function effectiveOutputName(output: Output, index: number): string;
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/ir/node.d.ts
|
|
106
|
+
/** Base structure for all IR nodes */
|
|
107
|
+
interface BaseNode<K extends string, Attrs> {
|
|
108
|
+
kind: K;
|
|
109
|
+
meta?: NodeMeta;
|
|
110
|
+
attrs: Attrs;
|
|
111
|
+
}
|
|
112
|
+
type Literal = BaseNode<"literal", {
|
|
113
|
+
str: string;
|
|
114
|
+
}>;
|
|
115
|
+
type Sequence = BaseNode<"sequence", {
|
|
116
|
+
nodes: Expr[];
|
|
117
|
+
join?: string;
|
|
118
|
+
}>;
|
|
119
|
+
type Optional = BaseNode<"optional", {
|
|
120
|
+
node: Expr;
|
|
121
|
+
}>;
|
|
122
|
+
type Alternative = BaseNode<"alternative", {
|
|
123
|
+
alts: Expr[];
|
|
124
|
+
}>;
|
|
125
|
+
type Repeat = BaseNode<"repeat", {
|
|
126
|
+
node: Expr;
|
|
127
|
+
join?: string;
|
|
128
|
+
countMin?: number;
|
|
129
|
+
countMax?: number;
|
|
130
|
+
}>;
|
|
131
|
+
type Int = BaseNode<"int", {
|
|
132
|
+
minValue?: number;
|
|
133
|
+
maxValue?: number;
|
|
134
|
+
}>;
|
|
135
|
+
type Float = BaseNode<"float", {
|
|
136
|
+
minValue?: number;
|
|
137
|
+
maxValue?: number;
|
|
138
|
+
}>;
|
|
139
|
+
type Str = BaseNode<"str", Record<string, never>>;
|
|
140
|
+
type Path = BaseNode<"path", {
|
|
141
|
+
resolveParent?: boolean;
|
|
142
|
+
mutable?: boolean;
|
|
143
|
+
mediaTypes?: MediaTypeIdentifier[];
|
|
144
|
+
}>;
|
|
145
|
+
type StructuralNode = Sequence | Optional | Alternative | Repeat;
|
|
146
|
+
type Terminal = Literal | Int | Float | Str | Path;
|
|
147
|
+
type Expr = StructuralNode | Terminal;
|
|
148
|
+
declare function isTerminal(expr: Expr): expr is Terminal;
|
|
149
|
+
declare function isStructural(expr: Expr): expr is StructuralNode;
|
|
150
|
+
//#endregion
|
|
151
|
+
//#region src/ir/builders.d.ts
|
|
152
|
+
declare function lit(str: string): Literal;
|
|
153
|
+
declare function str(meta?: NodeMeta | string): Str;
|
|
154
|
+
declare function int(meta?: NodeMeta | string): Int;
|
|
155
|
+
declare function float(meta?: NodeMeta | string): Float;
|
|
156
|
+
declare function path(meta?: NodeMeta | string): Path;
|
|
157
|
+
declare function seq(...nodes: Expr[]): Sequence;
|
|
158
|
+
declare function seqJoin(join: string, ...nodes: Expr[]): Sequence;
|
|
159
|
+
declare function opt(node: Expr, meta?: NodeMeta | string): Optional;
|
|
160
|
+
declare function rep(node: Expr, meta?: NodeMeta | string): Repeat;
|
|
161
|
+
declare function repJoin(join: string, node: Expr, meta?: NodeMeta | string): Repeat;
|
|
162
|
+
declare function alt(...alts: Expr[]): Alternative;
|
|
163
|
+
//#endregion
|
|
164
|
+
//#region src/ir/format.d.ts
|
|
165
|
+
declare function format(expr: Expr, meta?: AppMeta): string;
|
|
166
|
+
//#endregion
|
|
167
|
+
//#region src/ir/passes/pass.d.ts
|
|
168
|
+
declare enum PassStatus {
|
|
169
|
+
Unchanged = "unchanged",
|
|
170
|
+
Changed = "changed",
|
|
171
|
+
ChangedNeedsRerun = "changed-needs-rerun"
|
|
172
|
+
}
|
|
173
|
+
interface PassResult {
|
|
174
|
+
expr: Expr;
|
|
175
|
+
status: PassStatus;
|
|
176
|
+
warnings?: string[];
|
|
177
|
+
}
|
|
178
|
+
interface Pass {
|
|
179
|
+
readonly name: string;
|
|
180
|
+
apply(expr: Expr): PassResult;
|
|
181
|
+
}
|
|
182
|
+
declare function compose(...passes: Pass[]): Pass;
|
|
183
|
+
declare function fixpoint(pass: Pass, maxIterations?: number): Pass;
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/ir/passes/canonicalize.d.ts
|
|
186
|
+
/**
|
|
187
|
+
* Canonicalize IR for consistent representation:
|
|
188
|
+
* - Sort alternatives by kind, then name, then structure
|
|
189
|
+
* - Deduplicate identical alternatives
|
|
190
|
+
*/
|
|
191
|
+
declare const canonicalize: Pass;
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/ir/passes/flatten.d.ts
|
|
194
|
+
/**
|
|
195
|
+
* Flatten passes
|
|
196
|
+
* - seq(a, seq(b, c)) -> seq(a, b, c)
|
|
197
|
+
* - alt(a, alt(b, c)) -> alt(a, b, c)
|
|
198
|
+
*/
|
|
199
|
+
declare const flatten: Pass;
|
|
200
|
+
//#endregion
|
|
201
|
+
//#region src/ir/passes/pipeline.d.ts
|
|
202
|
+
declare const defaultPipeline: Pass;
|
|
203
|
+
declare function createPipeline(passes: Pass[], options?: {
|
|
204
|
+
fixpoint?: boolean;
|
|
205
|
+
maxIterations?: number;
|
|
206
|
+
}): Pass;
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/ir/passes/simplify.d.ts
|
|
209
|
+
/**
|
|
210
|
+
* Simplify passes:
|
|
211
|
+
* - optional(optional(T)) -> optional(T)
|
|
212
|
+
* - repeat(repeat(T)) -> repeat(T) with merged constraints
|
|
213
|
+
* - seq(T) -> T, alt(T) -> T (singleton unwrapping)
|
|
214
|
+
* - seq(lit("a"), lit("b")) -> seq(lit("ab")) (merge consecutive literals)
|
|
215
|
+
*
|
|
216
|
+
* Every collapse that drops a wrapper layer merges that layer's `NodeMeta`
|
|
217
|
+
* into the surviving node via `mergeMeta`, so names and attached outputs are
|
|
218
|
+
* never lost.
|
|
219
|
+
*/
|
|
220
|
+
declare const simplify: Pass;
|
|
221
|
+
//#endregion
|
|
222
|
+
//#region src/ir/passes/remove-empty.d.ts
|
|
223
|
+
/**
|
|
224
|
+
* Remove empty nodes:
|
|
225
|
+
* - seq() → removed
|
|
226
|
+
* - alt() → removed
|
|
227
|
+
* - opt(seq()) → removed
|
|
228
|
+
* - rep(alt()) → removed
|
|
229
|
+
*/
|
|
230
|
+
declare const removeEmpty: Pass;
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/frontend/frontend.d.ts
|
|
233
|
+
interface ParseResult {
|
|
234
|
+
meta?: AppMeta;
|
|
235
|
+
expr: Expr;
|
|
236
|
+
errors: ParseError[];
|
|
237
|
+
warnings: ParseWarning[];
|
|
238
|
+
}
|
|
239
|
+
interface ParseError {
|
|
240
|
+
message: string;
|
|
241
|
+
location?: SourceLocation;
|
|
242
|
+
}
|
|
243
|
+
interface ParseWarning {
|
|
244
|
+
message: string;
|
|
245
|
+
location?: SourceLocation;
|
|
246
|
+
}
|
|
247
|
+
interface SourceLocation {
|
|
248
|
+
file?: string;
|
|
249
|
+
line?: number;
|
|
250
|
+
column?: number;
|
|
251
|
+
}
|
|
252
|
+
interface Frontend {
|
|
253
|
+
readonly name: string;
|
|
254
|
+
readonly extensions: string[];
|
|
255
|
+
parse(source: string, filename?: string): ParseResult;
|
|
256
|
+
}
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/bindings/resolved-output.d.ts
|
|
259
|
+
/**
|
|
260
|
+
* Resolved token in an output path template. Refs point at solved bindings;
|
|
261
|
+
* literals are emitted verbatim.
|
|
262
|
+
*/
|
|
263
|
+
type ResolvedToken = {
|
|
264
|
+
kind: "literal";
|
|
265
|
+
value: string;
|
|
266
|
+
} | {
|
|
267
|
+
kind: "ref";
|
|
268
|
+
binding: BindingId;
|
|
269
|
+
stripExtensions?: string[];
|
|
270
|
+
fallback?: string;
|
|
271
|
+
};
|
|
272
|
+
/**
|
|
273
|
+
* One wrapper layer on a binding's path from the root. Atoms are stored
|
|
274
|
+
* root-to-leaf in `Binding.gate`; backends nest wrappers in array order.
|
|
275
|
+
*
|
|
276
|
+
* - `present`: the binding is inside the active branch of `binding` (a non-null
|
|
277
|
+
* `optional`, `true` for a `bool`, `> 0` for a `count`). Reads as a boolean
|
|
278
|
+
* guard at codegen.
|
|
279
|
+
* - `variant`: the binding is inside the `variant` arm of the union bound by
|
|
280
|
+
* `binding`. Reads as a discriminator check.
|
|
281
|
+
* - `iter`: the binding is inside a `repeat` whose value is a `list`. Reads as
|
|
282
|
+
* a per-element loop variable bound to `binding`.
|
|
283
|
+
*/
|
|
284
|
+
type GateAtom = {
|
|
285
|
+
kind: "present";
|
|
286
|
+
binding: BindingId;
|
|
287
|
+
} | {
|
|
288
|
+
kind: "variant";
|
|
289
|
+
binding: BindingId;
|
|
290
|
+
variant: string;
|
|
291
|
+
} | {
|
|
292
|
+
kind: "iter";
|
|
293
|
+
binding: BindingId;
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* Output specification translated against the binding registry. Pure template
|
|
297
|
+
* data: a name and a token sequence. Per-output gating is derived at codegen
|
|
298
|
+
* time from the declaring scope's gate plus each ref binding's gate.
|
|
299
|
+
*/
|
|
300
|
+
interface ResolvedOutput {
|
|
301
|
+
name: string;
|
|
302
|
+
doc?: Documentation;
|
|
303
|
+
tokens: ResolvedToken[];
|
|
304
|
+
mediaTypes?: MediaTypeIdentifier[];
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Outputs declared on one struct binding, grouped under that scope. The
|
|
308
|
+
* solver guarantees a binding on every output-carrying sequence (forcing a
|
|
309
|
+
* struct binding even when it would otherwise collapse), so the scope is
|
|
310
|
+
* always a real BindingId. Per-output gating derives from the scope binding's
|
|
311
|
+
* `gate` plus each ref binding's `gate`.
|
|
312
|
+
*/
|
|
313
|
+
interface OutputScope {
|
|
314
|
+
scope: BindingId;
|
|
315
|
+
outputs: ResolvedOutput[];
|
|
316
|
+
}
|
|
317
|
+
//#endregion
|
|
318
|
+
//#region src/bindings/types.d.ts
|
|
319
|
+
type BoundType = {
|
|
320
|
+
kind: "scalar";
|
|
321
|
+
scalar: ScalarKind;
|
|
322
|
+
} | {
|
|
323
|
+
kind: "bool";
|
|
324
|
+
} | {
|
|
325
|
+
kind: "count";
|
|
326
|
+
} | {
|
|
327
|
+
kind: "literal";
|
|
328
|
+
value: string | number;
|
|
329
|
+
} | {
|
|
330
|
+
kind: "optional";
|
|
331
|
+
inner: BoundType;
|
|
332
|
+
} | {
|
|
333
|
+
kind: "list";
|
|
334
|
+
item: BoundType;
|
|
335
|
+
} | {
|
|
336
|
+
kind: "struct";
|
|
337
|
+
fields: Record<string, BoundType>;
|
|
338
|
+
} | {
|
|
339
|
+
kind: "union";
|
|
340
|
+
variants: BoundVariant[];
|
|
341
|
+
};
|
|
342
|
+
interface BoundVariant {
|
|
343
|
+
name?: string;
|
|
344
|
+
type: BoundType;
|
|
345
|
+
}
|
|
346
|
+
//#endregion
|
|
347
|
+
//#region src/bindings/binding.d.ts
|
|
348
|
+
type BindingId = string;
|
|
349
|
+
/**
|
|
350
|
+
* One step in a binding's access path relative to top-level `params`.
|
|
351
|
+
*
|
|
352
|
+
* - `field`: descend into a named field of the enclosing struct scope. Renders
|
|
353
|
+
* as `params.name` (TS) / `params["name"]` (Python).
|
|
354
|
+
* - `iter`: the access base resets to the per-element loop variable bound to
|
|
355
|
+
* `binding` (a `repeat`-of-list). The renderer substitutes the active loop
|
|
356
|
+
* variable at emit time (from the `iter` gate atom's loop, or the
|
|
357
|
+
* arg-builder's local loop), so segments after an `iter` build off the
|
|
358
|
+
* element rather than off `params`.
|
|
359
|
+
*
|
|
360
|
+
* There is deliberately no `variant` or `directValue` segment: complex-union
|
|
361
|
+
* variant fields are plain `field` segments off the union's own path (the
|
|
362
|
+
* `@type` discriminant lives in `GateAtom`, not the access path), and the
|
|
363
|
+
* solver's wrapper collapses (`optional<scalar>`, scalar lists) are expressed
|
|
364
|
+
* by a binding simply inheriting its parent wrapper's path.
|
|
365
|
+
*/
|
|
366
|
+
type AccessSegment = {
|
|
367
|
+
kind: "field";
|
|
368
|
+
name: string;
|
|
369
|
+
} | {
|
|
370
|
+
kind: "iter";
|
|
371
|
+
binding: BindingId;
|
|
372
|
+
};
|
|
373
|
+
/**
|
|
374
|
+
* A binding's location relative to top-level `params`, as a structured segment
|
|
375
|
+
* sequence. Computed once by the solver (`assignAccessPaths`) and rendered by
|
|
376
|
+
* each backend's `renderAccess`, so the arg-builder and outputs emitter share
|
|
377
|
+
* one source of truth instead of each re-deriving paths.
|
|
378
|
+
*/
|
|
379
|
+
type AccessPath = AccessSegment[];
|
|
380
|
+
interface Binding {
|
|
381
|
+
id: BindingId;
|
|
382
|
+
node: Expr;
|
|
383
|
+
name: string;
|
|
384
|
+
type: BoundType;
|
|
385
|
+
/**
|
|
386
|
+
* Wrapper layers on the path from the root to this binding, root-to-leaf.
|
|
387
|
+
* Captures the optional/repeat/alternative ancestors as `present`/`iter`/
|
|
388
|
+
* `variant` atoms. Backends nest wrappers in array order; "is this binding
|
|
389
|
+
* conditionally active?" reduces to `gate.length > 0`.
|
|
390
|
+
*/
|
|
391
|
+
gate: GateAtom[];
|
|
392
|
+
/**
|
|
393
|
+
* Access path relative to top-level `params`, assigned by the solver's
|
|
394
|
+
* `assignAccessPaths` pass after types settle. Backends render it via
|
|
395
|
+
* `renderAccess` rather than re-walking the IR to recompute where this
|
|
396
|
+
* binding lives.
|
|
397
|
+
*/
|
|
398
|
+
access: AccessPath;
|
|
399
|
+
}
|
|
400
|
+
type BindingRegistry = Map<BindingId, Binding>;
|
|
401
|
+
type OutputDiagnosticLevel = "error" | "warning";
|
|
402
|
+
interface OutputDiagnostic {
|
|
403
|
+
output: string;
|
|
404
|
+
message: string;
|
|
405
|
+
level: OutputDiagnosticLevel;
|
|
406
|
+
}
|
|
407
|
+
interface OutputValidationResult {
|
|
408
|
+
errors: OutputDiagnostic[];
|
|
409
|
+
warnings: OutputDiagnostic[];
|
|
410
|
+
}
|
|
411
|
+
interface SolveResult {
|
|
412
|
+
bindings: BindingRegistry;
|
|
413
|
+
resolve: (node: Expr) => Binding | undefined;
|
|
414
|
+
}
|
|
415
|
+
declare function createRegistry(): BindingRegistry;
|
|
416
|
+
//#endregion
|
|
417
|
+
//#region src/bindings/output-gate.d.ts
|
|
418
|
+
/**
|
|
419
|
+
* The unified wrapper sequence for a single output: the scope's gate, then for
|
|
420
|
+
* each ref token both the ref binding's path-gate and (if its type is itself
|
|
421
|
+
* "thick" - nullable or iterable) a self-atom on the ref binding. Atoms are
|
|
422
|
+
* deduped while preserving first-occurrence order.
|
|
423
|
+
*
|
|
424
|
+
* The self-atom encodes facts derivable from `Binding.type` alone:
|
|
425
|
+
* - `optional`, `bool`, `count` -> `present(binding)` (value may be absent)
|
|
426
|
+
* - `list` -> `iter(binding)` (iterate per element)
|
|
427
|
+
*
|
|
428
|
+
* `scopeGate` is the gate of the scope's struct binding (often `[]` at the
|
|
429
|
+
* root). Backends nest wrappers in array order; the atom kind decides whether
|
|
430
|
+
* it renders as a guard (`present` / `variant`) or a loop (`iter`).
|
|
431
|
+
*/
|
|
432
|
+
declare function outputGate(scopeGate: GateAtom[], output: ResolvedOutput, bindings: BindingRegistry): GateAtom[];
|
|
433
|
+
declare function atomKey(atom: GateAtom): string;
|
|
434
|
+
//#endregion
|
|
435
|
+
//#region src/bindings/format.d.ts
|
|
436
|
+
interface FormatExtras {
|
|
437
|
+
scopes?: OutputScope[];
|
|
438
|
+
diagnostics?: OutputValidationResult;
|
|
439
|
+
}
|
|
440
|
+
declare function formatSolveResult(result: SolveResult, expr: Expr, extras?: FormatExtras): string;
|
|
441
|
+
//#endregion
|
|
442
|
+
//#region src/solver/resolve-outputs.d.ts
|
|
443
|
+
interface OutputResolution {
|
|
444
|
+
scopes: OutputScope[];
|
|
445
|
+
diagnostics: OutputValidationResult;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Translate each `NodeMeta.outputs` entry against the binding registry,
|
|
449
|
+
* grouped by the declaring struct binding (the "scope"). The solver forces a
|
|
450
|
+
* binding on every output-carrying sequence, so an output without a scope
|
|
451
|
+
* binding indicates a frontend bug (outputs attached to a non-sequence
|
|
452
|
+
* node) - it is reported as a diagnostic and dropped.
|
|
453
|
+
*/
|
|
454
|
+
declare function resolveOutputs(root: Expr, solved: SolveResult): OutputResolution;
|
|
455
|
+
//#endregion
|
|
456
|
+
//#region src/solver/solver.d.ts
|
|
457
|
+
interface SolveOptions {
|
|
458
|
+
namingStrategy?: NamingStrategy;
|
|
459
|
+
}
|
|
460
|
+
interface NamingStrategy {
|
|
461
|
+
getName: (node: Expr, path: string[]) => string;
|
|
462
|
+
generateId: () => BindingId;
|
|
463
|
+
}
|
|
464
|
+
declare function defaultNamingStrategy(): NamingStrategy;
|
|
465
|
+
declare function solve(expr: Expr, options?: SolveOptions): SolveResult;
|
|
466
|
+
//#endregion
|
|
467
|
+
//#region src/manifest/types.d.ts
|
|
468
|
+
interface ProjectMeta {
|
|
469
|
+
name?: string;
|
|
470
|
+
version?: string;
|
|
471
|
+
doc?: Documentation;
|
|
472
|
+
license?: Documentation;
|
|
473
|
+
}
|
|
474
|
+
interface PackageMeta {
|
|
475
|
+
name?: string;
|
|
476
|
+
version?: string;
|
|
477
|
+
docker?: string;
|
|
478
|
+
doc?: Documentation;
|
|
479
|
+
}
|
|
480
|
+
//#endregion
|
|
481
|
+
//#region src/manifest/context.d.ts
|
|
482
|
+
interface CodegenContext {
|
|
483
|
+
expr: Expr;
|
|
484
|
+
bindings: BindingRegistry;
|
|
485
|
+
resolve: SolveResult["resolve"];
|
|
486
|
+
outputScopes: OutputScope[];
|
|
487
|
+
outputDiagnostics: OutputValidationResult;
|
|
488
|
+
app?: AppMeta;
|
|
489
|
+
package?: PackageMeta;
|
|
490
|
+
project?: ProjectMeta;
|
|
491
|
+
}
|
|
492
|
+
declare function createContext(expr: Expr, solveResult: SolveResult, outputs: OutputResolution, meta?: {
|
|
493
|
+
app?: AppMeta;
|
|
494
|
+
package?: PackageMeta;
|
|
495
|
+
project?: ProjectMeta;
|
|
496
|
+
}): CodegenContext;
|
|
497
|
+
//#endregion
|
|
498
|
+
//#region src/backend/scope.d.ts
|
|
499
|
+
/** Symbol collision avoidance for code generation. */
|
|
500
|
+
declare class Scope {
|
|
501
|
+
private readonly reserved;
|
|
502
|
+
private readonly used;
|
|
503
|
+
private readonly parent?;
|
|
504
|
+
constructor(reserved?: Iterable<string>, parent?: Scope);
|
|
505
|
+
/** Check if a symbol is already taken (in this scope or any parent). */
|
|
506
|
+
has(symbol: string): boolean;
|
|
507
|
+
/**
|
|
508
|
+
* Add a symbol, appending a numeric suffix to avoid collisions. Returns the
|
|
509
|
+
* safe name.
|
|
510
|
+
*
|
|
511
|
+
* When a `recase` transform is given, a disambiguated candidate is routed back
|
|
512
|
+
* through it so the suffix is absorbed into the identifier's casing - e.g.
|
|
513
|
+
* `pascalCase` folds `Config_2` into `Config2` - rather than leaving a
|
|
514
|
+
* mixed-case `Config_2`. Uniqueness is always checked on the final emitted
|
|
515
|
+
* form, so two hints that case-collide still get distinct names. Defaults to
|
|
516
|
+
* identity (the bare `<name>_<n>` suffix) for callers that don't case-normalize.
|
|
517
|
+
*/
|
|
518
|
+
add(candidate: string, recase?: (s: string) => string): string;
|
|
519
|
+
/** Create a child scope that inherits this scope's restrictions. */
|
|
520
|
+
child(reserved?: Iterable<string>): Scope;
|
|
521
|
+
}
|
|
522
|
+
//#endregion
|
|
523
|
+
//#region src/backend/backend.d.ts
|
|
524
|
+
interface EmitResult {
|
|
525
|
+
files: Map<string, string>;
|
|
526
|
+
errors: EmitError[];
|
|
527
|
+
warnings: EmitWarning[];
|
|
528
|
+
}
|
|
529
|
+
interface EmitError {
|
|
530
|
+
message: string;
|
|
531
|
+
}
|
|
532
|
+
interface EmitWarning {
|
|
533
|
+
message: string;
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* What the suite-level dispatcher needs to route a config object to one app's
|
|
537
|
+
* dict-style executor, keyed by the root `@type` discriminator.
|
|
538
|
+
*/
|
|
539
|
+
interface AppEntrypoint {
|
|
540
|
+
/** Root `@type` discriminator value (`<package>/<app>`). */
|
|
541
|
+
type: string;
|
|
542
|
+
/**
|
|
543
|
+
* Dict-style execute function name - `<tool>Execute` / `<tool>_execute` for a
|
|
544
|
+
* struct root, `<tool>` for a non-struct root. Takes `(params, runner)`.
|
|
545
|
+
*/
|
|
546
|
+
executeFn: string;
|
|
547
|
+
}
|
|
548
|
+
interface EmittedApp extends EmitResult {
|
|
549
|
+
meta?: AppMeta;
|
|
550
|
+
/**
|
|
551
|
+
* Dispatch entrypoint, present when the app has a stable `@type` (both an id
|
|
552
|
+
* and a package name are known). Consumed by `emitPackage` to build the
|
|
553
|
+
* suite-level `execute(params, runner)` dispatcher.
|
|
554
|
+
*/
|
|
555
|
+
entrypoint?: AppEntrypoint;
|
|
556
|
+
}
|
|
557
|
+
interface EmittedPackage extends EmitResult {
|
|
558
|
+
meta?: PackageMeta;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* A code generator for one target language. Implementations emit in up to
|
|
562
|
+
* three tiers; only `emitApp` is mandatory.
|
|
563
|
+
*
|
|
564
|
+
* The CLI's `--mode` flag selects which tiers run: `scripts` = `emitApp` only,
|
|
565
|
+
* `single` = `emitApp` + one `emitPackage`, `multi` = all three tiers.
|
|
566
|
+
*
|
|
567
|
+
* Paths in returned file maps are relative to the emit tier's natural root
|
|
568
|
+
* (package directory for app/package emit, project root for project emit).
|
|
569
|
+
* Orchestration is responsible for prefixing/merging the maps.
|
|
570
|
+
*/
|
|
571
|
+
interface Backend {
|
|
572
|
+
readonly name: string;
|
|
573
|
+
readonly target: string;
|
|
574
|
+
/**
|
|
575
|
+
* Emit the per-tool file(s) for one app. Mandatory.
|
|
576
|
+
*
|
|
577
|
+
* When emitting many tools into one suite barrel, pass a `scope` shared across
|
|
578
|
+
* the package (from `newPackageScope`) so emitted top-level names stay unique
|
|
579
|
+
* across tools - a flat `export *` / `from .x import *` re-export otherwise
|
|
580
|
+
* collides same-named types. Omit it for standalone single-tool emission.
|
|
581
|
+
*/
|
|
582
|
+
emitApp(ctx: CodegenContext, scope?: Scope): EmittedApp;
|
|
583
|
+
/**
|
|
584
|
+
* Create a fresh symbol scope seeded with this backend's reserved words, to be
|
|
585
|
+
* shared across all `emitApp` calls for one package. Optional; callers fall
|
|
586
|
+
* back to per-tool scoping (still safe via name prefixing) when absent.
|
|
587
|
+
*/
|
|
588
|
+
newPackageScope?(): Scope;
|
|
589
|
+
/**
|
|
590
|
+
* Emit suite-level files for a package containing many apps (e.g. the
|
|
591
|
+
* `__init__.py` re-exporting `from .bet import *` per tool, or an
|
|
592
|
+
* `index.ts` doing `export * from "./bet.js"`). Optional; defaulted to
|
|
593
|
+
* no-op by callers when absent.
|
|
594
|
+
*/
|
|
595
|
+
emitPackage?(pkg: PackageMeta, apps: EmittedApp[]): EmittedPackage;
|
|
596
|
+
/**
|
|
597
|
+
* Emit project-level artifacts spanning many packages (e.g. root
|
|
598
|
+
* `pyproject.toml`, top-level `__init__.py`, runner helpers).
|
|
599
|
+
* Wired up by Plan 2's CLI catalog mode; backends opt in as needed.
|
|
600
|
+
*/
|
|
601
|
+
emitProject?(proj: ProjectMeta, packages: EmittedPackage[]): EmitResult;
|
|
602
|
+
}
|
|
603
|
+
interface TypeMap {
|
|
604
|
+
map(type: BoundType): string;
|
|
605
|
+
imports(type: BoundType): string[];
|
|
606
|
+
}
|
|
607
|
+
//#endregion
|
|
608
|
+
//#region src/backend/boutiques/boutiques.d.ts
|
|
609
|
+
interface BtDescriptor {
|
|
610
|
+
name?: string;
|
|
611
|
+
id?: string;
|
|
612
|
+
description?: string;
|
|
613
|
+
"schema-version"?: string;
|
|
614
|
+
"tool-version"?: string;
|
|
615
|
+
author?: string;
|
|
616
|
+
url?: string;
|
|
617
|
+
"container-image"?: {
|
|
618
|
+
image: string;
|
|
619
|
+
type?: string;
|
|
620
|
+
};
|
|
621
|
+
"command-line"?: string;
|
|
622
|
+
inputs?: BtInput[];
|
|
623
|
+
"stdout-output"?: {
|
|
624
|
+
id: string;
|
|
625
|
+
name?: string;
|
|
626
|
+
description?: string;
|
|
627
|
+
};
|
|
628
|
+
"stderr-output"?: {
|
|
629
|
+
id: string;
|
|
630
|
+
name?: string;
|
|
631
|
+
description?: string;
|
|
632
|
+
};
|
|
633
|
+
"output-files"?: BtOutputFile[];
|
|
634
|
+
}
|
|
635
|
+
interface BtOutputFile {
|
|
636
|
+
id: string;
|
|
637
|
+
name?: string;
|
|
638
|
+
description?: string;
|
|
639
|
+
"path-template": string;
|
|
640
|
+
optional?: boolean;
|
|
641
|
+
list?: boolean;
|
|
642
|
+
"path-template-stripped-extensions"?: string[];
|
|
643
|
+
}
|
|
644
|
+
interface BtInput {
|
|
645
|
+
id: string;
|
|
646
|
+
name?: string;
|
|
647
|
+
description?: string;
|
|
648
|
+
type: string | BtDescriptor | BtDescriptor[];
|
|
649
|
+
"value-key": string;
|
|
650
|
+
optional?: boolean;
|
|
651
|
+
list?: boolean;
|
|
652
|
+
"list-separator"?: string;
|
|
653
|
+
"min-list-entries"?: number;
|
|
654
|
+
"max-list-entries"?: number;
|
|
655
|
+
"command-line-flag"?: string;
|
|
656
|
+
"command-line-flag-separator"?: string;
|
|
657
|
+
"value-choices"?: (string | number)[];
|
|
658
|
+
"default-value"?: string | number | boolean;
|
|
659
|
+
minimum?: number;
|
|
660
|
+
maximum?: number;
|
|
661
|
+
integer?: boolean;
|
|
662
|
+
"resolve-parent"?: boolean;
|
|
663
|
+
mutable?: boolean;
|
|
664
|
+
}
|
|
665
|
+
declare function generateBoutiques(ctx: CodegenContext): {
|
|
666
|
+
descriptor: BtDescriptor;
|
|
667
|
+
warnings: EmitWarning[];
|
|
668
|
+
};
|
|
669
|
+
declare class BoutiquesBackend implements Backend {
|
|
670
|
+
readonly name = "boutiques";
|
|
671
|
+
readonly target = "boutiques";
|
|
672
|
+
emitApp(ctx: CodegenContext): EmittedApp;
|
|
673
|
+
}
|
|
674
|
+
//#endregion
|
|
675
|
+
//#region src/backend/code-builder.d.ts
|
|
676
|
+
/** Line-buffer abstraction for code emission. */
|
|
677
|
+
declare class CodeBuilder {
|
|
678
|
+
private readonly lines;
|
|
679
|
+
private depth;
|
|
680
|
+
private readonly indentStr;
|
|
681
|
+
constructor(indent?: string);
|
|
682
|
+
/** Append a line at the current indentation level. */
|
|
683
|
+
line(text: string): this;
|
|
684
|
+
/** Append a blank line. */
|
|
685
|
+
blank(): this;
|
|
686
|
+
/** Append a comment line. */
|
|
687
|
+
comment(text: string, prefix?: string): this;
|
|
688
|
+
/** Run a callback with increased indentation. */
|
|
689
|
+
indent(fn: () => void): this;
|
|
690
|
+
/** Append all lines from another CodeBuilder at the current indentation level. */
|
|
691
|
+
append(other: CodeBuilder): this;
|
|
692
|
+
/** Return the built code as a string. */
|
|
693
|
+
toString(): string;
|
|
694
|
+
}
|
|
695
|
+
//#endregion
|
|
696
|
+
//#region src/backend/collect-field-info.d.ts
|
|
697
|
+
/**
|
|
698
|
+
* Metadata extracted for each field of a struct type.
|
|
699
|
+
*
|
|
700
|
+
* `doc` is the field's description, recovered from wrapper nodes via `findDoc`.
|
|
701
|
+
* `defaultValue` is pulled from the wrapper or binding node's metadata.
|
|
702
|
+
*/
|
|
703
|
+
interface FieldInfo {
|
|
704
|
+
doc?: string;
|
|
705
|
+
defaultValue?: string | number | boolean;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Collect field metadata (doc, defaultValue) for each field of a struct type.
|
|
709
|
+
*
|
|
710
|
+
* Walks the IR tree to find the sequence node containing the struct's fields,
|
|
711
|
+
* then resolves each child to its field binding. Metadata is recovered from both
|
|
712
|
+
* the wrapper node (where the parser hoists doc) and the binding node (where the
|
|
713
|
+
* solver places the binding after sequence collapse).
|
|
714
|
+
*/
|
|
715
|
+
declare function collectFieldInfo(ctx: CodegenContext, structType: Extract<BoundType, {
|
|
716
|
+
kind: "struct";
|
|
717
|
+
}>): Map<string, FieldInfo>;
|
|
718
|
+
//#endregion
|
|
719
|
+
//#region src/backend/collect-named-types.d.ts
|
|
720
|
+
/** A named compound type (struct or union) discovered during type collection. */
|
|
721
|
+
interface NamedType {
|
|
722
|
+
name: string;
|
|
723
|
+
type: BoundType;
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Recursively collect all struct/union types and assign unique names.
|
|
727
|
+
*
|
|
728
|
+
* Walks the BoundType tree depth-first, using structural keys (`structKey`,
|
|
729
|
+
* `unionKey`) to deduplicate types that appear multiple times in the tree.
|
|
730
|
+
* Each unique struct/union gets a name generated by applying `nameTransform`
|
|
731
|
+
* to a hint string (derived from the root name or field/variant names).
|
|
732
|
+
*
|
|
733
|
+
* @param rootType - The root BoundType to walk.
|
|
734
|
+
* @param rootName - The hint for the root type's name (already tool-qualified).
|
|
735
|
+
* @param scope - Symbol scope for collision avoidance.
|
|
736
|
+
* @param nameTransform - Converts a hint string to a type name (e.g. pascalCase, snake_case).
|
|
737
|
+
* @param nestedPrefix - Prepended to every NON-root type name so a suite's flat
|
|
738
|
+
* barrel (`export * from`/`from .x import *`) can't collide two tools' types
|
|
739
|
+
* that share a local field/variant name (e.g. `Outputtype`). Pass the tool's
|
|
740
|
+
* type prefix (its root name); defaults to "" for single-tool emission.
|
|
741
|
+
* @returns `namedTypes` maps structural keys to assigned names, `typeDecls` lists declarations in order.
|
|
742
|
+
*/
|
|
743
|
+
declare function collectNamedTypes(rootType: BoundType, rootName: string, scope: Scope, nameTransform: (hint: string) => string, nestedPrefix?: string): {
|
|
744
|
+
namedTypes: Map<string, string>;
|
|
745
|
+
typeDecls: NamedType[];
|
|
746
|
+
};
|
|
747
|
+
/**
|
|
748
|
+
* Create a type name resolver from a namedTypes map.
|
|
749
|
+
* Returns a function that maps a BoundType to its assigned name (if any).
|
|
750
|
+
*/
|
|
751
|
+
declare function resolveTypeName(namedTypes: Map<string, string>): (type: BoundType) => string | undefined;
|
|
752
|
+
//#endregion
|
|
753
|
+
//#region src/backend/find-doc.d.ts
|
|
754
|
+
/**
|
|
755
|
+
* Find a description from an IR node, traversing through wrapper nodes.
|
|
756
|
+
*
|
|
757
|
+
* The parser's `wrapNode` hoists doc metadata to the outermost wrapper node,
|
|
758
|
+
* but the solver's simplify pass can collapse sequences, burying descriptions
|
|
759
|
+
* deeper in the tree.
|
|
760
|
+
*
|
|
761
|
+
* This traversal is type-aware: it only enters sequences when the corresponding
|
|
762
|
+
* BoundType is not a struct. Struct sequences have their own field collection
|
|
763
|
+
* call, so entering them would steal nested struct children's descriptions.
|
|
764
|
+
*
|
|
765
|
+
* @param node - The IR node to search for a description.
|
|
766
|
+
* @param fieldType - The BoundType of the field, used to determine traversal boundaries.
|
|
767
|
+
*/
|
|
768
|
+
declare function findDoc(node: Expr, fieldType: BoundType): string | undefined;
|
|
769
|
+
//#endregion
|
|
770
|
+
//#region src/backend/find-struct-node.d.ts
|
|
771
|
+
/**
|
|
772
|
+
* Find the sequence node whose child bindings match a struct type's fields.
|
|
773
|
+
*
|
|
774
|
+
* Traverses through optional, repeat, and alternative wrappers to find the
|
|
775
|
+
* sequence that directly contains the struct's field bindings. This is necessary
|
|
776
|
+
* because the solver may collapse `seq(lit("--flag"), terminal)` into the terminal,
|
|
777
|
+
* burying bindings deeper in the tree.
|
|
778
|
+
*
|
|
779
|
+
* Uses a two-phase check for sequences:
|
|
780
|
+
* 1. Direct binding check (`ctx.resolve`) - matches when bindings are on immediate children
|
|
781
|
+
* 2. Recursive binding check (`resolveFieldBinding`) - matches when solver collapsed
|
|
782
|
+
* a seq(lit, terminal) and the binding is buried deeper
|
|
783
|
+
*
|
|
784
|
+
* Phase 1 is tried first to avoid falsely matching an outer sequence when an inner
|
|
785
|
+
* sequence is the actual struct owner (e.g. `seq(lit("--flag"), seq(field1, field2))`).
|
|
786
|
+
*/
|
|
787
|
+
declare function findStructNode(node: Expr, ctx: CodegenContext, structType: Extract<BoundType, {
|
|
788
|
+
kind: "struct";
|
|
789
|
+
}>): Extract<Expr, {
|
|
790
|
+
kind: "sequence";
|
|
791
|
+
}> | undefined;
|
|
792
|
+
//#endregion
|
|
793
|
+
//#region src/backend/resolve-field-binding.d.ts
|
|
794
|
+
/**
|
|
795
|
+
* Resolve a struct child node to its field binding, handling collapsed sequences.
|
|
796
|
+
*
|
|
797
|
+
* When the solver's simplify pass collapses `seq(lit("--flag"), terminal)` into
|
|
798
|
+
* just the terminal, the binding ends up on the inner node while metadata (doc,
|
|
799
|
+
* defaultValue) may remain on the outermost wrapper. This function recursively
|
|
800
|
+
* descends through collapsed sequences to find the binding, tracking the outermost
|
|
801
|
+
* node for metadata recovery.
|
|
802
|
+
*
|
|
803
|
+
* Uses type identity (`===`) to verify the binding matches the struct's field type,
|
|
804
|
+
* preventing cross-nesting name collisions where an inner struct has a field with
|
|
805
|
+
* the same name as the outer struct.
|
|
806
|
+
*/
|
|
807
|
+
declare function resolveFieldBinding(node: Expr, ctx: CodegenContext, structType: Extract<BoundType, {
|
|
808
|
+
kind: "struct";
|
|
809
|
+
}>, outermost?: Expr): {
|
|
810
|
+
binding: Binding;
|
|
811
|
+
wrapperNode: Expr;
|
|
812
|
+
} | undefined;
|
|
813
|
+
//#endregion
|
|
814
|
+
//#region src/backend/resolve-output-tokens.d.ts
|
|
815
|
+
/**
|
|
816
|
+
* Compact consecutive literal tokens. Backends that emit string concatenation
|
|
817
|
+
* benefit from a shorter token stream; backends that template each token
|
|
818
|
+
* individually can ignore this and use `output.tokens` directly.
|
|
819
|
+
*/
|
|
820
|
+
declare function compactTokens(tokens: ResolvedToken[]): ResolvedToken[];
|
|
821
|
+
/**
|
|
822
|
+
* One output ready for codegen. `gate` is the wrapper sequence (outermost
|
|
823
|
+
* first); the backend renders each atom as the appropriate scope-introducing
|
|
824
|
+
* statement, then emits the path expression inside the innermost layer.
|
|
825
|
+
*/
|
|
826
|
+
interface OutputEmitPlan {
|
|
827
|
+
name: string;
|
|
828
|
+
gate: GateAtom[];
|
|
829
|
+
tokens: ResolvedToken[];
|
|
830
|
+
resolved: ResolvedOutput;
|
|
831
|
+
}
|
|
832
|
+
declare function planOutput(scopeGate: GateAtom[], output: ResolvedOutput, bindings: BindingRegistry): OutputEmitPlan;
|
|
833
|
+
/**
|
|
834
|
+
* Does the output have any conditional wrapper? Equivalent to "is at least one
|
|
835
|
+
* atom a `present` or `variant`?". `iter` alone means the output emits a list
|
|
836
|
+
* and is not conditionally absent.
|
|
837
|
+
*/
|
|
838
|
+
declare function isGated(plan: OutputEmitPlan): boolean;
|
|
839
|
+
/** Does the output iterate (emit zero-or-more values)? */
|
|
840
|
+
declare function isIterated(plan: OutputEmitPlan): boolean;
|
|
841
|
+
/**
|
|
842
|
+
* Convenience for backends emitting all outputs of a scope at once. The caller
|
|
843
|
+
* provides the scope's gate (typically `bindings.get(scope.scope)?.gate ?? []`).
|
|
844
|
+
*/
|
|
845
|
+
declare function planScope(scope: OutputScope, scopeGate: GateAtom[], bindings: BindingRegistry): OutputEmitPlan[];
|
|
846
|
+
//#endregion
|
|
847
|
+
//#region src/backend/sig-entries.d.ts
|
|
848
|
+
/**
|
|
849
|
+
* One entry of a kwarg-style signature, shared across language backends. Each
|
|
850
|
+
* entry describes a single user-facing parameter of the `_params()` factory
|
|
851
|
+
* and the kwarg wrapper:
|
|
852
|
+
* - `sigType`/`sigDefault` go directly into the function signature
|
|
853
|
+
* - `isOptional`/`hasExplicitDefault` drive the dict-build branches (required
|
|
854
|
+
* and explicitly-defaulted fields are always set; optional-no-default fields
|
|
855
|
+
* are conditionally set when not None/null)
|
|
856
|
+
* - `doc` is rendered into the per-param doc block (Args / @param)
|
|
857
|
+
*
|
|
858
|
+
* `name` is the scrubbed host identifier (used in the signature and function
|
|
859
|
+
* body); `wireKey` is the Boutiques field name (used as the dict key /
|
|
860
|
+
* TypedDict field key). They diverge when the wire key collides with a host
|
|
861
|
+
* reserved word, is not a valid identifier, or shadows a local in the emitting
|
|
862
|
+
* function (e.g. wire `float` -> host `float_`, wire `4d_input` -> host
|
|
863
|
+
* `v_4d_input`).
|
|
864
|
+
*/
|
|
865
|
+
interface SigEntry {
|
|
866
|
+
/** Scrubbed host identifier - safe to use in signatures and as a local. */
|
|
867
|
+
name: string;
|
|
868
|
+
/** Boutiques field name - used as the dict key / TypedDict field key. */
|
|
869
|
+
wireKey: string;
|
|
870
|
+
sigType: string;
|
|
871
|
+
/** Rendered default expression in the host language, or undefined for required-no-default. */
|
|
872
|
+
sigDefault?: string;
|
|
873
|
+
/** True iff the BoundType is `optional` (i.e. dict-build conditionally includes). */
|
|
874
|
+
isOptional: boolean;
|
|
875
|
+
/** True iff the field carries an explicit defaultValue in its FieldInfo. */
|
|
876
|
+
hasExplicitDefault: boolean;
|
|
877
|
+
doc?: string;
|
|
878
|
+
}
|
|
879
|
+
/** Per-backend rendering hooks for `buildSigEntries`. */
|
|
880
|
+
interface SigOptions {
|
|
881
|
+
/** Render a non-optional BoundType as a language-native type expression. */
|
|
882
|
+
renderType: (t: BoundType) => string;
|
|
883
|
+
/** Suffix appended to `renderType(inner)` for optional fields (e.g. ` | None`, ` | null`). */
|
|
884
|
+
nullableSuffix: string;
|
|
885
|
+
/** Default expression for optional-no-default fields (e.g. `None`, `null`). */
|
|
886
|
+
nullableDefault: string;
|
|
887
|
+
/** Render a JS scalar default as a host-language literal (e.g. `True`/`true`). */
|
|
888
|
+
renderDefault: (v: string | number | boolean) => string;
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Build per-field signature entries for the kwarg wrapper and params factory.
|
|
892
|
+
* Skips `@type` (the factory injects it as a constant). Required-no-default
|
|
893
|
+
* entries are placed before defaulted ones so the resulting signature is
|
|
894
|
+
* syntactically valid in both Python and TS.
|
|
895
|
+
*
|
|
896
|
+
* `registerLocal` is called once per field with the wire key; it must return
|
|
897
|
+
* a scrubbed, unique host identifier (typically by combining a language-aware
|
|
898
|
+
* scrub function with `Scope.add()`). The caller's scope should already have
|
|
899
|
+
* the function's other locals (`params`, `runner`, ...) reserved so this
|
|
900
|
+
* registration cannot collide with them.
|
|
901
|
+
*/
|
|
902
|
+
declare function buildSigEntries(rootType: Extract<BoundType, {
|
|
903
|
+
kind: "struct";
|
|
904
|
+
}>, fieldInfo: Map<string, FieldInfo>, registerLocal: (wireKey: string) => string, opts: SigOptions): SigEntry[];
|
|
905
|
+
//#endregion
|
|
906
|
+
//#region src/backend/type-keys.d.ts
|
|
907
|
+
/**
|
|
908
|
+
* Stable, fully structural identity key for any BoundType.
|
|
909
|
+
*
|
|
910
|
+
* Two types share a key iff they are structurally identical - same shape AND
|
|
911
|
+
* same leaf types/literal values, recursively. This is what `collectNamedTypes`
|
|
912
|
+
* dedups on: distinct nominal types must get distinct keys so each gets its own
|
|
913
|
+
* generated name.
|
|
914
|
+
*
|
|
915
|
+
* Keying on field/variant *names* alone is too coarse: discriminated-union
|
|
916
|
+
* variants that differ only by their `@type` literal (e.g. ANTs' `transform_*`
|
|
917
|
+
* variants, all `{ "@type": <literal>, gradient_step: float }`) would collapse
|
|
918
|
+
* to one identity, emitting `Transform = TransformRigid | TransformRigid | ...`
|
|
919
|
+
* and breaking discriminated-union narrowing. Including the field types (and
|
|
920
|
+
* thus the `@type` literal value) keeps them distinct.
|
|
921
|
+
*/
|
|
922
|
+
declare function typeKey(type: BoundType): string;
|
|
923
|
+
/** Stable identity key for a struct type (field names + field types). */
|
|
924
|
+
declare function structKey(type: Extract<BoundType, {
|
|
925
|
+
kind: "struct";
|
|
926
|
+
}>): string;
|
|
927
|
+
/** Stable identity key for a union type (variant names + variant types). */
|
|
928
|
+
declare function unionKey(type: Extract<BoundType, {
|
|
929
|
+
kind: "union";
|
|
930
|
+
}>): string;
|
|
931
|
+
//#endregion
|
|
932
|
+
//#region src/backend/python/python.d.ts
|
|
933
|
+
declare function generatePython(ctx: CodegenContext, packageScope?: Scope): string;
|
|
934
|
+
declare class PythonBackend implements Backend {
|
|
935
|
+
readonly name = "python";
|
|
936
|
+
readonly target = "python";
|
|
937
|
+
emitApp(ctx: CodegenContext, scope?: Scope): EmittedApp;
|
|
938
|
+
newPackageScope(): Scope;
|
|
939
|
+
emitPackage(pkg: PackageMeta, apps: EmittedApp[]): EmittedPackage;
|
|
940
|
+
emitProject(proj: ProjectMeta, packages: EmittedPackage[]): EmitResult;
|
|
941
|
+
}
|
|
942
|
+
//#endregion
|
|
943
|
+
//#region src/backend/snippet-core.d.ts
|
|
944
|
+
/**
|
|
945
|
+
* Per-language rendering hooks for the call-site snippet renderer. The recursive
|
|
946
|
+
* structure (struct -> object literal, union -> picked variant, list -> array)
|
|
947
|
+
* is language-agnostic; only leaf-literal syntax, object keys, and indentation
|
|
948
|
+
* differ, and those are supplied here.
|
|
949
|
+
*/
|
|
950
|
+
interface SnippetDialect {
|
|
951
|
+
/** One indentation level (e.g. `" "` for Python, `" "` for TypeScript). */
|
|
952
|
+
indentUnit: string;
|
|
953
|
+
/** Render a string value as a host literal (quoted). */
|
|
954
|
+
string(value: string): string;
|
|
955
|
+
/** Render a boolean value as a host literal (`True`/`true`). */
|
|
956
|
+
boolean(value: boolean): string;
|
|
957
|
+
/** Render a number value as a host literal. */
|
|
958
|
+
number(value: number): string;
|
|
959
|
+
/** Host literal for a null/None value. */
|
|
960
|
+
null: string;
|
|
961
|
+
/** Render an object-literal key from a wire key, quoting when not a bare identifier. */
|
|
962
|
+
objKey(wireKey: string): string;
|
|
963
|
+
}
|
|
964
|
+
/** Options shared by both language renderers. */
|
|
965
|
+
interface SnippetOptions {
|
|
966
|
+
/**
|
|
967
|
+
* Module the package is imported from (e.g. `"niwrap"`). Defaults to the
|
|
968
|
+
* project name on the context. When unset and no project name is available,
|
|
969
|
+
* Python falls back to a bare `import <pkg>` and TypeScript omits the import.
|
|
970
|
+
*/
|
|
971
|
+
packageRoot?: string;
|
|
972
|
+
/** Whether to prepend an import line. Defaults to `true`. */
|
|
973
|
+
includeImport?: boolean;
|
|
974
|
+
}
|
|
975
|
+
/**
|
|
976
|
+
* Render a struct config as a host object literal (Python dict / TS object).
|
|
977
|
+
* Keys are the Boutiques wire names (the generated TypedDict / interface keys) -
|
|
978
|
+
* nested structs have no constructor function in the generated code, so callers
|
|
979
|
+
* build them as plain object literals.
|
|
980
|
+
*
|
|
981
|
+
* `@type` is emitted from the struct's literal discriminator field when present
|
|
982
|
+
* (union variants carry a required, load-bearing `@type`); for the root call the
|
|
983
|
+
* tag is injected via `injectAtType` (the root's `@type` is derived from
|
|
984
|
+
* `pkg/appId`, not stored as a field). Non-`@type` literal fields have no
|
|
985
|
+
* runtime representation and are skipped.
|
|
986
|
+
*/
|
|
987
|
+
declare function renderStructLiteral(value: unknown, type: Extract<BoundType, {
|
|
988
|
+
kind: "struct";
|
|
989
|
+
}>, indent: string, d: SnippetDialect, injectAtType?: string): string;
|
|
990
|
+
/**
|
|
991
|
+
* Render a config value to a host-language expression, guided by its BoundType.
|
|
992
|
+
*
|
|
993
|
+
* `indent` is the leading whitespace of the line the value starts on; multi-line
|
|
994
|
+
* forms (object/array literals) place their members one level deeper and close
|
|
995
|
+
* back at `indent`. The renderer follows the BoundType tree for shape and reads
|
|
996
|
+
* the parallel config object for values, so unknown / absent keys are simply
|
|
997
|
+
* omitted (a partial config produces a partial snippet).
|
|
998
|
+
*/
|
|
999
|
+
declare function renderValue(value: unknown, type: BoundType, indent: string, d: SnippetDialect): string;
|
|
1000
|
+
//#endregion
|
|
1001
|
+
//#region src/backend/python/snippet.d.ts
|
|
1002
|
+
/**
|
|
1003
|
+
* Render a Python call snippet for one tool from a config object (the params
|
|
1004
|
+
* dict the form produces, keyed by Boutiques wire names).
|
|
1005
|
+
*
|
|
1006
|
+
* Struct-rooted tools use the ergonomic kwarg wrapper -
|
|
1007
|
+
* `fsl.bet(infile=..., fractional_intensity=0.5)` - whose keyword names are the
|
|
1008
|
+
* *scrubbed host* identifiers (`float` -> `float_`), not the wire keys; the
|
|
1009
|
+
* per-field mapping comes from the same `buildSigEntries` the generated wrapper
|
|
1010
|
+
* is built from, so the snippet matches the real signature. Nested structs /
|
|
1011
|
+
* union variants / lists-of-structs have no constructor in the generated code,
|
|
1012
|
+
* so they render as plain dict literals keyed by wire names.
|
|
1013
|
+
*
|
|
1014
|
+
* Union- (or otherwise non-struct-) rooted tools have no kwarg wrapper; the
|
|
1015
|
+
* single dict-style `<tool>` entry is called with one object-literal argument.
|
|
1016
|
+
*
|
|
1017
|
+
* The snippet matches the *standalone* (single-descriptor) emission of the same
|
|
1018
|
+
* context - which is how the hub compiles - not a catalog emission where a
|
|
1019
|
+
* shared package scope could suffix-bump a name.
|
|
1020
|
+
*
|
|
1021
|
+
* @param ctx - The compiled context (compile -> pipeline -> solve ->
|
|
1022
|
+
* resolveOutputs -> createContext, as in the CLI's `readAndCompile`).
|
|
1023
|
+
* @param config - The params object, keyed by Boutiques *wire* names (not host
|
|
1024
|
+
* identifiers). Every union-typed value - including the root of a union-rooted
|
|
1025
|
+
* tool - must carry its `@type` discriminator so the variant can be matched;
|
|
1026
|
+
* the root struct's `@type` is supplied by the renderer, so omit it there.
|
|
1027
|
+
* @param opts - Import and package-root options.
|
|
1028
|
+
*/
|
|
1029
|
+
declare function renderPythonCall(ctx: CodegenContext, config: Record<string, unknown>, opts?: SnippetOptions): string;
|
|
1030
|
+
//#endregion
|
|
1031
|
+
//#region src/backend/schema/jsonschema.d.ts
|
|
1032
|
+
interface JsonSchema {
|
|
1033
|
+
type?: string | string[];
|
|
1034
|
+
items?: JsonSchema;
|
|
1035
|
+
properties?: Record<string, JsonSchema>;
|
|
1036
|
+
required?: string[];
|
|
1037
|
+
oneOf?: JsonSchema[];
|
|
1038
|
+
enum?: (string | number)[];
|
|
1039
|
+
const?: string | number;
|
|
1040
|
+
[key: string]: unknown;
|
|
1041
|
+
}
|
|
1042
|
+
declare function generateSchema(ctx: CodegenContext): JsonSchema;
|
|
1043
|
+
/**
|
|
1044
|
+
* JSON Schema for a tool's **Outputs object**: the set of files it produces
|
|
1045
|
+
* (resolved outputs + mutable inputs surfaced as outputs) plus its captured
|
|
1046
|
+
* stdout/stderr streams. Built from the same `collectOutputFields` /
|
|
1047
|
+
* `streamFields` source of truth the Python and TypeScript backends use to type
|
|
1048
|
+
* the Outputs dataclass/interface, so the three describe the same shape.
|
|
1049
|
+
*
|
|
1050
|
+
* Field encoding (mirrors how the language backends type each field):
|
|
1051
|
+
* - required single -> `{ type: "string", x-styx-type: "path" }`
|
|
1052
|
+
* - optional single -> `{ type: ["string", "null"], x-styx-type: "path" }`
|
|
1053
|
+
* - list output -> `{ type: "array", items: { type: "string", x-styx-type: "path" } }`
|
|
1054
|
+
* - stream field -> `{ type: "array", items: { type: "string" } }` (lines of
|
|
1055
|
+
* text, NOT paths - the absent `x-styx-type` lets a consumer tell them apart)
|
|
1056
|
+
*
|
|
1057
|
+
* EVERY field is `required`: unlike the inputs schema (where an optional param
|
|
1058
|
+
* key is genuinely omitted, so "not in `required`" is faithful), an Outputs
|
|
1059
|
+
* field is always present - a gated single is `null`, a gated list is an empty
|
|
1060
|
+
* array. So optionality is carried by the `null` type branch, and a strict
|
|
1061
|
+
* validator accepts the actual emitted object (e.g. `{ "out_file": null }`).
|
|
1062
|
+
*/
|
|
1063
|
+
declare function generateOutputsSchema(ctx: CodegenContext): JsonSchema;
|
|
1064
|
+
declare class JsonSchemaBackend implements Backend {
|
|
1065
|
+
readonly name = "json-schema";
|
|
1066
|
+
readonly target = "json-schema";
|
|
1067
|
+
/** One scope per package so per-tool schema file stems stay unique in the suite directory. */
|
|
1068
|
+
newPackageScope(): Scope;
|
|
1069
|
+
emitApp(ctx: CodegenContext, scope?: Scope): EmittedApp;
|
|
1070
|
+
}
|
|
1071
|
+
//#endregion
|
|
1072
|
+
//#region src/backend/string-case.d.ts
|
|
1073
|
+
declare function snakeCase(s: string): string;
|
|
1074
|
+
declare function screamingSnakeCase(s: string): string;
|
|
1075
|
+
declare function pascalCase(s: string): string;
|
|
1076
|
+
declare function camelCase(s: string): string;
|
|
1077
|
+
//#endregion
|
|
1078
|
+
//#region src/backend/styxdefs-compat.d.ts
|
|
1079
|
+
/**
|
|
1080
|
+
* Runtime version floors baked into generated dependency metadata.
|
|
1081
|
+
*
|
|
1082
|
+
* styx2-generated code calls `mutable_copy` / `mutableCopy` (introduced in the
|
|
1083
|
+
* styxdefs 0.7.0 / styxdefs-js 0.2.0 release), so emitted packages genuinely
|
|
1084
|
+
* require that runtime floor. This is the single source of truth: bump here and
|
|
1085
|
+
* both the Python and TypeScript backends pick it up.
|
|
1086
|
+
*/
|
|
1087
|
+
declare const STYXDEFS_COMPAT: {
|
|
1088
|
+
/** PEP 508 specifier for the Python `styxdefs` package. */readonly python: ">=0.7.0,<0.8.0"; /** npm semver range for the `styxdefs` package. */
|
|
1089
|
+
readonly npm: "^0.2.0";
|
|
1090
|
+
};
|
|
1091
|
+
/**
|
|
1092
|
+
* Extra Python runtime packages the root distribution pulls in (container +
|
|
1093
|
+
* graph runners). Left unpinned - styxdefs's floor constrains them transitively
|
|
1094
|
+
* via their own inter-package pins.
|
|
1095
|
+
*/
|
|
1096
|
+
declare const PYTHON_RUNNER_DEPS: readonly ["styxdocker", "styxsingularity", "styxgraph"];
|
|
1097
|
+
//#endregion
|
|
1098
|
+
//#region src/backend/typescript/typescript.d.ts
|
|
1099
|
+
declare function generateTypeScript(ctx: CodegenContext, packageScope?: Scope): string;
|
|
1100
|
+
declare class TypeScriptBackend implements Backend {
|
|
1101
|
+
readonly name = "typescript";
|
|
1102
|
+
readonly target = "typescript";
|
|
1103
|
+
emitApp(ctx: CodegenContext, scope?: Scope): EmittedApp;
|
|
1104
|
+
newPackageScope(): Scope;
|
|
1105
|
+
emitPackage(pkg: PackageMeta, apps: EmittedApp[]): EmittedPackage;
|
|
1106
|
+
emitProject(proj: ProjectMeta, packages: EmittedPackage[]): EmitResult;
|
|
1107
|
+
}
|
|
1108
|
+
//#endregion
|
|
1109
|
+
//#region src/backend/typescript/snippet.d.ts
|
|
1110
|
+
/**
|
|
1111
|
+
* Render a TypeScript call snippet for one tool from a config object (keyed by
|
|
1112
|
+
* Boutiques wire names).
|
|
1113
|
+
*
|
|
1114
|
+
* The generated v2 kwarg wrapper takes *positional* arguments, which can't skip
|
|
1115
|
+
* a middle optional - so the runnable object-style entry is the dict-style
|
|
1116
|
+
* `<tool>Execute(params)` (struct roots). The snippet builds the params object
|
|
1117
|
+
* literal (wire-keyed, with the root `@type` injected) and passes it there.
|
|
1118
|
+
* Union- (or otherwise non-struct-) rooted tools call the dict-style `<tool>`
|
|
1119
|
+
* entry the same way. Nested structs / union variants / lists-of-structs have no
|
|
1120
|
+
* constructor in the generated code and render as object literals.
|
|
1121
|
+
*
|
|
1122
|
+
* The snippet matches the *standalone* (single-descriptor) emission of the same
|
|
1123
|
+
* context - which is how the hub compiles - not a catalog emission where a
|
|
1124
|
+
* shared package scope could suffix-bump a name.
|
|
1125
|
+
*
|
|
1126
|
+
* @param ctx - The compiled context (compile -> pipeline -> solve ->
|
|
1127
|
+
* resolveOutputs -> createContext, as in the CLI's `readAndCompile`).
|
|
1128
|
+
* @param config - The params object, keyed by Boutiques *wire* names. Every
|
|
1129
|
+
* union-typed value - including the root of a union-rooted tool - must carry
|
|
1130
|
+
* its `@type` discriminator so the variant can be matched; the root struct's
|
|
1131
|
+
* `@type` is supplied by the renderer, so omit it there.
|
|
1132
|
+
* @param opts - Import and package-root options.
|
|
1133
|
+
*/
|
|
1134
|
+
declare function renderTypeScriptCall(ctx: CodegenContext, config: Record<string, unknown>, opts?: SnippetOptions): string;
|
|
1135
|
+
//#endregion
|
|
1136
|
+
//#region src/index.d.ts
|
|
1137
|
+
declare function compile(source: string, filenameOrOptions?: string | {
|
|
1138
|
+
format?: FormatName;
|
|
1139
|
+
filename?: string;
|
|
1140
|
+
}): ParseResult;
|
|
1141
|
+
//#endregion
|
|
1142
|
+
export { AccessPath, AccessSegment, Alternative, AppMeta, Backend, Binding, BindingId, BindingRegistry, BoundType, BoundVariant, BoutiquesBackend, CodeBuilder, CodegenContext, Documentation, EmitError, EmitResult, EmitWarning, EmittedApp, EmittedPackage, Expr, FieldInfo, Float, FormatName, Frontend, GateAtom, Int, JsonSchema, JsonSchemaBackend, Literal, MediaTypeIdentifier, NamedType, NamingStrategy, NodeMeta, NodeRef, Optional, Output, OutputDiagnostic, OutputDiagnosticLevel, OutputEmitPlan, OutputResolution, OutputScope, OutputToken, OutputValidationResult, PYTHON_RUNNER_DEPS, PackageMeta, ParseError, ParseResult, ParseWarning, Pass, PassResult, PassStatus, Path, ProjectMeta, PythonBackend, Repeat, ResolvedOutput, ResolvedToken, STYXDEFS_COMPAT, ScalarKind, Scope, Sequence, SigEntry, SigOptions, SnippetDialect, SnippetOptions, SolveOptions, SolveResult, SourceLocation, Str, StreamOutput, StructuralNode, Terminal, TypeMap, TypeScriptBackend, alt, atomKey, buildSigEntries, camelCase, canonicalize, collectFieldInfo, collectNamedTypes, compactTokens, compile, compose, createContext, createPipeline, createRegistry, defaultNamingStrategy, defaultPipeline, detectFormat, effectiveOutputName, findDoc, findStructNode, fixpoint, flatten, float, format, formatSolveResult, generateBoutiques, generateOutputsSchema, generatePython, generateSchema, generateTypeScript, int, isGated, isIterated, isStructural, isTerminal, lit, nodeRef, opt, outputGate, pascalCase, path, planOutput, planScope, removeEmpty, renderPythonCall, renderStructLiteral, renderTypeScriptCall, renderValue, rep, repJoin, resolveFieldBinding, resolveOutputs, resolveTypeName, screamingSnakeCase, seq, seqJoin, simplify, snakeCase, solve, str, structKey, typeKey, unionKey };
|
|
1143
|
+
//# sourceMappingURL=index.d.mts.map
|