toolroll 0.9.33 → 0.9.36

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 (74) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +7 -0
  3. package/dist/assignment.d.ts +1 -0
  4. package/dist/assignment.js +2 -2
  5. package/dist/browser/workspace.css +1 -1
  6. package/dist/browser/workspace.js +17 -17
  7. package/dist/browser-crew.js +1 -0
  8. package/dist/browser-workspace.d.ts +5 -3
  9. package/dist/builder.js +4 -7
  10. package/dist/chat-acceptance.d.ts +1 -1
  11. package/dist/cli.d.ts +1 -1
  12. package/dist/cli.js +124 -63
  13. package/dist/contracts/contract-test.d.ts +45 -0
  14. package/dist/contracts/contract-test.js +69 -0
  15. package/dist/contracts/contract.d.ts +87 -0
  16. package/dist/contracts/contract.js +308 -0
  17. package/dist/contracts/flow-propose.d.ts +325 -0
  18. package/dist/contracts/flow-propose.js +41 -0
  19. package/dist/contracts/flow.d.ts +19400 -0
  20. package/dist/contracts/flow.js +359 -0
  21. package/dist/contracts/handoff.d.ts +91 -0
  22. package/dist/contracts/handoff.js +82 -0
  23. package/dist/contracts/plan.d.ts +58 -0
  24. package/dist/contracts/plan.js +67 -0
  25. package/dist/contracts/proof.d.ts +136 -0
  26. package/dist/contracts/proof.js +110 -0
  27. package/dist/contracts/verification-receipt.d.ts +148 -0
  28. package/dist/contracts/verification-receipt.js +87 -0
  29. package/dist/demo.js +28 -11
  30. package/dist/desktop-update.d.ts +1 -1
  31. package/dist/evidence.d.ts +3 -40
  32. package/dist/evidence.js +7 -3
  33. package/dist/flow-gallery.d.ts +3 -2
  34. package/dist/flow-share.d.ts +10 -32
  35. package/dist/flow-share.js +65 -83
  36. package/dist/flow-starters.d.ts +2 -1
  37. package/dist/flow-triggers.d.ts +15 -72
  38. package/dist/flow-triggers.js +94 -83
  39. package/dist/flows.d.ts +37 -218
  40. package/dist/flows.js +350 -385
  41. package/dist/mate-tools.js +14 -44
  42. package/dist/mcp-connect.d.ts +3 -0
  43. package/dist/mcp-connect.js +16 -4
  44. package/dist/operate.js +83 -12
  45. package/dist/plan.d.ts +12 -12
  46. package/dist/plan.js +109 -72
  47. package/dist/planner-source.js +2 -1
  48. package/dist/planner.js +55 -25
  49. package/dist/process-recovery-eligibility.d.ts +2 -2
  50. package/dist/process-recovery-eligibility.js +13 -8
  51. package/dist/project-admission.d.ts +93 -0
  52. package/dist/project-admission.js +134 -0
  53. package/dist/project-delete-ui.js +5 -2
  54. package/dist/proof.d.ts +15 -91
  55. package/dist/proof.js +90 -249
  56. package/dist/result-evidence-readers.d.ts +42 -0
  57. package/dist/result-evidence-readers.js +91 -0
  58. package/dist/runner.d.ts +10 -0
  59. package/dist/runner.js +16 -0
  60. package/dist/scope.js +4 -3
  61. package/dist/serve.d.ts +4 -0
  62. package/dist/serve.js +112 -160
  63. package/dist/setup-guide.d.ts +2 -2
  64. package/dist/store.d.ts +2 -0
  65. package/dist/store.js +4 -0
  66. package/dist/surface.js +16 -3
  67. package/dist/task-review-brief.d.ts +75 -0
  68. package/dist/task-review-brief.js +179 -0
  69. package/dist/text-limits.d.ts +87 -0
  70. package/dist/text-limits.js +86 -0
  71. package/dist/verification-evidence.js +24 -12
  72. package/dist/when-html.d.ts +2 -0
  73. package/dist/when-html.js +13 -0
  74. package/package.json +3 -2
