@azure-id/orc 1.2.0 → 1.4.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.
@@ -0,0 +1,409 @@
1
+ "use strict";
2
+ /**
3
+ * fixtures/hookui.js — canned `orc statusline …` responses.
4
+ *
5
+ * ONE OF EVERY STATE, INCLUDING THE UGLY ONES. You cannot design a caution
6
+ * strip on a layout that validates, a `5/5` chip on a line with two things on
7
+ * it, or a refused palette row on a project where nothing is refused.
8
+ *
9
+ * So this set carries: the feature OFF with a saved layout, a line at 5/5, a
10
+ * line 3 blocked by the dense-prefix rule, one hard error and two warnings, a
11
+ * refused component, a component rendering an em dash, and a preview in all
12
+ * three degraded forms.
13
+ *
14
+ * The ANSI here is REAL — the panel's job is to turn escape sequences into DOM,
15
+ * and a fixture of plain text would exercise none of that.
16
+ */
17
+
18
+ const E = String.fromCharCode(27);
19
+ const R = E + "[0m";
20
+ const dim = (s) => E + "[90m" + s + R;
21
+ const green = (s) => E + "[32m" + s + R;
22
+ const amber = (s) => E + "[33m" + s + R;
23
+ const red = (s) => E + "[31m" + s + R;
24
+
25
+ // The rendered bar, in its four forms. Line 3 is deliberately the shortest —
26
+ // the board's third line usually is.
27
+ const previewText =
28
+ amber("🚀") + " " + dim("ORC ") + "1.3.0 · Opus 5/high · " + dim("context ") + green("38%") + " · " + amber("██████░░░░") + "\n" +
29
+ " ▰ " + dim("status ") + "quick · Q3 DO · " + dim("agents ") + " 7 · " + dim("Dur ") + " 48m · main\n" +
30
+ " " + dim("cache ") + "●" + " " + green("███████▊░░") + " · " + dim("MTok ") + "412K · " + red("—");
31
+
32
+ const previewNoColor =
33
+ "🚀 ORC 1.3.0 · Opus 5/high · context 38% · ██████░░░░\n" +
34
+ " ▰ status quick · Q3 DO · agents 7 · Dur 48m · main\n" +
35
+ " cache ● ███████▊░░ · MTok 412K · —";
36
+
37
+ const previewAscii =
38
+ "++ ORC 1.3.0 - Opus 5/high - context 38% - ######....\n" +
39
+ " = status quick - Q3 DO - agents 7 - Dur 48m - main\n" +
40
+ " cache o #######|.. - MTok 412K - -";
41
+
42
+ const preview = {
43
+ ok: true,
44
+ width: 120,
45
+ state: "healthy",
46
+ fixture: "a healthy session mid-run",
47
+ fixtures: {
48
+ healthy: "a healthy session mid-run",
49
+ degraded: "the wrong tier, a full window, and nothing running",
50
+ empty: "a payload with nothing in it — every component on its unknown form",
51
+ },
52
+ text: previewText,
53
+ strippings: { no_color: previewNoColor, ascii: previewAscii, no_motion: previewNoColor },
54
+ static_width: [58, 62, 44],
55
+ errors: [],
56
+ };
57
+
58
+ // A rendered sample per renderer, which is what makes the shape gallery a
59
+ // gallery rather than a dropdown of words.
60
+ const P = (id) => ({
61
+ bare: "38%",
62
+ plain: dim(id + " ") + "38%",
63
+ "label-value": dim(id.toUpperCase() + ": ") + "38%",
64
+ bracket: "[" + dim(id.toUpperCase() + " ") + "38%]",
65
+ paren: "(38%)",
66
+ badge: "▏" + dim(id.toUpperCase() + " ") + "38%▕",
67
+ pill: E + "[7m" + id.slice(0, 3).toUpperCase() + R + "38%",
68
+ bar: "38% " + amber("███░░░░░░░"),
69
+ blocks: amber("███░░░░░░░"),
70
+ fine: amber("███▊ "),
71
+ dots: "●●●○○",
72
+ gauge: "◔",
73
+ ring: "◔",
74
+ shape: green("●"),
75
+ word: green("ok"),
76
+ icon: "✅",
77
+ spark: "▁▂▃▅▆▇",
78
+ trend: "▲",
79
+ });
80
+
81
+ const components = {
82
+ ok: true,
83
+ schema: 1,
84
+ catalog_hash: "b7c1d2e3f4a5968708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f",
85
+ count: 6,
86
+ groups: { A: "Session and tier", B: "Quota and spend", D: "Knowledge", H: "Project and VCS" },
87
+ components: [
88
+ {
89
+ id: "verdict", group: "A", label: null,
90
+ summary: "The ORC-ready verdict icon.",
91
+ renderers: ["icon", "shape", "word", "badge"],
92
+ defaults: { render: "icon" },
93
+ states: ["ready", "boosted", "degrade"],
94
+ shapes: { ready: "✅", boosted: "🚀", degrade: "⛔" },
95
+ bounded: false, series: null, unknown: "dash", cost: "free",
96
+ refused_reason: null, params: null, binding: "verdict.state",
97
+ composite: null, time_based: false,
98
+ previews: { icon: "🚀", shape: "🚀", word: green("boosted"), badge: "▏🚀▕" },
99
+ },
100
+ {
101
+ id: "context", group: "A", label: "context",
102
+ summary: "How full the context window is.",
103
+ renderers: ["plain", "label-value", "bar", "blocks", "fine", "dots", "gauge", "ring", "bare"],
104
+ defaults: { render: "plain", format: "percent", min_width: 3, align: "right", ramp: "heat" },
105
+ states: ["ok", "warn", "full"],
106
+ shapes: { ok: "●", warn: "◐", full: "○" },
107
+ bounded: true, series: null, unknown: "dash", cost: "free",
108
+ refused_reason: null, params: null, binding: "ctx.used_pct",
109
+ composite: null, time_based: false,
110
+ previews: P("context"),
111
+ },
112
+ {
113
+ id: "quota-5h", group: "B", label: "5h",
114
+ summary: "The 5-hour usage window.",
115
+ renderers: ["plain", "bar", "blocks", "spark", "bare"],
116
+ defaults: { render: "plain", format: "percent", min_width: 3, align: "right", ramp: "heat" },
117
+ states: ["ok", "warn", "critical"],
118
+ shapes: { ok: "●", warn: "◐", critical: "○" },
119
+ bounded: true, series: "quota5h", unknown: "dash", cost: "free",
120
+ refused_reason: null, params: null, binding: "quota.5h.pct",
121
+ composite: null, time_based: false,
122
+ previews: P("5h"),
123
+ },
124
+ // A COMPONENT RENDERING AN EM DASH. Its file does not exist in this
125
+ // project, so it says so — and it is still placeable, because `—` and "this
126
+ // build has no such segment" are different facts.
127
+ {
128
+ id: "wiki", group: "D", label: "wiki",
129
+ summary: "How old the project wiki is, from the wiki's own oldest anchor.",
130
+ renderers: ["word", "shape", "badge"],
131
+ defaults: { render: "word" },
132
+ states: ["fresh", "aging", "stale", "unregistered", "none"],
133
+ shapes: { fresh: "●", aging: "◐", stale: "○", unregistered: "?", none: "·" },
134
+ bounded: false, series: null, unknown: "dash", cost: "new-read",
135
+ refused_reason: null, params: null, binding: "wiki.tier",
136
+ composite: null, time_based: false,
137
+ previews: { word: "—", shape: "—", badge: "▏—▕" },
138
+ },
139
+ {
140
+ id: "branch", group: "H", label: null,
141
+ summary: "The current git branch, read from .git/HEAD with NO subprocess.",
142
+ renderers: ["bare", "plain", "badge"],
143
+ defaults: { render: "bare", truncate: "middle", max_len: 24 },
144
+ states: null, shapes: null, bounded: false, series: null,
145
+ unknown: "hide", cost: "scan", refused_reason: null, params: null,
146
+ binding: "git.branch", composite: null, time_based: false,
147
+ previews: { bare: "main", plain: dim("branch ") + "main", badge: "▏main▕" },
148
+ },
149
+ // A REFUSED ROW. It keeps its slot, carries the measurement, and gets NO
150
+ // BUTTON AT ALL — never a disabled one. "We decided against this" and "we
151
+ // forgot" must not look the same.
152
+ {
153
+ id: "git-dirty", group: "H", label: "±",
154
+ summary: "Uncommitted changes.",
155
+ renderers: ["plain", "label-value", "bare"],
156
+ defaults: { render: "plain" },
157
+ states: null, shapes: null, bounded: false, series: null,
158
+ unknown: "dash", cost: "refused",
159
+ refused_reason:
160
+ "it needs a `git status` subprocess, and W0 measured one at 53ms against roughly 15ms of headroom on a surface that re-renders on every keystroke.",
161
+ params: null, binding: null, composite: null, time_based: false,
162
+ previews: {},
163
+ },
164
+ ],
165
+ renderers: {
166
+ bare: { kind: "text", form: "value", needs: null, width: null, decoration: false },
167
+ plain: { kind: "text", form: "label value", needs: null, width: null, decoration: false },
168
+ "label-value": { kind: "text", form: "LABEL: value", needs: null, width: null, decoration: false },
169
+ bracket: { kind: "text", form: "[LABEL: value]", needs: null, width: null, decoration: false },
170
+ paren: { kind: "text", form: "(value)", needs: null, width: null, decoration: false },
171
+ badge: { kind: "text", form: "▏LABEL value▕", needs: null, width: null, decoration: false },
172
+ pill: { kind: "text", form: "⟪LABEL⟫value", needs: null, width: null, decoration: false },
173
+ word: { kind: "text", form: "STATE", needs: "states", width: null, decoration: false },
174
+ bar: { kind: "bar", form: null, needs: "bounded", width: [4, 16], decoration: false },
175
+ blocks: { kind: "bar", form: null, needs: "bounded", width: [2, 16], decoration: false },
176
+ fine: { kind: "bar", form: null, needs: "bounded", width: [2, 16], decoration: false },
177
+ dots: { kind: "bar", form: null, needs: "ordinal", width: [2, 10], decoration: false },
178
+ gauge: { kind: "bar", form: null, needs: "bounded", width: [1, 1], decoration: false },
179
+ ring: { kind: "bar", form: null, needs: "bounded", width: [1, 1], decoration: false },
180
+ shape: { kind: "state", form: null, needs: "states", width: null, decoration: false },
181
+ icon: { kind: "state", form: null, needs: "states", width: null, decoration: false },
182
+ spark: { kind: "series", form: null, needs: "series", width: [4, 16], decoration: false },
183
+ trend: { kind: "series", form: null, needs: "series", width: null, decoration: false },
184
+ },
185
+ glyph_sets: ["blocks", "bars", "pipes", "braille", "shade", "minimal", "ascii"],
186
+ ramps: {
187
+ heat: { stops: [0, 60, 85], colors: ["green", "yellow", "red"], why: "high is bad" },
188
+ cool: { stops: [0, 60, 85], colors: ["red", "yellow", "green"], why: "high is good" },
189
+ mono: { stops: [0, 60, 85], colors: [null, null, null], why: "NO_COLOR-safe: emphasis, not hue" },
190
+ state: { stops: null, colors: null, why: "the component's own state colours" },
191
+ },
192
+ themes: {
193
+ terminal: { ok: "green", warn: "yellow", critical: "red", muted: "bright-black", accent: "cyan", label: "bright-black", value: "default" },
194
+ dim: { ok: "green", warn: "yellow", critical: "red", muted: "bright-black", accent: "bright-black", label: "bright-black", value: "bright-black" },
195
+ "high-contrast": { ok: "bright-green", warn: "bright-yellow", critical: "bright-red", muted: "white", accent: "bright-cyan", label: "bright-white", value: "bright-white" },
196
+ mono: { ok: null, warn: null, critical: null, muted: null, accent: null, label: null, value: null },
197
+ },
198
+ hide_when: [
199
+ { id: "never", says: "always render. A state keeps its slot." },
200
+ { id: "empty", says: "hide when the value is absent" },
201
+ { id: "zero", says: "hide when the value is exactly 0" },
202
+ { id: "unknown", says: "hide when the value could not be computed" },
203
+ { id: "ok", says: "hide while healthy — show me only problems" },
204
+ { id: "idle", says: "hide when no run is active" },
205
+ { id: "no-run", says: "hide when no ORC run was opened this session" },
206
+ { id: "narrow", says: "hide below this component's min_cols" },
207
+ { id: "wide", says: "hide above this component's max_cols" },
208
+ ],
209
+ formats: ["percent", "ratio", "fraction", "decimal", "plain"],
210
+ compact: ["off", "si", "bytes"],
211
+ cases: ["none", "upper", "lower", "title"],
212
+ truncate: ["end", "middle", "none"],
213
+ emphasis: ["normal", "bold", "dim", "italic", "underline", "reverse", "strike"],
214
+ refused_emphasis: ["blink"],
215
+ colors: ["red", "green", "yellow", "blue", "magenta", "cyan", "bright-black", "bright-cyan", "default"],
216
+ max_per_line: 5,
217
+ lines: 3,
218
+ dense_prefix: "A line may hold a component only if every line above it holds at least one.",
219
+ };
220
+
221
+ // THE FEATURE IS OFF WITH A LAYOUT SAVED — the state a user is in for most of
222
+ // the time they are composing, and the one the gate card exists for. Line 1 is
223
+ // at 5/5; line 3 is empty, so the board can show a full line and an ordinary
224
+ // one at once.
225
+ const show = {
226
+ ok: false,
227
+ enabled: false,
228
+ saved: true,
229
+ preset: null,
230
+ theme: "terminal",
231
+ glyphs: "blocks",
232
+ ansi: "auto",
233
+ align_columns: false,
234
+ lines: [
235
+ {
236
+ line: 1, separator: " · ", theme: null, max_width: 0, count: 5, counted: 5, full: true,
237
+ items: [
238
+ { pos: 1, id: "i1", type: "verdict", render: "icon", label: null, label_color: "bright-black", value_color: "default", ramp: null, emphasis: [], hide_when: [], unknown: "dash", known: true },
239
+ { pos: 2, id: "i2", type: "context", render: "bar", label: "CTX", label_color: "bright-black", value_color: null, ramp: "heat", emphasis: ["bold"], hide_when: [], unknown: "dash", known: true },
240
+ { pos: 3, id: "i3", type: "quota-5h", render: "plain", label: "5h", label_color: "bright-black", value_color: "default", ramp: "heat", emphasis: [], hide_when: [], unknown: "dash", known: true },
241
+ { pos: 4, id: "i4", type: "branch", render: "bare", label: null, label_color: "bright-black", value_color: "default", ramp: null, emphasis: [], hide_when: [], unknown: "hide", known: true },
242
+ { pos: 5, id: "i5", type: "wiki", render: "word", label: "wiki", label_color: "bright-black", value_color: "default", ramp: null, emphasis: [], hide_when: [], unknown: "dash", known: true },
243
+ ],
244
+ },
245
+ {
246
+ line: 2, separator: " · ", theme: null, max_width: 0, count: 2, counted: 2, full: false,
247
+ items: [
248
+ { pos: 1, id: "i6", type: "context", render: "fine", label: null, label_color: "bright-black", value_color: "default", ramp: null, emphasis: [], hide_when: ["ok"], unknown: "dash", known: true },
249
+ // AN UNKNOWN COMPONENT ID — what an upgrade that retired a component
250
+ // leaves behind. Reported, never auto-repaired.
251
+ { pos: 2, id: "i7", type: "retired-thing", render: "bare", label: null, label_color: null, value_color: null, ramp: null, emphasis: [], hide_when: [], unknown: null, known: false },
252
+ ],
253
+ },
254
+ { line: 3, separator: " · ", theme: null, max_width: 0, count: 0, counted: 0, full: false, items: [] },
255
+ ],
256
+ // ONE HARD ERROR and TWO WARNINGS, so the caution strip can show that an error
257
+ // is a refusal and a warning is a fact the user then owns.
258
+ errors: ['unknown component "retired-thing" on line 2 position 2 — did you mean "resume"?'],
259
+ warnings: [
260
+ "line 1 shows the same value twice (context, context)",
261
+ '"verdict" carries meaning in its colour (ready/boosted/degrade) and you set a flat colour — a green ⛔ is a status line that lies',
262
+ ],
263
+ preview: previewText,
264
+ dense_prefix: components.dense_prefix,
265
+ };
266
+
267
+ const presets = {
268
+ ok: true,
269
+ presets: [
270
+ { name: "orc-default", summary: "Today's two lines, exactly. The byte-identical baseline.", active: false, preview: previewNoColor.split("\n").slice(0, 2).join("\n") },
271
+ { name: "minimal", summary: "One line, four slots, the dim theme. The support answer for a busy terminal.", active: false, preview: dim("🚀 ORC 1.3.0 · Opus 5/high · ") + amber("███▊ ") + dim(" · main") },
272
+ { name: "cost-watch", summary: "What this session is spending, in every unit the payload gives for free.", active: true, preview: previewText.split("\n").slice(0, 2).join("\n") },
273
+ { name: "mono", summary: "No colour anywhere — shapes and emphasis only. The right preset for a README screenshot.", active: false, preview: previewNoColor },
274
+ ],
275
+ };
276
+
277
+ const explain = {
278
+ ok: true,
279
+ id: "i2",
280
+ type: "context",
281
+ line: 1,
282
+ pos: 2,
283
+ resolved: [
284
+ { field: "render", value: "bar", source: "item" },
285
+ { field: "label", value: "CTX", source: "item" },
286
+ { field: "label_color", value: "bright-black", source: "theme:terminal" },
287
+ { field: "glyphs", value: "blocks", source: "file" },
288
+ { field: "min_width", value: 3, source: "catalogue" },
289
+ { field: "ramp", value: "heat", source: "catalogue" },
290
+ ],
291
+ order: ["catalogue", "theme", "file", "line", "item"],
292
+ };
293
+
294
+
295
+ // ── the SECOND board (v1.4.0) ──────────────────────────────────────────────
296
+ // A designer cannot lay out a per-agent row against the status line's
297
+ // components, so the fixture set carries both boards. Same rule as everywhere
298
+ // else here: one of every state, including the ugly ones — a failed agent, an
299
+ // agent whose window size is unknown, and one whose token count has not been
300
+ // seen yet.
301
+ const subComponents = {
302
+ ok: true,
303
+ schema: 1,
304
+ catalog_hash: components.catalog_hash,
305
+ count: 4,
306
+ board: "subagent",
307
+ boards: ["status", "subagent"],
308
+ config_key: "subagent_line_custom",
309
+ setting: "subagentStatusLine",
310
+ groups: { T: "One subagent (the agent-panel row)" },
311
+ components: [
312
+ {
313
+ id: "task-name", group: "T", board: "subagent", label: null,
314
+ summary: "The agent's name.",
315
+ renderers: ["bare", "plain", "badge", "pill"],
316
+ defaults: { render: "bare", truncate: "middle", max_len: 28 },
317
+ states: null, shapes: null, bounded: false, series: null,
318
+ unknown: "dash", cost: "free", refused_reason: null, params: null,
319
+ binding: "task.name", composite: null, time_based: false,
320
+ previews: { bare: "orc-executor-opus-5-low", plain: dim("task-name ") + "orc-executor-opus-5-low", badge: "▏orc-executor-opus-5-low▕", pill: E + "[7mTASK" + R + "orc-executor-opus-5-low" },
321
+ },
322
+ {
323
+ id: "task-tier", group: "T", board: "subagent", label: null,
324
+ summary: "The model and effort this agent is ACTUALLY running at — observed, not derived from its name and not self-reported.",
325
+ renderers: ["bare", "plain", "label-value", "badge"],
326
+ defaults: { render: "bare" },
327
+ states: null, shapes: null, bounded: false, series: null,
328
+ unknown: "dash", cost: "free", refused_reason: null, params: null,
329
+ binding: "task.tier", composite: null, time_based: false,
330
+ previews: { bare: "O5/low", plain: dim("tier ") + "O5/low", "label-value": dim("TIER: ") + "O5/low", badge: "▏O5/low▕" },
331
+ },
332
+ {
333
+ id: "task-tokens", group: "T", board: "subagent", label: null,
334
+ summary: "How many tokens this agent has used. THE NUMBER v1.2.0 SAID COULD NOT BE MEASURED.",
335
+ renderers: ["plain", "label-value", "bare"],
336
+ defaults: { render: "plain", compact: "si" },
337
+ states: null, shapes: null, bounded: false, series: null,
338
+ unknown: "dash", cost: "free", refused_reason: null, params: null,
339
+ binding: "task.tokens", composite: null, time_based: false,
340
+ previews: { plain: "84K", "label-value": dim("TOKENS: ") + "84K", bare: "84K" },
341
+ },
342
+ {
343
+ id: "task-status", group: "T", board: "subagent", label: null,
344
+ summary: "What this agent is doing.",
345
+ renderers: ["word", "shape", "badge", "bare"],
346
+ defaults: { render: "word" },
347
+ states: ["pending", "running", "completed", "failed"],
348
+ shapes: { pending: "○", running: "●", completed: "✓", failed: "▲" },
349
+ bounded: false, series: null, unknown: "dash", cost: "free",
350
+ refused_reason: null, params: null, binding: "task.status",
351
+ composite: null, time_based: false,
352
+ previews: { word: amber("running"), shape: amber("●"), badge: "▏" + amber("running") + "▕", bare: "running" },
353
+ },
354
+ ],
355
+ renderers: components.renderers,
356
+ glyph_sets: components.glyph_sets,
357
+ ramps: components.ramps,
358
+ themes: components.themes,
359
+ hide_when: components.hide_when,
360
+ formats: components.formats,
361
+ compact: components.compact,
362
+ cases: components.cases,
363
+ truncate: components.truncate,
364
+ emphasis: components.emphasis,
365
+ refused_emphasis: components.refused_emphasis,
366
+ colors: components.colors,
367
+ max_per_line: 5,
368
+ // ONE LINE by construction: Claude Code renders one row per task.
369
+ lines: 1,
370
+ dense_prefix: components.dense_prefix,
371
+ };
372
+
373
+ const subShow = {
374
+ ok: true,
375
+ enabled: true,
376
+ saved: true,
377
+ preset: "agent-default",
378
+ theme: "terminal",
379
+ glyphs: "blocks",
380
+ ansi: "auto",
381
+ align_columns: false,
382
+ lines: [
383
+ {
384
+ line: 1, separator: " · ", theme: null, max_width: 0, count: 4, counted: 4, full: false,
385
+ items: [
386
+ { pos: 1, id: "s1", type: "task-status", render: "shape", label: null, label_color: "bright-black", value_color: "default", ramp: null, emphasis: [], hide_when: [], unknown: "dash", known: true },
387
+ { pos: 2, id: "s2", type: "task-name", render: "bare", label: null, label_color: "bright-black", value_color: "default", ramp: null, emphasis: [], hide_when: [], unknown: "dash", known: true },
388
+ { pos: 3, id: "s3", type: "task-tier", render: "bare", label: null, label_color: "bright-black", value_color: "default", ramp: null, emphasis: ["dim"], hide_when: [], unknown: "dash", known: true },
389
+ { pos: 4, id: "s4", type: "task-tokens", render: "plain", label: null, label_color: "bright-black", value_color: "default", ramp: null, emphasis: [], hide_when: [], unknown: "dash", known: true },
390
+ ],
391
+ },
392
+ ],
393
+ errors: [],
394
+ // A layout can be perfectly valid and still worth a caution.
395
+ warnings: ["task-tokens is a FLOOR: an agent that finishes between two redraws is never counted"],
396
+ preview: amber("●") + " orc-executor-opus-5-low · " + dim("O5/low") + " · 84K",
397
+ dense_prefix: components.dense_prefix,
398
+ };
399
+
400
+ const subPresets = {
401
+ ok: true,
402
+ presets: [
403
+ { name: "agent-default", board: "subagent", summary: "What the agent is, what it is running at, and what it has cost so far.", active: true, preview: "orc-executor-opus-5-low · " + dim("O5/low") + " · 84K · " + dim("for ") + " 17m" },
404
+ { name: "agent-watch", board: "subagent", summary: "For a run you are watching: status, its own context window, and the clock.", active: false, preview: amber("●") + " orc-executor-opus-5-low · " + green("███▎░░░░") + " · " + dim("for ") + " 17m" },
405
+ { name: "agent-tier", board: "subagent", summary: "The downgrade check, made visible: the model and effort ORC actually got, per agent.", active: false, preview: "orc-executor-opus-5-low · claude-opus-5 · low · " + amber("running") },
406
+ ],
407
+ };
408
+
409
+ module.exports = { show, components, presets, preview, explain, subShow, subComponents, subPresets };
@@ -27,6 +27,7 @@ const { stats, budgetForecast, budgetRates } = require("./stats.js");
27
27
  const { pact } = require("./pact.js");
