harness-dispatch 0.4.0 → 0.5.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 +228 -86
- package/config.default.yaml +416 -397
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +2 -2
- package/dist/auth.js.map +1 -1
- package/dist/billing.d.ts +35 -4
- package/dist/billing.d.ts.map +1 -1
- package/dist/billing.js +48 -17
- package/dist/billing.js.map +1 -1
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +253 -23
- package/dist/bin.js.map +1 -1
- package/dist/breaker-store.d.ts +60 -9
- package/dist/breaker-store.d.ts.map +1 -1
- package/dist/breaker-store.js +246 -50
- package/dist/breaker-store.js.map +1 -1
- package/dist/circuit-breaker.d.ts +35 -0
- package/dist/circuit-breaker.d.ts.map +1 -1
- package/dist/circuit-breaker.js +68 -11
- package/dist/circuit-breaker.js.map +1 -1
- package/dist/config/coercions.d.ts +31 -0
- package/dist/config/coercions.d.ts.map +1 -0
- package/dist/config/coercions.js +169 -0
- package/dist/config/coercions.js.map +1 -0
- package/dist/config/env-interpolation.d.ts +36 -0
- package/dist/config/env-interpolation.d.ts.map +1 -0
- package/dist/config/env-interpolation.js +73 -0
- package/dist/config/env-interpolation.js.map +1 -0
- package/dist/config/protocol.d.ts +51 -0
- package/dist/config/protocol.d.ts.map +1 -0
- package/dist/config/protocol.js +300 -0
- package/dist/config/protocol.js.map +1 -0
- package/dist/config/validation.d.ts +72 -0
- package/dist/config/validation.d.ts.map +1 -0
- package/dist/config/validation.js +189 -0
- package/dist/config/validation.js.map +1 -0
- package/dist/config.d.ts +19 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +229 -511
- package/dist/config.js.map +1 -1
- package/dist/dispatch-log.d.ts.map +1 -1
- package/dist/dispatch-log.js +2 -3
- package/dist/dispatch-log.js.map +1 -1
- package/dist/dispatchers/generic-cli.d.ts +15 -1
- package/dist/dispatchers/generic-cli.d.ts.map +1 -1
- package/dist/dispatchers/generic-cli.js +65 -5
- package/dist/dispatchers/generic-cli.js.map +1 -1
- package/dist/dispatchers/openai-compatible.d.ts.map +1 -1
- package/dist/dispatchers/openai-compatible.js +52 -2
- package/dist/dispatchers/openai-compatible.js.map +1 -1
- package/dist/dispatchers/shared/kill-tree.d.ts +17 -4
- package/dist/dispatchers/shared/kill-tree.d.ts.map +1 -1
- package/dist/dispatchers/shared/kill-tree.js +28 -4
- package/dist/dispatchers/shared/kill-tree.js.map +1 -1
- package/dist/dispatchers/shared/rate-limit-headers.d.ts +17 -0
- package/dist/dispatchers/shared/rate-limit-headers.d.ts.map +1 -1
- package/dist/dispatchers/shared/rate-limit-headers.js +27 -0
- package/dist/dispatchers/shared/rate-limit-headers.js.map +1 -1
- package/dist/dispatchers/shared/stream-subprocess.d.ts.map +1 -1
- package/dist/dispatchers/shared/stream-subprocess.js +5 -0
- package/dist/dispatchers/shared/stream-subprocess.js.map +1 -1
- package/dist/dispatchers/shared/subprocess.d.ts.map +1 -1
- package/dist/dispatchers/shared/subprocess.js +3 -0
- package/dist/dispatchers/shared/subprocess.js.map +1 -1
- package/dist/dispatchers/shared/which-available.d.ts.map +1 -1
- package/dist/dispatchers/shared/which-available.js +16 -2
- package/dist/dispatchers/shared/which-available.js.map +1 -1
- package/dist/file-lock.d.ts +17 -0
- package/dist/file-lock.d.ts.map +1 -0
- package/dist/file-lock.js +143 -0
- package/dist/file-lock.js.map +1 -0
- package/dist/http/server.d.ts +11 -0
- package/dist/http/server.d.ts.map +1 -1
- package/dist/http/server.js +331 -162
- package/dist/http/server.js.map +1 -1
- package/dist/job-runner.js +23 -5
- package/dist/job-runner.js.map +1 -1
- package/dist/jobs.d.ts +91 -1
- package/dist/jobs.d.ts.map +1 -1
- package/dist/jobs.js +647 -36
- package/dist/jobs.js.map +1 -1
- package/dist/leaderboard.d.ts +24 -1
- package/dist/leaderboard.d.ts.map +1 -1
- package/dist/leaderboard.js +94 -2
- package/dist/leaderboard.js.map +1 -1
- package/dist/mcp/config-hot-reload.d.ts.map +1 -1
- package/dist/mcp/config-hot-reload.js +1 -1
- package/dist/mcp/config-hot-reload.js.map +1 -1
- package/dist/mcp/dispatcher-factory.d.ts +16 -1
- package/dist/mcp/dispatcher-factory.d.ts.map +1 -1
- package/dist/mcp/dispatcher-factory.js +41 -3
- package/dist/mcp/dispatcher-factory.js.map +1 -1
- package/dist/mcp/tools.d.ts +23 -4
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +163 -16
- package/dist/mcp/tools.js.map +1 -1
- package/dist/observability/index.d.ts +16 -3
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +23 -7
- package/dist/observability/index.js.map +1 -1
- package/dist/observability/spans.d.ts.map +1 -1
- package/dist/observability/spans.js +4 -1
- package/dist/observability/spans.js.map +1 -1
- package/dist/quota.d.ts +88 -22
- package/dist/quota.d.ts.map +1 -1
- package/dist/quota.js +163 -58
- package/dist/quota.js.map +1 -1
- package/dist/route-policy.d.ts.map +1 -1
- package/dist/route-policy.js +13 -3
- package/dist/route-policy.js.map +1 -1
- package/dist/router.d.ts +25 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +94 -40
- package/dist/router.js.map +1 -1
- package/dist/safety.d.ts.map +1 -1
- package/dist/safety.js +11 -2
- package/dist/safety.js.map +1 -1
- package/dist/state-dir.d.ts +17 -0
- package/dist/state-dir.d.ts.map +1 -0
- package/dist/state-dir.js +21 -0
- package/dist/state-dir.js.map +1 -0
- package/dist/status.d.ts +36 -0
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +61 -4
- package/dist/status.js.map +1 -1
- package/dist/types.d.ts +50 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/working-dir.d.ts +13 -0
- package/dist/working-dir.d.ts.map +1 -1
- package/dist/working-dir.js +27 -0
- package/dist/working-dir.js.map +1 -1
- package/dist/workspace-lock.d.ts +40 -0
- package/dist/workspace-lock.d.ts.map +1 -0
- package/dist/workspace-lock.js +258 -0
- package/dist/workspace-lock.js.map +1 -0
- package/dist/workspaces.d.ts +15 -0
- package/dist/workspaces.d.ts.map +1 -1
- package/dist/workspaces.js +104 -12
- package/dist/workspaces.js.map +1 -1
- package/package.json +98 -96
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsing for a route's `protocol:` block — how a CLI harness is actually
|
|
3
|
+
* invoked and how its output is read.
|
|
4
|
+
*
|
|
5
|
+
* Split out of config.ts. This is the largest single concern in that file and
|
|
6
|
+
* the most self-contained: it turns YAML into a CliProtocolConfig and knows
|
|
7
|
+
* nothing about routes, billing, or defaults merging.
|
|
8
|
+
*
|
|
9
|
+
* It is also the reason `harness: generic` works at all — every CLI harness,
|
|
10
|
+
* built-in or user-added, is driven by this structure rather than by
|
|
11
|
+
* TypeScript. That is why a malformed protocol block skips the whole entry
|
|
12
|
+
* with a warning instead of landing a route that would fail at dispatch time.
|
|
13
|
+
*/
|
|
14
|
+
import { str } from "./coercions.js";
|
|
15
|
+
const SAFETY_PROFILES = ["read_only", "workspace_edit", "full_auto"];
|
|
16
|
+
/** The full set of `{{name}}` tokens expandToken() in generic-cli.ts understands. */
|
|
17
|
+
export const KNOWN_ARG_PLACEHOLDERS = new Set([
|
|
18
|
+
"{{prompt}}",
|
|
19
|
+
"{{model}}",
|
|
20
|
+
"{{safety}}",
|
|
21
|
+
"{{working_dir}}",
|
|
22
|
+
"{{file_dirs}}",
|
|
23
|
+
"{{native_args}}",
|
|
24
|
+
]);
|
|
25
|
+
export function stringArrayFrom(raw) {
|
|
26
|
+
if (!Array.isArray(raw))
|
|
27
|
+
return undefined;
|
|
28
|
+
const out = raw.filter((v) => typeof v === "string");
|
|
29
|
+
return out.length > 0 ? out : undefined;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse `protocol:` for any route (see CliProtocolConfig in types.ts).
|
|
33
|
+
* Three shapes:
|
|
34
|
+
* - A string ("cursor", "codex", ...) — looked up in presets by
|
|
35
|
+
* name. Lets a config select a known protocol without retyping it, and
|
|
36
|
+
* is the extension point for "others add further protocols" — a new
|
|
37
|
+
* named entry in the shipped config.default.yaml is immediately selectable here,
|
|
38
|
+
* no code changes.
|
|
39
|
+
* - An object with `extends: <preset name>` — starts from that preset and
|
|
40
|
+
* overrides only the fields present, for the common "95% the same, one
|
|
41
|
+
* flag different" case. safety merges per-profile (overriding just
|
|
42
|
+
* full_auto doesn't erase read_only/workspace_edit from the preset).
|
|
43
|
+
* - A plain object — the full protocol, no preset involved (unchanged
|
|
44
|
+
* behavior from before presets existed).
|
|
45
|
+
*
|
|
46
|
+
* Returns undefined — with a warning — for anything malformed, so a broken
|
|
47
|
+
* block degrades to "route unusable" (isAvailable() checks for a missing
|
|
48
|
+
* protocol) rather than a half-built dispatcher silently doing the wrong
|
|
49
|
+
* thing.
|
|
50
|
+
*/
|
|
51
|
+
export function protocolFrom(raw, routeLabel, warnings,
|
|
52
|
+
// REQUIRED, deliberately not defaulted to {}. A default made a forgotten
|
|
53
|
+
// argument resolve every preset name to nothing — silently, at runtime,
|
|
54
|
+
// which is the exact failure mode this file's own history is made of. As a
|
|
55
|
+
// required parameter the compiler catches it instead.
|
|
56
|
+
presets) {
|
|
57
|
+
if (typeof raw === "string") {
|
|
58
|
+
const preset = presets[raw];
|
|
59
|
+
if (!preset) {
|
|
60
|
+
warnings.push(`${routeLabel}: protocol "${raw}" is not a known preset (expected one of: ` +
|
|
61
|
+
`${Object.keys(presets).join(", ")}) — entry ignored.`);
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
return preset;
|
|
65
|
+
}
|
|
66
|
+
if (raw === null || typeof raw !== "object")
|
|
67
|
+
return undefined;
|
|
68
|
+
const r = raw;
|
|
69
|
+
let base;
|
|
70
|
+
if (typeof r.extends === "string") {
|
|
71
|
+
base = presets[r.extends];
|
|
72
|
+
if (!base) {
|
|
73
|
+
warnings.push(`${routeLabel}: protocol.extends "${r.extends}" is not a known preset (expected one of: ` +
|
|
74
|
+
`${Object.keys(presets).join(", ")}) — entry ignored.`);
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return parseProtocolFields(r, routeLabel, warnings, base);
|
|
79
|
+
}
|
|
80
|
+
export function parseProtocolFields(r, routeLabel, warnings, base) {
|
|
81
|
+
const args = stringArrayFrom(r.args) ?? base?.args;
|
|
82
|
+
if (args === undefined) {
|
|
83
|
+
warnings.push(`${routeLabel}: protocol.args is required — entry ignored.`);
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
const outputRaw = r.output;
|
|
87
|
+
let output = base?.output;
|
|
88
|
+
if (outputRaw !== undefined) {
|
|
89
|
+
if (outputRaw === null || typeof outputRaw !== "object") {
|
|
90
|
+
warnings.push(`${routeLabel}: protocol.output must be an object — entry ignored.`);
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const o = outputRaw;
|
|
94
|
+
if (o.mode !== "text" && o.mode !== "json_field" && o.mode !== "jsonl_stream") {
|
|
95
|
+
warnings.push(`${routeLabel}: protocol.output.mode must be one of text | json_field | jsonl_stream — entry ignored.`);
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
output = { mode: o.mode };
|
|
99
|
+
const fields = stringArrayFrom(o.fields);
|
|
100
|
+
if (fields !== undefined)
|
|
101
|
+
output.fields = fields;
|
|
102
|
+
const usageRaw = o.usage;
|
|
103
|
+
if (usageRaw !== null && typeof usageRaw === "object") {
|
|
104
|
+
const u = usageRaw;
|
|
105
|
+
const input = stringArrayFrom(u.input);
|
|
106
|
+
const outputTokens = stringArrayFrom(u.output);
|
|
107
|
+
if (input !== undefined && outputTokens !== undefined)
|
|
108
|
+
output.usage = { input, output: outputTokens };
|
|
109
|
+
}
|
|
110
|
+
const eventRulesRaw = o.event_rules;
|
|
111
|
+
if (Array.isArray(eventRulesRaw)) {
|
|
112
|
+
const eventRules = [];
|
|
113
|
+
for (const [i, ruleRaw] of eventRulesRaw.entries()) {
|
|
114
|
+
const rule = eventRuleFrom(ruleRaw, `${routeLabel}: protocol.output.event_rules[${i}]`, warnings);
|
|
115
|
+
if (rule)
|
|
116
|
+
eventRules.push(rule);
|
|
117
|
+
}
|
|
118
|
+
if (eventRules.length > 0)
|
|
119
|
+
output.eventRules = eventRules;
|
|
120
|
+
}
|
|
121
|
+
const errorRaw = o.error;
|
|
122
|
+
if (errorRaw !== null && typeof errorRaw === "object") {
|
|
123
|
+
const e = errorRaw;
|
|
124
|
+
const field = str(e.field);
|
|
125
|
+
if (field !== undefined) {
|
|
126
|
+
const messageFields = stringArrayFrom(e.message_fields);
|
|
127
|
+
output.error = messageFields !== undefined ? { field, messageFields } : { field };
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
warnings.push(`${routeLabel}: protocol.output.error.field is required — error detection ignored.`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (output === undefined) {
|
|
135
|
+
warnings.push(`${routeLabel}: protocol.output is required — entry ignored.`);
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
const protocol = { args, output };
|
|
139
|
+
const stdin = typeof r.stdin === "boolean" ? r.stdin : base?.stdin;
|
|
140
|
+
if (stdin !== undefined)
|
|
141
|
+
protocol.stdin = stdin;
|
|
142
|
+
const modelRaw = r.model;
|
|
143
|
+
if (modelRaw !== undefined && modelRaw !== null) {
|
|
144
|
+
const m = modelRaw;
|
|
145
|
+
if (typeof m.flag === "string" && m.flag) {
|
|
146
|
+
protocol.model = { flag: m.flag };
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
warnings.push(`${routeLabel}: protocol.model set but missing a "flag" string — ignored.`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else if (base?.model) {
|
|
153
|
+
protocol.model = base.model;
|
|
154
|
+
}
|
|
155
|
+
const workingDirRaw = r.working_dir;
|
|
156
|
+
if (workingDirRaw !== undefined && workingDirRaw !== null) {
|
|
157
|
+
const wd = workingDirRaw;
|
|
158
|
+
if (typeof wd.flag === "string" && wd.flag) {
|
|
159
|
+
protocol.workingDir = { flag: wd.flag };
|
|
160
|
+
const extraArgsWhenSet = stringArrayFrom(wd.extra_args_when_set);
|
|
161
|
+
if (extraArgsWhenSet !== undefined)
|
|
162
|
+
protocol.workingDir.extraArgsWhenSet = extraArgsWhenSet;
|
|
163
|
+
if (wd.fallback === "home")
|
|
164
|
+
protocol.workingDir.fallback = "home";
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
warnings.push(`${routeLabel}: protocol.working_dir set but missing a "flag" string — ignored.`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else if (base?.workingDir) {
|
|
171
|
+
protocol.workingDir = base.workingDir;
|
|
172
|
+
}
|
|
173
|
+
const fileDirsRaw = r.file_dirs;
|
|
174
|
+
if (fileDirsRaw !== undefined && fileDirsRaw !== null) {
|
|
175
|
+
const fd = fileDirsRaw;
|
|
176
|
+
if (typeof fd.flag === "string" && fd.flag) {
|
|
177
|
+
protocol.fileDirs = { flag: fd.flag };
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
warnings.push(`${routeLabel}: protocol.file_dirs set but missing a "flag" string — ignored.`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else if (base?.fileDirs) {
|
|
184
|
+
protocol.fileDirs = base.fileDirs;
|
|
185
|
+
}
|
|
186
|
+
const fileListHeader = str(r.file_list_header) ?? base?.fileListHeader;
|
|
187
|
+
if (fileListHeader !== undefined)
|
|
188
|
+
protocol.fileListHeader = fileListHeader;
|
|
189
|
+
const fileListBullet = (typeof r.file_list_bullet === "string" ? r.file_list_bullet : undefined) ?? base?.fileListBullet;
|
|
190
|
+
if (fileListBullet !== undefined)
|
|
191
|
+
protocol.fileListBullet = fileListBullet;
|
|
192
|
+
const apiKeyEnvVar = str(r.api_key_env_var) ?? base?.apiKeyEnvVar;
|
|
193
|
+
if (apiKeyEnvVar !== undefined)
|
|
194
|
+
protocol.apiKeyEnvVar = apiKeyEnvVar;
|
|
195
|
+
const safetyRaw = r.safety;
|
|
196
|
+
const safety = { ...base?.safety };
|
|
197
|
+
if (safetyRaw !== null && typeof safetyRaw === "object") {
|
|
198
|
+
for (const profile of SAFETY_PROFILES) {
|
|
199
|
+
const profileArgs = stringArrayFrom(safetyRaw[profile]);
|
|
200
|
+
if (profileArgs !== undefined)
|
|
201
|
+
safety[profile] = profileArgs;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (Object.keys(safety).length > 0)
|
|
205
|
+
protocol.safety = safety;
|
|
206
|
+
if (typeof r.success_requires_output === "boolean") {
|
|
207
|
+
protocol.successRequiresOutput = r.success_requires_output;
|
|
208
|
+
}
|
|
209
|
+
else if (base?.successRequiresOutput !== undefined) {
|
|
210
|
+
protocol.successRequiresOutput = base.successRequiresOutput;
|
|
211
|
+
}
|
|
212
|
+
const endpointNativeArgsRaw = r.endpoint_native_args;
|
|
213
|
+
if (endpointNativeArgsRaw !== null && typeof endpointNativeArgsRaw === "object") {
|
|
214
|
+
const ena = {};
|
|
215
|
+
for (const [k, v] of Object.entries(endpointNativeArgsRaw)) {
|
|
216
|
+
const args2 = stringArrayFrom(v);
|
|
217
|
+
if (args2 !== undefined)
|
|
218
|
+
ena[k] = args2;
|
|
219
|
+
}
|
|
220
|
+
if (Object.keys(ena).length > 0)
|
|
221
|
+
protocol.endpointNativeArgs = ena;
|
|
222
|
+
}
|
|
223
|
+
else if (base?.endpointNativeArgs) {
|
|
224
|
+
protocol.endpointNativeArgs = base.endpointNativeArgs;
|
|
225
|
+
}
|
|
226
|
+
// Placeholder sanity checks on the FINAL merged args (so `extends:` results
|
|
227
|
+
// are covered too). A typo'd placeholder is the most likely user error in a
|
|
228
|
+
// hand-written protocol, and without these warnings it doesn't just fail
|
|
229
|
+
// silently — it "succeeds": the CLI receives the literal "{{promt}}" token,
|
|
230
|
+
// never receives the prompt, exits 0, and the run reports ok.
|
|
231
|
+
// Matches embedded forms too ("--flag={{prompt}}"), not just whole-token
|
|
232
|
+
// typos — expansion only ever substitutes a token that IS a placeholder,
|
|
233
|
+
// so anything merely containing one goes through literally.
|
|
234
|
+
for (const token of protocol.args) {
|
|
235
|
+
if (token.includes("{{") && !KNOWN_ARG_PLACEHOLDERS.has(token)) {
|
|
236
|
+
warnings.push(`${routeLabel}: protocol.args contains unrecognized placeholder "${token}" — it will be ` +
|
|
237
|
+
`passed to the CLI as a literal argument, not substituted. Placeholders only work as ` +
|
|
238
|
+
`a whole standalone argument. Known placeholders: ` +
|
|
239
|
+
`${[...KNOWN_ARG_PLACEHOLDERS].join(", ")}.`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (!protocol.stdin && !protocol.args.includes("{{prompt}}")) {
|
|
243
|
+
warnings.push(`${routeLabel}: protocol.args has no {{prompt}} placeholder and stdin is not true — ` +
|
|
244
|
+
`the prompt is never sent to the CLI. Add "{{prompt}}" to args, or set stdin: true.`);
|
|
245
|
+
}
|
|
246
|
+
return protocol;
|
|
247
|
+
}
|
|
248
|
+
export function eventRuleFrom(raw, label, warnings) {
|
|
249
|
+
if (raw === null || typeof raw !== "object") {
|
|
250
|
+
warnings.push(`${label}: must be an object — ignored.`);
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
const r = raw;
|
|
254
|
+
// "when" is optional — omitted or {} means "matches every line" (e.g. a
|
|
255
|
+
// usage rule that should fire regardless of event type, matching Codex's
|
|
256
|
+
// original unconditional `if (event.usage) {...}` check).
|
|
257
|
+
const whenRaw = r.when ?? {};
|
|
258
|
+
if (whenRaw === null || typeof whenRaw !== "object" || Array.isArray(whenRaw)) {
|
|
259
|
+
warnings.push(`${label}: "when" must be a {field: value} map — ignored.`);
|
|
260
|
+
return undefined;
|
|
261
|
+
}
|
|
262
|
+
const when = {};
|
|
263
|
+
for (const [k, v] of Object.entries(whenRaw)) {
|
|
264
|
+
if (typeof v === "string")
|
|
265
|
+
when[k] = v;
|
|
266
|
+
}
|
|
267
|
+
const emit = r.emit;
|
|
268
|
+
if (emit !== "text" &&
|
|
269
|
+
emit !== "tool_use" &&
|
|
270
|
+
emit !== "thinking" &&
|
|
271
|
+
emit !== "usage" &&
|
|
272
|
+
emit !== "error") {
|
|
273
|
+
warnings.push(`${label}: "emit" must be one of text | tool_use | thinking | usage | error — ignored.`);
|
|
274
|
+
return undefined;
|
|
275
|
+
}
|
|
276
|
+
const rule = { when, emit };
|
|
277
|
+
const textField = str(r.text_field);
|
|
278
|
+
if (textField !== undefined)
|
|
279
|
+
rule.textField = textField;
|
|
280
|
+
const nameField = str(r.name_field);
|
|
281
|
+
if (nameField !== undefined)
|
|
282
|
+
rule.nameField = nameField;
|
|
283
|
+
const inputField = str(r.input_field);
|
|
284
|
+
if (inputField !== undefined)
|
|
285
|
+
rule.inputField = inputField;
|
|
286
|
+
const chunkField = str(r.chunk_field);
|
|
287
|
+
if (chunkField !== undefined)
|
|
288
|
+
rule.chunkField = chunkField;
|
|
289
|
+
const inputTokenFields = stringArrayFrom(r.input_token_fields);
|
|
290
|
+
if (inputTokenFields !== undefined)
|
|
291
|
+
rule.inputTokenFields = inputTokenFields;
|
|
292
|
+
const outputTokenFields = stringArrayFrom(r.output_token_fields);
|
|
293
|
+
if (outputTokenFields !== undefined)
|
|
294
|
+
rule.outputTokenFields = outputTokenFields;
|
|
295
|
+
const messageField = str(r.message_field);
|
|
296
|
+
if (messageField !== undefined)
|
|
297
|
+
rule.messageField = messageField;
|
|
298
|
+
return rule;
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/config/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a config file is ALLOWED to say, and what to warn about when it says
|
|
3
|
+
* something else.
|
|
4
|
+
*
|
|
5
|
+
* Split out of config.ts. This module exists because of a specific, repeated
|
|
6
|
+
* failure: the parser reads what it recognises and cannot distinguish a key it
|
|
7
|
+
* does not know from a key that is absent. Four silent-drop defects came from
|
|
8
|
+
* that — a misspelled `workspace_policy` or `safety_profile` left the route
|
|
9
|
+
* running under the LESS restrictive default, silently.
|
|
10
|
+
*
|
|
11
|
+
* So the legal surface is enumerated here rather than implied by whatever the
|
|
12
|
+
* builders happen to read. Keeping it in one file is the point: a per-shape
|
|
13
|
+
* copy is what drifted last time.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Warn on any unrecognised value for an enum that FAILS OPEN.
|
|
17
|
+
*
|
|
18
|
+
* Every *From() validator returns undefined on a mismatch and the caller
|
|
19
|
+
* falls back to a default — silently. For most fields that is merely
|
|
20
|
+
* annoying, but for these three the default is LESS restrictive than what the
|
|
21
|
+
* operator asked for:
|
|
22
|
+
*
|
|
23
|
+
* safety_profile: read_onlyy -> undefined -> DEFAULT_SAFETY_PROFILE
|
|
24
|
+
* -> workspace_edit (write access)
|
|
25
|
+
* workspace_policy: coppy -> undefined -> shared_locked
|
|
26
|
+
* -> a SHARED workspace, not an
|
|
27
|
+
* isolated copy
|
|
28
|
+
*
|
|
29
|
+
* A typo therefore quietly grants more than intended, which is the wrong
|
|
30
|
+
* direction for a safety control. The same parser already warns loudly for a
|
|
31
|
+
* malformed `protocol` block, so this is consistency as much as safety.
|
|
32
|
+
*
|
|
33
|
+
* Walks the raw tree rather than hooking each builder: the same keys appear
|
|
34
|
+
* under services:, clis:, endpoints: and overrides:, and a single walk cannot
|
|
35
|
+
* miss a format the way four separate call sites can.
|
|
36
|
+
*/
|
|
37
|
+
export declare const FAIL_OPEN_ENUMS: Record<string, readonly string[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Every key this parser understands at the top level of config.yaml.
|
|
40
|
+
*
|
|
41
|
+
* `doctor` reported "no unrecognized config entries" while a typo'd or
|
|
42
|
+
* invented top-level key produced no warning at all — the check's own name
|
|
43
|
+
* promised something it never did. A misspelled `max_concurrent_runs` is
|
|
44
|
+
* indistinguishable from not setting it, which is exactly the silent-default
|
|
45
|
+
* class that has bitten this file twice already.
|
|
46
|
+
*/
|
|
47
|
+
export declare const KNOWN_TOP_LEVEL_KEYS: Set<string>;
|
|
48
|
+
/**
|
|
49
|
+
* Every key a `clis:` or `endpoints:` entry may carry.
|
|
50
|
+
*
|
|
51
|
+
* ROOT-CAUSE FIX, not a fourth instance. Three separate silent-drop defects
|
|
52
|
+
* were found in this file in one day — workspace_policy ignored for `clis:`,
|
|
53
|
+
* api_keys ignored for `endpoints:`, unknown top-level keys unwarned — and
|
|
54
|
+
* each was patched individually. Measured afterwards: a route carrying
|
|
55
|
+
* `workspace_polcy`, `safety_profil` and `tierr` still produced ZERO warnings
|
|
56
|
+
* and silently got none of the three.
|
|
57
|
+
*
|
|
58
|
+
* The mechanism is that this parser reads what it recognises and cannot
|
|
59
|
+
* distinguish a key it does not know from a key that is absent. Nothing
|
|
60
|
+
* enumerated the legal surface, so every future misspelling was guaranteed to
|
|
61
|
+
* fail the same silent way — and these are safety and isolation controls, so
|
|
62
|
+
* "silently absent" means "silently less restrictive".
|
|
63
|
+
*
|
|
64
|
+
* Kept as one list for both entry shapes on purpose. Splitting it per shape
|
|
65
|
+
* would recreate the original defect, where two parallel field lists drifted
|
|
66
|
+
* and each was missing something the other had.
|
|
67
|
+
*/
|
|
68
|
+
export declare const KNOWN_ROUTE_KEYS: Set<string>;
|
|
69
|
+
export declare function warnUnknownRouteKeys(entry: Record<string, unknown>, label: string, warnings: string[]): void;
|
|
70
|
+
export declare function warnUnknownTopLevelKeys(raw: Record<string, unknown>, warnings: string[]): void;
|
|
71
|
+
export declare function warnUnknownSafetyEnums(node: unknown, warnings: string[], where?: string): void;
|
|
72
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/config/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAsB7D,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,aAiB/B,CAAC;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,gBAAgB,aAU3B,CAAC;AAEH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,GACjB,IAAI,CAQN;AAeD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAgB9F;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,SAAK,GAAG,IAAI,CAqC1F"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a config file is ALLOWED to say, and what to warn about when it says
|
|
3
|
+
* something else.
|
|
4
|
+
*
|
|
5
|
+
* Split out of config.ts. This module exists because of a specific, repeated
|
|
6
|
+
* failure: the parser reads what it recognises and cannot distinguish a key it
|
|
7
|
+
* does not know from a key that is absent. Four silent-drop defects came from
|
|
8
|
+
* that — a misspelled `workspace_policy` or `safety_profile` left the route
|
|
9
|
+
* running under the LESS restrictive default, silently.
|
|
10
|
+
*
|
|
11
|
+
* So the legal surface is enumerated here rather than implied by whatever the
|
|
12
|
+
* builders happen to read. Keeping it in one file is the point: a per-shape
|
|
13
|
+
* copy is what drifted last time.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Warn on any unrecognised value for an enum that FAILS OPEN.
|
|
17
|
+
*
|
|
18
|
+
* Every *From() validator returns undefined on a mismatch and the caller
|
|
19
|
+
* falls back to a default — silently. For most fields that is merely
|
|
20
|
+
* annoying, but for these three the default is LESS restrictive than what the
|
|
21
|
+
* operator asked for:
|
|
22
|
+
*
|
|
23
|
+
* safety_profile: read_onlyy -> undefined -> DEFAULT_SAFETY_PROFILE
|
|
24
|
+
* -> workspace_edit (write access)
|
|
25
|
+
* workspace_policy: coppy -> undefined -> shared_locked
|
|
26
|
+
* -> a SHARED workspace, not an
|
|
27
|
+
* isolated copy
|
|
28
|
+
*
|
|
29
|
+
* A typo therefore quietly grants more than intended, which is the wrong
|
|
30
|
+
* direction for a safety control. The same parser already warns loudly for a
|
|
31
|
+
* malformed `protocol` block, so this is consistency as much as safety.
|
|
32
|
+
*
|
|
33
|
+
* Walks the raw tree rather than hooking each builder: the same keys appear
|
|
34
|
+
* under services:, clis:, endpoints: and overrides:, and a single walk cannot
|
|
35
|
+
* miss a format the way four separate call sites can.
|
|
36
|
+
*/
|
|
37
|
+
export const FAIL_OPEN_ENUMS = {
|
|
38
|
+
// Billing enums, added after a review found `billing_kind: metered-api`
|
|
39
|
+
// (hyphen, not underscore) silently resolving to the harness default of
|
|
40
|
+
// `included_plan_then_flexible_credits` with paidUsagePossible false and no
|
|
41
|
+
// warning. This block existed precisely for enums whose fallback is LESS
|
|
42
|
+
// restrictive than the value attempted, and billing is the other hard
|
|
43
|
+
// constraint the product states — a typo here silently marks a metered route
|
|
44
|
+
// as free.
|
|
45
|
+
billing_kind: [
|
|
46
|
+
"local_compute",
|
|
47
|
+
"included_plan_usage",
|
|
48
|
+
"included_plan_then_flexible_credits",
|
|
49
|
+
"included_credit_then_optional_overage",
|
|
50
|
+
"included_usage_then_on_demand",
|
|
51
|
+
"metered_api",
|
|
52
|
+
"free_quota",
|
|
53
|
+
"unknown",
|
|
54
|
+
],
|
|
55
|
+
billing_confidence: ["documented", "inferred", "unknown", "unsupported"],
|
|
56
|
+
safety_profile: ["read_only", "workspace_edit", "full_auto"],
|
|
57
|
+
effective_safety: ["read_only", "workspace_edit", "full_auto"],
|
|
58
|
+
workspace_policy: ["shared", "shared_locked", "git_worktree", "copy"],
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Every key this parser understands at the top level of config.yaml.
|
|
62
|
+
*
|
|
63
|
+
* `doctor` reported "no unrecognized config entries" while a typo'd or
|
|
64
|
+
* invented top-level key produced no warning at all — the check's own name
|
|
65
|
+
* promised something it never did. A misspelled `max_concurrent_runs` is
|
|
66
|
+
* indistinguishable from not setting it, which is exactly the silent-default
|
|
67
|
+
* class that has bitten this file twice already.
|
|
68
|
+
*/
|
|
69
|
+
export const KNOWN_TOP_LEVEL_KEYS = new Set([
|
|
70
|
+
"version",
|
|
71
|
+
"clis",
|
|
72
|
+
"endpoints",
|
|
73
|
+
"services",
|
|
74
|
+
"disabled",
|
|
75
|
+
"overrides",
|
|
76
|
+
"api_keys",
|
|
77
|
+
"protocols",
|
|
78
|
+
"policy",
|
|
79
|
+
"telemetry",
|
|
80
|
+
"retention",
|
|
81
|
+
"leaderboard",
|
|
82
|
+
"max_concurrent_runs",
|
|
83
|
+
"default_safety_profile",
|
|
84
|
+
"workspace_policy",
|
|
85
|
+
"protocol",
|
|
86
|
+
]);
|
|
87
|
+
/**
|
|
88
|
+
* Every key a `clis:` or `endpoints:` entry may carry.
|
|
89
|
+
*
|
|
90
|
+
* ROOT-CAUSE FIX, not a fourth instance. Three separate silent-drop defects
|
|
91
|
+
* were found in this file in one day — workspace_policy ignored for `clis:`,
|
|
92
|
+
* api_keys ignored for `endpoints:`, unknown top-level keys unwarned — and
|
|
93
|
+
* each was patched individually. Measured afterwards: a route carrying
|
|
94
|
+
* `workspace_polcy`, `safety_profil` and `tierr` still produced ZERO warnings
|
|
95
|
+
* and silently got none of the three.
|
|
96
|
+
*
|
|
97
|
+
* The mechanism is that this parser reads what it recognises and cannot
|
|
98
|
+
* distinguish a key it does not know from a key that is absent. Nothing
|
|
99
|
+
* enumerated the legal surface, so every future misspelling was guaranteed to
|
|
100
|
+
* fail the same silent way — and these are safety and isolation controls, so
|
|
101
|
+
* "silently absent" means "silently less restrictive".
|
|
102
|
+
*
|
|
103
|
+
* Kept as one list for both entry shapes on purpose. Splitting it per shape
|
|
104
|
+
* would recreate the original defect, where two parallel field lists drifted
|
|
105
|
+
* and each was missing something the other had.
|
|
106
|
+
*/
|
|
107
|
+
export const KNOWN_ROUTE_KEYS = new Set([
|
|
108
|
+
"name", "harness", "type", "command", "enabled", "model", "models", "model_hint",
|
|
109
|
+
"tier", "weight", "cli_capability", "capabilities", "timeout_ms",
|
|
110
|
+
"max_input_tokens", "max_output_tokens", "thinking_level",
|
|
111
|
+
"leaderboard_model", "escalate_model", "escalate_on",
|
|
112
|
+
"api_key", "base_url", "protocol", "filter",
|
|
113
|
+
"provider", "surface", "auth_source", "billing_kind", "billing_confidence",
|
|
114
|
+
"billing_notes", "paid_usage_possible", "allow_paid_usage",
|
|
115
|
+
"safety_profile", "effective_safety", "workspace_policy",
|
|
116
|
+
"endpoint_mode", "endpoint_provider", "wire_protocol",
|
|
117
|
+
]);
|
|
118
|
+
export function warnUnknownRouteKeys(entry, label, warnings) {
|
|
119
|
+
for (const key of Object.keys(entry)) {
|
|
120
|
+
if (KNOWN_ROUTE_KEYS.has(key))
|
|
121
|
+
continue;
|
|
122
|
+
warnings.push(`${label}: unknown key "${key}" — IGNORED. If this was meant to be a ` +
|
|
123
|
+
`safety or workspace setting, it is NOT in effect; check the spelling.`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Keys the parser ACCEPTS and nothing reads.
|
|
128
|
+
*
|
|
129
|
+
* Silently allowing them is worse than rejecting them: `default_safety_profile`
|
|
130
|
+
* is a safety-control name that does nothing at all, which is the exact
|
|
131
|
+
* failure this module exists to prevent. They stay allow-listed (so they are
|
|
132
|
+
* not reported as typos) but say plainly that setting them has no effect.
|
|
133
|
+
*
|
|
134
|
+
* Verified read-nowhere in src/ at the time of writing; if one is implemented
|
|
135
|
+
* later, delete it from here and the warning goes away.
|
|
136
|
+
*/
|
|
137
|
+
const ACCEPTED_BUT_UNIMPLEMENTED = new Set(["protocols", "default_safety_profile"]);
|
|
138
|
+
export function warnUnknownTopLevelKeys(raw, warnings) {
|
|
139
|
+
for (const key of Object.keys(raw)) {
|
|
140
|
+
if (ACCEPTED_BUT_UNIMPLEMENTED.has(key)) {
|
|
141
|
+
warnings.push(`${key}: recognised but NOT IMPLEMENTED — setting it has no effect. ` +
|
|
142
|
+
`Remove it, or track the gap; it is not a typo.`);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (KNOWN_TOP_LEVEL_KEYS.has(key))
|
|
146
|
+
continue;
|
|
147
|
+
if (key.endsWith("_api_key"))
|
|
148
|
+
continue; // documented per-route shorthand
|
|
149
|
+
warnings.push(`unknown top-level config key: ${key} — IGNORED. Check the spelling against ` +
|
|
150
|
+
`the documented keys (${[...KNOWN_TOP_LEVEL_KEYS].slice(0, 6).join(", ")}, ...).`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
export function warnUnknownSafetyEnums(node, warnings, where = "") {
|
|
154
|
+
if (Array.isArray(node)) {
|
|
155
|
+
for (const [i, v] of node.entries())
|
|
156
|
+
warnUnknownSafetyEnums(v, warnings, `${where}[${i}]`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (node === null || typeof node !== "object")
|
|
160
|
+
return;
|
|
161
|
+
const obj = node;
|
|
162
|
+
const label = typeof obj.name === "string" && obj.name !== "" ? String(obj.name) : where || "config";
|
|
163
|
+
for (const [key, allowed] of Object.entries(FAIL_OPEN_ENUMS)) {
|
|
164
|
+
const value = obj[key];
|
|
165
|
+
if (value === undefined)
|
|
166
|
+
continue;
|
|
167
|
+
if (typeof value === "string" && allowed.includes(value))
|
|
168
|
+
continue;
|
|
169
|
+
// effective_safety may also be a per-request map; validate it entry by
|
|
170
|
+
// entry so a typo in one key still warns without condemning the whole
|
|
171
|
+
// block. See effectiveSafetyFrom().
|
|
172
|
+
if (key === "effective_safety" && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
173
|
+
const entries = Object.entries(value);
|
|
174
|
+
const bad = entries.filter(([k, v]) => !allowed.includes(k) || typeof v !== "string" || !allowed.includes(v));
|
|
175
|
+
if (bad.length === 0)
|
|
176
|
+
continue;
|
|
177
|
+
warnings.push(`${label}: effective_safety: ${bad.map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ")} ` +
|
|
178
|
+
`is not a ${allowed.join("/")} pair — IGNORED for those requests.`);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
warnings.push(`${label}: ${key}: ${JSON.stringify(value)} is not one of ${allowed.join(", ")} — ` +
|
|
182
|
+
`IGNORED, and the default applies instead, which is less restrictive than what ` +
|
|
183
|
+
`this looks like it was meant to set. Fix the value.`);
|
|
184
|
+
}
|
|
185
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
186
|
+
warnUnknownSafetyEnums(v, warnings, where ? `${where}.${k}` : k);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/config/validation.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -12,14 +12,31 @@
|
|
|
12
12
|
* All string values are scanned for ${ENV_VAR} references and replaced with
|
|
13
13
|
* the corresponding environment variable.
|
|
14
14
|
*/
|
|
15
|
+
/** Injection seam for tests. Set via loadConfig({ whichFn }) if needed. */
|
|
16
|
+
export type WhichFn = (cmd: string) => Promise<string | null>;
|
|
15
17
|
import type { CliProtocolConfig, RouterConfig } from "./types.js";
|
|
16
18
|
/** Named, selectable protocols — every harness in CLI_DEFAULTS that defines one, keyed by its harness name (see protocolFrom()'s string/`extends:` handling). */
|
|
17
19
|
export declare const PROTOCOL_PRESETS: Record<string, CliProtocolConfig>;
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Commands auto-detect probes on PATH, exported so `doctor` can name them.
|
|
22
|
+
*
|
|
23
|
+
* A zero-route install used to report "0 ready route(s)" and stop, which tells
|
|
24
|
+
* a new user nothing about what was looked for or what to install. Keyed the
|
|
25
|
+
* same way as AUTO_DETECT_NAME so the two cannot drift.
|
|
26
|
+
*/
|
|
27
|
+
export declare const AUTO_DETECT_COMMANDS: Record<string, string>;
|
|
20
28
|
export interface LoadConfigOptions {
|
|
21
29
|
/** Override `which` for tests — return null when a CLI is "not found". */
|
|
22
30
|
whichFn?: WhichFn;
|
|
31
|
+
/**
|
|
32
|
+
* Treat a missing explicit path as auto-detect rather than an error.
|
|
33
|
+
*
|
|
34
|
+
* Only `configure` sets this: the path it is given is its OUTPUT, which
|
|
35
|
+
* legitimately does not exist yet. For every other command an explicit
|
|
36
|
+
* --config that is not there is a typo, and silently auto-detecting printed
|
|
37
|
+
* a confident route table for a config that was never loaded.
|
|
38
|
+
*/
|
|
39
|
+
allowMissing?: boolean;
|
|
23
40
|
}
|
|
24
41
|
/**
|
|
25
42
|
* Load a RouterConfig.
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAyBH,2EAA2E;AAC3E,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AA+B9D,OAAO,KAAK,EAOV,iBAAiB,EAGjB,YAAY,EAOb,MAAM,YAAY,CAAC;AAsEpB,iKAAiK;AACjK,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAI9D,CAAC;AAQF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKvD,CAAC;AAgrBF,MAAM,WAAW,iBAAiB;IAChC,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAC9B,IAAI,CAAC,EAAE,MAAM,EACb,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAwGvB;AAMD,MAAM,WAAW,aAAa;IAC5B,IAAI,IAAI,IAAI,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,EACnC,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GACpD,aAAa,CAkCf"}
|