@@ -0,0 +1,308 @@
1
+ /**
2
+ * The one way Toolroll describes a contract (docs/plans/zod-revamp.md): one Zod schema, and everything else — the
3
+ * TypeScript type, the runtime check, the JSON Schema a model gets, the text limits — derived from it.
4
+ *
5
+ * The helpers here hold the ground rules every contract shares: limits come from TEXT_LIMITS, persisted payloads are
6
+ * versioned, refusals name the path, and a model-facing schema is exactly what its JSON Schema says (no refinements or
7
+ * transforms; those checks run in plain code after parsing, with a named error).
8
+ */
9
+ import { z } from "zod";
10
+ import { limitRule, TEXT_LIMITS } from "../text-limits.js";
11
+ /**
12
+ * A string bounded by its TEXT_LIMITS entry, never a literal. The limit rule rides along as the field's description,
13
+ * so a model reads the bound before it writes. Zod counts UTF-16 code units; for a limit named in bytes this is the
14
+ * schema's necessary bound (a string within N bytes is within N code units), and the byte count itself is checked in
15
+ * plain code after parsing.
16
+ */
17
+ export function limited(field, limitKey) {
18
+ const limit = TEXT_LIMITS[limitKey];
19
+ const unit = limitKey.endsWith("Bytes") ? "bytes" : "characters";
20
+ return z.string().max(limit, { error: `over ${limit.toLocaleString("en-US")} ${unit}` }).describe(limitRule(field, limit, unit));
21
+ }
22
+ /** A versioned payload envelope: a strict object whose `version` is exactly `version`. */
23
+ export function versioned(version, shape) {
24
+ return z.strictObject({ version: z.literal(version), ...shape });
25
+ }
26
+ /** `["steps", 0, "routes", 0, "goesTo"]` as `steps[0].routes[0].goesTo`. */
27
+ export function pathOf(path) {
28
+ let out = "";
29
+ for (const part of path) {
30
+ if (typeof part === "number")
31
+ out += `[${part}]`;
32
+ else
33
+ out += out === "" ? String(part) : `.${String(part)}`;
34
+ }
35
+ return out === "" ? "payload" : out;
36
+ }
37
+ function got(input) {
38
+ if (input === null)
39
+ return "null";
40
+ if (Array.isArray(input))
41
+ return "an array";
42
+ return typeof input === "object" ? "an object" : `a ${typeof input}`;
43
+ }
44
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
45
+ /** The keys an object schema allows at `path` in `input`, following arrays, wrappers and (by its discriminator) a union. */
46
+ function keysAt(schema, input, path) {
47
+ let node = schema, value = input;
48
+ for (let at = 0; node !== undefined;) {
49
+ const def = node._zod.def;
50
+ if (def.type === "optional" || def.type === "nullable" || def.type === "readonly") {
51
+ node = def["innerType"];
52
+ continue;
53
+ }
54
+ if (def.type === "lazy") {
55
+ node = def["getter"]();
56
+ continue;
57
+ }
58
+ if (def.type === "union") {
59
+ const options = def["options"];
60
+ const by = def["discriminator"];
61
+ const wanted = by !== undefined && isRecord(value) ? value[by] : undefined;
62
+ node = options.find(option => {
63
+ const shape = option._zod.def["shape"];
64
+ if (shape === undefined)
65
+ return false;
66
+ if (by === undefined)
67
+ return true;
68
+ const literal = shape[by]?._zod.def;
69
+ return literal !== undefined && literal["values"]?.includes(wanted) === true;
70
+ });
71
+ continue;
72
+ }
73
+ if (at === path.length)
74
+ return def.type === "object" ? Object.keys(def["shape"]) : null;
75
+ const part = path[at++];
76
+ if (def.type === "array" && typeof part === "number") {
77
+ node = def["element"];
78
+ value = Array.isArray(value) ? value[part] : undefined;
79
+ continue;
80
+ }
81
+ if (def.type === "object" && typeof part === "string") {
82
+ const shape = def["shape"];
83
+ node = shape[part] ?? def["catchall"];
84
+ value = isRecord(value) ? value[part] : undefined;
85
+ continue;
86
+ }
87
+ return null;
88
+ }
89
+ return null;
90
+ }
91
+ /** Edit distance, for "did you mean" (short strings only). */
92
+ function distance(a, b) {
93
+ const row = Array.from({ length: b.length + 1 }, (_, index) => index);
94
+ for (let i = 1; i <= a.length; i++) {
95
+ let last = row[0];
96
+ row[0] = i;
97
+ for (let j = 1; j <= b.length; j++) {
98
+ const was = row[j];
99
+ row[j] = Math.min(row[j] + 1, row[j - 1] + 1, last + (a[i - 1] === b[j - 1] ? 0 : 1));
100
+ last = was;
101
+ }
102
+ }
103
+ return row[b.length];
104
+ }
105
+ /** The allowed key an unknown one most likely meant, or null. */
106
+ function suggestion(key, known, options) {
107
+ if (known === null || known.length === 0)
108
+ return null;
109
+ const alias = options.aliases?.[key]?.find(one => known.includes(one));
110
+ if (alias !== undefined)
111
+ return alias;
112
+ const close = known
113
+ .map(one => ({ one, far: one.toLowerCase() === key.toLowerCase() ? 0 : distance(one.toLowerCase(), key.toLowerCase()) }))
114
+ .filter(({ one, far }) => far <= (Math.min(one.length, key.length) >= 6 ? 2 : 1))
115
+ .sort((a, b) => a.far - b.far);
116
+ return close[0]?.one ?? null;
117
+ }
118
+ function issuesOf(issue, where = {}) {
119
+ const at = pathOf(issue.path);
120
+ const one = (kind, what) => ({ path: at, kind, line: `${at}: ${what}` });
121
+ switch (issue.code) {
122
+ case "unrecognized_keys": {
123
+ const known = where.schema === undefined ? null : keysAt(where.schema, where.input, issue.path);
124
+ return issue.keys.map(key => {
125
+ const meant = suggestion(key, known, where.options ?? {});
126
+ return { path: at, kind: "unknown-key", line: `${at}: unknown key '${key}'${meant === null ? "" : ` (did you mean ${meant}?)`}` };
127
+ });
128
+ }
129
+ case "invalid_type": {
130
+ const missing = "input" in issue ? issue.input === undefined : / received undefined$/.test(issue.message);
131
+ // A null where a value belongs is a value left out.
132
+ if (missing || ("input" in issue && issue.input === null && issue.expected !== "null"))
133
+ return [one("required", "required")];
134
+ const expected = issue.expected === "array" ? "an array" : issue.expected === "object" ? "an object" : issue.expected === "null" ? "null" : `a ${issue.expected}`;
135
+ return [one("wrong-type", `must be ${expected}${"input" in issue ? ` (got ${got(issue.input)})` : ""}`)];
136
+ }
137
+ case "too_big":
138
+ if (issue.origin === "array" || issue.origin === "set")
139
+ return [one("too-many", `at most ${String(issue.maximum)} items`)];
140
+ if (issue.origin === "number" || issue.origin === "int" || issue.origin === "bigint")
141
+ return [one("bad-value", `at most ${String(issue.maximum)}`)];
142
+ return [one("too-long", issue.origin === "string" && issue.message.startsWith("over ") ? issue.message : `at most ${String(issue.maximum)}${issue.origin === "string" ? " characters" : ""}`)];
143
+ case "too_small":
144
+ if (issue.origin === "string" && Number(issue.minimum) === 1)
145
+ return [one("empty", "must not be empty")];
146
+ if (issue.origin === "array" || issue.origin === "set")
147
+ return [one("too-few", `at least ${String(issue.minimum)} item${Number(issue.minimum) === 1 ? "" : "s"}`)];
148
+ if (issue.origin === "number" || issue.origin === "int" || issue.origin === "bigint")
149
+ return [one("bad-value", `at least ${String(issue.minimum)}`)];
150
+ return [one("too-few", `at least ${String(issue.minimum)}`)];
151
+ case "invalid_value":
152
+ return [one("bad-value", `must be ${issue.values.length === 1 ? JSON.stringify(issue.values[0]) : `one of ${issue.values.map(value => JSON.stringify(value)).join(", ")}`}`)];
153
+ case "invalid_union": {
154
+ // A discriminated union names its choices (`steps[0].kind: must be one of "inbox", "task", ...`).
155
+ const by = issue.discriminator, options = issue.options;
156
+ if (typeof by === "string" && Array.isArray(options)) {
157
+ const given = "input" in issue && isRecord(issue.input) ? issue.input[by] : undefined;
158
+ const path = at === "payload" || issue.path.at(-1) === by ? at : `${at}.${by}`;
159
+ const line = given === undefined || given === null ? "required" : `must be one of ${options.map(value => JSON.stringify(value)).join(", ")}`;
160
+ return [{ path, kind: given === undefined || given === null ? "required" : "bad-value", line: `${path}: ${line}` }];
161
+ }
162
+ return [one("invalid", "does not match any allowed shape")];
163
+ }
164
+ case "invalid_format":
165
+ // A pattern's own words say what it wants (`must be a short id: lowercase letters, numbers and dashes`).
166
+ return [one("bad-value", issue.message.startsWith("Invalid") ? `must match ${issue.format === "regex" ? issue.pattern ?? "its pattern" : issue.format}` : issue.message)];
167
+ default:
168
+ return [one("invalid", issue.message)];
169
+ }
170
+ }
171
+ /**
172
+ * A Zod error as path-named issues, in the error's own order. Given the schema and input it came from, an unknown key
173
+ * also says which allowed key it most likely meant (`unknown key 'onFail' (did you mean ifFails?)`).
174
+ */
175
+ export function contractIssues(error, where = {}) {
176
+ return error.issues.flatMap(issue => issuesOf(issue, where));
177
+ }
178
+ /** A Zod error as path-named lines: `steps[0].routes[0].goesTo: required`, `routes[0]: unknown key 'to'`. */
179
+ export function contractError(error, where = {}) {
180
+ return contractIssues(error, where).map(issue => issue.line);
181
+ }
182
+ /**
183
+ * A contract issue as a problem with a reason code built from its path — `missing-goal`, `criteria[0].how-too-long`,
184
+ * `checks-too-many`, `payload-unknown-key`, `bad-version`, `newer-version` — so callers that branch on a reason, and
185
+ * durable outcomes that recorded one, read the same as before the contract.
186
+ */
187
+ export function contractProblemOf(issue) {
188
+ const at = issue.path;
189
+ const reason = (() => {
190
+ switch (issue.kind) {
191
+ case "required":
192
+ case "empty":
193
+ case "too-few":
194
+ return `missing-${at}`;
195
+ case "too-long":
196
+ return `${at}-too-long`;
197
+ case "too-many":
198
+ return `${at}-too-many`;
199
+ case "unknown-key":
200
+ return `${at}-unknown-key`;
201
+ case "newer-version":
202
+ return "newer-version";
203
+ default:
204
+ return `bad-${at}`;
205
+ }
206
+ })();
207
+ return { reason, message: issue.line };
208
+ }
209
+ /** Parse with the input reported, so a missing field reads `required` rather than a wrong type. */
210
+ export function parseContract(schema, input, options = {}) {
211
+ const parsed = schema.safeParse(input, { reportInput: true });
212
+ return parsed.success ? { ok: true, value: parsed.data } : { ok: false, issues: contractIssues(parsed.error, { schema, input, options }) };
213
+ }
214
+ /**
215
+ * Read a versioned payload. The current version parses as itself; an older known version (0 for a payload saved
216
+ * before it carried `version`) is upgraded by its adapter and then parsed by the same schema; a newer version is
217
+ * refused plainly; anything else is an unknown version.
218
+ */
219
+ export function readVersioned(schema, input, upgrades = {}, options = {}) {
220
+ const current = schema.shape.version.value;
221
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
222
+ return { ok: false, issues: [{ path: "payload", kind: "wrong-type", line: `payload: must be an object (got ${got(input)})` }] };
223
+ }
224
+ const body = input;
225
+ const version = Object.prototype.hasOwnProperty.call(body, "version") ? body["version"] : 0;
226
+ if (version === current)
227
+ return parseContract(schema, body, options);
228
+ if (typeof version === "number" && Number.isInteger(version) && version > current) {
229
+ return { ok: false, issues: [{ path: "version", kind: "newer-version", line: `version: made by a newer Toolroll (version ${version}; this one reads up to ${current})` }] };
230
+ }
231
+ const upgrade = typeof version === "number" ? upgrades[version] : undefined;
232
+ if (upgrade === undefined) {
233
+ return { ok: false, issues: [{ path: "version", kind: "bad-value", line: `version: unknown version ${JSON.stringify(version)} (this Toolroll reads ${current}${Object.keys(upgrades).length === 0 ? "" : ` and ${Object.keys(upgrades).join(", ")}`})` }] };
234
+ }
235
+ return parseContract(schema, upgrade(body), options);
236
+ }
237
+ /** The Zod node kinds a model-facing schema may use: each says exactly what its JSON Schema says. */
238
+ const MODEL_FACING_TYPES = new Set(["string", "number", "int", "boolean", "null", "literal", "enum", "array", "object", "optional", "nullable", "union", "tuple", "record", "lazy", "readonly", "unknown", "any"]);
239
+ /** Checks that only constrain (never rewrite) and that JSON Schema can state. */
240
+ const MODEL_FACING_CHECKS = new Set(["max_length", "min_length", "length_equals", "greater_than", "less_than", "multiple_of", "number_format", "string_format", "size_equals", "max_size", "min_size"]);
241
+ /** Every node of a schema graph, refusing a refinement, transform, preprocess or unknown node by its schema path. */
242
+ function assertModelFacing(schema, at, seen) {
243
+ if (seen.has(schema))
244
+ return;
245
+ seen.add(schema);
246
+ const def = schema._zod.def;
247
+ const where = at === "" ? "the schema" : at;
248
+ if (def.type === "pipe") {
249
+ const into = def["in"]?._zod.def.type;
250
+ const out = def["out"]?._zod.def.type;
251
+ const what = into === "transform" ? "preprocess" : out === "transform" ? "transform" : "pipe";
252
+ throw new Error(`toModelSchema: ${where} uses ${what}; a model-facing schema must be JSON-Schema-exact — check it in plain code after parsing`);
253
+ }
254
+ if (def.type === "transform")
255
+ throw new Error(`toModelSchema: ${where} uses transform; a model-facing schema must be JSON-Schema-exact — check it in plain code after parsing`);
256
+ if (!MODEL_FACING_TYPES.has(def.type))
257
+ throw new Error(`toModelSchema: ${where} uses a ${def.type} node, which a model-facing schema may not use`);
258
+ for (const check of def.checks ?? []) {
259
+ const kind = check._zod.def.check;
260
+ if (kind === "custom")
261
+ throw new Error(`toModelSchema: ${where} uses refine or superRefine; a model-facing schema must be JSON-Schema-exact — check it in plain code after parsing`);
262
+ if (!MODEL_FACING_CHECKS.has(kind))
263
+ throw new Error(`toModelSchema: ${where} uses a ${kind} check, which rewrites or cannot be stated in JSON Schema`);
264
+ }
265
+ const child = (value, path) => assertModelFacing(value, path, seen);
266
+ const join = (key) => (at === "" ? key : `${at}.${key}`);
267
+ switch (def.type) {
268
+ case "object":
269
+ for (const [key, value] of Object.entries(def["shape"]))
270
+ child(value, join(key));
271
+ // A strict object's catchall is `never` (additionalProperties: false); any other catchall is a schema too.
272
+ if (def["catchall"] !== undefined && def["catchall"]._zod.def.type !== "never")
273
+ child(def["catchall"], join("*"));
274
+ break;
275
+ case "array":
276
+ child(def["element"], `${at}[]`);
277
+ break;
278
+ case "optional":
279
+ case "nullable":
280
+ case "readonly":
281
+ child(def["innerType"], at);
282
+ break;
283
+ case "union":
284
+ def["options"].forEach((option, index) => child(option, `${at}|${index}`));
285
+ break;
286
+ case "tuple":
287
+ def["items"].forEach((item, index) => child(item, `${at}[${index}]`));
288
+ if (def["rest"] !== undefined && def["rest"] !== null)
289
+ child(def["rest"], `${at}[]`);
290
+ break;
291
+ case "record":
292
+ child(def["keyType"], `${at}{key}`);
293
+ child(def["valueType"], `${at}{}`);
294
+ break;
295
+ case "lazy":
296
+ child(def["getter"](), at);
297
+ break;
298
+ }
299
+ }
300
+ /**
301
+ * The JSON Schema a model gets for `schema` (Claude's `--json-schema`). Throws when the schema uses refine,
302
+ * superRefine, transform or preprocess anywhere: what a model is told must be everything the schema checks.
303
+ */
304
+ export function toModelSchema(schema) {
305
+ assertModelFacing(schema, "", new Set());
306
+ const { $schema: _dialect, ...json } = z.toJSONSchema(schema, { target: "draft-2020-12", unrepresentable: "throw" });
307
+ return json;
308
+ }
@@ -0,0 +1,325 @@
1
+ /**
2
+ * The lead's `propose_flow` input (docs/plans/zod-revamp.md, item 3): one schema, built from the flow contract's own
3
+ * step and trigger schemas, that is both the JSON Schema the lead is given and the check its call is read with
4
+ * (mate-tools.ts). The lead-tools contract (item 5) imports it from here rather than restating it.
5
+ */
6
+ import { z } from "zod";
7
+ export declare const PROPOSE_FLOW_OPERATIONS: readonly ["create", "edit", "add_card", "move_card", "approve", "send_back", "choose", "cancel_card", "comment", "assign", "follow", "unfollow", "save_script", "add_trigger", "pause_trigger", "resume_trigger", "remove_trigger", "kit", "starter"];
8
+ export declare const proposeFlowInputSchema: z.ZodObject<{
9
+ operation: z.ZodEnum<{
10
+ add_card: "add_card";
11
+ add_trigger: "add_trigger";
12
+ approve: "approve";
13
+ assign: "assign";
14
+ cancel_card: "cancel_card";
15
+ choose: "choose";
16
+ comment: "comment";
17
+ create: "create";
18
+ edit: "edit";
19
+ follow: "follow";
20
+ kit: "kit";
21
+ move_card: "move_card";
22
+ pause_trigger: "pause_trigger";
23
+ remove_trigger: "remove_trigger";
24
+ resume_trigger: "resume_trigger";
25
+ save_script: "save_script";
26
+ send_back: "send_back";
27
+ starter: "starter";
28
+ unfollow: "unfollow";
29
+ }>;
30
+ repo: z.ZodOptional<z.ZodString>;
31
+ flow: z.ZodOptional<z.ZodInt>;
32
+ card: z.ZodOptional<z.ZodInt>;
33
+ kit: z.ZodOptional<z.ZodEnum<{
34
+ [x: string]: string;
35
+ }>>;
36
+ starter: z.ZodOptional<z.ZodEnum<{
37
+ "ci-fix": "ci-fix";
38
+ "issue-task": "issue-task";
39
+ overnight: "overnight";
40
+ "plane-review": "plane-review";
41
+ }>>;
42
+ name: z.ZodOptional<z.ZodString>;
43
+ template: z.ZodOptional<z.ZodEnum<{
44
+ [x: string]: string;
45
+ }>>;
46
+ steps: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<readonly [z.ZodObject<{
47
+ id: z.ZodOptional<z.ZodString>;
48
+ title: z.ZodString;
49
+ kind: z.ZodLiteral<"inbox">;
50
+ ifFails: z.ZodOptional<z.ZodString>;
51
+ next: z.ZodOptional<z.ZodString>;
52
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
53
+ thenMoveTo: z.ZodOptional<z.ZodString>;
54
+ }, z.core.$strict>, z.ZodObject<{
55
+ id: z.ZodOptional<z.ZodString>;
56
+ title: z.ZodString;
57
+ kind: z.ZodLiteral<"task">;
58
+ ifFails: z.ZodOptional<z.ZodString>;
59
+ instructions: z.ZodOptional<z.ZodString>;
60
+ next: z.ZodOptional<z.ZodString>;
61
+ planning: z.ZodOptional<z.ZodEnum<{
62
+ auto: "auto";
63
+ required: "required";
64
+ skip: "skip";
65
+ }>>;
66
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
67
+ repo: z.ZodOptional<z.ZodString>;
68
+ }, z.core.$strict>, z.ZodObject<{
69
+ id: z.ZodOptional<z.ZodString>;
70
+ title: z.ZodString;
71
+ kind: z.ZodLiteral<"report">;
72
+ ifFails: z.ZodOptional<z.ZodString>;
73
+ instructions: z.ZodOptional<z.ZodString>;
74
+ next: z.ZodOptional<z.ZodString>;
75
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
76
+ }, z.core.$strict>, z.ZodObject<{
77
+ id: z.ZodOptional<z.ZodString>;
78
+ title: z.ZodString;
79
+ kind: z.ZodLiteral<"approval">;
80
+ decider: z.ZodOptional<z.ZodNullable<z.ZodString>>;
81
+ ifFails: z.ZodOptional<z.ZodString>;
82
+ next: z.ZodOptional<z.ZodString>;
83
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
84
+ teammate: z.ZodOptional<z.ZodString>;
85
+ thenMoveTo: z.ZodOptional<z.ZodString>;
86
+ }, z.core.$strict>, z.ZodObject<{
87
+ id: z.ZodOptional<z.ZodString>;
88
+ title: z.ZodString;
89
+ kind: z.ZodLiteral<"check">;
90
+ ifFails: z.ZodOptional<z.ZodString>;
91
+ next: z.ZodOptional<z.ZodString>;
92
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
93
+ routes: z.ZodOptional<z.ZodArray<z.ZodObject<{
94
+ answer: z.ZodString;
95
+ goesTo: z.ZodString;
96
+ }, z.core.$strict>>>;
97
+ runIn: z.ZodOptional<z.ZodEnum<{
98
+ copy: "copy";
99
+ folder: "folder";
100
+ }>>;
101
+ script: z.ZodOptional<z.ZodString>;
102
+ secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
103
+ }, z.core.$strict>, z.ZodObject<{
104
+ id: z.ZodOptional<z.ZodString>;
105
+ title: z.ZodString;
106
+ kind: z.ZodLiteral<"pull-request">;
107
+ ifFails: z.ZodOptional<z.ZodString>;
108
+ merge: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodEnum<{
109
+ merge: "merge";
110
+ rebase: "rebase";
111
+ squash: "squash";
112
+ }>]>>;
113
+ next: z.ZodOptional<z.ZodString>;
114
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
115
+ }, z.core.$strict>, z.ZodObject<{
116
+ id: z.ZodOptional<z.ZodString>;
117
+ title: z.ZodString;
118
+ kind: z.ZodLiteral<"update">;
119
+ close: z.ZodOptional<z.ZodBoolean>;
120
+ ifFails: z.ZodOptional<z.ZodString>;
121
+ message: z.ZodOptional<z.ZodString>;
122
+ next: z.ZodOptional<z.ZodString>;
123
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
124
+ }, z.core.$strict>, z.ZodObject<{
125
+ id: z.ZodOptional<z.ZodString>;
126
+ title: z.ZodString;
127
+ kind: z.ZodLiteral<"notify">;
128
+ ifFails: z.ZodOptional<z.ZodString>;
129
+ message: z.ZodOptional<z.ZodString>;
130
+ next: z.ZodOptional<z.ZodString>;
131
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
132
+ }, z.core.$strict>, z.ZodObject<{
133
+ id: z.ZodOptional<z.ZodString>;
134
+ title: z.ZodString;
135
+ kind: z.ZodLiteral<"sort">;
136
+ alsoNote: z.ZodOptional<z.ZodArray<z.ZodObject<{
137
+ id: z.ZodOptional<z.ZodString>;
138
+ question: z.ZodString;
139
+ kind: z.ZodOptional<z.ZodEnum<{
140
+ score: "score";
141
+ "yes-no": "yes-no";
142
+ }>>;
143
+ levels: z.ZodOptional<z.ZodArray<z.ZodString>>;
144
+ }, z.core.$strict>>>;
145
+ answers: z.ZodOptional<z.ZodArray<z.ZodObject<{
146
+ answer: z.ZodString;
147
+ means: z.ZodOptional<z.ZodString>;
148
+ goesTo: z.ZodString;
149
+ }, z.core.$strict>>>;
150
+ ifNotSure: z.ZodOptional<z.ZodString>;
151
+ question: z.ZodOptional<z.ZodString>;
152
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
153
+ sureAt: z.ZodOptional<z.ZodNumber>;
154
+ }, z.core.$strict>, z.ZodObject<{
155
+ id: z.ZodOptional<z.ZodString>;
156
+ title: z.ZodString;
157
+ kind: z.ZodLiteral<"draft">;
158
+ ifFails: z.ZodOptional<z.ZodString>;
159
+ instructions: z.ZodOptional<z.ZodString>;
160
+ next: z.ZodOptional<z.ZodString>;
161
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
162
+ }, z.core.$strict>, z.ZodObject<{
163
+ id: z.ZodOptional<z.ZodString>;
164
+ title: z.ZodString;
165
+ kind: z.ZodLiteral<"request">;
166
+ body: z.ZodOptional<z.ZodString>;
167
+ headers: z.ZodOptional<z.ZodObject<{}, z.core.$catchall<z.ZodString>>>;
168
+ ifFails: z.ZodOptional<z.ZodString>;
169
+ method: z.ZodOptional<z.ZodEnum<{
170
+ DELETE: "DELETE";
171
+ GET: "GET";
172
+ PATCH: "PATCH";
173
+ POST: "POST";
174
+ PUT: "PUT";
175
+ }>>;
176
+ next: z.ZodOptional<z.ZodString>;
177
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
178
+ url: z.ZodOptional<z.ZodString>;
179
+ }, z.core.$strict>, z.ZodObject<{
180
+ id: z.ZodOptional<z.ZodString>;
181
+ title: z.ZodString;
182
+ kind: z.ZodLiteral<"email">;
183
+ body: z.ZodOptional<z.ZodString>;
184
+ ifFails: z.ZodOptional<z.ZodString>;
185
+ next: z.ZodOptional<z.ZodString>;
186
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
187
+ subject: z.ZodOptional<z.ZodString>;
188
+ to: z.ZodOptional<z.ZodString>;
189
+ }, z.core.$strict>, z.ZodObject<{
190
+ id: z.ZodOptional<z.ZodString>;
191
+ title: z.ZodString;
192
+ kind: z.ZodLiteral<"tool">;
193
+ args: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{}, z.core.$catchall<z.ZodUnknown>>, z.ZodString]>>;
194
+ ifFails: z.ZodOptional<z.ZodString>;
195
+ next: z.ZodOptional<z.ZodString>;
196
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
197
+ server: z.ZodOptional<z.ZodString>;
198
+ tool: z.ZodOptional<z.ZodString>;
199
+ }, z.core.$strict>, z.ZodObject<{
200
+ id: z.ZodOptional<z.ZodString>;
201
+ title: z.ZodString;
202
+ kind: z.ZodLiteral<"wait">;
203
+ from: z.ZodOptional<z.ZodString>;
204
+ ifNoReply: z.ZodOptional<z.ZodString>;
205
+ next: z.ZodOptional<z.ZodString>;
206
+ timeZone: z.ZodOptional<z.ZodString>;
207
+ until: z.ZodOptional<z.ZodString>;
208
+ wait: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
209
+ waitFor: z.ZodOptional<z.ZodEnum<{
210
+ hours: "hours";
211
+ reply: "reply";
212
+ time: "time";
213
+ }>>;
214
+ }, z.core.$strict>, z.ZodObject<{
215
+ id: z.ZodOptional<z.ZodString>;
216
+ title: z.ZodString;
217
+ kind: z.ZodLiteral<"teammate">;
218
+ ifFails: z.ZodOptional<z.ZodString>;
219
+ instructions: z.ZodOptional<z.ZodString>;
220
+ next: z.ZodOptional<z.ZodString>;
221
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
222
+ reply: z.ZodOptional<z.ZodBoolean>;
223
+ routes: z.ZodOptional<z.ZodArray<z.ZodObject<{
224
+ answer: z.ZodString;
225
+ goesTo: z.ZodString;
226
+ }, z.core.$strict>>>;
227
+ teammate: z.ZodOptional<z.ZodString>;
228
+ }, z.core.$strict>, z.ZodObject<{
229
+ id: z.ZodOptional<z.ZodString>;
230
+ title: z.ZodString;
231
+ kind: z.ZodLiteral<"send">;
232
+ ifFails: z.ZodOptional<z.ZodString>;
233
+ next: z.ZodOptional<z.ZodString>;
234
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
235
+ }, z.core.$strict>, z.ZodObject<{
236
+ id: z.ZodOptional<z.ZodString>;
237
+ title: z.ZodString;
238
+ kind: z.ZodLiteral<"choose">;
239
+ ifNoReply: z.ZodOptional<z.ZodString>;
240
+ ifReplied: z.ZodOptional<z.ZodString>;
241
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
242
+ label: z.ZodString;
243
+ goesTo: z.ZodOptional<z.ZodString>;
244
+ }, z.core.$strict>>>;
245
+ remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
246
+ thenMoveTo: z.ZodOptional<z.ZodString>;
247
+ }, z.core.$strict>, z.ZodObject<{
248
+ id: z.ZodOptional<z.ZodString>;
249
+ title: z.ZodString;
250
+ kind: z.ZodLiteral<"done">;
251
+ }, z.core.$strict>], "kind">>>;
252
+ title: z.ZodOptional<z.ZodString>;
253
+ description: z.ZodOptional<z.ZodString>;
254
+ zone: z.ZodOptional<z.ZodString>;
255
+ note: z.ZodOptional<z.ZodString>;
256
+ choice: z.ZodOptional<z.ZodInt>;
257
+ trigger: z.ZodOptional<z.ZodInt>;
258
+ owner: z.ZodOptional<z.ZodString>;
259
+ script: z.ZodOptional<z.ZodObject<{
260
+ name: z.ZodOptional<z.ZodString>;
261
+ about: z.ZodOptional<z.ZodString>;
262
+ body: z.ZodOptional<z.ZodString>;
263
+ timeoutMinutes: z.ZodOptional<z.ZodInt>;
264
+ language: z.ZodOptional<z.ZodEnum<{
265
+ node: "node";
266
+ python: "python";
267
+ shell: "shell";
268
+ }>>;
269
+ file: z.ZodOptional<z.ZodString>;
270
+ }, z.core.$strict>>;
271
+ settings: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
272
+ zone: z.ZodOptional<z.ZodString>;
273
+ kind: z.ZodLiteral<"button">;
274
+ label: z.ZodString;
275
+ questions: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodString]>>;
276
+ }, z.core.$strict>, z.ZodObject<{
277
+ zone: z.ZodOptional<z.ZodString>;
278
+ kind: z.ZodLiteral<"schedule">;
279
+ schedule: z.ZodString;
280
+ title: z.ZodOptional<z.ZodString>;
281
+ description: z.ZodOptional<z.ZodString>;
282
+ script: z.ZodOptional<z.ZodString>;
283
+ secrets: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodString]>>;
284
+ }, z.core.$strict>, z.ZodObject<{
285
+ zone: z.ZodOptional<z.ZodString>;
286
+ kind: z.ZodLiteral<"github">;
287
+ repo: z.ZodOptional<z.ZodString>;
288
+ watch: z.ZodOptional<z.ZodEnum<{
289
+ checks: "checks";
290
+ issues: "issues";
291
+ pulls: "pulls";
292
+ }>>;
293
+ label: z.ZodOptional<z.ZodString>;
294
+ branch: z.ZodOptional<z.ZodString>;
295
+ from: z.ZodOptional<z.ZodEnum<{
296
+ anyone: "anyone";
297
+ team: "team";
298
+ }>>;
299
+ }, z.core.$strict>, z.ZodObject<{
300
+ zone: z.ZodOptional<z.ZodString>;
301
+ kind: z.ZodLiteral<"linear">;
302
+ team: z.ZodOptional<z.ZodString>;
303
+ state: z.ZodOptional<z.ZodString>;
304
+ label: z.ZodOptional<z.ZodString>;
305
+ }, z.core.$strict>, z.ZodObject<{
306
+ zone: z.ZodOptional<z.ZodString>;
307
+ kind: z.ZodLiteral<"flow">;
308
+ when: z.ZodOptional<z.ZodString>;
309
+ follow: z.ZodInt;
310
+ }, z.core.$strict>, z.ZodObject<{
311
+ zone: z.ZodOptional<z.ZodString>;
312
+ kind: z.ZodLiteral<"email">;
313
+ folder: z.ZodOptional<z.ZodString>;
314
+ sender: z.ZodOptional<z.ZodString>;
315
+ subject: z.ZodOptional<z.ZodString>;
316
+ }, z.core.$strict>, z.ZodObject<{
317
+ zone: z.ZodOptional<z.ZodString>;
318
+ kind: z.ZodLiteral<"plane-review">;
319
+ at: z.ZodOptional<z.ZodString>;
320
+ timeZone: z.ZodOptional<z.ZodString>;
321
+ }, z.core.$strict>], "kind">>;
322
+ }, z.core.$strict>;
323
+ export type ProposeFlowInput = z.infer<typeof proposeFlowInputSchema>;
324
+ /** What the lead is told propose_flow takes: exactly the schema its call is read with. */
325
+ export declare const PROPOSE_FLOW_MODEL_SCHEMA: Readonly<Record<string, unknown>>;