28
28
  const { boundary } = require("./boundary.js");
29
29
  const { usage, waitLanes, waitStatus } = require("./wait.js");
30
+ const hookui = require("./hookui.js");
30
31
  const { handoff } = require("./handoff.js");
31
32
  const { exportState, mocks } = require("./maintenance.js");
32
33
  const { chGoals, chDims, challengeRoles, challengeCouncil, challengeCycles, challengeList, challengeShow, challengeDiff, challengeDiffMissing, challengeLint } = require("./challenge.js");
@@ -202,6 +203,22 @@ module.exports.get = function get(route, q) {
202
203
  return pact;
203
204
  case "/api/usage":
204
205
  return usage;
206
+ // v1.3.0 — the CLI Hook Interface. ONE OF EVERY STATE, including the ugly
207
+ // ones: the feature off with a layout saved, a line at 5/5, a line 3 the
208
+ // dense-prefix rule blocks, one hard error and two warnings, a refused
209
+ // palette row, and a component rendering an em dash.
210
+ // v1.4.0 — TWO BOARDS. The fixture set carries both, because a designer
211
+ // cannot lay out a per-agent row against the status line's components.
212
+ case "/api/statusline/show":
213
+ return q && q.board === "subagent" ? hookui.subShow : hookui.show;
214
+ case "/api/statusline/components":
215
+ return q && q.board === "subagent" ? hookui.subComponents : hookui.components;
216
+ case "/api/statusline/presets":
217
+ return q && q.board === "subagent" ? hookui.subPresets : hookui.presets;
218
+ case "/api/statusline/preview":
219
+ return hookui.preview;
220
+ case "/api/statusline/explain":
221
+ return hookui.explain;
205
222
  case "/api/wait/lanes":
206
223
  return waitLanes;
207
224
  case "/api/wait/status":
@@ -0,0 +1,119 @@
1
+ {
2
+ "hookui.title": "CLI Hook Interface",
3
+ "hookui.sub": "Build the ORC status line. Three lines. Each line holds 1 to 5 parts.",
4
+ "hookui.noData": "The status line cannot be read.",
5
+ "hookui.gate": "Status",
6
+ "hookui.on": "on",
7
+ "hookui.off": "off",
8
+ "hookui.saved": "layout saved",
9
+ "hookui.gateOnNote": "Your lines are showing. ORC's built-in two lines are disabled.",
10
+ "hookui.gateOffNote": "ORC shows its built-in two lines. Build a layout below, then enable this. Nothing here changes the bar until you do.",
11
+ "hookui.turnOn": "Enable",
12
+ "hookui.turnOff": "Disable",
13
+ "hookui.switchFailed": "The switch could not be changed.",
14
+ "hookui.cautions": "Cautions",
15
+ "hookui.preview": "Preview",
16
+ "hookui.previewUnavailable": "The preview cannot be drawn until the layout is valid.",
17
+ "hookui.degrades": "The same layout, in the three forms a terminal can force.",
18
+ "hookui.degNoColor": "no colour",
19
+ "hookui.degAscii": "plain text",
20
+ "hookui.degNoMotion": "no motion",
21
+ "hookui.cells": "{n} cell wide",
22
+ "hookui.cellsPlural": "{n} cells wide",
23
+ "hookui.board": "The board",
24
+ "hookui.lineN": "Line {n}",
25
+ "hookui.lineNPlural": "Line {n}",
26
+ "hookui.add": "+ add a part",
27
+ "hookui.addTo": "+ line {n}",
28
+ "hookui.addToPlural": "+ line {n}",
29
+ "hookui.toLine": "line {n}",
30
+ "hookui.toLinePlural": "line {n}",
31
+ "hookui.fillFirst": "Put something on line {n} first.",
32
+ "hookui.lineFull": "Line {n} is full.",
33
+ "hookui.separator": "Between parts",
34
+ "hookui.sepChange": "line {n} separator = \"{s}\"",
35
+ "hookui.moveLeft": "Move left",
36
+ "hookui.moveRight": "Move right",
37
+ "hookui.edit": "Change this part",
38
+ "hookui.remove": "Take this part off",
39
+ "hookui.removed": "{id} removed",
40
+ "hookui.moved": "{id} moved to line {n}",
41
+ "hookui.added": "{id} added to line {n}",
42
+ "hookui.unknownComponent": "This ORC version does not have this part.",
43
+ "hookui.shape": "Shape",
44
+ "hookui.shapeChange": "{id} shape = {r}",
45
+ "hookui.glyphs": "Symbols",
46
+ "hookui.glyphChange": "{id} symbols = {v}",
47
+ "hookui.words": "Words",
48
+ "hookui.label": "Name",
49
+ "hookui.labelPlaceholder": "type any name",
50
+ "hookui.labelChange": "{id} name = \"{v}\"",
51
+ "hookui.case": "Letters",
52
+ "hookui.caseChange": "{id} letters = {v}",
53
+ "hookui.colour": "Colour",
54
+ "hookui.labelColour": "Name colour",
55
+ "hookui.valueColour": "Value colour",
56
+ "hookui.colourChange": "{id} colour = {v}",
57
+ "hookui.ramp": "Colour by value",
58
+ "hookui.rampChange": "{id} colour by value = {v}",
59
+ "hookui.stateColourWarn": "This part says something with its colour ({s}). A fixed colour hides that.",
60
+ "hookui.emphasis": "Weight",
61
+ "hookui.emphasisChange": "{id} weight = {v}",
62
+ "hookui.fontWhy": "Your terminal owns the font size. ORC cannot change it. Bold looks bigger and dim looks smaller. To make a part take more room, give it more cells.",
63
+ "hookui.numbers": "Numbers",
64
+ "hookui.format": "Form",
65
+ "hookui.formatChange": "{id} form = {v}",
66
+ "hookui.compact": "Short form",
67
+ "hookui.compactChange": "{id} short form = {v}",
68
+ "hookui.minWidthWarn": "A number that changes width pushes everything to its right. Set a minimum width to stop that.",
69
+ "hookui.whenToShow": "When to show",
70
+ "hookui.hideChange": "{id} hide when = {v}",
71
+ "hookui.explain": "Where these came from",
72
+ "hookui.explainFailed": "That cannot be read right now.",
73
+ "hookui.palette": "Parts you can add",
74
+ "hookui.searchPlaceholder": "search",
75
+ "hookui.matches": "{n} match",
76
+ "hookui.matchesPlural": "{n} matches",
77
+ "hookui.noMatch": "Nothing matches that.",
78
+ "hookui.presets": "Ready-made layouts",
79
+ "hookui.active": "in use",
80
+ "hookui.apply": "Use this",
81
+ "hookui.applyTitle": "Use \"{name}\"?",
82
+ "hookui.applyWarn": "This REPLACES your whole layout. Every part you placed is removed and the ready-made one takes its place. This cannot be undone.",
83
+ "hookui.applyFailed": "That layout could not be used.",
84
+ "hookui.resetLayout": "Start again",
85
+ "hookui.resetTitle": "Start again?",
86
+ "hookui.resetWarn": "This REPLACES your layout with ORC's built-in one. Every part you placed is removed. This cannot be undone.",
87
+ "hookui.advanced": "More",
88
+ "hookui.theme": "Colour set",
89
+ "hookui.themeChange": "colour set = {v}",
90
+ "hookui.recompile": "Rebuild",
91
+ "hookui.recompiled": "Rebuilt.",
92
+ "hookui.recompileFailed": "The rebuild failed.",
93
+ "hookui.compileNote": "ORC rebuilds the layout after every change, so you never have to. This button is for after you upgrade ORC.",
94
+ "hookui.clone": "Copy",
95
+ "hookui.cloned": "{id} copied",
96
+ "hookui.expand": "Split",
97
+ "hookui.expanded": "{id} split into its parts",
98
+ "hookui.minWidth": "Least width",
99
+ "hookui.minWidthChange": "{id} least width = {v}",
100
+ "hookui.precision": "Decimals",
101
+ "hookui.precisionChange": "{id} decimals = {v}",
102
+ "hookui.width": "Cells",
103
+ "hookui.widthChange": "{id} cells = {v}",
104
+ "hookui.widthWhy": "More cells is the only kind of bigger a terminal has.",
105
+ "hookui.before": "Before",
106
+ "hookui.beforeChange": "{id} before = \"{v}\"",
107
+ "hookui.after": "After",
108
+ "hookui.afterChange": "{id} after = \"{v}\"",
109
+ "hookui.narrow": "On a narrow terminal",
110
+ "hookui.minCols": "Show above",
111
+ "hookui.minColsChange": "{id} show above {v} columns",
112
+ "hookui.priority": "Drop order",
113
+ "hookui.priorityChange": "{id} drop order = {v}",
114
+ "hookui.priorityWhy": "When the line does not fit, 1 goes first and 5 goes last. You choose what survives, not the right edge.",
115
+ "hookui.boardStatus": "The status line",
116
+ "hookui.boardSubagent": "One row per agent",
117
+ "hookui.boardStatusSub": "The two lines at the bottom of your terminal.",
118
+ "hookui.boardSubagentSub": "The row Claude Code draws for each subagent in the agent panel. One line, and it shows what that agent is running at and what it has cost so far."
119
+ }
@@ -1,21 +1,22 @@
1
- {
2
- "nav.overview": "Overview",
3
- "nav.settings": "Settings",
4
- "nav.lanes": "Lanes",
5
- "nav.runs": "Runs",
6
- "nav.knowledge": "Knowledge",
7
- "nav.stats": "Stats",
8
- "nav.flow": "Flow",
9
- "nav.crosslink": "Crosslink",
10
- "nav.learn": "Learn",
11
- "nav.mockrun": "Mocked Skill Use",
12
- "nav.experiment": "Experiment",
13
- "nav.maintenance": "Maintenance",
14
- "nav.pact": "Promises",
15
- "nav.boundary": "Boundary",
16
- "nav.handoff": "Self-serve",
17
- "nav.challenge": "Challenge",
18
- "nav.extra": "Extra",
19
- "nav.wait": "Wait",
20
- "nav.docs": "Docs"
21
- }
1
+ {
2
+ "nav.overview": "Overview",
3
+ "nav.settings": "Settings",
4
+ "nav.lanes": "Lanes",
5
+ "nav.runs": "Runs",
6
+ "nav.knowledge": "Knowledge",
7
+ "nav.stats": "Stats",
8
+ "nav.flow": "Flow",
9
+ "nav.crosslink": "Crosslink",
10
+ "nav.learn": "Learn",
11
+ "nav.mockrun": "Mocked Skill Use",
12
+ "nav.experiment": "Experiment",
13
+ "nav.maintenance": "Maintenance",
14
+ "nav.pact": "Promises",
15
+ "nav.boundary": "Boundary",
16
+ "nav.handoff": "Self-serve",
17
+ "nav.challenge": "Challenge",
18
+ "nav.extra": "Extra",
19
+ "nav.wait": "Wait",
20
+ "nav.docs": "Docs",
21
+ "nav.hookui": "CLI Hook Interface"
22
+ }
@@ -88,5 +88,8 @@
88
88
  "overview.extraOrphan.chip": "{n} dispatch",
89
89
  "overview.extraOrphan.chipPlural": "{n} dispatches",
90
90
  "overview.extraOrphan.slug": "never reported back",
91
- "overview.extraOrphan.where": "Extra · Recovery"
91
+ "overview.extraOrphan.where": "Extra · Recovery",
92
+ "overview.item.statuslineOrphaned.cta": "Open the CLI Hook Interface",
93
+ "overview.item.statuslineInvalid.cta": "Open the CLI Hook Interface",
94
+ "overview.item.statuslineUnreadable.cta": "Open the CLI Hook Interface"
92
95
  }
