toolroll 0.9.36 → 0.9.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +77 -0
- package/dist/assignment-adapters.d.ts +12 -48
- package/dist/assignment-adapters.js +33 -43
- package/dist/browser/THIRD_PARTY_NOTICES.txt +3 -3
- package/dist/browser/workspace.css +1 -1
- package/dist/browser/workspace.js +26 -26
- package/dist/browser-crew.js +5 -0
- package/dist/browser-workspace.d.ts +2 -0
- package/dist/build-review.d.ts +1 -1
- package/dist/build-review.js +2 -1
- package/dist/chat-acceptance.d.ts +1 -1
- package/dist/chat-actions.d.ts +18 -12
- package/dist/chat-actions.js +15 -65
- package/dist/chat-ask.js +5 -5
- package/dist/chat-channel.js +20 -9
- package/dist/chat-decide.d.ts +18 -4
- package/dist/chat-decide.js +31 -11
- package/dist/chat-delivery-state.d.ts +12 -70
- package/dist/chat-delivery-state.js +17 -135
- package/dist/chat-delivery.js +58 -30
- package/dist/chat-flow.js +8 -6
- package/dist/chat-inbox.js +1 -1
- package/dist/coding-context.d.ts +2 -39
- package/dist/coding-context.js +2 -1
- package/dist/coding-handoff.d.ts +6 -25
- package/dist/coding-handoff.js +11 -5
- package/dist/coding-types.d.ts +2 -26
- package/dist/coding-workspace.d.ts +2 -0
- package/dist/coding-workspace.js +50 -14
- package/dist/contracts/acceptance-terms.d.ts +14 -0
- package/dist/contracts/acceptance-terms.js +16 -0
- package/dist/contracts/chat-actions.d.ts +328 -0
- package/dist/contracts/chat-actions.js +133 -0
- package/dist/contracts/chat-callback-rows.d.ts +59 -0
- package/dist/contracts/chat-callback-rows.js +46 -0
- package/dist/contracts/chat-content.d.ts +276 -0
- package/dist/contracts/chat-content.js +127 -0
- package/dist/contracts/chat-tables.d.ts +6 -0
- package/dist/contracts/chat-tables.js +136 -0
- package/dist/contracts/coding-context.d.ts +97 -0
- package/dist/contracts/coding-context.js +60 -0
- package/dist/contracts/coding-handoff.d.ts +44 -0
- package/dist/contracts/coding-handoff.js +47 -0
- package/dist/contracts/coding-workspace.d.ts +165 -0
- package/dist/contracts/coding-workspace.js +71 -0
- package/dist/contracts/contract.d.ts +7 -2
- package/dist/contracts/contract.js +21 -12
- package/dist/contracts/decision.d.ts +45 -0
- package/dist/contracts/decision.js +45 -0
- package/dist/contracts/discord-callback.d.ts +45 -0
- package/dist/contracts/discord-callback.js +34 -0
- package/dist/contracts/flow-card.d.ts +50 -0
- package/dist/contracts/flow-card.js +46 -0
- package/dist/contracts/flow-send.d.ts +119 -0
- package/dist/contracts/flow-send.js +112 -0
- package/dist/contracts/flow.d.ts +5 -0
- package/dist/contracts/flow.js +5 -0
- package/dist/contracts/gateway-tools.d.ts +374 -0
- package/dist/contracts/gateway-tools.js +94 -0
- package/dist/contracts/lead-context.d.ts +165 -0
- package/dist/contracts/lead-context.js +73 -0
- package/dist/contracts/lead-tools.d.ts +1905 -0
- package/dist/contracts/lead-tools.js +265 -0
- package/dist/contracts/memory-pass.d.ts +158 -0
- package/dist/contracts/memory-pass.js +102 -0
- package/dist/contracts/project-knowledge.d.ts +126 -0
- package/dist/contracts/project-knowledge.js +93 -0
- package/dist/contracts/project-memory.d.ts +117 -0
- package/dist/contracts/project-memory.js +51 -0
- package/dist/contracts/project-skills.d.ts +121 -0
- package/dist/contracts/project-skills.js +76 -0
- package/dist/contracts/review-findings.d.ts +46 -0
- package/dist/contracts/review-findings.js +48 -0
- package/dist/contracts/route.d.ts +484 -0
- package/dist/contracts/route.js +128 -0
- package/dist/contracts/scope.d.ts +105 -0
- package/dist/contracts/scope.js +114 -0
- package/dist/contracts/scout-report.d.ts +234 -0
- package/dist/contracts/scout-report.js +141 -0
- package/dist/contracts/slack-callback.d.ts +43 -0
- package/dist/contracts/slack-callback.js +35 -0
- package/dist/contracts/sort-answer.d.ts +83 -0
- package/dist/contracts/sort-answer.js +77 -0
- package/dist/contracts/stage-output.d.ts +127 -0
- package/dist/contracts/stage-output.js +166 -0
- package/dist/contracts/task-sizing.d.ts +24 -0
- package/dist/contracts/task-sizing.js +28 -0
- package/dist/contracts/teammate-turn.d.ts +43 -0
- package/dist/contracts/teammate-turn.js +51 -0
- package/dist/contracts/teams-callback.d.ts +14 -0
- package/dist/contracts/teams-callback.js +14 -0
- package/dist/contracts/telegram-callback.d.ts +120 -0
- package/dist/contracts/telegram-callback.js +97 -0
- package/dist/decision.d.ts +11 -20
- package/dist/decision.js +86 -167
- package/dist/desktop-update.d.ts +1 -1
- package/dist/discord-chat.js +31 -20
- package/dist/flow-engine.js +14 -17
- package/dist/flow-items.d.ts +4 -13
- package/dist/flow-items.js +1 -15
- package/dist/flow-send.d.ts +6 -37
- package/dist/flow-send.js +18 -14
- package/dist/flow-share.js +7 -1
- package/dist/flow-sort.d.ts +7 -26
- package/dist/flow-sort.js +25 -20
- package/dist/flow-steps.js +3 -2
- package/dist/flows.d.ts +2 -4
- package/dist/flows.js +9 -5
- package/dist/invoke.js +4 -4
- package/dist/lead-context.d.ts +4 -2
- package/dist/lead-context.js +24 -17
- package/dist/mate-progress.d.ts +26 -0
- package/dist/mate-progress.js +24 -0
- package/dist/mate-tools.d.ts +4 -0
- package/dist/mate-tools.js +108 -275
- package/dist/mate.js +11 -2
- package/dist/mcp-connect.d.ts +24 -4
- package/dist/mcp-connect.js +78 -15
- package/dist/mcp.js +84 -216
- package/dist/memory-pass.d.ts +17 -42
- package/dist/memory-pass.js +54 -26
- package/dist/phase-routing.d.ts +19 -72
- package/dist/phase-routing.js +34 -164
- package/dist/project-knowledge.d.ts +16 -35
- package/dist/project-knowledge.js +42 -21
- package/dist/project-memory.d.ts +2 -28
- package/dist/project-memory.js +28 -13
- package/dist/project-skills.d.ts +16 -38
- package/dist/project-skills.js +41 -32
- package/dist/project-tools.d.ts +1 -0
- package/dist/project-tools.js +4 -4
- package/dist/provider.d.ts +2 -0
- package/dist/provider.js +4 -16
- package/dist/result-shots.d.ts +1 -1
- package/dist/result-shots.js +2 -1
- package/dist/review-switch.d.ts +3 -8
- package/dist/reviewer.d.ts +8 -12
- package/dist/reviewer.js +11 -35
- package/dist/scope.d.ts +21 -43
- package/dist/scope.js +42 -128
- package/dist/scout-report.d.ts +9 -194
- package/dist/scout-report.js +113 -264
- package/dist/scout.js +15 -11
- package/dist/serve.js +23 -5
- package/dist/setup-guide.d.ts +2 -2
- package/dist/slack-chat.js +26 -20
- package/dist/slack-state.js +2 -1
- package/dist/store.d.ts +9 -32
- package/dist/store.js +18 -15
- package/dist/structured-output.js +2 -1
- package/dist/subscription-chat.d.ts +4 -0
- package/dist/subscription-chat.js +4 -1
- package/dist/task-review-brief.d.ts +1 -7
- package/dist/task-review-brief.js +6 -6
- package/dist/task-sizing.d.ts +3 -27
- package/dist/task-sizing.js +11 -26
- package/dist/task-text.d.ts +0 -5
- package/dist/task-text.js +1 -3
- package/dist/teammate-question.js +7 -5
- package/dist/teammate-work.js +9 -5
- package/dist/teammates.d.ts +13 -64
- package/dist/teammates.js +32 -33
- package/dist/teams-chat.js +20 -11
- package/dist/telegram-flow.d.ts +9 -0
- package/dist/telegram-flow.js +44 -8
- package/dist/telegram-mate.d.ts +4 -14
- package/dist/telegram-mate.js +9 -8
- package/dist/telegram-team.d.ts +2 -19
- package/dist/telegram.d.ts +1 -1
- package/dist/telegram.js +94 -68
- package/dist/text-limits.d.ts +142 -1
- package/dist/text-limits.js +144 -1
- package/dist/tools-ui.d.ts +2 -1
- package/dist/tools-ui.js +7 -4
- package/package.json +17 -12
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A sealed route (phase-routing.ts): which exact agent plans, builds, repairs and reviews a task, as a scope's
|
|
3
|
+
* `proposed_route_json` / `approved_route_json` and a standing order's route keep it. One schema covering both versions
|
|
4
|
+
* a route has been saved in — version 1 (sealed before sizing: no `size`, routine and strong tiers) and version 2 —
|
|
5
|
+
* plus the override list and the task size it carries. The rules JSON Schema cannot state run in plain code after
|
|
6
|
+
* parsing, each with a path-named error: the legs run plan, build, repair, review in that order; the posture is what
|
|
7
|
+
* the legs actually run; one override per phase.
|
|
8
|
+
*
|
|
9
|
+
* Reading never rewrites: a version 1 route stays version 1 (its digest domain and bytes are its own), and reads with
|
|
10
|
+
* no size. phase-routing.ts `canonicalRouteJson` / `routeDigestOf` encode the parsed value, so a sealed route's digest
|
|
11
|
+
* is what it always was.
|
|
12
|
+
*/
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import { type ContractResult } from "./contract.js";
|
|
15
|
+
/** The phases a route has a leg for, in the order its legs run. */
|
|
16
|
+
export declare const ROUTE_PHASES: readonly ["plan", "build", "repair", "review"];
|
|
17
|
+
/** provider.ts's provider ids, restated (provider.ts sits above phase-routing.ts in the module graph) and pinned to
|
|
18
|
+
* them by the test suite. */
|
|
19
|
+
export declare const ROUTE_PROVIDERS: readonly ["claude", "codex", "openrouter", "gemini"];
|
|
20
|
+
/** provider.ts's MODEL_ID, restated for the same reason: an exact model id is argv-safe — no leading dash, no
|
|
21
|
+
* whitespace or control bytes. */
|
|
22
|
+
export declare const MODEL_ID_SHAPE: RegExp;
|
|
23
|
+
export declare const RISKS: readonly ["routine", "elevated", "high"];
|
|
24
|
+
export declare const TASK_SIZE_WORDS: readonly ["small", "medium", "large"];
|
|
25
|
+
/** The route version this code seals; version 1 (before sizing) still reads. */
|
|
26
|
+
export declare const ROUTE_VERSION = 2;
|
|
27
|
+
/** How big a change the task is, as it was sized (by the classifier, the description, or a person). */
|
|
28
|
+
export declare const taskSizingSchema: z.ZodObject<{
|
|
29
|
+
size: z.ZodEnum<{
|
|
30
|
+
large: "large";
|
|
31
|
+
medium: "medium";
|
|
32
|
+
small: "small";
|
|
33
|
+
}>;
|
|
34
|
+
risky: z.ZodBoolean;
|
|
35
|
+
source: z.ZodEnum<{
|
|
36
|
+
classifier: "classifier";
|
|
37
|
+
heuristic: "heuristic";
|
|
38
|
+
person: "person";
|
|
39
|
+
}>;
|
|
40
|
+
reason: z.ZodString;
|
|
41
|
+
}, z.core.$strict>;
|
|
42
|
+
/** An approver's explicit per-phase choice, recorded with attribution. */
|
|
43
|
+
export declare const routeOverrideSchema: z.ZodObject<{
|
|
44
|
+
phase: z.ZodEnum<{
|
|
45
|
+
build: "build";
|
|
46
|
+
plan: "plan";
|
|
47
|
+
repair: "repair";
|
|
48
|
+
review: "review";
|
|
49
|
+
}>;
|
|
50
|
+
provider: z.ZodEnum<{
|
|
51
|
+
claude: "claude";
|
|
52
|
+
codex: "codex";
|
|
53
|
+
gemini: "gemini";
|
|
54
|
+
openrouter: "openrouter";
|
|
55
|
+
}>;
|
|
56
|
+
model: z.ZodString;
|
|
57
|
+
by: z.ZodString;
|
|
58
|
+
at: z.ZodString;
|
|
59
|
+
}, z.core.$strict>;
|
|
60
|
+
/** One leg of a version 2 route: the light tier exists. */
|
|
61
|
+
export declare const routeLegSchema: z.ZodObject<{
|
|
62
|
+
phase: z.ZodEnum<{
|
|
63
|
+
build: "build";
|
|
64
|
+
plan: "plan";
|
|
65
|
+
repair: "repair";
|
|
66
|
+
review: "review";
|
|
67
|
+
}>;
|
|
68
|
+
provider: z.ZodEnum<{
|
|
69
|
+
claude: "claude";
|
|
70
|
+
codex: "codex";
|
|
71
|
+
gemini: "gemini";
|
|
72
|
+
openrouter: "openrouter";
|
|
73
|
+
}>;
|
|
74
|
+
model: z.ZodString;
|
|
75
|
+
tier: z.ZodEnum<{
|
|
76
|
+
light: "light";
|
|
77
|
+
routine: "routine";
|
|
78
|
+
strong: "strong";
|
|
79
|
+
}>;
|
|
80
|
+
chosen: z.ZodEnum<{
|
|
81
|
+
override: "override";
|
|
82
|
+
pinned: "pinned";
|
|
83
|
+
recommended: "recommended";
|
|
84
|
+
}>;
|
|
85
|
+
recommended: z.ZodObject<{
|
|
86
|
+
provider: z.ZodEnum<{
|
|
87
|
+
claude: "claude";
|
|
88
|
+
codex: "codex";
|
|
89
|
+
gemini: "gemini";
|
|
90
|
+
openrouter: "openrouter";
|
|
91
|
+
}>;
|
|
92
|
+
model: z.ZodString;
|
|
93
|
+
tier: z.ZodEnum<{
|
|
94
|
+
light: "light";
|
|
95
|
+
routine: "routine";
|
|
96
|
+
strong: "strong";
|
|
97
|
+
}>;
|
|
98
|
+
}, z.core.$strict>;
|
|
99
|
+
reasons: z.ZodArray<z.ZodString>;
|
|
100
|
+
problem: z.ZodNullable<z.ZodString>;
|
|
101
|
+
}, z.core.$strict>;
|
|
102
|
+
export declare const sealedRouteV1Schema: z.ZodObject<{
|
|
103
|
+
version: z.ZodLiteral<1>;
|
|
104
|
+
risk: z.ZodEnum<{
|
|
105
|
+
elevated: "elevated";
|
|
106
|
+
high: "high";
|
|
107
|
+
routine: "routine";
|
|
108
|
+
}>;
|
|
109
|
+
qualityMode: z.ZodEnum<{
|
|
110
|
+
default: "default";
|
|
111
|
+
strict: "strict";
|
|
112
|
+
}>;
|
|
113
|
+
publication: z.ZodEnum<{
|
|
114
|
+
automerge: "automerge";
|
|
115
|
+
none: "none";
|
|
116
|
+
notify: "notify";
|
|
117
|
+
}>;
|
|
118
|
+
evidence: z.ZodArray<z.ZodEnum<{
|
|
119
|
+
"changed-path": "changed-path";
|
|
120
|
+
check: "check";
|
|
121
|
+
"manual-review": "manual-review";
|
|
122
|
+
screenshot: "screenshot";
|
|
123
|
+
}>>;
|
|
124
|
+
posture: z.ZodEnum<{
|
|
125
|
+
economy: "economy";
|
|
126
|
+
strong: "strong";
|
|
127
|
+
}>;
|
|
128
|
+
demands: z.ZodArray<z.ZodString>;
|
|
129
|
+
legs: z.ZodArray<z.ZodObject<{
|
|
130
|
+
phase: z.ZodEnum<{
|
|
131
|
+
build: "build";
|
|
132
|
+
plan: "plan";
|
|
133
|
+
repair: "repair";
|
|
134
|
+
review: "review";
|
|
135
|
+
}>;
|
|
136
|
+
provider: z.ZodEnum<{
|
|
137
|
+
claude: "claude";
|
|
138
|
+
codex: "codex";
|
|
139
|
+
gemini: "gemini";
|
|
140
|
+
openrouter: "openrouter";
|
|
141
|
+
}>;
|
|
142
|
+
model: z.ZodString;
|
|
143
|
+
tier: z.ZodEnum<{
|
|
144
|
+
routine: "routine";
|
|
145
|
+
strong: "strong";
|
|
146
|
+
}>;
|
|
147
|
+
chosen: z.ZodEnum<{
|
|
148
|
+
override: "override";
|
|
149
|
+
pinned: "pinned";
|
|
150
|
+
recommended: "recommended";
|
|
151
|
+
}>;
|
|
152
|
+
recommended: z.ZodObject<{
|
|
153
|
+
provider: z.ZodEnum<{
|
|
154
|
+
claude: "claude";
|
|
155
|
+
codex: "codex";
|
|
156
|
+
gemini: "gemini";
|
|
157
|
+
openrouter: "openrouter";
|
|
158
|
+
}>;
|
|
159
|
+
model: z.ZodString;
|
|
160
|
+
tier: z.ZodEnum<{
|
|
161
|
+
routine: "routine";
|
|
162
|
+
strong: "strong";
|
|
163
|
+
}>;
|
|
164
|
+
}, z.core.$strict>;
|
|
165
|
+
reasons: z.ZodArray<z.ZodString>;
|
|
166
|
+
problem: z.ZodNullable<z.ZodString>;
|
|
167
|
+
}, z.core.$strict>>;
|
|
168
|
+
overrides: z.ZodArray<z.ZodObject<{
|
|
169
|
+
phase: z.ZodEnum<{
|
|
170
|
+
build: "build";
|
|
171
|
+
plan: "plan";
|
|
172
|
+
repair: "repair";
|
|
173
|
+
review: "review";
|
|
174
|
+
}>;
|
|
175
|
+
provider: z.ZodEnum<{
|
|
176
|
+
claude: "claude";
|
|
177
|
+
codex: "codex";
|
|
178
|
+
gemini: "gemini";
|
|
179
|
+
openrouter: "openrouter";
|
|
180
|
+
}>;
|
|
181
|
+
model: z.ZodString;
|
|
182
|
+
by: z.ZodString;
|
|
183
|
+
at: z.ZodString;
|
|
184
|
+
}, z.core.$strict>>;
|
|
185
|
+
}, z.core.$strict>;
|
|
186
|
+
export declare const sealedRouteV2Schema: z.ZodObject<{
|
|
187
|
+
version: z.ZodLiteral<2>;
|
|
188
|
+
risk: z.ZodEnum<{
|
|
189
|
+
elevated: "elevated";
|
|
190
|
+
high: "high";
|
|
191
|
+
routine: "routine";
|
|
192
|
+
}>;
|
|
193
|
+
qualityMode: z.ZodEnum<{
|
|
194
|
+
default: "default";
|
|
195
|
+
strict: "strict";
|
|
196
|
+
}>;
|
|
197
|
+
publication: z.ZodEnum<{
|
|
198
|
+
automerge: "automerge";
|
|
199
|
+
none: "none";
|
|
200
|
+
notify: "notify";
|
|
201
|
+
}>;
|
|
202
|
+
evidence: z.ZodArray<z.ZodEnum<{
|
|
203
|
+
"changed-path": "changed-path";
|
|
204
|
+
check: "check";
|
|
205
|
+
"manual-review": "manual-review";
|
|
206
|
+
screenshot: "screenshot";
|
|
207
|
+
}>>;
|
|
208
|
+
posture: z.ZodEnum<{
|
|
209
|
+
economy: "economy";
|
|
210
|
+
strong: "strong";
|
|
211
|
+
}>;
|
|
212
|
+
demands: z.ZodArray<z.ZodString>;
|
|
213
|
+
legs: z.ZodArray<z.ZodObject<{
|
|
214
|
+
phase: z.ZodEnum<{
|
|
215
|
+
build: "build";
|
|
216
|
+
plan: "plan";
|
|
217
|
+
repair: "repair";
|
|
218
|
+
review: "review";
|
|
219
|
+
}>;
|
|
220
|
+
provider: z.ZodEnum<{
|
|
221
|
+
claude: "claude";
|
|
222
|
+
codex: "codex";
|
|
223
|
+
gemini: "gemini";
|
|
224
|
+
openrouter: "openrouter";
|
|
225
|
+
}>;
|
|
226
|
+
model: z.ZodString;
|
|
227
|
+
tier: z.ZodEnum<{
|
|
228
|
+
light: "light";
|
|
229
|
+
routine: "routine";
|
|
230
|
+
strong: "strong";
|
|
231
|
+
}>;
|
|
232
|
+
chosen: z.ZodEnum<{
|
|
233
|
+
override: "override";
|
|
234
|
+
pinned: "pinned";
|
|
235
|
+
recommended: "recommended";
|
|
236
|
+
}>;
|
|
237
|
+
recommended: z.ZodObject<{
|
|
238
|
+
provider: z.ZodEnum<{
|
|
239
|
+
claude: "claude";
|
|
240
|
+
codex: "codex";
|
|
241
|
+
gemini: "gemini";
|
|
242
|
+
openrouter: "openrouter";
|
|
243
|
+
}>;
|
|
244
|
+
model: z.ZodString;
|
|
245
|
+
tier: z.ZodEnum<{
|
|
246
|
+
light: "light";
|
|
247
|
+
routine: "routine";
|
|
248
|
+
strong: "strong";
|
|
249
|
+
}>;
|
|
250
|
+
}, z.core.$strict>;
|
|
251
|
+
reasons: z.ZodArray<z.ZodString>;
|
|
252
|
+
problem: z.ZodNullable<z.ZodString>;
|
|
253
|
+
}, z.core.$strict>>;
|
|
254
|
+
overrides: z.ZodArray<z.ZodObject<{
|
|
255
|
+
phase: z.ZodEnum<{
|
|
256
|
+
build: "build";
|
|
257
|
+
plan: "plan";
|
|
258
|
+
repair: "repair";
|
|
259
|
+
review: "review";
|
|
260
|
+
}>;
|
|
261
|
+
provider: z.ZodEnum<{
|
|
262
|
+
claude: "claude";
|
|
263
|
+
codex: "codex";
|
|
264
|
+
gemini: "gemini";
|
|
265
|
+
openrouter: "openrouter";
|
|
266
|
+
}>;
|
|
267
|
+
model: z.ZodString;
|
|
268
|
+
by: z.ZodString;
|
|
269
|
+
at: z.ZodString;
|
|
270
|
+
}, z.core.$strict>>;
|
|
271
|
+
size: z.ZodNullable<z.ZodObject<{
|
|
272
|
+
size: z.ZodEnum<{
|
|
273
|
+
large: "large";
|
|
274
|
+
medium: "medium";
|
|
275
|
+
small: "small";
|
|
276
|
+
}>;
|
|
277
|
+
risky: z.ZodBoolean;
|
|
278
|
+
source: z.ZodEnum<{
|
|
279
|
+
classifier: "classifier";
|
|
280
|
+
heuristic: "heuristic";
|
|
281
|
+
person: "person";
|
|
282
|
+
}>;
|
|
283
|
+
reason: z.ZodString;
|
|
284
|
+
}, z.core.$strict>>;
|
|
285
|
+
}, z.core.$strict>;
|
|
286
|
+
/** A sealed route as saved, in either version. */
|
|
287
|
+
export declare const sealedRouteSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
288
|
+
version: z.ZodLiteral<1>;
|
|
289
|
+
risk: z.ZodEnum<{
|
|
290
|
+
elevated: "elevated";
|
|
291
|
+
high: "high";
|
|
292
|
+
routine: "routine";
|
|
293
|
+
}>;
|
|
294
|
+
qualityMode: z.ZodEnum<{
|
|
295
|
+
default: "default";
|
|
296
|
+
strict: "strict";
|
|
297
|
+
}>;
|
|
298
|
+
publication: z.ZodEnum<{
|
|
299
|
+
automerge: "automerge";
|
|
300
|
+
none: "none";
|
|
301
|
+
notify: "notify";
|
|
302
|
+
}>;
|
|
303
|
+
evidence: z.ZodArray<z.ZodEnum<{
|
|
304
|
+
"changed-path": "changed-path";
|
|
305
|
+
check: "check";
|
|
306
|
+
"manual-review": "manual-review";
|
|
307
|
+
screenshot: "screenshot";
|
|
308
|
+
}>>;
|
|
309
|
+
posture: z.ZodEnum<{
|
|
310
|
+
economy: "economy";
|
|
311
|
+
strong: "strong";
|
|
312
|
+
}>;
|
|
313
|
+
demands: z.ZodArray<z.ZodString>;
|
|
314
|
+
legs: z.ZodArray<z.ZodObject<{
|
|
315
|
+
phase: z.ZodEnum<{
|
|
316
|
+
build: "build";
|
|
317
|
+
plan: "plan";
|
|
318
|
+
repair: "repair";
|
|
319
|
+
review: "review";
|
|
320
|
+
}>;
|
|
321
|
+
provider: z.ZodEnum<{
|
|
322
|
+
claude: "claude";
|
|
323
|
+
codex: "codex";
|
|
324
|
+
gemini: "gemini";
|
|
325
|
+
openrouter: "openrouter";
|
|
326
|
+
}>;
|
|
327
|
+
model: z.ZodString;
|
|
328
|
+
tier: z.ZodEnum<{
|
|
329
|
+
routine: "routine";
|
|
330
|
+
strong: "strong";
|
|
331
|
+
}>;
|
|
332
|
+
chosen: z.ZodEnum<{
|
|
333
|
+
override: "override";
|
|
334
|
+
pinned: "pinned";
|
|
335
|
+
recommended: "recommended";
|
|
336
|
+
}>;
|
|
337
|
+
recommended: z.ZodObject<{
|
|
338
|
+
provider: z.ZodEnum<{
|
|
339
|
+
claude: "claude";
|
|
340
|
+
codex: "codex";
|
|
341
|
+
gemini: "gemini";
|
|
342
|
+
openrouter: "openrouter";
|
|
343
|
+
}>;
|
|
344
|
+
model: z.ZodString;
|
|
345
|
+
tier: z.ZodEnum<{
|
|
346
|
+
routine: "routine";
|
|
347
|
+
strong: "strong";
|
|
348
|
+
}>;
|
|
349
|
+
}, z.core.$strict>;
|
|
350
|
+
reasons: z.ZodArray<z.ZodString>;
|
|
351
|
+
problem: z.ZodNullable<z.ZodString>;
|
|
352
|
+
}, z.core.$strict>>;
|
|
353
|
+
overrides: z.ZodArray<z.ZodObject<{
|
|
354
|
+
phase: z.ZodEnum<{
|
|
355
|
+
build: "build";
|
|
356
|
+
plan: "plan";
|
|
357
|
+
repair: "repair";
|
|
358
|
+
review: "review";
|
|
359
|
+
}>;
|
|
360
|
+
provider: z.ZodEnum<{
|
|
361
|
+
claude: "claude";
|
|
362
|
+
codex: "codex";
|
|
363
|
+
gemini: "gemini";
|
|
364
|
+
openrouter: "openrouter";
|
|
365
|
+
}>;
|
|
366
|
+
model: z.ZodString;
|
|
367
|
+
by: z.ZodString;
|
|
368
|
+
at: z.ZodString;
|
|
369
|
+
}, z.core.$strict>>;
|
|
370
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
371
|
+
version: z.ZodLiteral<2>;
|
|
372
|
+
risk: z.ZodEnum<{
|
|
373
|
+
elevated: "elevated";
|
|
374
|
+
high: "high";
|
|
375
|
+
routine: "routine";
|
|
376
|
+
}>;
|
|
377
|
+
qualityMode: z.ZodEnum<{
|
|
378
|
+
default: "default";
|
|
379
|
+
strict: "strict";
|
|
380
|
+
}>;
|
|
381
|
+
publication: z.ZodEnum<{
|
|
382
|
+
automerge: "automerge";
|
|
383
|
+
none: "none";
|
|
384
|
+
notify: "notify";
|
|
385
|
+
}>;
|
|
386
|
+
evidence: z.ZodArray<z.ZodEnum<{
|
|
387
|
+
"changed-path": "changed-path";
|
|
388
|
+
check: "check";
|
|
389
|
+
"manual-review": "manual-review";
|
|
390
|
+
screenshot: "screenshot";
|
|
391
|
+
}>>;
|
|
392
|
+
posture: z.ZodEnum<{
|
|
393
|
+
economy: "economy";
|
|
394
|
+
strong: "strong";
|
|
395
|
+
}>;
|
|
396
|
+
demands: z.ZodArray<z.ZodString>;
|
|
397
|
+
legs: z.ZodArray<z.ZodObject<{
|
|
398
|
+
phase: z.ZodEnum<{
|
|
399
|
+
build: "build";
|
|
400
|
+
plan: "plan";
|
|
401
|
+
repair: "repair";
|
|
402
|
+
review: "review";
|
|
403
|
+
}>;
|
|
404
|
+
provider: z.ZodEnum<{
|
|
405
|
+
claude: "claude";
|
|
406
|
+
codex: "codex";
|
|
407
|
+
gemini: "gemini";
|
|
408
|
+
openrouter: "openrouter";
|
|
409
|
+
}>;
|
|
410
|
+
model: z.ZodString;
|
|
411
|
+
tier: z.ZodEnum<{
|
|
412
|
+
light: "light";
|
|
413
|
+
routine: "routine";
|
|
414
|
+
strong: "strong";
|
|
415
|
+
}>;
|
|
416
|
+
chosen: z.ZodEnum<{
|
|
417
|
+
override: "override";
|
|
418
|
+
pinned: "pinned";
|
|
419
|
+
recommended: "recommended";
|
|
420
|
+
}>;
|
|
421
|
+
recommended: z.ZodObject<{
|
|
422
|
+
provider: z.ZodEnum<{
|
|
423
|
+
claude: "claude";
|
|
424
|
+
codex: "codex";
|
|
425
|
+
gemini: "gemini";
|
|
426
|
+
openrouter: "openrouter";
|
|
427
|
+
}>;
|
|
428
|
+
model: z.ZodString;
|
|
429
|
+
tier: z.ZodEnum<{
|
|
430
|
+
light: "light";
|
|
431
|
+
routine: "routine";
|
|
432
|
+
strong: "strong";
|
|
433
|
+
}>;
|
|
434
|
+
}, z.core.$strict>;
|
|
435
|
+
reasons: z.ZodArray<z.ZodString>;
|
|
436
|
+
problem: z.ZodNullable<z.ZodString>;
|
|
437
|
+
}, z.core.$strict>>;
|
|
438
|
+
overrides: z.ZodArray<z.ZodObject<{
|
|
439
|
+
phase: z.ZodEnum<{
|
|
440
|
+
build: "build";
|
|
441
|
+
plan: "plan";
|
|
442
|
+
repair: "repair";
|
|
443
|
+
review: "review";
|
|
444
|
+
}>;
|
|
445
|
+
provider: z.ZodEnum<{
|
|
446
|
+
claude: "claude";
|
|
447
|
+
codex: "codex";
|
|
448
|
+
gemini: "gemini";
|
|
449
|
+
openrouter: "openrouter";
|
|
450
|
+
}>;
|
|
451
|
+
model: z.ZodString;
|
|
452
|
+
by: z.ZodString;
|
|
453
|
+
at: z.ZodString;
|
|
454
|
+
}, z.core.$strict>>;
|
|
455
|
+
size: z.ZodNullable<z.ZodObject<{
|
|
456
|
+
size: z.ZodEnum<{
|
|
457
|
+
large: "large";
|
|
458
|
+
medium: "medium";
|
|
459
|
+
small: "small";
|
|
460
|
+
}>;
|
|
461
|
+
risky: z.ZodBoolean;
|
|
462
|
+
source: z.ZodEnum<{
|
|
463
|
+
classifier: "classifier";
|
|
464
|
+
heuristic: "heuristic";
|
|
465
|
+
person: "person";
|
|
466
|
+
}>;
|
|
467
|
+
reason: z.ZodString;
|
|
468
|
+
}, z.core.$strict>>;
|
|
469
|
+
}, z.core.$strict>], "version">;
|
|
470
|
+
export type SealedRoute = z.infer<typeof sealedRouteSchema>;
|
|
471
|
+
export type RouteVersion = SealedRoute["version"];
|
|
472
|
+
export type RouteLeg = z.infer<typeof routeLegSchema>;
|
|
473
|
+
export type RouteOverride = z.infer<typeof routeOverrideSchema>;
|
|
474
|
+
export type TaskSizing = z.infer<typeof taskSizingSchema>;
|
|
475
|
+
/** A route as every reader returns it: a version 1 route reads with no size. */
|
|
476
|
+
export type PhaseRoute = Omit<z.infer<typeof sealedRouteV2Schema>, "version"> & {
|
|
477
|
+
version: RouteVersion;
|
|
478
|
+
};
|
|
479
|
+
/** The posture legs actually run under: strong only when a leg runs a configured strong agent as recommended. */
|
|
480
|
+
export declare function postureOf(legs: readonly Pick<RouteLeg, "chosen" | "tier">[]): "economy" | "strong";
|
|
481
|
+
/** Read a task's recorded override list (a list on its own, as `route_overrides_json` keeps it). */
|
|
482
|
+
export declare function readRouteOverrides(input: unknown): ContractResult<RouteOverride[]>;
|
|
483
|
+
/** Read a sealed route: either version as itself, every leg, override and the size proved, nothing unknown. */
|
|
484
|
+
export declare function readSealedRoute(input: unknown): ContractResult<PhaseRoute>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A sealed route (phase-routing.ts): which exact agent plans, builds, repairs and reviews a task, as a scope's
|
|
3
|
+
* `proposed_route_json` / `approved_route_json` and a standing order's route keep it. One schema covering both versions
|
|
4
|
+
* a route has been saved in — version 1 (sealed before sizing: no `size`, routine and strong tiers) and version 2 —
|
|
5
|
+
* plus the override list and the task size it carries. The rules JSON Schema cannot state run in plain code after
|
|
6
|
+
* parsing, each with a path-named error: the legs run plan, build, repair, review in that order; the posture is what
|
|
7
|
+
* the legs actually run; one override per phase.
|
|
8
|
+
*
|
|
9
|
+
* Reading never rewrites: a version 1 route stays version 1 (its digest domain and bytes are its own), and reads with
|
|
10
|
+
* no size. phase-routing.ts `canonicalRouteJson` / `routeDigestOf` encode the parsed value, so a sealed route's digest
|
|
11
|
+
* is what it always was.
|
|
12
|
+
*/
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import { EVIDENCE_KINDS } from "./acceptance-terms.js";
|
|
15
|
+
import { limited, parseContract, versioned } from "./contract.js";
|
|
16
|
+
/** The phases a route has a leg for, in the order its legs run. */
|
|
17
|
+
export const ROUTE_PHASES = ["plan", "build", "repair", "review"];
|
|
18
|
+
/** provider.ts's provider ids, restated (provider.ts sits above phase-routing.ts in the module graph) and pinned to
|
|
19
|
+
* them by the test suite. */
|
|
20
|
+
export const ROUTE_PROVIDERS = ["claude", "codex", "openrouter", "gemini"];
|
|
21
|
+
/** provider.ts's MODEL_ID, restated for the same reason: an exact model id is argv-safe — no leading dash, no
|
|
22
|
+
* whitespace or control bytes. */
|
|
23
|
+
export const MODEL_ID_SHAPE = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/;
|
|
24
|
+
export const RISKS = ["routine", "elevated", "high"];
|
|
25
|
+
export const TASK_SIZE_WORDS = ["small", "medium", "large"];
|
|
26
|
+
/** The route version this code seals; version 1 (before sizing) still reads. */
|
|
27
|
+
export const ROUTE_VERSION = 2;
|
|
28
|
+
const phase = z.enum(ROUTE_PHASES);
|
|
29
|
+
const provider = z.enum(ROUTE_PROVIDERS);
|
|
30
|
+
const model = z.string().regex(MODEL_ID_SHAPE, { error: "must be an exact model id: letters, digits and . _ : / -, not starting with a dash" });
|
|
31
|
+
const text = z.string().min(1);
|
|
32
|
+
/** How big a change the task is, as it was sized (by the classifier, the description, or a person). */
|
|
33
|
+
export const taskSizingSchema = z.strictObject({
|
|
34
|
+
size: z.enum(TASK_SIZE_WORDS),
|
|
35
|
+
risky: z.boolean(),
|
|
36
|
+
source: z.enum(["classifier", "heuristic", "person"]),
|
|
37
|
+
reason: limited("size reason", "sizeReason"),
|
|
38
|
+
});
|
|
39
|
+
/** An approver's explicit per-phase choice, recorded with attribution. */
|
|
40
|
+
export const routeOverrideSchema = z.strictObject({ phase, provider, model, by: text, at: text });
|
|
41
|
+
function legSchema(tiers) {
|
|
42
|
+
const tier = z.enum(tiers);
|
|
43
|
+
return z.strictObject({
|
|
44
|
+
phase,
|
|
45
|
+
provider,
|
|
46
|
+
model,
|
|
47
|
+
tier,
|
|
48
|
+
chosen: z.enum(["recommended", "override", "pinned"]),
|
|
49
|
+
recommended: z.strictObject({ provider, model, tier }),
|
|
50
|
+
reasons: z.array(z.string()),
|
|
51
|
+
problem: text.nullable(),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/** One leg of a version 2 route: the light tier exists. */
|
|
55
|
+
export const routeLegSchema = legSchema(["light", "routine", "strong"]);
|
|
56
|
+
const terms = {
|
|
57
|
+
risk: z.enum(RISKS),
|
|
58
|
+
qualityMode: z.enum(["default", "strict"]),
|
|
59
|
+
publication: z.enum(["none", "notify", "automerge"]),
|
|
60
|
+
evidence: z.array(z.enum(EVIDENCE_KINDS)),
|
|
61
|
+
posture: z.enum(["economy", "strong"]),
|
|
62
|
+
demands: z.array(z.string()),
|
|
63
|
+
};
|
|
64
|
+
export const sealedRouteV1Schema = versioned(1, {
|
|
65
|
+
...terms,
|
|
66
|
+
legs: z.array(legSchema(["routine", "strong"])).length(ROUTE_PHASES.length),
|
|
67
|
+
overrides: z.array(routeOverrideSchema),
|
|
68
|
+
});
|
|
69
|
+
export const sealedRouteV2Schema = versioned(ROUTE_VERSION, {
|
|
70
|
+
...terms,
|
|
71
|
+
legs: z.array(routeLegSchema).length(ROUTE_PHASES.length),
|
|
72
|
+
overrides: z.array(routeOverrideSchema),
|
|
73
|
+
size: taskSizingSchema.nullable(),
|
|
74
|
+
});
|
|
75
|
+
/** A sealed route as saved, in either version. */
|
|
76
|
+
export const sealedRouteSchema = z.discriminatedUnion("version", [sealedRouteV1Schema, sealedRouteV2Schema]);
|
|
77
|
+
/** The posture legs actually run under: strong only when a leg runs a configured strong agent as recommended. */
|
|
78
|
+
export function postureOf(legs) {
|
|
79
|
+
return legs.some(leg => leg.chosen === "recommended" && leg.tier === "strong") ? "strong" : "economy";
|
|
80
|
+
}
|
|
81
|
+
const issue = (path, what) => ({ path, kind: "bad-value", line: `${path}: ${what}` });
|
|
82
|
+
/** Overrides as read: one per phase (a second is named by path), in phase order. */
|
|
83
|
+
function overridesOf(overrides, at) {
|
|
84
|
+
const issues = overrides.flatMap((one, index) => overrides.findIndex(other => other.phase === one.phase) === index ? [] : [issue(`${at}[${index}].phase`, `${JSON.stringify(one.phase)} appears twice`)]);
|
|
85
|
+
if (issues.length > 0)
|
|
86
|
+
return { ok: false, issues };
|
|
87
|
+
return { ok: true, value: [...overrides].sort((a, b) => ROUTE_PHASES.indexOf(a.phase) - ROUTE_PHASES.indexOf(b.phase)) };
|
|
88
|
+
}
|
|
89
|
+
/** Read a task's recorded override list (a list on its own, as `route_overrides_json` keeps it). */
|
|
90
|
+
export function readRouteOverrides(input) {
|
|
91
|
+
const parsed = parseContract(z.object({ overrides: z.array(routeOverrideSchema) }), { overrides: input });
|
|
92
|
+
return parsed.ok ? overridesOf(parsed.value.overrides, "overrides") : parsed;
|
|
93
|
+
}
|
|
94
|
+
/** Read a sealed route: either version as itself, every leg, override and the size proved, nothing unknown. */
|
|
95
|
+
export function readSealedRoute(input) {
|
|
96
|
+
const version = typeof input === "object" && input !== null ? input["version"] : undefined;
|
|
97
|
+
if (typeof version === "number" && Number.isInteger(version) && version > ROUTE_VERSION) {
|
|
98
|
+
return { ok: false, issues: [{ path: "version", kind: "newer-version", line: `version: made by a newer Toolroll (version ${version}; this one reads up to ${ROUTE_VERSION})` }] };
|
|
99
|
+
}
|
|
100
|
+
const parsed = parseContract(sealedRouteSchema, input);
|
|
101
|
+
if (!parsed.ok)
|
|
102
|
+
return parsed;
|
|
103
|
+
const route = parsed.value;
|
|
104
|
+
const issues = route.legs.flatMap((leg, index) => (leg.phase === ROUTE_PHASES[index] ? [] : [issue(`legs[${index}].phase`, `must be ${JSON.stringify(ROUTE_PHASES[index])} (legs run plan, build, repair, review)`)]));
|
|
105
|
+
const posture = postureOf(route.legs);
|
|
106
|
+
if (posture !== route.posture)
|
|
107
|
+
issues.push(issue("posture", `must be ${JSON.stringify(posture)}: that is what its legs run`));
|
|
108
|
+
const overrides = overridesOf(route.overrides, "overrides");
|
|
109
|
+
if (!overrides.ok)
|
|
110
|
+
issues.push(...overrides.issues);
|
|
111
|
+
if (issues.length > 0 || !overrides.ok)
|
|
112
|
+
return { ok: false, issues };
|
|
113
|
+
return {
|
|
114
|
+
ok: true,
|
|
115
|
+
value: {
|
|
116
|
+
version: route.version,
|
|
117
|
+
risk: route.risk,
|
|
118
|
+
qualityMode: route.qualityMode,
|
|
119
|
+
publication: route.publication,
|
|
120
|
+
evidence: [...route.evidence].sort(),
|
|
121
|
+
posture: route.posture,
|
|
122
|
+
demands: route.demands,
|
|
123
|
+
legs: route.legs,
|
|
124
|
+
overrides: overrides.value,
|
|
125
|
+
size: route.version === 1 ? null : route.size,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|