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.
Files changed (140) hide show
  1. package/README.md +228 -86
  2. package/config.default.yaml +416 -397
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +2 -2
  5. package/dist/auth.js.map +1 -1
  6. package/dist/billing.d.ts +35 -4
  7. package/dist/billing.d.ts.map +1 -1
  8. package/dist/billing.js +48 -17
  9. package/dist/billing.js.map +1 -1
  10. package/dist/bin.d.ts.map +1 -1
  11. package/dist/bin.js +253 -23
  12. package/dist/bin.js.map +1 -1
  13. package/dist/breaker-store.d.ts +60 -9
  14. package/dist/breaker-store.d.ts.map +1 -1
  15. package/dist/breaker-store.js +246 -50
  16. package/dist/breaker-store.js.map +1 -1
  17. package/dist/circuit-breaker.d.ts +35 -0
  18. package/dist/circuit-breaker.d.ts.map +1 -1
  19. package/dist/circuit-breaker.js +68 -11
  20. package/dist/circuit-breaker.js.map +1 -1
  21. package/dist/config/coercions.d.ts +31 -0
  22. package/dist/config/coercions.d.ts.map +1 -0
  23. package/dist/config/coercions.js +169 -0
  24. package/dist/config/coercions.js.map +1 -0
  25. package/dist/config/env-interpolation.d.ts +36 -0
  26. package/dist/config/env-interpolation.d.ts.map +1 -0
  27. package/dist/config/env-interpolation.js +73 -0
  28. package/dist/config/env-interpolation.js.map +1 -0
  29. package/dist/config/protocol.d.ts +51 -0
  30. package/dist/config/protocol.d.ts.map +1 -0
  31. package/dist/config/protocol.js +300 -0
  32. package/dist/config/protocol.js.map +1 -0
  33. package/dist/config/validation.d.ts +72 -0
  34. package/dist/config/validation.d.ts.map +1 -0
  35. package/dist/config/validation.js +189 -0
  36. package/dist/config/validation.js.map +1 -0
  37. package/dist/config.d.ts +19 -2
  38. package/dist/config.d.ts.map +1 -1
  39. package/dist/config.js +229 -511
  40. package/dist/config.js.map +1 -1
  41. package/dist/dispatch-log.d.ts.map +1 -1
  42. package/dist/dispatch-log.js +2 -3
  43. package/dist/dispatch-log.js.map +1 -1
  44. package/dist/dispatchers/generic-cli.d.ts +15 -1
  45. package/dist/dispatchers/generic-cli.d.ts.map +1 -1
  46. package/dist/dispatchers/generic-cli.js +65 -5
  47. package/dist/dispatchers/generic-cli.js.map +1 -1
  48. package/dist/dispatchers/openai-compatible.d.ts.map +1 -1
  49. package/dist/dispatchers/openai-compatible.js +52 -2
  50. package/dist/dispatchers/openai-compatible.js.map +1 -1
  51. package/dist/dispatchers/shared/kill-tree.d.ts +17 -4
  52. package/dist/dispatchers/shared/kill-tree.d.ts.map +1 -1
  53. package/dist/dispatchers/shared/kill-tree.js +28 -4
  54. package/dist/dispatchers/shared/kill-tree.js.map +1 -1
  55. package/dist/dispatchers/shared/rate-limit-headers.d.ts +17 -0
  56. package/dist/dispatchers/shared/rate-limit-headers.d.ts.map +1 -1
  57. package/dist/dispatchers/shared/rate-limit-headers.js +27 -0
  58. package/dist/dispatchers/shared/rate-limit-headers.js.map +1 -1
  59. package/dist/dispatchers/shared/stream-subprocess.d.ts.map +1 -1
  60. package/dist/dispatchers/shared/stream-subprocess.js +5 -0
  61. package/dist/dispatchers/shared/stream-subprocess.js.map +1 -1
  62. package/dist/dispatchers/shared/subprocess.d.ts.map +1 -1
  63. package/dist/dispatchers/shared/subprocess.js +3 -0
  64. package/dist/dispatchers/shared/subprocess.js.map +1 -1
  65. package/dist/dispatchers/shared/which-available.d.ts.map +1 -1
  66. package/dist/dispatchers/shared/which-available.js +16 -2
  67. package/dist/dispatchers/shared/which-available.js.map +1 -1
  68. package/dist/file-lock.d.ts +17 -0
  69. package/dist/file-lock.d.ts.map +1 -0
  70. package/dist/file-lock.js +143 -0
  71. package/dist/file-lock.js.map +1 -0
  72. package/dist/http/server.d.ts +11 -0
  73. package/dist/http/server.d.ts.map +1 -1
  74. package/dist/http/server.js +331 -162
  75. package/dist/http/server.js.map +1 -1
  76. package/dist/job-runner.js +23 -5
  77. package/dist/job-runner.js.map +1 -1
  78. package/dist/jobs.d.ts +91 -1
  79. package/dist/jobs.d.ts.map +1 -1
  80. package/dist/jobs.js +647 -36
  81. package/dist/jobs.js.map +1 -1
  82. package/dist/leaderboard.d.ts +24 -1
  83. package/dist/leaderboard.d.ts.map +1 -1
  84. package/dist/leaderboard.js +94 -2
  85. package/dist/leaderboard.js.map +1 -1
  86. package/dist/mcp/config-hot-reload.d.ts.map +1 -1
  87. package/dist/mcp/config-hot-reload.js +1 -1
  88. package/dist/mcp/config-hot-reload.js.map +1 -1
  89. package/dist/mcp/dispatcher-factory.d.ts +16 -1
  90. package/dist/mcp/dispatcher-factory.d.ts.map +1 -1
  91. package/dist/mcp/dispatcher-factory.js +41 -3
  92. package/dist/mcp/dispatcher-factory.js.map +1 -1
  93. package/dist/mcp/tools.d.ts +23 -4
  94. package/dist/mcp/tools.d.ts.map +1 -1
  95. package/dist/mcp/tools.js +163 -16
  96. package/dist/mcp/tools.js.map +1 -1
  97. package/dist/observability/index.d.ts +16 -3
  98. package/dist/observability/index.d.ts.map +1 -1
  99. package/dist/observability/index.js +23 -7
  100. package/dist/observability/index.js.map +1 -1
  101. package/dist/observability/spans.d.ts.map +1 -1
  102. package/dist/observability/spans.js +4 -1
  103. package/dist/observability/spans.js.map +1 -1
  104. package/dist/quota.d.ts +88 -22
  105. package/dist/quota.d.ts.map +1 -1
  106. package/dist/quota.js +163 -58
  107. package/dist/quota.js.map +1 -1
  108. package/dist/route-policy.d.ts.map +1 -1
  109. package/dist/route-policy.js +13 -3
  110. package/dist/route-policy.js.map +1 -1
  111. package/dist/router.d.ts +25 -1
  112. package/dist/router.d.ts.map +1 -1
  113. package/dist/router.js +94 -40
  114. package/dist/router.js.map +1 -1
  115. package/dist/safety.d.ts.map +1 -1
  116. package/dist/safety.js +11 -2
  117. package/dist/safety.js.map +1 -1
  118. package/dist/state-dir.d.ts +17 -0
  119. package/dist/state-dir.d.ts.map +1 -0
  120. package/dist/state-dir.js +21 -0
  121. package/dist/state-dir.js.map +1 -0
  122. package/dist/status.d.ts +36 -0
  123. package/dist/status.d.ts.map +1 -1
  124. package/dist/status.js +61 -4
  125. package/dist/status.js.map +1 -1
  126. package/dist/types.d.ts +50 -1
  127. package/dist/types.d.ts.map +1 -1
  128. package/dist/working-dir.d.ts +13 -0
  129. package/dist/working-dir.d.ts.map +1 -1
  130. package/dist/working-dir.js +27 -0
  131. package/dist/working-dir.js.map +1 -1
  132. package/dist/workspace-lock.d.ts +40 -0
  133. package/dist/workspace-lock.d.ts.map +1 -0
  134. package/dist/workspace-lock.js +258 -0
  135. package/dist/workspace-lock.js.map +1 -0
  136. package/dist/workspaces.d.ts +15 -0
  137. package/dist/workspaces.d.ts.map +1 -1
  138. package/dist/workspaces.js +104 -12
  139. package/dist/workspaces.js.map +1 -1
  140. 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
- /** Injection seam for tests. Set via loadConfig({ whichFn }) if needed. */
19
- export type WhichFn = (cmd: string) => Promise<string | null>;
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.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAWH,OAAO,KAAK,EAOV,iBAAiB,EAGjB,YAAY,EAOb,MAAM,YAAY,CAAC;AA+EpB,iKAAiK;AACjK,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAI9D,CAAC;AA4DF,2EAA2E;AAC3E,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AA09B9D,MAAM,WAAW,iBAAiB;IAChC,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAC9B,IAAI,CAAC,EAAE,MAAM,EACb,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAwEvB;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"}
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"}