@@ -29,5 +29,7 @@
29
29
  "tour.13.title": "A long document, in one picture",
30
30
  "tour.13.text": "Each block is a section, sized by how long it is and coloured by its state. Nothing here loads the document itself - ORC works from this map instead, which is why a long document does not end the session.",
31
31
  "tour.14.title": "Work that runs somewhere else",
32
- "tour.14.text": "One line from nothing to a hundred: how hard a task scored. Every part of it shows where that work actually runs — Claude in blue, a provider you connected in green. A range you have not connected keeps its slot, so \"I left the hard work on Claude on purpose\" never looks like \"there is no hard work\". Nothing leaves this machine until you connect something, test it, and press Apply."
32
+ "tour.14.text": "One line from nothing to a hundred: how hard a task scored. Every part of it shows where that work actually runs — Claude in blue, a provider you connected in green. A range you have not connected keeps its slot, so \"I left the hard work on Claude on purpose\" never looks like \"there is no hard work\". Nothing leaves this machine until you connect something, test it, and press Apply.",
33
+ "tour.15.title": "Build your own status line",
34
+ "tour.15.text": "Three lines, each holding up to five parts. Line 1 must have something before line 2 can. The preview at the top is exactly what your terminal will show — it is drawn by the same code the bar runs."
33
35
  }