@relayflows/sdk 2.0.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 (231) hide show
  1. package/dist/authored-flow-error.d.ts +9 -0
  2. package/dist/authored-flow-error.d.ts.map +1 -0
  3. package/dist/authored-flow-error.js +13 -0
  4. package/dist/authored-flow-error.js.map +1 -0
  5. package/dist/authored-flow-executor.d.ts +28 -0
  6. package/dist/authored-flow-executor.d.ts.map +1 -0
  7. package/dist/authored-flow-executor.js +203 -0
  8. package/dist/authored-flow-executor.js.map +1 -0
  9. package/dist/authored-flow-lifecycle.d.ts +61 -0
  10. package/dist/authored-flow-lifecycle.d.ts.map +1 -0
  11. package/dist/authored-flow-lifecycle.js +284 -0
  12. package/dist/authored-flow-lifecycle.js.map +1 -0
  13. package/dist/authored-flow-loader.d.ts +7 -0
  14. package/dist/authored-flow-loader.d.ts.map +1 -0
  15. package/dist/authored-flow-loader.js +39 -0
  16. package/dist/authored-flow-loader.js.map +1 -0
  17. package/dist/authored-flow-operation.d.ts +43 -0
  18. package/dist/authored-flow-operation.d.ts.map +1 -0
  19. package/dist/authored-flow-operation.js +176 -0
  20. package/dist/authored-flow-operation.js.map +1 -0
  21. package/dist/authored-flow.d.ts +12 -0
  22. package/dist/authored-flow.d.ts.map +1 -0
  23. package/dist/authored-flow.js +13 -0
  24. package/dist/authored-flow.js.map +1 -0
  25. package/dist/authored-promise-graph.d.ts +67 -0
  26. package/dist/authored-promise-graph.d.ts.map +1 -0
  27. package/dist/authored-promise-graph.js +206 -0
  28. package/dist/authored-promise-graph.js.map +1 -0
  29. package/dist/backlog-picker.d.ts +55 -0
  30. package/dist/backlog-picker.d.ts.map +1 -0
  31. package/dist/backlog-picker.js +117 -0
  32. package/dist/backlog-picker.js.map +1 -0
  33. package/dist/canonical.d.ts +18 -0
  34. package/dist/canonical.d.ts.map +1 -0
  35. package/dist/canonical.js +55 -0
  36. package/dist/canonical.js.map +1 -0
  37. package/dist/cli/check.d.ts +30 -0
  38. package/dist/cli/check.d.ts.map +1 -0
  39. package/dist/cli/check.js +324 -0
  40. package/dist/cli/check.js.map +1 -0
  41. package/dist/cli/direct-run.d.ts +3 -0
  42. package/dist/cli/direct-run.d.ts.map +1 -0
  43. package/dist/cli/direct-run.js +69 -0
  44. package/dist/cli/direct-run.js.map +1 -0
  45. package/dist/cli/hn-monitor.d.ts +107 -0
  46. package/dist/cli/hn-monitor.d.ts.map +1 -0
  47. package/dist/cli/hn-monitor.js +220 -0
  48. package/dist/cli/hn-monitor.js.map +1 -0
  49. package/dist/cli/interruptible-sleep.d.ts +13 -0
  50. package/dist/cli/interruptible-sleep.d.ts.map +1 -0
  51. package/dist/cli/interruptible-sleep.js +31 -0
  52. package/dist/cli/interruptible-sleep.js.map +1 -0
  53. package/dist/cli/run.d.ts +54 -0
  54. package/dist/cli/run.d.ts.map +1 -0
  55. package/dist/cli/run.js +316 -0
  56. package/dist/cli/run.js.map +1 -0
  57. package/dist/cli/tick-runner.d.ts +151 -0
  58. package/dist/cli/tick-runner.d.ts.map +1 -0
  59. package/dist/cli/tick-runner.js +258 -0
  60. package/dist/cli/tick-runner.js.map +1 -0
  61. package/dist/cli-adapter.d.ts +29 -0
  62. package/dist/cli-adapter.d.ts.map +1 -0
  63. package/dist/cli-adapter.js +92 -0
  64. package/dist/cli-adapter.js.map +1 -0
  65. package/dist/cli-executable.d.ts +3 -0
  66. package/dist/cli-executable.d.ts.map +1 -0
  67. package/dist/cli-executable.js +10 -0
  68. package/dist/cli-executable.js.map +1 -0
  69. package/dist/cli.d.ts +9 -0
  70. package/dist/cli.d.ts.map +1 -0
  71. package/dist/cli.js +348 -0
  72. package/dist/cli.js.map +1 -0
  73. package/dist/compile.d.ts +42 -0
  74. package/dist/compile.d.ts.map +1 -0
  75. package/dist/compile.js +515 -0
  76. package/dist/compile.js.map +1 -0
  77. package/dist/demo-hn-monitor.d.ts +2 -0
  78. package/dist/demo-hn-monitor.d.ts.map +1 -0
  79. package/dist/demo-hn-monitor.js +118 -0
  80. package/dist/demo-hn-monitor.js.map +1 -0
  81. package/dist/dir-watcher-poller.d.ts +73 -0
  82. package/dist/dir-watcher-poller.d.ts.map +1 -0
  83. package/dist/dir-watcher-poller.js +80 -0
  84. package/dist/dir-watcher-poller.js.map +1 -0
  85. package/dist/direct-input.d.ts +10 -0
  86. package/dist/direct-input.d.ts.map +1 -0
  87. package/dist/direct-input.js +61 -0
  88. package/dist/direct-input.js.map +1 -0
  89. package/dist/failure-kinds.d.ts +25 -0
  90. package/dist/failure-kinds.d.ts.map +1 -0
  91. package/dist/failure-kinds.js +64 -0
  92. package/dist/failure-kinds.js.map +1 -0
  93. package/dist/gate-contract.d.ts +24 -0
  94. package/dist/gate-contract.d.ts.map +1 -0
  95. package/dist/gate-contract.js +50 -0
  96. package/dist/gate-contract.js.map +1 -0
  97. package/dist/hn-poller.d.ts +50 -0
  98. package/dist/hn-poller.d.ts.map +1 -0
  99. package/dist/hn-poller.js +79 -0
  100. package/dist/hn-poller.js.map +1 -0
  101. package/dist/index.d.ts +21 -0
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +30 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/journal-client.d.ts +122 -0
  106. package/dist/journal-client.d.ts.map +1 -0
  107. package/dist/journal-client.js +277 -0
  108. package/dist/journal-client.js.map +1 -0
  109. package/dist/json-schema-bound.d.ts +7 -0
  110. package/dist/json-schema-bound.d.ts.map +1 -0
  111. package/dist/json-schema-bound.js +353 -0
  112. package/dist/json-schema-bound.js.map +1 -0
  113. package/dist/json-schema.d.ts +5 -0
  114. package/dist/json-schema.d.ts.map +1 -0
  115. package/dist/json-schema.js +72 -0
  116. package/dist/json-schema.js.map +1 -0
  117. package/dist/json-value.d.ts +6 -0
  118. package/dist/json-value.d.ts.map +1 -0
  119. package/dist/json-value.js +94 -0
  120. package/dist/json-value.js.map +1 -0
  121. package/dist/model-name.d.ts +7 -0
  122. package/dist/model-name.d.ts.map +1 -0
  123. package/dist/model-name.js +21 -0
  124. package/dist/model-name.js.map +1 -0
  125. package/dist/output-schema.d.ts +8 -0
  126. package/dist/output-schema.d.ts.map +1 -0
  127. package/dist/output-schema.js +28 -0
  128. package/dist/output-schema.js.map +1 -0
  129. package/dist/preflight.d.ts +80 -0
  130. package/dist/preflight.d.ts.map +1 -0
  131. package/dist/preflight.js +361 -0
  132. package/dist/preflight.js.map +1 -0
  133. package/dist/protocol.d.ts +359 -0
  134. package/dist/protocol.d.ts.map +1 -0
  135. package/dist/protocol.js +15 -0
  136. package/dist/protocol.js.map +1 -0
  137. package/dist/spec.d.ts +294 -0
  138. package/dist/spec.d.ts.map +1 -0
  139. package/dist/spec.js +13 -0
  140. package/dist/spec.js.map +1 -0
  141. package/dist/step-dependencies.d.ts +2 -0
  142. package/dist/step-dependencies.d.ts.map +1 -0
  143. package/dist/step-dependencies.js +88 -0
  144. package/dist/step-dependencies.js.map +1 -0
  145. package/dist/step-fields.d.ts +17 -0
  146. package/dist/step-fields.d.ts.map +1 -0
  147. package/dist/step-fields.js +32 -0
  148. package/dist/step-fields.js.map +1 -0
  149. package/dist/tick-source.d.ts +205 -0
  150. package/dist/tick-source.d.ts.map +1 -0
  151. package/dist/tick-source.js +234 -0
  152. package/dist/tick-source.js.map +1 -0
  153. package/dist/unknown-keys.d.ts +7 -0
  154. package/dist/unknown-keys.d.ts.map +1 -0
  155. package/dist/unknown-keys.js +47 -0
  156. package/dist/unknown-keys.js.map +1 -0
  157. package/dist/validate.d.ts +7 -0
  158. package/dist/validate.d.ts.map +1 -0
  159. package/dist/validate.js +458 -0
  160. package/dist/validate.js.map +1 -0
  161. package/dist/work-package-consumer.d.ts +33 -0
  162. package/dist/work-package-consumer.d.ts.map +1 -0
  163. package/dist/work-package-consumer.js +44 -0
  164. package/dist/work-package-consumer.js.map +1 -0
  165. package/dist/work-package-validator.d.ts +15 -0
  166. package/dist/work-package-validator.d.ts.map +1 -0
  167. package/dist/work-package-validator.js +72 -0
  168. package/dist/work-package-validator.js.map +1 -0
  169. package/dist/worker-cli.d.ts +16 -0
  170. package/dist/worker-cli.d.ts.map +1 -0
  171. package/dist/worker-cli.js +77 -0
  172. package/dist/worker-cli.js.map +1 -0
  173. package/dist/worker.d.ts +57 -0
  174. package/dist/worker.d.ts.map +1 -0
  175. package/dist/worker.js +129 -0
  176. package/dist/worker.js.map +1 -0
  177. package/dist/wrapper-runtime.d.ts +10 -0
  178. package/dist/wrapper-runtime.d.ts.map +1 -0
  179. package/dist/wrapper-runtime.js +83 -0
  180. package/dist/wrapper-runtime.js.map +1 -0
  181. package/dist/wrapper-session.d.ts +16 -0
  182. package/dist/wrapper-session.d.ts.map +1 -0
  183. package/dist/wrapper-session.js +244 -0
  184. package/dist/wrapper-session.js.map +1 -0
  185. package/package.json +50 -0
  186. package/src/authored-flow-error.ts +31 -0
  187. package/src/authored-flow-executor.ts +365 -0
  188. package/src/authored-flow-lifecycle.ts +344 -0
  189. package/src/authored-flow-loader.ts +44 -0
  190. package/src/authored-flow-operation.ts +252 -0
  191. package/src/authored-flow.ts +21 -0
  192. package/src/authored-promise-graph.ts +196 -0
  193. package/src/backlog-picker.ts +153 -0
  194. package/src/canonical.ts +57 -0
  195. package/src/cli/check.ts +391 -0
  196. package/src/cli/direct-run.ts +86 -0
  197. package/src/cli/hn-monitor.ts +286 -0
  198. package/src/cli/interruptible-sleep.ts +27 -0
  199. package/src/cli/run.ts +439 -0
  200. package/src/cli/tick-runner.ts +378 -0
  201. package/src/cli-adapter.ts +115 -0
  202. package/src/cli-executable.ts +12 -0
  203. package/src/cli.ts +364 -0
  204. package/src/compile.ts +573 -0
  205. package/src/demo-hn-monitor.ts +132 -0
  206. package/src/dir-watcher-poller.ts +122 -0
  207. package/src/direct-input.ts +69 -0
  208. package/src/failure-kinds.ts +77 -0
  209. package/src/gate-contract.ts +72 -0
  210. package/src/hn-poller.ts +104 -0
  211. package/src/index.ts +195 -0
  212. package/src/journal-client.ts +379 -0
  213. package/src/json-schema-bound.ts +357 -0
  214. package/src/json-schema.ts +65 -0
  215. package/src/json-value.ts +110 -0
  216. package/src/model-name.ts +20 -0
  217. package/src/output-schema.ts +33 -0
  218. package/src/preflight.ts +482 -0
  219. package/src/protocol.ts +364 -0
  220. package/src/spec.ts +343 -0
  221. package/src/step-dependencies.ts +100 -0
  222. package/src/step-fields.ts +36 -0
  223. package/src/tick-source.ts +334 -0
  224. package/src/unknown-keys.ts +52 -0
  225. package/src/validate.ts +503 -0
  226. package/src/work-package-consumer.ts +73 -0
  227. package/src/work-package-validator.ts +90 -0
  228. package/src/worker-cli.ts +110 -0
  229. package/src/worker.ts +150 -0
  230. package/src/wrapper-runtime.ts +93 -0
  231. package/src/wrapper-session.ts +287 -0
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Produce author-facing diagnostics for keys outside a closed schema. A key
3
+ * that differs only in casing/separators always matches; otherwise a small
4
+ * edit distance catches plain misspellings.
5
+ */
6
+ export declare function unknownKeyErrors(object: Record<string, unknown>, allowed: readonly string[], at: string): string[];
7
+ //# sourceMappingURL=unknown-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unknown-keys.d.ts","sourceRoot":"","sources":["../src/unknown-keys.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,EAAE,EAAE,MAAM,GACT,MAAM,EAAE,CAYV"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Produce author-facing diagnostics for keys outside a closed schema. A key
3
+ * that differs only in casing/separators always matches; otherwise a small
4
+ * edit distance catches plain misspellings.
5
+ */
6
+ export function unknownKeyErrors(object, allowed, at) {
7
+ const errors = [];
8
+ for (const key of Object.keys(object)) {
9
+ if (allowed.includes(key))
10
+ continue;
11
+ const suggestion = nearestKey(key, allowed);
12
+ errors.push(suggestion !== null
13
+ ? `${at}: unknown key "${key}" — did you mean "${suggestion}"?`
14
+ : `${at}: unknown key "${key}" (expected one of ${allowed.join(' | ')})`);
15
+ }
16
+ return errors;
17
+ }
18
+ function nearestKey(key, allowed) {
19
+ const normalize = (value) => value.toLowerCase().replace(/[_-]/g, '');
20
+ let best = null;
21
+ let bestDistance = Number.POSITIVE_INFINITY;
22
+ for (const candidate of allowed) {
23
+ if (normalize(candidate) === normalize(key))
24
+ return candidate;
25
+ const distance = levenshtein(key.toLowerCase(), candidate.toLowerCase());
26
+ if (distance < bestDistance) {
27
+ bestDistance = distance;
28
+ best = candidate;
29
+ }
30
+ }
31
+ return best !== null && bestDistance <= 3 && bestDistance < best.length ? best : null;
32
+ }
33
+ function levenshtein(a, b) {
34
+ let previous = Array.from({ length: b.length + 1 }, (_, i) => i);
35
+ for (let i = 1; i <= a.length; i++) {
36
+ const current = [i];
37
+ for (let j = 1; j <= b.length; j++) {
38
+ const deletion = (previous[j] ?? 0) + 1;
39
+ const insertion = (current[j - 1] ?? 0) + 1;
40
+ const substitution = (previous[j - 1] ?? 0) + (a[i - 1] === b[j - 1] ? 0 : 1);
41
+ current[j] = Math.min(deletion, insertion, substitution);
42
+ }
43
+ previous = current;
44
+ }
45
+ return previous[b.length] ?? 0;
46
+ }
47
+ //# sourceMappingURL=unknown-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unknown-keys.js","sourceRoot":"","sources":["../src/unknown-keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface ValidationResult {
2
+ ok: boolean;
3
+ errors: string[];
4
+ }
5
+ /** Validate a parsed spec object. Returns `{ok, errors}`; never throws. */
6
+ export declare function validateSpec(spec: unknown): ValidationResult;
7
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAgCA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAubD,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAS5D"}
@@ -0,0 +1,458 @@
1
+ // Spec validation — fail-closed (AGENTS.md rule 4). The compiler runs every
2
+ // spec through this before emitting JSON; a malformed spec is rejected with a
3
+ // concrete error, never silently coerced. Zero-agent flows are legal: there is
4
+ // no requirement that any step be `llm` or `agent`.
5
+ import { SPEC_SCHEMA_VERSION } from './spec.js';
6
+ import { validateOutputDeclaration } from './output-schema.js';
7
+ import { modelNameError } from './model-name.js';
8
+ import { unknownKeyErrors } from './unknown-keys.js';
9
+ import { stepDependencyErrors } from './step-dependencies.js';
10
+ import { AGENT_DECLARATION_FIELDS, FLOW_FIELDS, STEP_COMMON_FIELDS, STEP_FIELDS_BY_TYPE, } from './step-fields.js';
11
+ import { jsonSchemaError, snapshotJsonSchema } from './json-schema.js';
12
+ import { snapshotJsonValue } from './json-value.js';
13
+ const STEP_TYPES = new Set([
14
+ 'deterministic',
15
+ 'llm',
16
+ 'agent',
17
+ ]);
18
+ const RECOVERY_MODES = new Set([
19
+ 'reset',
20
+ 'inspect',
21
+ 'manual',
22
+ ]);
23
+ const DECIMAL_RE = /^\d+(\.\d+)?$/;
24
+ function isCanonicalPathSurface(value) {
25
+ if (!isNonEmptyString(value) || value.trim() !== value)
26
+ return false;
27
+ let tail = value;
28
+ if (tail.startsWith('/'))
29
+ tail = tail.slice(1);
30
+ else {
31
+ const scheme = tail.indexOf('://');
32
+ if (scheme >= 0) {
33
+ if (scheme === 0 || tail.slice(0, scheme).includes('/'))
34
+ return false;
35
+ tail = tail.slice(scheme + 3);
36
+ }
37
+ }
38
+ if (tail === '')
39
+ return true;
40
+ return tail.split('/').every((part) => part !== '' && part !== '.' && part !== '..');
41
+ }
42
+ // Allowed keys per authoring object level. Validation is fail-closed on
43
+ // unknown keys (AGENTS.md rule 4; RFC covenant 2): a typo'd key like
44
+ // `depends_on` must be an error naming the nearest valid key, never a
45
+ // silently discarded field — silently dropping `dependsOn` loses ordering.
46
+ const BUDGET_KEYS = ['maxTokensIn', 'maxTokensOut', 'maxDollars'];
47
+ const VERIFICATION_KEYS = {
48
+ exit_code: ['type', 'expect'],
49
+ output_contains: ['type', 'value'],
50
+ json_schema: ['type', 'schema'],
51
+ };
52
+ const SURFACES_KEYS = ['workspace', 'streams', 'external'];
53
+ const WORKSPACE_SURFACE_KEYS = ['surface'];
54
+ const STREAM_SURFACE_KEYS = ['stream'];
55
+ const PERMISSIONS_KEYS = ['fileGlobs', 'networkAllowlist', 'accessPreset'];
56
+ // A trigger may also declare an event subscription. Without these keys the
57
+ // compiler rejects the very fixture the kernel advertises
58
+ // (testdata/event-triggered-flow.yaml), so the feature is unauthorable through
59
+ // the supported SDK path even though the kernel accepts it.
60
+ const TRIGGER_KEYS = [
61
+ 'id',
62
+ 'executor',
63
+ 'eventType',
64
+ 'pattern',
65
+ 'dedupeKeyTemplate',
66
+ 'staleAfterMs',
67
+ ];
68
+ /**
69
+ * The kernel stores a silence budget as SQLite `INTEGER` and compares it in
70
+ * `i64` (`TriggerSpec::effective_stale_after_ms`), refusing anything wider.
71
+ * Mirror the bound here so an unrepresentable budget is a compile error rather
72
+ * than an engine error at submit time — a budget the sweep cannot represent
73
+ * fails OPEN, which is the silent death this field exists to prevent.
74
+ *
75
+ * The bound is `Number.MAX_SAFE_INTEGER`, NOT `i64::MAX`. Writing the i64
76
+ * bound as a JS literal does not express it: `9_223_372_036_854_775_807`
77
+ * rounds UP to 2^63 in a double, so `value > MAX` then ADMITTED exactly the
78
+ * one value the kernel refuses — the SDK/kernel-agreement failure this whole
79
+ * file exists to prevent, in miniature. Above 2^53 a JS number cannot name a
80
+ * specific integer at all, so any larger budget could not be transmitted
81
+ * faithfully even if the kernel would take it. 2^53 ms is ~285,000 years;
82
+ * nothing real is lost by refusing beyond it.
83
+ */
84
+ const MAX_STALE_AFTER_MS = Number.MAX_SAFE_INTEGER;
85
+ class Validator {
86
+ errors = [];
87
+ ids = new Set();
88
+ agentNames = new Set();
89
+ fail(msg) {
90
+ this.errors.push(msg);
91
+ }
92
+ /**
93
+ * Reject unknown keys at an authoring object level, suggesting the nearest
94
+ * valid key. Errors speak the author's vocabulary (RFC covenant 1):
95
+ * `unknown key "depends_on" — did you mean "dependsOn"?`.
96
+ */
97
+ checkKeys(obj, allowed, at) {
98
+ for (const error of unknownKeyErrors(obj, allowed, at))
99
+ this.fail(error);
100
+ }
101
+ result() {
102
+ return { ok: this.errors.length === 0, errors: this.errors };
103
+ }
104
+ run(spec) {
105
+ if (!isObject(spec)) {
106
+ this.fail('spec: expected an object');
107
+ return this.result();
108
+ }
109
+ const s = spec;
110
+ this.checkKeys(s, FLOW_FIELDS, 'spec');
111
+ if (!isNonEmptyString(s['version'])) {
112
+ this.fail(`spec.version: expected supported version "${SPEC_SCHEMA_VERSION}"`);
113
+ }
114
+ else if (s['version'] !== SPEC_SCHEMA_VERSION) {
115
+ this.fail(`spec.version: unsupported version "${s['version']}" (expected "${SPEC_SCHEMA_VERSION}")`);
116
+ }
117
+ if (s['name'] !== undefined && !isNonEmptyString(s['name'])) {
118
+ this.fail('spec.name: expected a non-empty string');
119
+ }
120
+ if (s['description'] !== undefined && typeof s['description'] !== 'string') {
121
+ this.fail('spec.description: expected a string');
122
+ }
123
+ if (s['cli'] !== undefined && !isNonEmptyString(s['cli'])) {
124
+ this.fail('spec.cli: expected a non-empty string');
125
+ }
126
+ if (s['agents'] !== undefined)
127
+ this.validateAgents(s['agents']);
128
+ if (s['triggers'] !== undefined)
129
+ this.validateTriggers(s['triggers']);
130
+ if (s['budget'] !== undefined)
131
+ this.validateBudget(s['budget']);
132
+ if (!Array.isArray(s['steps']) || s['steps'].length === 0) {
133
+ this.fail('spec.steps: expected a non-empty array');
134
+ return this.result();
135
+ }
136
+ const steps = s['steps'];
137
+ for (let i = 0; i < steps.length; i++) {
138
+ this.validateStep(steps[i], i);
139
+ }
140
+ // Dependents must reference real step ids and form a DAG (no cycles).
141
+ for (const error of stepDependencyErrors(steps, this.ids))
142
+ this.fail(error);
143
+ return this.result();
144
+ }
145
+ validateAgents(value) {
146
+ if (!isObject(value)) {
147
+ this.fail('spec.agents: expected a map of named { cli, model } declarations');
148
+ return;
149
+ }
150
+ for (const [name, raw] of Object.entries(value)) {
151
+ const at = `spec.agents.${name}`;
152
+ if (!isNonEmptyString(name) || name !== name.trim()) {
153
+ this.fail('spec.agents: agent names must be non-empty trimmed strings');
154
+ continue;
155
+ }
156
+ this.agentNames.add(name);
157
+ if (!isObject(raw)) {
158
+ this.fail(`${at}: expected an object with cli and model`);
159
+ continue;
160
+ }
161
+ this.checkKeys(raw, AGENT_DECLARATION_FIELDS, at);
162
+ const declaration = raw;
163
+ if (!isNonEmptyString(declaration.cli) || declaration.cli !== declaration.cli.trim()) {
164
+ this.fail(`${at}.cli: expected a non-empty trimmed string`);
165
+ }
166
+ this.validateModel(declaration.model, at, true);
167
+ }
168
+ }
169
+ validateBudget(b) {
170
+ if (!isObject(b)) {
171
+ this.fail('spec.budget: expected an object');
172
+ return;
173
+ }
174
+ this.checkKeys(b, BUDGET_KEYS, 'spec.budget');
175
+ const budget = b;
176
+ if (budget.maxTokensIn !== undefined &&
177
+ !isNonNegInt(budget.maxTokensIn)) {
178
+ this.fail('spec.budget.maxTokensIn: expected a non-negative integer');
179
+ }
180
+ if (budget.maxTokensOut !== undefined &&
181
+ !isNonNegInt(budget.maxTokensOut)) {
182
+ this.fail('spec.budget.maxTokensOut: expected a non-negative integer');
183
+ }
184
+ if (budget.maxDollars !== undefined) {
185
+ if (typeof budget.maxDollars !== 'string' || !DECIMAL_RE.test(budget.maxDollars)) {
186
+ this.fail('spec.budget.maxDollars: expected a decimal string, e.g. "1.50"');
187
+ }
188
+ }
189
+ }
190
+ validateTriggers(value) {
191
+ if (!Array.isArray(value)) {
192
+ this.fail('spec.triggers: expected an array');
193
+ return;
194
+ }
195
+ const ids = new Set();
196
+ for (const [index, trigger] of value.entries()) {
197
+ const at = `spec.triggers[${index}]`;
198
+ if (!isObject(trigger)) {
199
+ this.fail(`${at}: expected an object`);
200
+ continue;
201
+ }
202
+ this.checkKeys(trigger, TRIGGER_KEYS, at);
203
+ const candidate = trigger;
204
+ if (!isNonEmptyString(candidate.id)) {
205
+ this.fail(`${at}.id: expected a non-empty string`);
206
+ }
207
+ else if (ids.has(candidate.id)) {
208
+ this.fail(`${at}.id: duplicate trigger id "${candidate.id}"`);
209
+ }
210
+ else {
211
+ ids.add(candidate.id);
212
+ }
213
+ if (!isNonEmptyString(candidate.executor)) {
214
+ this.fail(`${at}.executor: expected a non-empty string`);
215
+ }
216
+ this.validateStaleAfterMs(candidate.staleAfterMs, `${at}.staleAfterMs`);
217
+ }
218
+ }
219
+ /**
220
+ * A silence budget must be a positive, i64-representable whole number of
221
+ * milliseconds. Zero is refused rather than treated as "no budget": a
222
+ * zero-length budget marks the subscription stale on the very next sweep,
223
+ * which reads as a permanently-broken schedule and trains an operator to
224
+ * ignore the alert.
225
+ */
226
+ validateStaleAfterMs(value, at) {
227
+ if (value === undefined)
228
+ return;
229
+ if (typeof value !== 'number' || !Number.isInteger(value)) {
230
+ this.fail(`${at}: expected an integer number of milliseconds`);
231
+ return;
232
+ }
233
+ if (value <= 0) {
234
+ this.fail(`${at}: expected a positive number of milliseconds, got ${value}`);
235
+ return;
236
+ }
237
+ if (value > MAX_STALE_AFTER_MS) {
238
+ this.fail(`${at}: ${value} exceeds ${MAX_STALE_AFTER_MS}, the largest budget that survives the `
239
+ + `SDK -> kernel boundary exactly (the sweep stores it as i64)`);
240
+ }
241
+ }
242
+ validateStep(step, index) {
243
+ const at = `spec.steps[${index}]`;
244
+ if (!isObject(step)) {
245
+ this.fail(`${at}: expected an object`);
246
+ return;
247
+ }
248
+ const st = step;
249
+ if (!isNonEmptyString(st['id'])) {
250
+ this.fail(`${at}.id: expected a non-empty string`);
251
+ }
252
+ else if (this.ids.has(st['id'])) {
253
+ this.fail(`${at}.id: duplicate step id "${st['id']}"`);
254
+ }
255
+ else {
256
+ this.ids.add(st['id']);
257
+ }
258
+ if (!isNonEmptyString(st['type']) || !STEP_TYPES.has(st['type'])) {
259
+ this.fail(`${at}.type: expected one of deterministic | llm | agent`);
260
+ return;
261
+ }
262
+ const type = st['type'];
263
+ this.checkKeys(st, [...STEP_COMMON_FIELDS, ...STEP_FIELDS_BY_TYPE[type]], at);
264
+ if (st['dependsOn'] !== undefined) {
265
+ if (!Array.isArray(st['dependsOn']) || !st['dependsOn'].every(isNonEmptyString)) {
266
+ this.fail(`${at}.dependsOn: expected an array of step ids`);
267
+ }
268
+ }
269
+ if (st['verification'] !== undefined) {
270
+ this.validateVerification(st['verification'], `${at}.verification`, type);
271
+ }
272
+ if (st['maxIterations'] !== undefined && !isPosInt(st['maxIterations'])) {
273
+ this.fail(`${at}.maxIterations: expected a positive integer`);
274
+ }
275
+ if (type === 'deterministic') {
276
+ this.validateDeterministic(st, at);
277
+ }
278
+ else if (type === 'llm') {
279
+ this.validateLlm(st, at);
280
+ for (const error of validateOutputDeclaration(st, at))
281
+ this.fail(error);
282
+ }
283
+ else {
284
+ this.validateAgent(st, at);
285
+ for (const error of validateOutputDeclaration(st, at))
286
+ this.fail(error);
287
+ }
288
+ }
289
+ validateVerification(v, at, stepType) {
290
+ if (!isObject(v)) {
291
+ this.fail(`${at}: expected an object`);
292
+ return;
293
+ }
294
+ const gate = v;
295
+ const gateKeys = typeof gate.type === 'string' ? VERIFICATION_KEYS[gate.type] : undefined;
296
+ if (gateKeys !== undefined) {
297
+ this.checkKeys(v, gateKeys, at);
298
+ }
299
+ if (gate.type === 'exit_code') {
300
+ if (stepType !== 'deterministic') {
301
+ this.fail(`${at}: exit_code is supported only on deterministic steps`);
302
+ }
303
+ // v0 judges exit_code == 0 exactly (kernel DESIGN.md §4). Fail closed
304
+ // rather than compile a spec whose gate the kernel cannot enforce.
305
+ if (gate.expect !== undefined && gate.expect !== 0) {
306
+ this.fail(`${at}.expect: v0 exit_code gate judges exit_code == 0; a custom expect is not supported`);
307
+ }
308
+ }
309
+ else if (gate.type === 'output_contains') {
310
+ if (typeof gate.value !== 'string' || gate.value.length === 0) {
311
+ this.fail(`${at}.value: expected a non-empty string`);
312
+ }
313
+ }
314
+ else if (gate.type === 'json_schema') {
315
+ try {
316
+ const schema = snapshotJsonSchema(gate.schema, `${at}.schema`);
317
+ const error = jsonSchemaError(schema);
318
+ if (error !== undefined) {
319
+ this.fail(`${at}.schema: invalid JSON Schema: ${error}`);
320
+ }
321
+ }
322
+ catch (error) {
323
+ this.fail(error instanceof Error ? error.message : `${at}.schema: expected JSON-compatible data`);
324
+ }
325
+ }
326
+ else {
327
+ this.fail(`${at}.type: expected exit_code | output_contains | json_schema`);
328
+ }
329
+ }
330
+ validateDeterministic(st, at) {
331
+ if (!isNonEmptyString(st.command)) {
332
+ this.fail(`${at}.command: expected a non-empty string`);
333
+ }
334
+ if (st.timeoutMs !== undefined && !isPosInt(st.timeoutMs)) {
335
+ this.fail(`${at}.timeoutMs: expected a positive integer`);
336
+ }
337
+ }
338
+ validateLlm(st, at) {
339
+ if (!isNonEmptyString(st.prompt)) {
340
+ this.fail(`${at}.prompt: expected a non-empty string`);
341
+ }
342
+ this.validateModel(st.model, at);
343
+ this.validateCli(st.cli, at);
344
+ }
345
+ validateAgent(st, at) {
346
+ if (!isNonEmptyString(st.instruction)) {
347
+ this.fail(`${at}.instruction: expected a non-empty string`);
348
+ }
349
+ if (st.agent !== undefined) {
350
+ if (!isNonEmptyString(st.agent)) {
351
+ this.fail(`${at}.agent: expected a non-empty named agent`);
352
+ }
353
+ else if (!this.agentNames.has(st.agent)) {
354
+ this.fail(`${at}.agent: unknown named agent "${st.agent}"`);
355
+ }
356
+ }
357
+ if (st.recoveryMode !== undefined && !RECOVERY_MODES.has(st.recoveryMode)) {
358
+ this.fail(`${at}.recoveryMode: expected reset | inspect | manual`);
359
+ }
360
+ this.validateCli(st.cli, at);
361
+ this.validateModel(st.model, at);
362
+ if (st.surfaces !== undefined)
363
+ this.validateSurfaces(st.surfaces, `${at}.surfaces`);
364
+ if (st.permissions !== undefined)
365
+ this.validatePermissions(st.permissions, `${at}.permissions`);
366
+ }
367
+ validateCli(cli, at) {
368
+ if (cli !== undefined && !isNonEmptyString(cli)) {
369
+ this.fail(`${at}.cli: expected a non-empty string`);
370
+ }
371
+ }
372
+ validateModel(model, at, required = false) {
373
+ // Rejecting the empty string matters: it would reach the CLI as
374
+ // RELAYFLOW_MODEL='', which reads as "declared, and declared as
375
+ // nothing" — the CLI cannot tell it from a real value and would
376
+ // pass an empty --model. Absent and empty must not look alike.
377
+ if (model === undefined && !required)
378
+ return;
379
+ const problem = modelNameError(model);
380
+ if (problem !== undefined)
381
+ this.fail(`${at}.model: ${problem}`);
382
+ }
383
+ validateSurfaces(surfaces, at) {
384
+ if (!isObject(surfaces)) {
385
+ this.fail(`${at}: expected an object`);
386
+ return;
387
+ }
388
+ const s = surfaces;
389
+ this.checkKeys(s, SURFACES_KEYS, at);
390
+ if (s['workspace'] !== undefined) {
391
+ if (!Array.isArray(s['workspace']) || !s['workspace'].every((w) => isObject(w) && isCanonicalPathSurface(w['surface']))) {
392
+ this.fail(`${at}.workspace: expected canonical {surface: string} entries without empty, . or .. path components`);
393
+ }
394
+ else {
395
+ for (const [i, w] of s['workspace'].entries()) {
396
+ this.checkKeys(w, WORKSPACE_SURFACE_KEYS, `${at}.workspace[${i}]`);
397
+ }
398
+ }
399
+ }
400
+ if (s['streams'] !== undefined) {
401
+ if (!Array.isArray(s['streams']) || !s['streams'].every((w) => isObject(w) && isNonEmptyString(w['stream']))) {
402
+ this.fail(`${at}.streams: expected an array of {stream: string}`);
403
+ }
404
+ else {
405
+ for (const [i, w] of s['streams'].entries()) {
406
+ this.checkKeys(w, STREAM_SURFACE_KEYS, `${at}.streams[${i}]`);
407
+ }
408
+ }
409
+ }
410
+ if (s['external'] !== undefined) {
411
+ if (!Array.isArray(s['external']) || !s['external'].every(isCanonicalPathSurface)) {
412
+ this.fail(`${at}.external: expected canonical path strings without empty, . or .. components`);
413
+ }
414
+ }
415
+ }
416
+ validatePermissions(p, at) {
417
+ if (!isObject(p)) {
418
+ this.fail(`${at}: expected an object`);
419
+ return;
420
+ }
421
+ this.checkKeys(p, PERMISSIONS_KEYS, at);
422
+ if (p.accessPreset !== undefined && p.accessPreset !== 'readonly' && p.accessPreset !== 'readwrite') {
423
+ this.fail(`${at}.accessPreset: expected readonly | readwrite`);
424
+ }
425
+ if (p.fileGlobs !== undefined && !(Array.isArray(p.fileGlobs) && p.fileGlobs.every(isNonEmptyString))) {
426
+ this.fail(`${at}.fileGlobs: expected an array of strings`);
427
+ }
428
+ if (p.networkAllowlist !== undefined && !(Array.isArray(p.networkAllowlist) && p.networkAllowlist.every(isNonEmptyString))) {
429
+ this.fail(`${at}.networkAllowlist: expected an array of strings`);
430
+ }
431
+ }
432
+ }
433
+ /** Validate a parsed spec object. Returns `{ok, errors}`; never throws. */
434
+ export function validateSpec(spec) {
435
+ try {
436
+ return new Validator().run(snapshotJsonValue(spec, 'spec'));
437
+ }
438
+ catch (error) {
439
+ return {
440
+ ok: false,
441
+ errors: [error instanceof Error ? error.message : 'spec: expected JSON-compatible data'],
442
+ };
443
+ }
444
+ }
445
+ // --- predicates -------------------------------------------------------------
446
+ function isObject(v) {
447
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
448
+ }
449
+ function isNonEmptyString(v) {
450
+ return typeof v === 'string' && v.length > 0;
451
+ }
452
+ function isNonNegInt(v) {
453
+ return typeof v === 'number' && Number.isInteger(v) && v >= 0;
454
+ }
455
+ function isPosInt(v) {
456
+ return typeof v === 'number' && Number.isInteger(v) && v > 0;
457
+ }
458
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /** The work-package shape emitted at the SDK boundary. */
2
+ export interface EmittedWorkPackage {
3
+ title: string;
4
+ files_in_scope: string[];
5
+ definition_of_done: string[];
6
+ description?: string;
7
+ gate?: number | null;
8
+ }
9
+ export type WorkPackageRefusalReason = 'missing_title' | 'missing_scope' | 'missing_definition_of_done' | 'nonexistent_files';
10
+ export type WorkPackageConsumption = {
11
+ accepted: true;
12
+ work: EmittedWorkPackage;
13
+ } | {
14
+ accepted: false;
15
+ reason: WorkPackageRefusalReason;
16
+ };
17
+ /** Resolve a scoped path; used to check that scoped files are really there. */
18
+ export type PathExists = (path: string) => boolean;
19
+ /**
20
+ * Validate an emitted package before admitting it as runnable work.
21
+ * Refusals are data so callers must handle an unverifiable package explicitly.
22
+ *
23
+ * The existence check is ON by default — review rejected making it opt-in
24
+ * (PR #28, P1): a caller using the one-argument API would silently skip it, so
25
+ * the guard would not guard. `pathExists` defaults to the real filesystem and
26
+ * is injectable purely so the behaviour can be tested without one. A package
27
+ * scoping files that are not there is refused: the picker derives files_in_scope from prose
28
+ * in ops/BACKLOG.md, so a stale or mistyped entry produces a package that reads
29
+ * as actionable and sends whoever picks it up looking for something that does
30
+ * not exist. Checking is cheap; a wrong scope is not.
31
+ */
32
+ export declare function consumeWorkPackage(input: unknown, pathExists?: PathExists): WorkPackageConsumption;
33
+ //# sourceMappingURL=work-package-consumer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-package-consumer.d.ts","sourceRoot":"","sources":["../src/work-package-consumer.ts"],"names":[],"mappings":"AAEA,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,MAAM,wBAAwB,GAChC,eAAe,GACf,eAAe,GACf,4BAA4B,GAC5B,mBAAmB,CAAC;AAExB,MAAM,MAAM,sBAAsB,GAC9B;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,GAC5C;IAAE,QAAQ,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,wBAAwB,CAAA;CAAE,CAAC;AAE1D,+EAA+E;AAC/E,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;AAKnD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,UAAU,GAAE,UAA8B,GACzC,sBAAsB,CAiBxB"}
@@ -0,0 +1,44 @@
1
+ import { existsSync } from 'node:fs';
2
+ /** Default: ask the filesystem. Injectable so the check is testable. */
3
+ const defaultPathExists = (path) => existsSync(path);
4
+ /**
5
+ * Validate an emitted package before admitting it as runnable work.
6
+ * Refusals are data so callers must handle an unverifiable package explicitly.
7
+ *
8
+ * The existence check is ON by default — review rejected making it opt-in
9
+ * (PR #28, P1): a caller using the one-argument API would silently skip it, so
10
+ * the guard would not guard. `pathExists` defaults to the real filesystem and
11
+ * is injectable purely so the behaviour can be tested without one. A package
12
+ * scoping files that are not there is refused: the picker derives files_in_scope from prose
13
+ * in ops/BACKLOG.md, so a stale or mistyped entry produces a package that reads
14
+ * as actionable and sends whoever picks it up looking for something that does
15
+ * not exist. Checking is cheap; a wrong scope is not.
16
+ */
17
+ export function consumeWorkPackage(input, pathExists = defaultPathExists) {
18
+ if (!isRecord(input) || !isNonEmptyString(input['title'])) {
19
+ return { accepted: false, reason: 'missing_title' };
20
+ }
21
+ if (!isNonEmptyStringArray(input['files_in_scope'])) {
22
+ return { accepted: false, reason: 'missing_scope' };
23
+ }
24
+ if (isNonEmptyStringArray(input['files_in_scope'])) {
25
+ const missing = input['files_in_scope'].filter((p) => !pathExists(p));
26
+ if (missing.length > 0) {
27
+ return { accepted: false, reason: 'nonexistent_files' };
28
+ }
29
+ }
30
+ if (!isNonEmptyStringArray(input['definition_of_done'])) {
31
+ return { accepted: false, reason: 'missing_definition_of_done' };
32
+ }
33
+ return { accepted: true, work: input };
34
+ }
35
+ function isRecord(value) {
36
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
37
+ }
38
+ function isNonEmptyString(value) {
39
+ return typeof value === 'string' && value.trim().length > 0;
40
+ }
41
+ function isNonEmptyStringArray(value) {
42
+ return Array.isArray(value) && value.length > 0 && value.every(isNonEmptyString);
43
+ }
44
+ //# sourceMappingURL=work-package-consumer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-package-consumer.js","sourceRoot":"","sources":["../src/work-package-consumer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAwBrC,wEAAwE;AACxE,MAAM,iBAAiB,GAAe,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAEjE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAc,EACd,aAAyB,iBAAiB;IAE1C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QAC1D,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IACtD,CAAC;IACD,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC;QACpD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IACtD,CAAC;IACD,IAAI,qBAAqB,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC;QACnD,MAAM,OAAO,GAAG,KAAK,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,4BAA4B,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAsC,EAAE,CAAC;AAC1E,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc;IAC3C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;AACnF,CAAC"}