@azure-id/orc 0.56.1 → 1.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.
- package/CHANGELOG.md +2367 -2218
- package/README-id.md +49 -107
- package/README.md +45 -133
- package/bin/build-agents.js +18 -11
- package/bin/cli.js +33060 -29855
- package/bin/onboarding-content.js +0 -3
- package/bin/test-run.js +491 -0
- package/bin/verify-contracts.js +4256 -3277
- package/bin/verify-package.js +563 -498
- package/bin/webui/api.js +1186 -1163
- package/bin/webui/app.html +9 -0
- package/bin/webui/css/06-responsive.css +120 -108
- package/bin/webui/css/panels/extra.css +29 -0
- package/bin/webui/css/panels/lanes.css +134 -0
- package/bin/webui/css/panels/settings.css +79 -3
- package/bin/webui/fixtures/extra.js +2036 -1934
- package/bin/webui/fixtures/flow.js +2 -2
- package/bin/webui/fixtures/index.js +503 -486
- package/bin/webui/fixtures/lanes.js +218 -0
- package/bin/webui/fixtures/settings.js +261 -34
- package/bin/webui/fixtures/stats.js +3 -3
- package/bin/webui/i18n/TERMS.md +135 -134
- package/bin/webui/i18n/en/extra.json +345 -313
- package/bin/webui/i18n/en/lanes.json +29 -0
- package/bin/webui/i18n/en/nav.json +1 -0
- package/bin/webui/i18n/en/overview.json +2 -0
- package/bin/webui/i18n/en/settings.json +16 -5
- package/bin/webui/i18n/id/extra.json +345 -313
- package/bin/webui/i18n/id/lanes.json +29 -0
- package/bin/webui/i18n/id/nav.json +1 -0
- package/bin/webui/i18n/id/overview.json +2 -0
- package/bin/webui/i18n/id/settings.json +15 -4
- package/bin/webui/js/01-i18n.js +1 -0
- package/bin/webui/js/panels/extra.js +3199 -3011
- package/bin/webui/js/panels/lanes.js +259 -0
- package/bin/webui/js/panels/overview.js +10 -0
- package/bin/webui/js/panels/settings.js +149 -3
- package/package.json +39 -39
- package/templates/agents/MODEL-MAPPING.md +23 -35
- package/templates/agents/orc-executor-opus-4-7-high.md +1 -1
- package/templates/agents/orc-executor-opus-4-7-med.md +1 -1
- package/templates/agents/orc-executor-opus-4-8-high.md +1 -1
- package/templates/agents/orc-executor-opus-5-high.md +1 -1
- package/templates/agents/orc-executor-opus-5-low.md +1 -1
- package/templates/agents/orc-executor-opus-5-med.md +1 -1
- package/templates/agents/orc-retro-opus-5-med.md +73 -73
- package/templates/agents/orc-retro-sonnet-5-high.md +72 -72
- package/templates/agents/orc-trace-writer-haiku-4-5.md +107 -107
- package/templates/commands/orc-route.md +1 -1
- package/templates/commands/orc.md +1 -1
- package/templates/skills/_shared/README.md +7 -3
- package/templates/skills/_shared/config-precedence.md +198 -0
- package/templates/skills/_shared/drift-recovery.md +1 -1
- package/templates/skills/_shared/extra-dispatch.md +159 -7
- package/templates/skills/_shared/interview.md +1 -1
- package/templates/skills/_shared/opus5-only.md +9 -7
- package/templates/skills/_shared/phases/README.md +82 -0
- package/templates/skills/{orc/references → _shared/phases}/analyst-gates.md +15 -3
- package/templates/skills/_shared/phases/execution.md +143 -0
- package/templates/skills/{orc/references → _shared/phases}/house-rules.md +13 -1
- package/templates/skills/{orc/references → _shared/phases}/intake.md +15 -2
- package/templates/skills/_shared/phases/mock-example.md +56 -0
- package/templates/skills/{orc/references → _shared/phases}/plan-handoff.md +16 -3
- package/templates/skills/_shared/phases/planning.md +135 -0
- package/templates/skills/_shared/phases/preflight.md +76 -0
- package/templates/skills/_shared/phases/review.md +53 -0
- package/templates/skills/_shared/phases/scoring.md +65 -0
- package/templates/skills/{orc/references → _shared/phases}/security-checklist.md +12 -1
- package/templates/skills/_shared/phases/security.md +55 -0
- package/templates/skills/_shared/phases/ship.md +88 -0
- package/templates/skills/{orc/references/stop-and-resume.md → _shared/phases/stop-resume.md} +169 -160
- package/templates/skills/_shared/phases/summary.md +48 -0
- package/templates/skills/_shared/phases/testgen.md +51 -0
- package/templates/skills/{orc/references/trace-protocol.md → _shared/phases/trace.md} +49 -6
- package/templates/skills/_shared/phases/verify.md +70 -0
- package/templates/skills/{orc/references → _shared/phases}/wave-grouping.md +14 -2
- package/templates/skills/{orc/references → _shared/phases}/wiki-consult.md +13 -1
- package/templates/skills/_shared/read-ladder.md +48 -0
- package/templates/skills/context-combiner/SKILL.md +214 -187
- package/templates/skills/orc/README.md +148 -150
- package/templates/skills/orc/SKILL.md +70 -358
- package/templates/skills/orc/config.md +137 -389
- package/templates/skills/orc/examples/full-run-mock.md +1 -1
- package/templates/skills/orc/references/effort-and-mode.md +16 -18
- package/templates/skills/orc/references/phases/intake.md +47 -0
- package/templates/skills/orc/references/phases/integration.md +19 -0
- package/templates/skills/orc/references/preflight-report.md +4 -4
- package/templates/skills/orc/references/ultra-mode.md +117 -123
- package/templates/skills/orc/schemas/planning-output.md +279 -279
- package/templates/skills/orc/subskills/orc-planner/SKILL.md +260 -264
- package/templates/skills/orc/subskills/orc-pr/stack-gate.md +4 -1
- package/templates/skills/orc-aftermath/SKILL.md +153 -136
- package/templates/skills/orc-analyze/SKILL.md +247 -220
- package/templates/skills/orc-analyze/references/branching.md +51 -51
- package/templates/skills/orc-analyze/references/thin-input.md +1 -1
- package/templates/skills/orc-analyze-mini/SKILL.md +128 -112
- package/templates/skills/orc-boundary/SKILL.md +244 -208
- package/templates/skills/orc-brainstorm/SKILL.md +372 -339
- package/templates/skills/orc-budget/SKILL.md +243 -225
- package/templates/skills/orc-challenge/README.md +1 -1
- package/templates/skills/orc-challenge/SKILL.md +293 -255
- package/templates/skills/orc-challenge/examples/council-full-roster.md +1 -1
- package/templates/skills/orc-claude/SKILL.md +216 -199
- package/templates/skills/orc-diy/README.md +2 -1
- package/templates/skills/orc-diy/SKILL.md +129 -70
- package/templates/skills/orc-diy/references/blocks/analyze.md +1 -1
- package/templates/skills/orc-diy/references/compile.md +21 -7
- package/templates/skills/orc-diy/references/flow-schema.md +2 -2
- package/templates/skills/orc-doc/SKILL.md +44 -7
- package/templates/skills/orc-explain/SKILL.md +19 -0
- package/templates/skills/orc-export/SKILL.md +26 -5
- package/templates/skills/orc-fast/SKILL.md +215 -187
- package/templates/skills/orc-grill/SKILL.md +233 -207
- package/templates/skills/orc-handoff/SKILL.md +223 -204
- package/templates/skills/orc-learn/SKILL.md +176 -156
- package/templates/skills/orc-mini/SKILL.md +41 -23
- package/templates/skills/orc-pact/SKILL.md +250 -218
- package/templates/skills/orc-pattern/SKILL.md +149 -124
- package/templates/skills/orc-poly/SKILL.md +237 -216
- package/templates/skills/orc-poly/references/gather.md +1 -1
- package/templates/skills/orc-pr-driver/SKILL.md +196 -167
- package/templates/skills/orc-pr-driver/references/orc-run-split.md +1 -1
- package/templates/skills/orc-pr-setup/SKILL.md +212 -184
- package/templates/skills/orc-quick/README.md +2 -2
- package/templates/skills/orc-quick/SKILL.md +45 -12
- package/templates/skills/orc-quick/references/dispatch-gate.md +2 -3
- package/templates/skills/orc-retro/SKILL.md +244 -222
- package/templates/skills/orc-retro/examples/retro-mock.md +171 -171
- package/templates/skills/orc-route/SKILL.md +183 -165
- package/templates/skills/orc-verify/SKILL.md +100 -86
- package/templates/skills/orc-wiki/SKILL.md +55 -206
- package/templates/skills/orc-wiki/references/phases/phase-0.md +71 -0
- package/templates/skills/orc-wiki/references/phases/phase-1.md +35 -0
- package/templates/skills/orc-wiki/references/phases/phase-2.md +52 -0
- package/templates/skills/orc-wiki/references/phases/phase-3.md +57 -0
- package/templates/skills/orc-wiki/references/phases/phase-3c.md +36 -0
- package/templates/agents/orc-advisor-fable-5.md +0 -50
- package/templates/agents/orc-analyst-fable-5.md +0 -115
- package/templates/agents/orc-judge-fable-5.md +0 -79
- package/templates/agents/orc-planner-fable-5.md +0 -152
- package/templates/agents/orc-reviewer-fable-5.md +0 -57
- package/templates/skills/_shared/fable5-override.md +0 -56
- package/templates/skills/orc-diy/references/blocks/execution.md +0 -42
- package/templates/skills/orc-diy/references/blocks/mock-example.md +0 -22
- package/templates/skills/orc-diy/references/blocks/planning.md +0 -34
- package/templates/skills/orc-diy/references/blocks/review.md +0 -18
- package/templates/skills/orc-diy/references/blocks/scoring.md +0 -16
- package/templates/skills/orc-diy/references/blocks/security.md +0 -25
- package/templates/skills/orc-diy/references/blocks/ship.md +0 -25
- package/templates/skills/orc-diy/references/blocks/summary.md +0 -18
- package/templates/skills/orc-diy/references/blocks/testgen.md +0 -17
- package/templates/skills/orc-diy/references/blocks/trace.md +0 -28
- package/templates/skills/orc-diy/references/blocks/verify.md +0 -25
|
@@ -1,486 +1,503 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* fixtures.js — canned API responses for `orc ui --fixtures`.
|
|
4
|
-
*
|
|
5
|
-
* This exists because you cannot DESIGN a state you cannot reach. On a healthy
|
|
6
|
-
* install with a fresh wiki and no paused runs, the STALE chip, the `waiting`
|
|
7
|
-
* run card, the shadowed-setting lock and the unhealthy doctor panel are
|
|
8
|
-
* unreachable — so they get built once, blind, and never looked at again.
|
|
9
|
-
*
|
|
10
|
-
* The rule for this file: carry ONE OF EVERY STATE, including the ugly ones.
|
|
11
|
-
* It also means the UI can be worked on with no ORC project at all.
|
|
12
|
-
*
|
|
13
|
-
* Shapes MUST match what `bin/cli.js --json` really emits. A fixture that has
|
|
14
|
-
* drifted from the CLI is worse than no fixture, so test/webui.test.js asserts
|
|
15
|
-
* the fixture key set against the live CLI output for the shared routes.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// v0.48.1 — the data lives one file per panel; this file is the ROUTER and
|
|
20
|
-
// nothing else. Adding a fixture is a new key in the panel's own file plus a
|
|
21
|
-
// case here; it is never an edit to a 1 700-line module.
|
|
22
|
-
const { PROJECT, doctor, where } = require("./shell.js");
|
|
23
|
-
const { config } = require("./settings.js");
|
|
24
|
-
const { wiki, wikiDocs, wikiShow, wikiCoverage, wikiCoverageFull, wikiUnregistered, wikiPlan, wikiDebt, wikiUsage, patterns, patternShow, gotchas, gotchasArchived, gotchaPrunePreview, wikiImpact } = require("./knowledge.js");
|
|
25
|
-
const { runs, runDetail, runDetailClosed, aftermath } = require("./runs.js");
|
|
26
|
-
const { stats, budgetForecast, budgetRates } = require("./stats.js");
|
|
27
|
-
const { pact } = require("./pact.js");
|
|
28
|
-
const { boundary } = require("./boundary.js");
|
|
29
|
-
const { handoff } = require("./handoff.js");
|
|
30
|
-
const { exportState, mocks } = require("./maintenance.js");
|
|
31
|
-
const { chGoals, chDims, challengeRoles, challengeCouncil, challengeCycles, challengeList, challengeShow, challengeDiff, challengeDiffMissing, challengeLint } = require("./challenge.js");
|
|
32
|
-
const { docList, docParts, docStatuses, docMapSections, docMap, docLint, docPlan, docShow, docSection, docShipped, docShippedDrifted, docNext, docAudit, docJournalRich, docJournalEmpty, docContext, docRules, docRulesFrozen, docForecast, docCost } = require("./docs.js");
|
|
33
|
-
const {
|
|
34
|
-
const {
|
|
35
|
-
const {
|
|
36
|
-
const {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
case "/api/doc/
|
|
82
|
-
return
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
case "/api/doc/
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
case "/api/
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return
|
|
159
|
-
case "/api/
|
|
160
|
-
return
|
|
161
|
-
case "/api/
|
|
162
|
-
return
|
|
163
|
-
case "/api/
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
return {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
case "/api/
|
|
192
|
-
return
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
//
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return
|
|
246
|
-
case "/api/
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
case "/api/gotchas
|
|
251
|
-
return
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
case "/api/
|
|
255
|
-
return
|
|
256
|
-
case "/api/
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
return
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
//
|
|
404
|
-
//
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
return
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
//
|
|
477
|
-
//
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
};
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* fixtures.js — canned API responses for `orc ui --fixtures`.
|
|
4
|
+
*
|
|
5
|
+
* This exists because you cannot DESIGN a state you cannot reach. On a healthy
|
|
6
|
+
* install with a fresh wiki and no paused runs, the STALE chip, the `waiting`
|
|
7
|
+
* run card, the shadowed-setting lock and the unhealthy doctor panel are
|
|
8
|
+
* unreachable — so they get built once, blind, and never looked at again.
|
|
9
|
+
*
|
|
10
|
+
* The rule for this file: carry ONE OF EVERY STATE, including the ugly ones.
|
|
11
|
+
* It also means the UI can be worked on with no ORC project at all.
|
|
12
|
+
*
|
|
13
|
+
* Shapes MUST match what `bin/cli.js --json` really emits. A fixture that has
|
|
14
|
+
* drifted from the CLI is worse than no fixture, so test/webui.test.js asserts
|
|
15
|
+
* the fixture key set against the live CLI output for the shared routes.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
// v0.48.1 — the data lives one file per panel; this file is the ROUTER and
|
|
20
|
+
// nothing else. Adding a fixture is a new key in the panel's own file plus a
|
|
21
|
+
// case here; it is never an edit to a 1 700-line module.
|
|
22
|
+
const { PROJECT, doctor, where } = require("./shell.js");
|
|
23
|
+
const { config } = require("./settings.js");
|
|
24
|
+
const { wiki, wikiDocs, wikiShow, wikiCoverage, wikiCoverageFull, wikiUnregistered, wikiPlan, wikiDebt, wikiUsage, patterns, patternShow, gotchas, gotchasArchived, gotchaPrunePreview, wikiImpact } = require("./knowledge.js");
|
|
25
|
+
const { runs, runDetail, runDetailClosed, aftermath } = require("./runs.js");
|
|
26
|
+
const { stats, budgetForecast, budgetRates } = require("./stats.js");
|
|
27
|
+
const { pact } = require("./pact.js");
|
|
28
|
+
const { boundary } = require("./boundary.js");
|
|
29
|
+
const { handoff } = require("./handoff.js");
|
|
30
|
+
const { exportState, mocks } = require("./maintenance.js");
|
|
31
|
+
const { chGoals, chDims, challengeRoles, challengeCouncil, challengeCycles, challengeList, challengeShow, challengeDiff, challengeDiffMissing, challengeLint } = require("./challenge.js");
|
|
32
|
+
const { docList, docParts, docStatuses, docMapSections, docMap, docLint, docPlan, docShow, docSection, docShipped, docShippedDrifted, docNext, docAudit, docJournalRich, docJournalEmpty, docContext, docRules, docRulesFrozen, docForecast, docCost } = require("./docs.js");
|
|
33
|
+
const { laneList, lanePhases, laneCalls } = require("./lanes.js");
|
|
34
|
+
const { diy } = require("./flow.js");
|
|
35
|
+
const { crosslink } = require("./crosslink.js");
|
|
36
|
+
const { mockDetail } = require("./mockrun.js");
|
|
37
|
+
const { extraProviders, extraList, extraListNoConnection, extraListNeverTested, extraTools, extraKeyhelp, extraModels, extraDoctor, extraRoute, extraRole, extraLanes, extraStats, extraRates, extraPingOk, extraPingBad, extraPingSaveOffer, extraJournal, extraReconcile, extraJournalPrune, extraPingLive, extraPingDeadModel, extraPingNotInstalled, extraInstall, extraDemotion } = require("./extra.js");
|
|
38
|
+
|
|
39
|
+
module.exports.get = function get(route, q) {
|
|
40
|
+
switch (route) {
|
|
41
|
+
// v1.0.0 W16 — the `orc lane` noun. `phases` is keyed by lane so the
|
|
42
|
+
// picker reaches BOTH designable states: a lane with a full pipeline and
|
|
43
|
+
// one that keeps its pipeline in its own spine. An unknown lane falls to
|
|
44
|
+
// the `orc` entry rather than returning nothing, because a fixture that
|
|
45
|
+
// 404s teaches the panel a state the CLI does not have (it exits 2).
|
|
46
|
+
// The run demotion. `demoted: true` on purpose — with it false the Promote
|
|
47
|
+
// button correctly does not render, and the modal behind it (the one place
|
|
48
|
+
// a required reason is collected) could never be designed.
|
|
49
|
+
case "/api/extra/demotion":
|
|
50
|
+
return extraDemotion;
|
|
51
|
+
case "/api/lanes":
|
|
52
|
+
return laneList;
|
|
53
|
+
case "/api/lane/phases":
|
|
54
|
+
return lanePhases[(q && q.lane) || "orc"] || lanePhases.orc;
|
|
55
|
+
case "/api/lane/calls":
|
|
56
|
+
return laneCalls;
|
|
57
|
+
case "/api/doc":
|
|
58
|
+
return docList;
|
|
59
|
+
case "/api/doc/one":
|
|
60
|
+
// The two SHIPPED states overlay the plain ones, so `shipped`,
|
|
61
|
+
// `shipped-drifted` and a FORCED ship are all reachable in the panel.
|
|
62
|
+
return (
|
|
63
|
+
{ [docShipped.slug]: docShipped, [docShippedDrifted.slug]: docShippedDrifted }[q && q.slug] ||
|
|
64
|
+
(q && docStatuses[q.slug]) ||
|
|
65
|
+
docStatuses["prd-checkout-refund-130826"]
|
|
66
|
+
);
|
|
67
|
+
case "/api/doc/show":
|
|
68
|
+
// The memory fields ride on whichever slug was asked for, so the header
|
|
69
|
+
// strip, the brief and the journal are all designable per state.
|
|
70
|
+
return {
|
|
71
|
+
...docShow,
|
|
72
|
+
slug: (q && q.slug) || docShow.slug,
|
|
73
|
+
created_at: "13-08-2026 09:02:11",
|
|
74
|
+
last_touched_at: "15-08-2026 17:05:00",
|
|
75
|
+
sessions: 3,
|
|
76
|
+
context: (docContext[q && q.slug] || docContext["prd-checkout-refund-130826"]).context,
|
|
77
|
+
journal: (q && q.slug === "collab-risk-and-payments-130826" ? docJournalEmpty : docJournalRich).journal,
|
|
78
|
+
shipped: (docStatuses[q && q.slug] || {}).shipped || null,
|
|
79
|
+
ship_history: [],
|
|
80
|
+
};
|
|
81
|
+
case "/api/doc/map":
|
|
82
|
+
return docMap;
|
|
83
|
+
case "/api/doc/lint":
|
|
84
|
+
return docLint;
|
|
85
|
+
case "/api/doc/plan":
|
|
86
|
+
return docPlan;
|
|
87
|
+
case "/api/doc/section":
|
|
88
|
+
return docSection;
|
|
89
|
+
// v0.48.1. Each of these has ONE OF EVERY STATE behind it: a free next, a
|
|
90
|
+
// paid next, a next that is blocked on a human; a clean audit and a dirty
|
|
91
|
+
// one; a rich journal and one with nothing recorded at all.
|
|
92
|
+
case "/api/doc/parts":
|
|
93
|
+
return docParts[(q && q.slug) || ""] || docParts["prd-checkout-refund-130826"];
|
|
94
|
+
case "/api/doc/next":
|
|
95
|
+
return docNext[(q && q.slug) || ""] || docNext["prd-checkout-refund-130826"];
|
|
96
|
+
case "/api/doc/audit":
|
|
97
|
+
return docAudit[(q && q.slug) || ""] || docAudit["prd-checkout-refund-130826"];
|
|
98
|
+
case "/api/doc/journal":
|
|
99
|
+
return (q && q.slug) === "collab-risk-and-payments-130826" ? docJournalEmpty : docJournalRich;
|
|
100
|
+
// v0.52.0 (D9) — BOTH shapes: a document routed off Claude, and one that is
|
|
101
|
+
// not. `off` is a state with its own card, never a missing card.
|
|
102
|
+
case "/api/doc/extra":
|
|
103
|
+
return q && String(q.slug || "").indexOf("prd-") === 0
|
|
104
|
+
? {
|
|
105
|
+
ok: true,
|
|
106
|
+
slug: String(q.slug),
|
|
107
|
+
extra: "writer",
|
|
108
|
+
stored: "writer",
|
|
109
|
+
source: "doc.json",
|
|
110
|
+
options: ["off", "writer", "checker", "both"],
|
|
111
|
+
resolve_order: ["doc.json (this document)", "config.extra_roles (the project)", "off"],
|
|
112
|
+
config_roles: ["executor", "doc-writer"],
|
|
113
|
+
shadowed_by_config: [],
|
|
114
|
+
why: "writer goes off Claude for this document; every other role stays on Claude.",
|
|
115
|
+
edges: { band: "[40,80)", edges: [40, 79], agree: true, resolved: { profile: "cheap", model: "deepseek-chat" } },
|
|
116
|
+
default: "off",
|
|
117
|
+
}
|
|
118
|
+
: {
|
|
119
|
+
ok: true,
|
|
120
|
+
slug: String(q && q.slug),
|
|
121
|
+
extra: "off",
|
|
122
|
+
stored: null,
|
|
123
|
+
source: "off",
|
|
124
|
+
options: ["off", "writer", "checker", "both"],
|
|
125
|
+
resolve_order: ["doc.json (this document)", "config.extra_roles (the project)", "off"],
|
|
126
|
+
config_roles: [],
|
|
127
|
+
shadowed_by_config: [],
|
|
128
|
+
why: "nothing in this document goes off Claude.",
|
|
129
|
+
edges: null,
|
|
130
|
+
default: "off",
|
|
131
|
+
};
|
|
132
|
+
case "/api/doc/context":
|
|
133
|
+
return docContext[(q && q.slug) || ""] || docContext["prd-checkout-refund-130826"];
|
|
134
|
+
// v0.49.2. One of every state behind each: a populated ledger AND an empty
|
|
135
|
+
// one, frozen-clean AND frozen-drifted, a real forecast AND a refusal AND a
|
|
136
|
+
// naive floor, a cost report joined AND one with no trace at all.
|
|
137
|
+
case "/api/doc/rules":
|
|
138
|
+
return docRules;
|
|
139
|
+
case "/api/doc/rules/one":
|
|
140
|
+
return docRulesFrozen[(q && q.slug) || ""] || docRulesFrozen["prd-checkout-refund-130826"];
|
|
141
|
+
case "/api/doc/forecast":
|
|
142
|
+
return docForecast[(q && q.slug) || ""] || docForecast["prd-checkout-refund-130826"];
|
|
143
|
+
case "/api/doc/cost":
|
|
144
|
+
return docCost[(q && q.slug) || ""] || docCost["prd-checkout-refund-130826"];
|
|
145
|
+
case "/api/challenge":
|
|
146
|
+
return challengeList;
|
|
147
|
+
case "/api/challenge/one":
|
|
148
|
+
return (q && challengeCycles[q.slug]) || challengeCycles["tsd-payments"];
|
|
149
|
+
case "/api/challenge/show":
|
|
150
|
+
// Only the rich cycle carries findings. Every other slug returns its own
|
|
151
|
+
// identity with an empty iteration list, which is the honest shape for a
|
|
152
|
+
// cycle nobody has judged yet — and stops the panel drawing one cycle's
|
|
153
|
+
// findings under another cycle's name.
|
|
154
|
+
return q && q.slug && q.slug !== challengeShow.slug
|
|
155
|
+
? { ...challengeShow, slug: q.slug, iterations: [], accepted: {}, rebuttals: {}, events: [] }
|
|
156
|
+
: challengeShow;
|
|
157
|
+
case "/api/challenge/diff":
|
|
158
|
+
return q && q.slug === "billing-webhooks" ? challengeDiffMissing : challengeDiff;
|
|
159
|
+
case "/api/challenge/lint":
|
|
160
|
+
return challengeLint;
|
|
161
|
+
case "/api/challenge/roles":
|
|
162
|
+
return challengeRoles;
|
|
163
|
+
case "/api/challenge/council":
|
|
164
|
+
// UNSET is an ANSWER, not an error — the panel has to be designable
|
|
165
|
+
// against a cycle nobody has answered the roster for.
|
|
166
|
+
return q && q.slug === "billing-webhooks"
|
|
167
|
+
? { ok: false, slug: "billing-webhooks", council: null, council_version: 1, suggested: challengeRoles.council.slice(0, 3), rows: challengeCycles["billing-webhooks"].council, lens_counts: {}, reason: "council-unset", hint: 'the roster is a decision, not a default; run `orc challenge council billing-webhooks --set <csv|all|none> --reason "…"`' }
|
|
168
|
+
: challengeCouncil;
|
|
169
|
+
case "/api/meta":
|
|
170
|
+
return undefined; // served for real even in fixture mode
|
|
171
|
+
case "/api/version":
|
|
172
|
+
// An update IS available here on purpose. "Up to date" is the state that
|
|
173
|
+
// needs no design; you cannot lay out the update chip, the rail dot or
|
|
174
|
+
// the upgrade row against a version that matches.
|
|
175
|
+
return { version: "0.43.2", latest: "0.44.0", update_available: true, install_spec: "github:azure-id/orc", checked_source: "https://raw.githubusercontent.com/azure-id/orc/main/package.json", checked_ref: "azure-id/orc@main", check_disabled: false };
|
|
176
|
+
case "/api/where":
|
|
177
|
+
return where;
|
|
178
|
+
case "/api/doctor":
|
|
179
|
+
return doctor;
|
|
180
|
+
case "/api/config":
|
|
181
|
+
return config;
|
|
182
|
+
case "/api/config/profiles":
|
|
183
|
+
return {
|
|
184
|
+
profiles: [
|
|
185
|
+
{ name: "solo-fast", desc: "One person, moving fast, reads their own diffs. Fewer gates, bigger waves.", keys: { max_wave_tasks: 4, batch_pause_every: 3 }, changes: [{ key: "batch_pause_every", from: 2, to: 3 }] },
|
|
186
|
+
{ name: "balanced", desc: "Today's defaults. Change nothing unless you know why.", keys: { max_wave_tasks: 3 }, changes: [{ key: "max_wave_tasks", from: 4, to: 3 }] },
|
|
187
|
+
{ name: "paranoid", desc: "Shared codebase, real users. Every gate on, small waves, pause often.", keys: { max_wave_tasks: 2, security_review: "on" }, changes: [{ key: "max_wave_tasks", from: 4, to: 2 }, { key: "security_review", from: "off", to: "on" }] },
|
|
188
|
+
{ name: "token-lean", desc: "Big repo, tight budget. Narrow scans, shallow analysis.", keys: { max_scouts: 1 }, changes: [{ key: "max_scouts", from: 3, to: 1 }] },
|
|
189
|
+
],
|
|
190
|
+
};
|
|
191
|
+
case "/api/config/recommend":
|
|
192
|
+
return {
|
|
193
|
+
recommended: "paranoid",
|
|
194
|
+
desc: "Shared codebase, real users. Every gate on, small waves, pause often.",
|
|
195
|
+
reasons: ["a real `npm test` script exists — gates have something to check", "CI is configured — this repo is shared, not a scratchpad", "7 contributors in history — coordination cost is real", "a project wiki exists — grounding is already cheap"],
|
|
196
|
+
scores: { "solo-fast": 0, paranoid: 3, "token-lean": 0 },
|
|
197
|
+
};
|
|
198
|
+
case "/api/overview":
|
|
199
|
+
return { where, doctor, wiki, patterns: patterns, runs_total: runs.total, waiting: runs.runs.filter((r) => r.status === "waiting").map((r) => ({ slug: r.slug, updated_ms: r.updated_ms, lane: r.lane })), diy, pact, boundary, wiki_debt: wikiDebt, extra_journal: extraJournal };
|
|
200
|
+
case "/api/pact":
|
|
201
|
+
return pact;
|
|
202
|
+
case "/api/boundary":
|
|
203
|
+
return boundary;
|
|
204
|
+
case "/api/handoff":
|
|
205
|
+
return handoff;
|
|
206
|
+
case "/api/wiki/plan":
|
|
207
|
+
return wikiPlan;
|
|
208
|
+
case "/api/wiki/debt":
|
|
209
|
+
return wikiDebt;
|
|
210
|
+
case "/api/wiki/usage":
|
|
211
|
+
return wikiUsage;
|
|
212
|
+
case "/api/budget/forecast":
|
|
213
|
+
// No plan path → the exit-3 "no forecast possible" state, which is what a
|
|
214
|
+
// first-time user sees and therefore has to be designed too.
|
|
215
|
+
return q && q.plan
|
|
216
|
+
? budgetForecast
|
|
217
|
+
: { ok: false, reason: "no-plan", hint: "pick a plan file — a forecast from a sentence is a guess that looks computed" };
|
|
218
|
+
case "/api/budget/rates":
|
|
219
|
+
return budgetRates;
|
|
220
|
+
case "/api/budget/actual":
|
|
221
|
+
return { ok: true, run: "store-credit", lane: "orc", trace: "run-orc-store-credit-100826-093012.txt", rows: [{ band: "[40,55)", dispatches: 3, forecast_weighted: 96000, actual_weighted: 138000, diff_pct: 44, tokens: { input: 9000, cache_write: 61000, cache_read: 121000, output: 11000 } }, { band: "[70,80)", dispatches: 1, forecast_weighted: 121000, actual_weighted: 304000, diff_pct: 151, tokens: { input: 12000, cache_write: 98000, cache_read: 240000, output: 24000 } }], actual: { tokens: { input: 21000, cache_write: 159000, cache_read: 361000, output: 35000 }, raw: 576000, weighted: 251100, usd: 7.02 }, cache_read_share: 0.71, unattributed: { blocks: 12, tokens: { input: 900, cache_write: 12000, cache_read: 24000, output: 1100 } }, joined: 17, dispatches: 19 };
|
|
222
|
+
case "/api/aftermath":
|
|
223
|
+
return aftermath;
|
|
224
|
+
case "/api/export":
|
|
225
|
+
return exportState;
|
|
226
|
+
case "/api/runs":
|
|
227
|
+
return runs;
|
|
228
|
+
case "/api/run": {
|
|
229
|
+
if (!q || !q.slug || q.slug === runDetail.slug) return runDetail;
|
|
230
|
+
// A closed run is its OWN detail shape — Reopen instead of Mark as done,
|
|
231
|
+
// and the recorded reason. Without it the closed state exists in the list
|
|
232
|
+
// and nowhere you can click.
|
|
233
|
+
if (q.slug === runDetailClosed.slug) return runDetailClosed;
|
|
234
|
+
const row = runs.runs.find((r) => r.slug === q.slug);
|
|
235
|
+
return {
|
|
236
|
+
...runDetail,
|
|
237
|
+
slug: q.slug,
|
|
238
|
+
status: (row && row.status) || "done",
|
|
239
|
+
resume: row && row.status === "waiting" ? runDetail.resume : null,
|
|
240
|
+
closed: (row && row.closed) || null,
|
|
241
|
+
stands: { lane: (row && row.lane) || "/orc-mini", phase: (row && row.phase) || "", wave: (row && row.wave) || "" },
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
case "/api/wiki":
|
|
245
|
+
return wiki;
|
|
246
|
+
case "/api/wiki/impact":
|
|
247
|
+
return wikiImpact;
|
|
248
|
+
case "/api/patterns":
|
|
249
|
+
return patterns;
|
|
250
|
+
case "/api/gotchas":
|
|
251
|
+
return gotchas;
|
|
252
|
+
// v0.49.1 — the wiki's CONTENTS, the pattern's CONTENTS, and the two gotcha
|
|
253
|
+
// reads the panel needs to preview an eviction and reach the archive.
|
|
254
|
+
case "/api/wiki/docs":
|
|
255
|
+
return wikiDocs;
|
|
256
|
+
case "/api/wiki/show":
|
|
257
|
+
// `--body` is opt-in: the default carries no prose at all.
|
|
258
|
+
return q && q.body ? wikiShow : (({ body, ...rest }) => rest)(wikiShow);
|
|
259
|
+
case "/api/wiki/coverage":
|
|
260
|
+
// Two of them, so 61% AND 100% are both designable. `?full=1` picks the
|
|
261
|
+
// happy one; a state with no fixture is a state nobody has looked at.
|
|
262
|
+
return q && q.full ? wikiCoverageFull : wikiCoverage;
|
|
263
|
+
case "/api/pattern/show": {
|
|
264
|
+
const one = patternShow[(q && q.lang) || "react"] || patternShow.react;
|
|
265
|
+
return q && q.body ? one : (({ body, ...rest }) => rest)(one);
|
|
266
|
+
}
|
|
267
|
+
case "/api/gotchas/archived":
|
|
268
|
+
return gotchasArchived;
|
|
269
|
+
case "/api/gotcha/prune/preview":
|
|
270
|
+
return gotchaPrunePreview;
|
|
271
|
+
case "/api/stats":
|
|
272
|
+
return stats;
|
|
273
|
+
case "/api/diy":
|
|
274
|
+
return diy;
|
|
275
|
+
case "/api/crosslink":
|
|
276
|
+
return crosslink;
|
|
277
|
+
case "/api/mocks":
|
|
278
|
+
return mocks;
|
|
279
|
+
case "/api/mock":
|
|
280
|
+
return mockDetail;
|
|
281
|
+
case "/api/stack":
|
|
282
|
+
return { slugs: ["billing-split"], slug: "billing-split", ambiguous: false, plan: { slug: "billing-split", ready: false, exists: true, plan_path: PROJECT + "/stacked-pr/billing-split/stack-plan.md", layers: 4, ticket: "PAY-2214", problems: ["3 unfilled placeholders (e.g. <risk> <owner> <base>)"] } };
|
|
283
|
+
case "/api/changelog":
|
|
284
|
+
// Two entries, so the modal has to handle a LIST rather than one release —
|
|
285
|
+
// skipping a version is the normal case, not the exotic one.
|
|
286
|
+
return {
|
|
287
|
+
version: "0.43.2",
|
|
288
|
+
latest: "0.44.0",
|
|
289
|
+
update_available: true,
|
|
290
|
+
source: "https://raw.githubusercontent.com/azure-id/orc/main/CHANGELOG.md",
|
|
291
|
+
check_disabled: false,
|
|
292
|
+
fetched: true,
|
|
293
|
+
entries: [
|
|
294
|
+
{
|
|
295
|
+
version: "0.44.0",
|
|
296
|
+
date: "2026-08-09",
|
|
297
|
+
title: "`orc ui`: the guided tour, and an upgrade you can read first",
|
|
298
|
+
body:
|
|
299
|
+
"**A version number is not a reason to upgrade.** The banner now fetches the\n" +
|
|
300
|
+
"changelog from the same branch `orc upgrade` installs from, so what you read\n" +
|
|
301
|
+
"and what you get can never be different releases.\n\n" +
|
|
302
|
+
"- First-run tour over the key surfaces, skippable per project\n" +
|
|
303
|
+
"- The upgrade spotlight clears when you actually reach the preview",
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
version: "0.43.3",
|
|
307
|
+
date: "2026-08-08",
|
|
308
|
+
title: "settings stop being a wall",
|
|
309
|
+
body: "Collapsible tiers and a filter across all of them at once.",
|
|
310
|
+
},
|
|
311
|
+
],
|
|
312
|
+
};
|
|
313
|
+
case "/api/crosslink/kinds":
|
|
314
|
+
// A short slice of the real catalog — enough to design the picker with,
|
|
315
|
+
// including the nested `auth/oidc` whose directory is sanitised to
|
|
316
|
+
// `auth-oidc` on disk. A picker that never sees one cannot be trusted.
|
|
317
|
+
return { kinds: ["grpc", "rest-endpoint", "graphql", "websocket", "message-queue", "webhook", "shared-db", "auth/oidc"] };
|
|
318
|
+
case "/api/experiment":
|
|
319
|
+
// can_launch:false is the fixture-mode state on purpose — a disabled
|
|
320
|
+
// launch button with a reason is a thing that needs designing.
|
|
321
|
+
return {
|
|
322
|
+
lanes: [
|
|
323
|
+
{ id: "orc", cmd: "/orc", what: "Full pipeline: intake → plan → scored parallel waves → review → verify → ship." },
|
|
324
|
+
{ id: "orc-quick", cmd: "/orc-quick", what: "Ask for anything. Look → ask once → do, and it always asks which agent." },
|
|
325
|
+
{ id: "orc-mini", cmd: "/orc-mini", what: "One executor, smoke gate, ship. No full review or verify phase." },
|
|
326
|
+
{ id: "orc-wiki", cmd: "/orc-wiki", what: "Build or refresh the project wiki. Expensive; always asks first." },
|
|
327
|
+
],
|
|
328
|
+
project_root: "/example/project",
|
|
329
|
+
platform: "linux",
|
|
330
|
+
can_launch: false,
|
|
331
|
+
};
|
|
332
|
+
case "/api/learn":
|
|
333
|
+
return { sections: require("../../onboarding-content.js").SECTIONS };
|
|
334
|
+
// The mocked runs are package content, identical on every machine and
|
|
335
|
+
// needing no project — so fixture mode serves the REAL catalogue. A canned
|
|
336
|
+
// copy here could only ever be a worse version of a file sitting next to
|
|
337
|
+
// it, and it would be the one thing on this panel that could go stale.
|
|
338
|
+
case "/api/mockruns":
|
|
339
|
+
return require("../../mockrun-catalog.js").catalogue();
|
|
340
|
+
case "/api/mockrun": {
|
|
341
|
+
const doc = require("../../mockrun-catalog.js").get(String((q && q.slug) || ""));
|
|
342
|
+
return doc ? { ...doc, found: true } : { slug: String((q && q.slug) || ""), found: false };
|
|
343
|
+
}
|
|
344
|
+
case "/api/fs/list":
|
|
345
|
+
// The folder picker on canned data. It carries the states that are hard
|
|
346
|
+
// to reach on a tidy machine: a plain folder, a git repo WITHOUT a wiki
|
|
347
|
+
// (the case that saves an inert edge), a repo with one, and the project
|
|
348
|
+
// itself — which the picker must refuse.
|
|
349
|
+
return {
|
|
350
|
+
path: "/example",
|
|
351
|
+
parent: "/",
|
|
352
|
+
sep: "/",
|
|
353
|
+
home: "/home/dev",
|
|
354
|
+
project_root: PROJECT,
|
|
355
|
+
is_project_root: false,
|
|
356
|
+
relative: "..",
|
|
357
|
+
truncated: false,
|
|
358
|
+
dirs: [
|
|
359
|
+
{ name: "payments-core", path: "/example/payments-core", is_repo: true, has_wiki: true },
|
|
360
|
+
{ name: "storefront-web", path: "/example/storefront-web", is_repo: true, has_wiki: false },
|
|
361
|
+
{ name: "ledger-batch", path: "/example/ledger-batch", is_repo: true, has_wiki: false },
|
|
362
|
+
{ name: "project", path: PROJECT, is_repo: true, has_wiki: true },
|
|
363
|
+
{ name: "scratch", path: "/example/scratch", is_repo: false, has_wiki: false },
|
|
364
|
+
],
|
|
365
|
+
};
|
|
366
|
+
case "/api/maintenance":
|
|
367
|
+
return {
|
|
368
|
+
actions: [
|
|
369
|
+
{ id: "update", label: "Re-copy this package's payload over the installed one", command: "orc update", network: false, names_files: false },
|
|
370
|
+
{ id: "prune", label: "Update AND delete ORC-named orphans from a pre-manifest install", command: "orc update --prune", network: false, names_files: true },
|
|
371
|
+
{ id: "fix", label: "Apply every fix orc doctor found (= update + prune + settings re-merge)", command: "orc doctor --fix", network: false, names_files: false },
|
|
372
|
+
{ id: "upgrade", label: "Fetch the LATEST package from the network, then apply it", command: "orc upgrade", network: true, names_files: false },
|
|
373
|
+
{ id: "update-global", label: "Re-copy this package's payload over the GLOBAL install in ~/.claude", command: "orc update --global", network: false, names_files: false, advanced: true },
|
|
374
|
+
],
|
|
375
|
+
};
|
|
376
|
+
case "/api/maintenance/preview":
|
|
377
|
+
return {
|
|
378
|
+
action: q.action,
|
|
379
|
+
label: "Preview (fixtures)",
|
|
380
|
+
command:
|
|
381
|
+
"orc " +
|
|
382
|
+
(q.action === "prune"
|
|
383
|
+
? "update --prune"
|
|
384
|
+
: q.action === "fix"
|
|
385
|
+
? "doctor --fix"
|
|
386
|
+
: q.action === "upgrade"
|
|
387
|
+
? "upgrade"
|
|
388
|
+
: q.action === "update-global"
|
|
389
|
+
? "update --global"
|
|
390
|
+
: "update"),
|
|
391
|
+
network: q.action === "upgrade",
|
|
392
|
+
names_files: q.action === "prune",
|
|
393
|
+
advanced: q.action === "update-global",
|
|
394
|
+
preview_command: q.action === "update-global" ? "orc doctor --global" : "orc doctor",
|
|
395
|
+
preview: doctor,
|
|
396
|
+
// Derived from the SAME list the Runs panel renders, so a run closed in
|
|
397
|
+
// the fixture set stops blocking the preview here too — which is the
|
|
398
|
+
// whole point of the v0.49.2 fix.
|
|
399
|
+
waiting_runs: runs.runs.filter((r) => r.status === "waiting").map((r) => r.slug),
|
|
400
|
+
dirty_tree: true,
|
|
401
|
+
};
|
|
402
|
+
// v0.50.0 — `orc extra`. One of every state, including the ugly ones: a
|
|
403
|
+
// stale catalog, a vault part-way through its countdown, a vault that
|
|
404
|
+
// deleted itself, a missing environment key, overlapping route rows and a
|
|
405
|
+
// routed model the provider no longer lists.
|
|
406
|
+
// v0.51.0 — the SETUP GATE has three states and each is reachable here:
|
|
407
|
+
// `?gate=none` is nothing connected, `?gate=untested` is a connection that
|
|
408
|
+
// has never answered, and the default is the gate open. Without all three
|
|
409
|
+
// you cannot design the panel a first-time user actually sees.
|
|
410
|
+
case "/api/extra": {
|
|
411
|
+
// The panel sends no query on this read, so a query-only switch would put
|
|
412
|
+
// the two shut-gate states somewhere nobody could ever look at them —
|
|
413
|
+
// which is the exact failure --fixtures exists to prevent. `ORC_UI_FIXTURE_GATE`
|
|
414
|
+
// makes both reachable in the running panel:
|
|
415
|
+
// ORC_UI_FIXTURE_GATE=none nothing connected at all
|
|
416
|
+
// ORC_UI_FIXTURE_GATE=untested connected, never answered
|
|
417
|
+
const g = (q && q.gate) || process.env.ORC_UI_FIXTURE_GATE || "";
|
|
418
|
+
return g === "none" ? extraListNoConnection : g === "untested" ? extraListNeverTested : extraList;
|
|
419
|
+
}
|
|
420
|
+
// v0.51.0 — the four LOCAL TOOL states, the three credential routes, and
|
|
421
|
+
// both model-entry shapes.
|
|
422
|
+
case "/api/extra/tools":
|
|
423
|
+
return extraTools;
|
|
424
|
+
case "/api/extra/keyhelp":
|
|
425
|
+
return q && q.profile === "local" ? extraKeyhelp.env : extraKeyhelp.login;
|
|
426
|
+
case "/api/extra/models":
|
|
427
|
+
return q && q.profile === "custom" ? extraModels.freeText : extraModels.list;
|
|
428
|
+
case "/api/extra/providers":
|
|
429
|
+
return extraProviders;
|
|
430
|
+
case "/api/extra/doctor":
|
|
431
|
+
return extraDoctor;
|
|
432
|
+
case "/api/extra/route":
|
|
433
|
+
return extraRoute;
|
|
434
|
+
case "/api/extra/role":
|
|
435
|
+
return extraRole;
|
|
436
|
+
case "/api/extra/lanes":
|
|
437
|
+
return extraLanes;
|
|
438
|
+
case "/api/extra/stats":
|
|
439
|
+
return extraStats;
|
|
440
|
+
case "/api/extra/rates":
|
|
441
|
+
return extraRates;
|
|
442
|
+
// v0.54.0 — RECOVERY. One reconcile fixture per state, including the ugly
|
|
443
|
+
// ones: an `in-flight` REFUSAL, a `reverted` block, a `streamed-opaque`
|
|
444
|
+
// journal with no per-turn attribution to render, and a `no-journal` answer
|
|
445
|
+
// for a dispatch that predates the feature.
|
|
446
|
+
case "/api/extra/journal":
|
|
447
|
+
return extraJournal;
|
|
448
|
+
case "/api/extra/reconcile":
|
|
449
|
+
return extraReconcile[String((q && q.task) || "")] || extraReconcile["T-12"];
|
|
450
|
+
case "/api/extra/journal/prune/preview":
|
|
451
|
+
return extraJournalPrune;
|
|
452
|
+
case "/api/extra/show":
|
|
453
|
+
return {
|
|
454
|
+
ok: true,
|
|
455
|
+
profile: extraList.profiles.find((p) => p.name === (q && q.profile)) || extraList.profiles[0],
|
|
456
|
+
catalog: null,
|
|
457
|
+
history: [],
|
|
458
|
+
};
|
|
459
|
+
case "/api/job":
|
|
460
|
+
return { id: null, running: false };
|
|
461
|
+
default:
|
|
462
|
+
return undefined;
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
// ── the states below are referenced above; declared after for readability ───
|
|
467
|
+
|
|
468
|
+
// The POST half (v0.50.0). Almost every mutation in fixture mode answers "nothing
|
|
469
|
+
// ran" and that is the honest answer — but the CONNECTION TEST'S OUTCOME is a
|
|
470
|
+
// state this panel is largely about, and a state you cannot design if the wire
|
|
471
|
+
// never lands. So exactly one route has canned answers, chosen deterministically
|
|
472
|
+
// from the profile so they agree with what the list already claims.
|
|
473
|
+
//
|
|
474
|
+
// A route with no entry here still gets the ordinary "nothing ran" reply.
|
|
475
|
+
module.exports.post = function post(route, body) {
|
|
476
|
+
// `add` answers OK so the CONNECT FLOW can be walked end to end in fixture
|
|
477
|
+
// mode — the add is only the step before the test, and the test's outcome is
|
|
478
|
+
// the state worth designing. Every other write still answers "nothing ran".
|
|
479
|
+
if (route === "/api/extra/add") return { exit_code: 0, data: { ok: true, next: "orc extra ping" } };
|
|
480
|
+
// v0.51.0 — a launch that could NOT happen and one that did. Both are exit 0,
|
|
481
|
+
// because "no terminal here" is an ANSWER carrying the command to paste.
|
|
482
|
+
if (route === "/api/extra/install")
|
|
483
|
+
return {
|
|
484
|
+
exit_code: 0,
|
|
485
|
+
data: (body && body.provider) === "codex" ? extraInstall.refused : extraInstall.launched,
|
|
486
|
+
};
|
|
487
|
+
if (route === "/api/extra/models/test")
|
|
488
|
+
return { exit_code: 0, data: { ok: true, test: extraPingLive } };
|
|
489
|
+
if (route !== "/api/extra/ping") return undefined;
|
|
490
|
+
const profile = String((body && body.profile) || "");
|
|
491
|
+
if (body && body.key && !body.passphrase) return { exit_code: 0, data: { ...extraPingSaveOffer, profile } };
|
|
492
|
+
// v0.51.0 — the PAID rung has THREE outcomes worth designing and each is
|
|
493
|
+
// reachable: it worked and still cannot say which model answered, the model
|
|
494
|
+
// was LISTED and is DEAD upstream, and the tool is not installed at all.
|
|
495
|
+
if (route === "/api/extra/ping" && body && body.live) {
|
|
496
|
+
if (profile === "toolc") return { exit_code: 1, data: { ...extraPingNotInstalled, profile } };
|
|
497
|
+
if (String(body.model || "").indexOf("free") !== -1)
|
|
498
|
+
return { exit_code: 1, data: { ...extraPingDeadModel, profile } };
|
|
499
|
+
return { exit_code: 0, data: { ...extraPingLive, profile: profile || extraPingLive.profile } };
|
|
500
|
+
}
|
|
501
|
+
if (profile === "router" || profile === "burned") return { exit_code: 1, data: { ...extraPingBad, profile } };
|
|
502
|
+
return { exit_code: 0, data: { ...extraPingOk, profile: profile || extraPingOk.profile } };
|
|
503
|
+
};
|