@studio-foundation/contracts 0.4.0-beta → 0.6.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 +1 -1
- package/dist/pipeline.d.ts +73 -1
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +6 -0
- package/dist/pipeline.js.map +1 -1
- package/dist/task.d.ts +25 -0
- package/dist/task.d.ts.map +1 -1
- package/dist/validation.d.ts +75 -4
- package/dist/validation.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @studio-foundation/contracts
|
|
2
2
|
|
|
3
|
-
**Studio** is
|
|
3
|
+
**Studio** is a declarative YAML runtime for AI agents. It orchestrates multi-stage agent workflows with structured output validation and automatic retry. This package is **contracts**: the shared TypeScript types and interfaces that every other Studio package imports. Zero dependencies, zero logic.
|
|
4
4
|
|
|
5
5
|
`contracts` is the leaf of the dependency graph. It defines the language all Studio packages speak: `PipelineDefinition`, `StageRun`, `OutputContract`, `AgentConfig`, `LLMRequest`, and the rest. Install it if you're writing tooling that reads or produces Studio configs, or if you're embedding Studio packages into your own code and need the types.
|
|
6
6
|
|
package/dist/pipeline.d.ts
CHANGED
|
@@ -67,7 +67,7 @@ export interface StageDefinition {
|
|
|
67
67
|
};
|
|
68
68
|
hooks?: StageHooks;
|
|
69
69
|
}
|
|
70
|
-
export type PipelineEntry = StageDefinition | StageGroup;
|
|
70
|
+
export type PipelineEntry = StageDefinition | StageGroup | MapStage | CallStage;
|
|
71
71
|
export interface StageGroup {
|
|
72
72
|
group: string;
|
|
73
73
|
max_iterations: number;
|
|
@@ -75,5 +75,77 @@ export interface StageGroup {
|
|
|
75
75
|
on_failure?: 'fail-fast' | 'collect-all';
|
|
76
76
|
stages: StageDefinition[];
|
|
77
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* A fan-out / map stage: run a sub-pipeline once per item of a list, then
|
|
80
|
+
* collect the structured outputs. Replaces the "shell `studio run` per item +
|
|
81
|
+
* scrape the log" glue — the child runs are spawned in-process via the engine's
|
|
82
|
+
* RunSpawner and their last-stage output is returned directly (no scraping).
|
|
83
|
+
*/
|
|
84
|
+
export interface MapStage {
|
|
85
|
+
map: string;
|
|
86
|
+
condition?: string;
|
|
87
|
+
over: string;
|
|
88
|
+
pipeline: string;
|
|
89
|
+
/**
|
|
90
|
+
* Per-item input template. Each value may reference the current item and the
|
|
91
|
+
* pipeline input via {{item}}, {{item.<path>}}, {{index}}, {{input.<path>}}.
|
|
92
|
+
* A value that is exactly "{{item}}" (or "{{input.x}}") keeps the resolved
|
|
93
|
+
* value's native type; mixed strings interpolate to text.
|
|
94
|
+
*/
|
|
95
|
+
input?: Record<string, unknown>;
|
|
96
|
+
as?: string;
|
|
97
|
+
concurrency?: number;
|
|
98
|
+
on_item_failure?: 'fail-fast' | 'collect-all';
|
|
99
|
+
/**
|
|
100
|
+
* Per-item resume (default: false). When `true`, a re-run of this map stage
|
|
101
|
+
* skips items that already completed successfully in an earlier run and
|
|
102
|
+
* re-spawns only the incomplete ones — the shape `discover_relationships.py`'s
|
|
103
|
+
* per-chunk votes cache has by hand, lifted into the engine so a run of
|
|
104
|
+
* hundreds of network-bound items isn't all-or-nothing (one timeout near the
|
|
105
|
+
* end no longer re-costs the whole stage).
|
|
106
|
+
*
|
|
107
|
+
* The resume key is derived from the **item input** (the sub-pipeline input
|
|
108
|
+
* built for this item), never its index or list position. So:
|
|
109
|
+
* - reordering or filtering the `over:` list still hits the cache — a verdict
|
|
110
|
+
* computed for item X is never replayed for a different item Y (the
|
|
111
|
+
* identity-vs-inputs trap recorded in wiki-creator's alias/page caches);
|
|
112
|
+
* - changing an item's content (or the `input:`/`as:` mapping, or the target
|
|
113
|
+
* `pipeline:`) changes the key, so that item is recomputed.
|
|
114
|
+
*
|
|
115
|
+
* A per-item **failure is never cached** — a failed item retries on the next
|
|
116
|
+
* run while completed items stay done. Resume is orthogonal to
|
|
117
|
+
* `on_item_failure`: the cache is consulted and written under both `fail-fast`
|
|
118
|
+
* and `collect-all`, and a cache-served item counts as a success (it never
|
|
119
|
+
* trips `fail-fast`).
|
|
120
|
+
*
|
|
121
|
+
* The cache lives on disk under `.studio/runs/map-cache/…`, keyed by parent
|
|
122
|
+
* pipeline + stage + sub-pipeline + item-input hash, so it survives a process
|
|
123
|
+
* restart between runs.
|
|
124
|
+
*/
|
|
125
|
+
resume?: boolean;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* A call stage: run a named pipeline once, inline, and expose its output to
|
|
129
|
+
* later parent stages under the stage name. This is `map` with the iteration
|
|
130
|
+
* removed — same RunSpawner machinery, structured output, no log scraping — for
|
|
131
|
+
* when the shape is a sequence, not a fan-out (e.g. chaining wiki-extraction →
|
|
132
|
+
* wiki-resolution → wiki-preparation → pages-export in one top-level pipeline).
|
|
133
|
+
*/
|
|
134
|
+
export interface CallStage {
|
|
135
|
+
call: string;
|
|
136
|
+
condition?: string;
|
|
137
|
+
pipeline?: string;
|
|
138
|
+
/**
|
|
139
|
+
* Input for the child run. Each value may reference the parent context via
|
|
140
|
+
* {{input}}, {{input.<path>}}, {{stages.<name>.output.<path>}} — the same
|
|
141
|
+
* substitution as `map`'s `input`, minus the per-item {{item}}/{{index}}. A
|
|
142
|
+
* value that is exactly one {{ref}} keeps the resolved value's native type;
|
|
143
|
+
* any other string interpolates to text. Omitted → the parent input is
|
|
144
|
+
* forwarded to the child unchanged.
|
|
145
|
+
*/
|
|
146
|
+
input?: Record<string, unknown>;
|
|
147
|
+
}
|
|
78
148
|
export declare function isStageGroup(entry: PipelineEntry): entry is StageGroup;
|
|
149
|
+
export declare function isMapStage(entry: PipelineEntry): entry is MapStage;
|
|
150
|
+
export declare function isCallStage(entry: PipelineEntry): entry is CallStage;
|
|
79
151
|
//# sourceMappingURL=pipeline.d.ts.map
|
package/dist/pipeline.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,cAAc,EAAE,CAAC;IACrC,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,IAAI,CAAC,EAAE;QACL,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAID,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,iBAAiB,CAAC,EAAE,YAAY,EAAE,CAAC;IACnC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,WAAW,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
|
package/dist/pipeline.js
CHANGED
|
@@ -2,4 +2,10 @@
|
|
|
2
2
|
export function isStageGroup(entry) {
|
|
3
3
|
return 'group' in entry && 'stages' in entry;
|
|
4
4
|
}
|
|
5
|
+
export function isMapStage(entry) {
|
|
6
|
+
return 'map' in entry && 'over' in entry;
|
|
7
|
+
}
|
|
8
|
+
export function isCallStage(entry) {
|
|
9
|
+
return 'call' in entry;
|
|
10
|
+
}
|
|
5
11
|
//# sourceMappingURL=pipeline.js.map
|
package/dist/pipeline.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA,iCAAiC;
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA,iCAAiC;AAuKjC,MAAM,UAAU,YAAY,CAAC,KAAoB;IAC/C,OAAO,OAAO,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,OAAO,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI,KAAK,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAoB;IAC9C,OAAO,MAAM,IAAI,KAAK,CAAC;AACzB,CAAC"}
|
package/dist/task.d.ts
CHANGED
|
@@ -1,2 +1,27 @@
|
|
|
1
1
|
export type TaskStatus = 'pending' | 'running' | 'success' | 'failed';
|
|
2
|
+
/**
|
|
3
|
+
* Input contract for a single agent run, carried from the engine to the runner.
|
|
4
|
+
*
|
|
5
|
+
* `description` is the default flat task text — most pipelines have only this.
|
|
6
|
+
* `fields`, when present, SUPERSEDES `description`: named fields are preserved
|
|
7
|
+
* structurally so anonymization can tokenize each independently (run-level
|
|
8
|
+
* shared keymap) BEFORE the prompt is assembled, and prompt assembly renders
|
|
9
|
+
* the fields. Field names are OPAQUE to the kernel — it imposes no domain
|
|
10
|
+
* meaning on them; an input opts into field-addressing, the kernel never
|
|
11
|
+
* requires it. One documented branch: `fields` present → field path; absent →
|
|
12
|
+
* flat-description path unchanged.
|
|
13
|
+
*/
|
|
14
|
+
export interface TaskInput {
|
|
15
|
+
description: string;
|
|
16
|
+
fields?: Record<string, string>;
|
|
17
|
+
/**
|
|
18
|
+
* Opaque scope: names of `fields` to anonymize. Treated as opaque strings —
|
|
19
|
+
* the kernel imposes no domain meaning (INV-04). Undefined → anonymize all
|
|
20
|
+
* fields (fail-safe); [] → anonymize none; ['a'] → only field `a`. Ignored
|
|
21
|
+
* when `fields` is absent.
|
|
22
|
+
*/
|
|
23
|
+
anonymize_fields?: string[];
|
|
24
|
+
expected_output?: string;
|
|
25
|
+
contract_name?: string;
|
|
26
|
+
}
|
|
2
27
|
//# sourceMappingURL=task.d.ts.map
|
package/dist/task.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
|
package/dist/validation.d.ts
CHANGED
|
@@ -5,14 +5,85 @@ export interface ToolCallRequirements {
|
|
|
5
5
|
required_tool_groups?: string[][];
|
|
6
6
|
counted_tools?: string[];
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* An external validator: a shell command that receives the stage output as JSON
|
|
10
|
+
* on stdin and prints `{ "valid": boolean, "errors": string[] }` to stdout.
|
|
11
|
+
*
|
|
12
|
+
* This is the escape hatch for validation the declarative schema cannot express
|
|
13
|
+
* (cross-field rules, computed constraints) and for validators written in another
|
|
14
|
+
* language. Field-level shape — types, enums, nested required fields — now lives
|
|
15
|
+
* declaratively in `schema.fields` (see FieldSpec); reach for an external validator
|
|
16
|
+
* only when a rule spans multiple fields or needs real code. Unlike a required tool,
|
|
17
|
+
* it runs against the ACTUAL stage output, so the agent cannot satisfy it by
|
|
18
|
+
* reporting different arguments than it emits.
|
|
19
|
+
*/
|
|
20
|
+
export interface ExternalValidator {
|
|
21
|
+
name: string;
|
|
22
|
+
/** Shell command. Receives the output JSON on stdin; prints {valid, errors} on stdout. */
|
|
23
|
+
command: string;
|
|
24
|
+
/** Optional timeout in milliseconds (default 30000). */
|
|
25
|
+
timeout_ms?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Post-execution filesystem check: the files/artifacts a stage MUST leave on
|
|
29
|
+
* disk to be considered done. A "success" return code doesn't prove the agent
|
|
30
|
+
* actually produced its outputs — this closes that gap. Each entry is a path or
|
|
31
|
+
* glob (relative to the repo workspace); a stage fails if any entry matches no
|
|
32
|
+
* existing file. Runs inside the RALPH loop, so a miss enriches the retry
|
|
33
|
+
* feedback before the stage is finally failed.
|
|
34
|
+
*/
|
|
35
|
+
export interface ExpectedOutputs {
|
|
36
|
+
/** Paths or glob patterns (relative to the repo workspace). Each must match ≥1 existing file. */
|
|
37
|
+
files: string[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The JSON type a field is expected to hold. `integer` is `number` narrowed to
|
|
41
|
+
* whole values; `object` excludes arrays and null (use `array` for lists).
|
|
42
|
+
*/
|
|
43
|
+
export type FieldType = 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array';
|
|
44
|
+
/**
|
|
45
|
+
* Declarative shape of a single field — the piece that lifts contract validation
|
|
46
|
+
* beyond "the key is present" (required_fields) to "the value is the right type,
|
|
47
|
+
* one of the allowed values, and structurally sound".
|
|
48
|
+
*
|
|
49
|
+
* Every check is optional and only fires when the field is actually present;
|
|
50
|
+
* presence is still governed by `required_fields`. This keeps the two orthogonal:
|
|
51
|
+
* `required_fields` says a field must exist, `fields` says what it must look like.
|
|
52
|
+
*
|
|
53
|
+
* Recursion covers nested structures the PoC contracts need:
|
|
54
|
+
* - `type: object` + `required_fields`/`fields` validates a sub-object
|
|
55
|
+
* - `type: array` + `items` validates every element (e.g. each `pages[]` entry)
|
|
56
|
+
*/
|
|
57
|
+
export interface FieldSpec {
|
|
58
|
+
/** Expected JSON type. On mismatch the field fails and nested checks are skipped. */
|
|
59
|
+
type?: FieldType;
|
|
60
|
+
/** Allowed values (enumeration), compared with strict equality. */
|
|
61
|
+
enum?: Array<string | number | boolean>;
|
|
62
|
+
/** For objects: names of nested fields that must be present. */
|
|
63
|
+
required_fields?: string[];
|
|
64
|
+
/** For objects: per-field specs applied to nested fields that are present. */
|
|
65
|
+
fields?: Record<string, FieldSpec>;
|
|
66
|
+
/** For arrays: the spec every element must satisfy. */
|
|
67
|
+
items?: FieldSpec;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A stage's output schema. `required_fields` checks top-level presence; `fields`
|
|
71
|
+
* adds declarative type/enum/nested validation for the fields it names. Both are
|
|
72
|
+
* optional and compose — a contract can use either, both, or neither.
|
|
73
|
+
*/
|
|
74
|
+
export interface OutputSchema {
|
|
75
|
+
required_fields?: string[];
|
|
76
|
+
fields?: Record<string, FieldSpec>;
|
|
77
|
+
}
|
|
8
78
|
export interface OutputContract {
|
|
9
79
|
name: string;
|
|
10
80
|
version: number;
|
|
11
|
-
schema?:
|
|
12
|
-
required_fields?: string[];
|
|
13
|
-
[key: string]: unknown;
|
|
14
|
-
};
|
|
81
|
+
schema?: OutputSchema;
|
|
15
82
|
tool_calls?: ToolCallRequirements;
|
|
83
|
+
/** External validators run against the real output inside the RALPH loop. */
|
|
84
|
+
validators?: ExternalValidator[];
|
|
85
|
+
/** Files/artifacts the stage must leave on disk. Checked post-execution. */
|
|
86
|
+
expected_outputs?: ExpectedOutputs;
|
|
16
87
|
custom_rules?: ValidationRule[];
|
|
17
88
|
post_validation?: {
|
|
18
89
|
rejection_detection: {
|
package/dist/validation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,iGAAiG;IACjG,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEzF;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,SAAS;IACxB,qFAAqF;IACrF,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,mEAAmE;IACnE,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACxC,gEAAgE;IAChE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnC,uDAAuD;IACvD,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC,6EAA6E;IAC7E,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,eAAe,CAAC;IACnC,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE;QAChB,mBAAmB,EAAE;YACnB,KAAK,EAAE,MAAM,CAAC;YACd,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;YAC3B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;YAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;YACvB,aAAa,CAAC,EAAE,MAAM,CAAC;YACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;SAC9B,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@studio-foundation/contracts",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Shared TypeScript types and interfaces for Studio
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Shared TypeScript types and interfaces for Studio packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|