@azure-id/orc 2.0.2 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/CHANGELOG.md +455 -0
  2. package/README-id.md +52 -23
  3. package/README.md +36 -20
  4. package/bin/build-agents.js +205 -206
  5. package/bin/clear-logs.js +620 -0
  6. package/bin/cli.js +47417 -46420
  7. package/bin/fix.js +459 -0
  8. package/bin/gotcha.js +288 -8
  9. package/bin/habit.js +1538 -1453
  10. package/bin/mockrun-catalog.js +3 -0
  11. package/bin/onboarding-content.js +2 -1
  12. package/bin/pricing.json +28 -21
  13. package/bin/trace-write.js +869 -657
  14. package/bin/verify-contracts.js +5552 -5471
  15. package/bin/verify-package.js +716 -705
  16. package/bin/webui/api.js +125 -6
  17. package/bin/webui/css/panels/hookui.css +79 -0
  18. package/bin/webui/fixtures/behaviour.js +30 -0
  19. package/bin/webui/fixtures/extra.js +2036 -2036
  20. package/bin/webui/fixtures/flow.js +81 -81
  21. package/bin/webui/fixtures/hookui.js +506 -431
  22. package/bin/webui/fixtures/index.js +32 -3
  23. package/bin/webui/fixtures/knowledge.js +2 -2
  24. package/bin/webui/fixtures/maintenance.js +123 -42
  25. package/bin/webui/fixtures/rules.js +1007 -1002
  26. package/bin/webui/fixtures/settings.js +6 -7
  27. package/bin/webui/fixtures/stats.js +9 -6
  28. package/bin/webui/fixtures/wait.js +98 -97
  29. package/bin/webui/i18n/en/behaviour.json +13 -0
  30. package/bin/webui/i18n/en/hookui.json +290 -194
  31. package/bin/webui/i18n/en/maintenance.json +71 -52
  32. package/bin/webui/i18n/en/settings.json +60 -60
  33. package/bin/webui/i18n/id/behaviour.json +13 -0
  34. package/bin/webui/i18n/id/hookui.json +290 -194
  35. package/bin/webui/i18n/id/maintenance.json +71 -52
  36. package/bin/webui/i18n/id/settings.json +60 -60
  37. package/bin/webui/js/05-banners.js +181 -172
  38. package/bin/webui/js/06-edit.js +193 -183
  39. package/bin/webui/js/panels/behaviour.js +77 -12
  40. package/bin/webui/js/panels/hookui.js +2196 -1691
  41. package/bin/webui/js/panels/maintenance.js +336 -235
  42. package/bin/webui/js/panels/settings.js +726 -719
  43. package/mock-run/INDEX.md +1 -0
  44. package/mock-run/a-normal-day.md +2 -2
  45. package/mock-run/extra-slots.md +177 -177
  46. package/mock-run/habits.md +1 -1
  47. package/mock-run/orc-aftermath.md +392 -392
  48. package/mock-run/orc-budget.md +29 -33
  49. package/mock-run/orc-cli.md +200 -200
  50. package/mock-run/orc-explain.md +86 -86
  51. package/mock-run/orc-extra.md +389 -392
  52. package/mock-run/orc-fast.md +2 -2
  53. package/mock-run/orc-fix.md +87 -0
  54. package/mock-run/orc-pattern.md +112 -112
  55. package/mock-run/orc-quick.md +146 -146
  56. package/mock-run/orc.md +4 -4
  57. package/package.json +1 -1
  58. package/templates/agents/MODEL-MAPPING.md +176 -173
  59. package/templates/agents/orc-analyze-mini-sonnet-5-high.md +2 -2
  60. package/templates/agents/{orc-claude-writer-opus-5-med.md → orc-claude-writer-opus-5-low.md} +4 -4
  61. package/templates/agents/orc-executor-haiku-4-5.md +1 -1
  62. package/templates/agents/orc-executor-opus-5-low.md +1 -1
  63. package/templates/agents/orc-executor-sonnet-4-6-high.md +1 -1
  64. package/templates/agents/orc-executor-sonnet-4-6-med.md +1 -1
  65. package/templates/agents/orc-executor-sonnet-5-high.md +2 -2
  66. package/templates/agents/orc-executor-sonnet-5-low.md +155 -0
  67. package/templates/agents/orc-executor-sonnet-5-med.md +155 -0
  68. package/templates/agents/orc-pattern-codifier-sonnet-5-high.md +2 -2
  69. package/templates/agents/orc-planner-mini-sonnet-5-high.md +2 -2
  70. package/templates/agents/{orc-recon-sonnet-4-6-med.md → orc-recon-sonnet-5-med.md} +4 -4
  71. package/templates/agents/orc-retro-sonnet-5-high.md +2 -2
  72. package/templates/agents/{orc-reviewer-opus-5-med.md → orc-reviewer-opus-5-low.md} +4 -4
  73. package/templates/agents/{orc-wiki-scanner-opus-5-med.md → orc-wiki-scanner-opus-5-low.md} +3 -3
  74. package/templates/agents/orc-wiki-scanner-sonnet-5-high.md +2 -2
  75. package/templates/commands/orc-fast.md +10 -10
  76. package/templates/commands/orc-fix.md +18 -0
  77. package/templates/commands/orc-wiki.md +64 -64
  78. package/templates/hooks/README.md +75 -7
  79. package/templates/hooks/orc-session-hook.js +78 -3
  80. package/templates/hooks/orc-statusline-render.js +317 -23
  81. package/templates/hooks/orc-statusline.js +162 -49
  82. package/templates/hooks/orc-subagent-line.js +23 -5
  83. package/templates/hooks/orc-weather-fetch.js +123 -0
  84. package/templates/skills/_shared/extra-dispatch.md +1331 -1331
  85. package/templates/skills/_shared/gotchas.md +27 -7
  86. package/templates/skills/_shared/habits.md +2 -2
  87. package/templates/skills/_shared/opus5-only.md +137 -137
  88. package/templates/skills/_shared/phases/review.md +2 -2
  89. package/templates/skills/_shared/phases/trace-verbs.md +17 -3
  90. package/templates/skills/_shared/phases/trace.md +136 -136
  91. package/templates/skills/_shared/review-slice.md +28 -1
  92. package/templates/skills/_shared/wait.md +1 -0
  93. package/templates/skills/orc/README.md +2 -2
  94. package/templates/skills/orc/SKILL.md +227 -227
  95. package/templates/skills/orc/config.md +25 -27
  96. package/templates/skills/orc/examples/full-run-mock.md +74 -73
  97. package/templates/skills/orc/references/effort-and-mode.md +222 -222
  98. package/templates/skills/orc/references/preflight-report.md +3 -3
  99. package/templates/skills/orc/references/ultra-mode.md +1 -1
  100. package/templates/skills/orc/schemas/checkpoint.md +122 -122
  101. package/templates/skills/orc/subskills/orc-review-verify/SKILL.md +3 -3
  102. package/templates/skills/orc/subskills/orc-review-verify/core.md +1 -1
  103. package/templates/skills/orc-analyze/SKILL.md +4 -2
  104. package/templates/skills/orc-claude/SKILL.md +14 -14
  105. package/templates/skills/orc-claude/examples/claude-run-mock.md +65 -65
  106. package/templates/skills/orc-diy/SKILL.md +5 -5
  107. package/templates/skills/orc-fast/SKILL.md +210 -208
  108. package/templates/skills/orc-fix/SKILL.md +110 -0
  109. package/templates/skills/orc-grill/SKILL.md +232 -232
  110. package/templates/skills/orc-grill/references/grill-doc.md +1 -1
  111. package/templates/skills/orc-mini/SKILL.md +4 -4
  112. package/templates/skills/orc-mini/examples/mini-run-mock.md +4 -2
  113. package/templates/skills/orc-quick/README.md +536 -536
  114. package/templates/skills/orc-quick/SKILL.md +2 -2
  115. package/templates/skills/orc-quick/references/context-doc.md +145 -145
  116. package/templates/skills/orc-quick/references/dispatch-gate.md +220 -219
  117. package/templates/skills/orc-quick/references/gh-mode.md +4 -2
  118. package/templates/skills/orc-retro/SKILL.md +1 -1
  119. package/templates/skills/orc-retro/examples/retro-mock.md +16 -16
  120. package/templates/skills/orc-wiki/README.md +325 -325
  121. package/templates/skills/orc-wiki/SKILL.md +195 -195
  122. package/templates/skills/orc-wiki/examples/wiki-run-mock.md +37 -37
  123. package/templates/skills/orc-wiki/references/extra.md +2 -2
  124. package/templates/skills/orc-wiki/references/partial-refresh.md +276 -271
  125. package/templates/skills/orc-wiki/references/phases/phase-0.md +1 -1
  126. package/templates/skills/orc-wiki/references/phases/phase-2.md +3 -3
  127. package/templates/skills/orc-wiki/references/phases/phase-3c.md +3 -2
  128. package/templates/agents/orc-claude-writer-opus-4-8-high.md +0 -48
  129. package/templates/agents/orc-wiki-scanner-opus-4-8-high.md +0 -74
@@ -1,431 +1,506 @@
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.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.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.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, structural: 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, structural: 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, structural: 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, structural: 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, structural: 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, structural: 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
- separators: [
217
- { value: " · ", name: "middle dot" },
218
- { value: " ", name: "one space" },
219
- { value: " ", name: "two spaces" },
220
- { value: " │ ", name: "upright line" },
221
- { value: " — ", name: "long dash" },
222
- { value: " - ", name: "hyphen" },
223
- { value: " / ", name: "slash" },
224
- { value: " • ", name: "bullet" },
225
- { value: " ▸ ", name: "small arrow" },
226
- { value: " » ", name: "double arrow" },
227
- { value: ", ", name: "comma" },
228
- { value: " | ", name: "pipe" },
229
- ],
230
- themes_about: {
231
- terminal: "the default: your terminal's own colours, one accent",
232
- dim: "everything quiet — labels and values both greyed",
233
- "high-contrast": "the brightest slot of every colour, for a pale terminal",
234
- mono: "no colour at all; weight and shape carry every state",
235
- },
236
- max_per_line: 5,
237
- lines: 3,
238
- dense_prefix: "A line may hold a component only if every line above it holds at least one.",
239
- };
240
-
241
- // THE FEATURE IS OFF WITH A LAYOUT SAVED — the state a user is in for most of
242
- // the time they are composing, and the one the gate card exists for. Line 1 is
243
- // at 5/5; line 3 is empty, so the board can show a full line and an ordinary
244
- // one at once.
245
- const show = {
246
- ok: false,
247
- enabled: false,
248
- saved: true,
249
- preset: null,
250
- theme: "terminal",
251
- glyphs: "blocks",
252
- ansi: "auto",
253
- align_columns: false,
254
- lines: [
255
- {
256
- line: 1, separator: " · ", theme: null, max_width: 0, count: 5, counted: 5, full: true,
257
- items: [
258
- { 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 },
259
- { 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 },
260
- { 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 },
261
- { 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 },
262
- { 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 },
263
- ],
264
- },
265
- {
266
- line: 2, separator: " · ", theme: null, max_width: 0, count: 2, counted: 2, full: false,
267
- items: [
268
- { 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 },
269
- // AN UNKNOWN COMPONENT ID — what an upgrade that retired a component
270
- // leaves behind. Reported, never auto-repaired.
271
- { 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 },
272
- ],
273
- },
274
- { line: 3, separator: " · ", theme: null, max_width: 0, count: 0, counted: 0, full: false, items: [] },
275
- ],
276
- // ONE HARD ERROR and TWO WARNINGS, so the caution strip can show that an error
277
- // is a refusal and a warning is a fact the user then owns.
278
- errors: ['unknown component "retired-thing" on line 2 position 2 — did you mean "resume"?'],
279
- warnings: [
280
- "line 1 shows the same value twice (context, context)",
281
- '"verdict" carries meaning in its colour (ready/boosted/degrade) and you set a flat colour — a green ⛔ is a status line that lies',
282
- ],
283
- preview: previewText,
284
- dense_prefix: components.dense_prefix,
285
- };
286
-
287
- const presets = {
288
- ok: true,
289
- presets: [
290
- { name: "orc-default", summary: "Today's two lines, exactly. The byte-identical baseline.", active: false, preview: previewNoColor.split("\n").slice(0, 2).join("\n") },
291
- { 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.5/high · ") + amber("███▊ ") + dim(" · main") },
292
- { 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") },
293
- { name: "mono", summary: "No colour anywhere — shapes and emphasis only. The right preset for a README screenshot.", active: false, preview: previewNoColor },
294
- ],
295
- };
296
-
297
- const explain = {
298
- ok: true,
299
- id: "i2",
300
- type: "context",
301
- line: 1,
302
- pos: 2,
303
- resolved: [
304
- { field: "render", value: "bar", source: "item" },
305
- { field: "label", value: "CTX", source: "item" },
306
- { field: "label_color", value: "bright-black", source: "theme:terminal" },
307
- { field: "glyphs", value: "blocks", source: "file" },
308
- { field: "min_width", value: 3, source: "catalogue" },
309
- { field: "ramp", value: "heat", source: "catalogue" },
310
- ],
311
- order: ["catalogue", "theme", "file", "line", "item"],
312
- };
313
-
314
-
315
- // ── the SECOND board (v1.4.0) ──────────────────────────────────────────────
316
- // A designer cannot lay out a per-agent row against the status line's
317
- // components, so the fixture set carries both boards. Same rule as everywhere
318
- // else here: one of every state, including the ugly ones — a failed agent, an
319
- // agent whose window size is unknown, and one whose token count has not been
320
- // seen yet.
321
- const subComponents = {
322
- ok: true,
323
- schema: 1,
324
- catalog_hash: components.catalog_hash,
325
- count: 4,
326
- board: "subagent",
327
- boards: ["status", "subagent"],
328
- config_key: "subagent_line_custom",
329
- setting: "subagentStatusLine",
330
- groups: { T: "One subagent (the agent-panel row)" },
331
- components: [
332
- {
333
- id: "task-name", group: "T", board: "subagent", label: null,
334
- summary: "The agent's name.",
335
- renderers: ["bare", "plain", "badge", "pill"],
336
- defaults: { render: "bare", truncate: "middle", max_len: 28 },
337
- states: null, shapes: null, bounded: false, series: null,
338
- unknown: "dash", cost: "free", refused_reason: null, params: null,
339
- binding: "task.name", composite: null, time_based: false, structural: false,
340
- 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" },
341
- },
342
- {
343
- id: "task-tier", group: "T", board: "subagent", label: null,
344
- summary: "The model and effort this agent is ACTUALLY running at — observed, not derived from its name and not self-reported.",
345
- renderers: ["bare", "plain", "label-value", "badge"],
346
- defaults: { render: "bare" },
347
- states: null, shapes: null, bounded: false, series: null,
348
- unknown: "dash", cost: "free", refused_reason: null, params: null,
349
- binding: "task.tier", composite: null, time_based: false, structural: false,
350
- previews: { bare: "O5/low", plain: dim("tier ") + "O5/low", "label-value": dim("TIER: ") + "O5/low", badge: "▏O5/low▕" },
351
- },
352
- {
353
- id: "task-tokens", group: "T", board: "subagent", label: null,
354
- summary: "How many tokens this agent has used. THE NUMBER v1.2.0 SAID COULD NOT BE MEASURED.",
355
- renderers: ["plain", "label-value", "bare"],
356
- defaults: { render: "plain", compact: "si" },
357
- states: null, shapes: null, bounded: false, series: null,
358
- unknown: "dash", cost: "free", refused_reason: null, params: null,
359
- binding: "task.tokens", composite: null, time_based: false, structural: false,
360
- previews: { plain: "84K", "label-value": dim("TOKENS: ") + "84K", bare: "84K" },
361
- },
362
- {
363
- id: "task-status", group: "T", board: "subagent", label: null,
364
- summary: "What this agent is doing.",
365
- renderers: ["word", "shape", "badge", "bare"],
366
- defaults: { render: "word" },
367
- states: ["pending", "running", "completed", "failed"],
368
- shapes: { pending: "○", running: "●", completed: "✓", failed: "▲" },
369
- bounded: false, series: null, unknown: "dash", cost: "free",
370
- refused_reason: null, params: null, binding: "task.status",
371
- composite: null, time_based: false, structural: false,
372
- previews: { word: amber("running"), shape: amber("●"), badge: "▏" + amber("running") + "▕", bare: "running" },
373
- },
374
- ],
375
- renderers: components.renderers,
376
- glyph_sets: components.glyph_sets,
377
- ramps: components.ramps,
378
- themes: components.themes,
379
- hide_when: components.hide_when,
380
- formats: components.formats,
381
- compact: components.compact,
382
- cases: components.cases,
383
- truncate: components.truncate,
384
- emphasis: components.emphasis,
385
- refused_emphasis: components.refused_emphasis,
386
- colors: components.colors,
387
- separators: components.separators,
388
- themes_about: components.themes_about,
389
- max_per_line: 5,
390
- // ONE LINE by construction: Claude Code renders one row per task.
391
- lines: 1,
392
- dense_prefix: components.dense_prefix,
393
- };
394
-
395
- const subShow = {
396
- ok: true,
397
- enabled: true,
398
- saved: true,
399
- preset: "agent-default",
400
- theme: "terminal",
401
- glyphs: "blocks",
402
- ansi: "auto",
403
- align_columns: false,
404
- lines: [
405
- {
406
- line: 1, separator: " · ", theme: null, max_width: 0, count: 4, counted: 4, full: false,
407
- items: [
408
- { 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 },
409
- { 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 },
410
- { 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 },
411
- { 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 },
412
- ],
413
- },
414
- ],
415
- errors: [],
416
- // A layout can be perfectly valid and still worth a caution.
417
- warnings: ["task-tokens is a FLOOR: an agent that finishes between two redraws is never counted"],
418
- preview: amber("●") + " orc-executor-opus-5-low · " + dim("O5/low") + " · 84K",
419
- dense_prefix: components.dense_prefix,
420
- };
421
-
422
- const subPresets = {
423
- ok: true,
424
- presets: [
425
- { 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" },
426
- { 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" },
427
- { 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-5 · low · " + amber("running") },
428
- ],
429
- };
430
-
431
- module.exports = { show, components, presets, preview, explain, subShow, subComponents, subPresets };
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.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.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.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: 8,
86
+ inherit_token: "inherit",
87
+ groups: { A: "Session and tier", B: "Quota and spend", D: "Knowledge", H: "Project and VCS", M: "Pets and motion" },
88
+ components: [
89
+ {
90
+ id: "verdict", group: "A", label: null,
91
+ summary: "The ORC-ready verdict icon.",
92
+ renderers: ["icon", "shape", "word", "badge"],
93
+ defaults: { render: "icon" },
94
+ states: ["ready", "boosted", "degrade"],
95
+ shapes: { ready: "✅", boosted: "🚀", degrade: "⛔" },
96
+ bounded: false, series: null, unknown: "dash", cost: "free",
97
+ refused_reason: null, params: null, binding: "verdict.state",
98
+ composite: null, time_based: false, structural: false,
99
+ previews: { icon: "🚀", shape: "🚀", word: green("boosted"), badge: "▏🚀▕" },
100
+ },
101
+ {
102
+ id: "context", group: "A", label: "context",
103
+ summary: "How full the context window is.",
104
+ renderers: ["plain", "label-value", "bar", "blocks", "fine", "dots", "gauge", "ring", "bare"],
105
+ defaults: { render: "plain", format: "percent", min_width: 3, align: "right", ramp: "heat" },
106
+ states: ["ok", "warn", "full"],
107
+ shapes: { ok: "●", warn: "◐", full: "○" },
108
+ bounded: true, series: null, unknown: "dash", cost: "free",
109
+ refused_reason: null, params: null, binding: "ctx.used_pct",
110
+ composite: null, time_based: false, structural: false,
111
+ previews: P("context"),
112
+ },
113
+ {
114
+ id: "quota-5h", group: "B", label: "5h",
115
+ summary: "The 5-hour usage window.",
116
+ renderers: ["plain", "bar", "blocks", "spark", "bare"],
117
+ defaults: { render: "plain", format: "percent", min_width: 3, align: "right", ramp: "heat" },
118
+ states: ["ok", "warn", "critical"],
119
+ shapes: { ok: "●", warn: "◐", critical: "○" },
120
+ bounded: true, series: "quota5h", unknown: "dash", cost: "free",
121
+ refused_reason: null, params: null, binding: "quota.5h.pct",
122
+ composite: null, time_based: false, structural: false,
123
+ previews: P("5h"),
124
+ },
125
+ // A COMPONENT RENDERING AN EM DASH. Its file does not exist in this
126
+ // project, so it says so — and it is still placeable, because `—` and "this
127
+ // build has no such segment" are different facts.
128
+ {
129
+ id: "wiki", group: "D", label: "wiki",
130
+ summary: "How old the project wiki is, from the wiki's own oldest anchor.",
131
+ renderers: ["word", "shape", "badge"],
132
+ defaults: { render: "word" },
133
+ states: ["fresh", "aging", "stale", "unregistered", "none"],
134
+ shapes: { fresh: "●", aging: "◐", stale: "○", unregistered: "?", none: "·" },
135
+ bounded: false, series: null, unknown: "dash", cost: "new-read",
136
+ refused_reason: null, params: null, binding: "wiki.tier",
137
+ composite: null, time_based: false, structural: false,
138
+ previews: { word: "—", shape: "—", badge: "▏—▕" },
139
+ },
140
+ {
141
+ id: "branch", group: "H", label: null,
142
+ summary: "The current git branch, read from .git/HEAD with NO subprocess.",
143
+ renderers: ["bare", "plain", "badge"],
144
+ defaults: { render: "bare", truncate: "middle", max_len: 24 },
145
+ states: null, shapes: null, bounded: false, series: null,
146
+ unknown: "hide", cost: "scan", refused_reason: null, params: null,
147
+ binding: "git.branch", composite: null, time_based: false, structural: false,
148
+ previews: { bare: "main", plain: dim("branch ") + "main", badge: "▏main▕" },
149
+ },
150
+ // A REFUSED ROW. It keeps its slot, carries the measurement, and gets NO
151
+ // BUTTON AT ALL — never a disabled one. "We decided against this" and "we
152
+ // forgot" must not look the same.
153
+ {
154
+ id: "git-dirty", group: "H", label: "±",
155
+ summary: "Uncommitted changes.",
156
+ renderers: ["plain", "label-value", "bare"],
157
+ defaults: { render: "plain" },
158
+ states: null, shapes: null, bounded: false, series: null,
159
+ unknown: "dash", cost: "refused",
160
+ refused_reason:
161
+ "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.",
162
+ params: null, binding: null, composite: null, time_based: false, structural: false,
163
+ previews: {},
164
+ },
165
+ // v2.0.4 — a PET and the WEATHER, both in the new group "M".
166
+ {
167
+ id: "pet-cat", group: "M", label: null,
168
+ summary: "A small cat that runs along the line. It moves only when the status line redraws.",
169
+ renderers: ["run", "bounce", "idle"],
170
+ defaults: { render: "run", width: 12 },
171
+ states: null, shapes: null, bounded: false, series: null,
172
+ unknown: "hide", cost: "free", refused_reason: null, params: null,
173
+ binding: null, composite: null, time_based: true, structural: false,
174
+ previews: { run: " =^.^= ", bounce: " =^.^= ", idle: "=^.^= " },
175
+ },
176
+ {
177
+ id: "weather", group: "M", label: null,
178
+ summary: "The temperature where you are, from a cached read.",
179
+ renderers: ["bare", "plain", "badge"],
180
+ defaults: { render: "bare" },
181
+ states: null, shapes: null, bounded: false, series: null,
182
+ unknown: "hide", cost: "new-read", refused_reason: null, params: null,
183
+ binding: "weather.temp", composite: null, time_based: false, structural: false,
184
+ previews: { bare: "21°C", plain: dim("weather ") + "21°C", badge: "▏21°C▕" },
185
+ },
186
+ ],
187
+ renderers: {
188
+ bare: { kind: "text", form: "value", needs: null, width: null, decoration: false },
189
+ plain: { kind: "text", form: "label value", needs: null, width: null, decoration: false },
190
+ "label-value": { kind: "text", form: "LABEL: value", needs: null, width: null, decoration: false },
191
+ bracket: { kind: "text", form: "[LABEL: value]", needs: null, width: null, decoration: false },
192
+ paren: { kind: "text", form: "(value)", needs: null, width: null, decoration: false },
193
+ badge: { kind: "text", form: "▏LABEL value▕", needs: null, width: null, decoration: false },
194
+ pill: { kind: "text", form: "⟪LABEL⟫value", needs: null, width: null, decoration: false },
195
+ word: { kind: "text", form: "STATE", needs: "states", width: null, decoration: false },
196
+ bar: { kind: "bar", form: null, needs: "bounded", width: [4, 16], decoration: false },
197
+ blocks: { kind: "bar", form: null, needs: "bounded", width: [2, 16], decoration: false },
198
+ fine: { kind: "bar", form: null, needs: "bounded", width: [2, 16], decoration: false },
199
+ dots: { kind: "bar", form: null, needs: "ordinal", width: [2, 10], decoration: false },
200
+ gauge: { kind: "bar", form: null, needs: "bounded", width: [1, 1], decoration: false },
201
+ ring: { kind: "bar", form: null, needs: "bounded", width: [1, 1], decoration: false },
202
+ shape: { kind: "state", form: null, needs: "states", width: null, decoration: false },
203
+ icon: { kind: "state", form: null, needs: "states", width: null, decoration: false },
204
+ spark: { kind: "series", form: null, needs: "series", width: [4, 16], decoration: false },
205
+ trend: { kind: "series", form: null, needs: "series", width: null, decoration: false },
206
+ run: { kind: "sprite", form: null, needs: null, width: [6, 40], decoration: false },
207
+ bounce: { kind: "sprite", form: null, needs: null, width: [6, 40], decoration: false },
208
+ idle: { kind: "sprite", form: null, needs: null, width: [6, 40], decoration: false },
209
+ },
210
+ glyph_sets: ["blocks", "bars", "pipes", "braille", "shade", "minimal", "ascii"],
211
+ ramps: {
212
+ heat: { stops: [0, 60, 85], colors: ["green", "yellow", "red"], why: "high is bad" },
213
+ cool: { stops: [0, 60, 85], colors: ["red", "yellow", "green"], why: "high is good" },
214
+ mono: { stops: [0, 60, 85], colors: [null, null, null], why: "NO_COLOR-safe: emphasis, not hue" },
215
+ state: { stops: null, colors: null, why: "the component's own state colours" },
216
+ },
217
+ themes: {
218
+ terminal: { ok: "green", warn: "yellow", critical: "red", muted: "bright-black", accent: "cyan", label: "bright-black", value: "default" },
219
+ dim: { ok: "green", warn: "yellow", critical: "red", muted: "bright-black", accent: "bright-black", label: "bright-black", value: "bright-black" },
220
+ "high-contrast": { ok: "bright-green", warn: "bright-yellow", critical: "bright-red", muted: "white", accent: "bright-cyan", label: "bright-white", value: "bright-white" },
221
+ mono: { ok: null, warn: null, critical: null, muted: null, accent: null, label: null, value: null },
222
+ },
223
+ hide_when: [
224
+ { id: "never", says: "always render. A state keeps its slot." },
225
+ { id: "empty", says: "hide when the value is absent" },
226
+ { id: "zero", says: "hide when the value is exactly 0" },
227
+ { id: "unknown", says: "hide when the value could not be computed" },
228
+ { id: "ok", says: "hide while healthy — show me only problems" },
229
+ { id: "idle", says: "hide when no run is active" },
230
+ { id: "no-run", says: "hide when no ORC run was opened this session" },
231
+ { id: "narrow", says: "hide below this component's min_cols" },
232
+ { id: "wide", says: "hide above this component's max_cols" },
233
+ ],
234
+ formats: ["percent", "ratio", "fraction", "decimal", "plain"],
235
+ compact: ["off", "si", "bytes"],
236
+ cases: ["none", "upper", "lower", "title", "small", "super", "sub"],
237
+ // v2.0.4 — what each case looks like, and every design option list the
238
+ // editor reads (contract §5). The panel names none of these itself.
239
+ case_samples: { none: "Weekly 61", upper: "WEEKLY 61", lower: "weekly 61", title: "Weekly 61", small: "ᴡᴇᴇᴋʟʏ 61", super: "ʷᵉᵉᵏˡʸ ⁶¹", sub: "wₑₑₖₗy ₆₁" },
240
+ label_positions: ["before", "after", "above", "below"],
241
+ value_positions: ["none", "before", "after"],
242
+ caption_positions: ["above", "below"],
243
+ caption_aligns: ["left", "center", "right"],
244
+ aligns: ["left", "right"],
245
+ signs: ["auto", "always", "never"],
246
+ unknowns: ["dash", "hide"],
247
+ line_aligns: ["left", "center", "right"],
248
+ caption_tokens: ["{value}", "{label}"],
249
+ limits: { caption: 40, max_len: 60, padding: 8, ramp_colors: [2, 8], brackets: 3, param_text: 60 },
250
+ truncate: ["end", "middle", "none"],
251
+ emphasis: ["normal", "bold", "dim", "italic", "underline", "reverse", "strike"],
252
+ refused_emphasis: ["blink"],
253
+ colors: ["red", "green", "yellow", "blue", "magenta", "cyan", "bright-black", "bright-cyan", "default"],
254
+ separators: [
255
+ { value: " · ", name: "middle dot" },
256
+ { value: " ", name: "one space" },
257
+ { value: " ", name: "two spaces" },
258
+ { value: " │ ", name: "upright line" },
259
+ { value: " — ", name: "long dash" },
260
+ { value: " - ", name: "hyphen" },
261
+ { value: " / ", name: "slash" },
262
+ { value: " • ", name: "bullet" },
263
+ { value: " ▸ ", name: "small arrow" },
264
+ { value: " » ", name: "double arrow" },
265
+ { value: ", ", name: "comma" },
266
+ { value: " | ", name: "pipe" },
267
+ ],
268
+ themes_about: {
269
+ terminal: "the default: your terminal's own colours, one accent",
270
+ dim: "everything quiet — labels and values both greyed",
271
+ "high-contrast": "the brightest slot of every colour, for a pale terminal",
272
+ mono: "no colour at all; weight and shape carry every state",
273
+ },
274
+ max_per_line: 5,
275
+ lines: 3,
276
+ dense_prefix: "A line may hold a component only if every line above it holds at least one.",
277
+ };
278
+
279
+ // v2.0.4 — WHAT EACH SHAPE USES (contract §5), so the editor can grey out a
280
+ // field the shape ignores. Written once per kind, as the CLI lists them.
281
+ const USES_ALL = ["label", "label_pos", "caption", "caption_pos", "caption_align", "caption_color", "caption_case", "brackets", "padding", "prefix", "suffix"];
282
+ const USES_KIND = {
283
+ text: ["case", "format", "compact", "min_width", "precision", "align", "sign", "max_len"],
284
+ bar: ["width", "ramp", "value_pos", "fill_color", "empty_color", "fill_char", "empty_char", "ramp_colors", "ramp_stops"],
285
+ series: ["width", "value_pos", "fill_color"],
286
+ state: ["glyph_by_state"],
287
+ };
288
+ for (const r of Object.values(components.renderers)) r.uses = USES_ALL.concat(USES_KIND[r.kind] || []);
289
+
290
+ // THE FEATURE IS OFF WITH A LAYOUT SAVED — the state a user is in for most of
291
+ // the time they are composing, and the one the gate card exists for. Line 1 is
292
+ // at 5/5; line 3 is empty, so the board can show a full line and an ordinary
293
+ // one at once.
294
+ const show = {
295
+ ok: false,
296
+ enabled: false,
297
+ saved: true,
298
+ preset: null,
299
+ theme: "terminal",
300
+ glyphs: "blocks",
301
+ ansi: "auto",
302
+ align_columns: false,
303
+ lines: [
304
+ {
305
+ line: 1, separator: " · ", theme: null, max_width: 0, count: 5, counted: 5, full: true, align: null, sep_color: "bright-black", prefix: "",
306
+ items: [
307
+ { 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 },
308
+ { 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 },
309
+ { 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 },
310
+ { 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 },
311
+ { 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 },
312
+ ],
313
+ },
314
+ {
315
+ line: 2, separator: " · ", theme: null, max_width: 0, count: 2, counted: 2, full: false, align: null, sep_color: null, prefix: " ",
316
+ items: [
317
+ { 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 },
318
+ // AN UNKNOWN COMPONENT ID — what an upgrade that retired a component
319
+ // leaves behind. Reported, never auto-repaired.
320
+ { 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 },
321
+ ],
322
+ },
323
+ { line: 3, separator: " · ", theme: null, max_width: 0, count: 0, counted: 0, full: false, align: null, sep_color: null, prefix: "", items: [] },
324
+ ],
325
+ // ONE HARD ERROR and TWO WARNINGS, so the caution strip can show that an error
326
+ // is a refusal and a warning is a fact the user then owns.
327
+ errors: ['unknown component "retired-thing" on line 2 position 2 — did you mean "resume"?'],
328
+ // v2.0.4 — the redraw timer is off and nothing on this board moves.
329
+ refresh_interval: null,
330
+ needs_refresh: null,
331
+ animated: false,
332
+ warnings: [
333
+ "line 1 shows the same value twice (context, context)",
334
+ '"verdict" carries meaning in its colour (ready/boosted/degrade) and you set a flat colour — a green ⛔ is a status line that lies',
335
+ ],
336
+ preview: previewText,
337
+ dense_prefix: components.dense_prefix,
338
+ };
339
+
340
+ const presets = {
341
+ ok: true,
342
+ presets: [
343
+ { name: "orc-default", summary: "Today's two lines, exactly. The byte-identical baseline.", active: false, preview: previewNoColor.split("\n").slice(0, 2).join("\n") },
344
+ { 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.5/high · ") + amber("███▊ ") + dim(" · main") },
345
+ { 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") },
346
+ { name: "mono", summary: "No colour anywhere — shapes and emphasis only. The right preset for a README screenshot.", active: false, preview: previewNoColor },
347
+ ],
348
+ };
349
+
350
+ const explain = {
351
+ ok: true,
352
+ id: "i2",
353
+ type: "context",
354
+ line: 1,
355
+ pos: 2,
356
+ resolved: [
357
+ { field: "render", value: "bar", source: "item" },
358
+ { field: "label", value: "CTX", source: "item" },
359
+ { field: "label_color", value: "bright-black", source: "theme:terminal" },
360
+ { field: "glyphs", value: "blocks", source: "file" },
361
+ { field: "min_width", value: 3, source: "catalogue" },
362
+ { field: "ramp", value: "heat", source: "catalogue" },
363
+ ],
364
+ order: ["catalogue", "theme", "file", "line", "item"],
365
+ };
366
+
367
+
368
+ // ── the SECOND board (v1.4.0) ──────────────────────────────────────────────
369
+ // A designer cannot lay out a per-agent row against the status line's
370
+ // components, so the fixture set carries both boards. Same rule as everywhere
371
+ // else here: one of every state, including the ugly ones — a failed agent, an
372
+ // agent whose window size is unknown, and one whose token count has not been
373
+ // seen yet.
374
+ const subComponents = {
375
+ ok: true,
376
+ schema: 1,
377
+ catalog_hash: components.catalog_hash,
378
+ count: 4,
379
+ inherit_token: components.inherit_token,
380
+ board: "subagent",
381
+ boards: ["status", "subagent"],
382
+ config_key: "subagent_line_custom",
383
+ setting: "subagentStatusLine",
384
+ groups: { T: "One subagent (the agent-panel row)" },
385
+ components: [
386
+ {
387
+ id: "task-name", group: "T", board: "subagent", label: null,
388
+ summary: "The agent's name.",
389
+ renderers: ["bare", "plain", "badge", "pill"],
390
+ defaults: { render: "bare", truncate: "middle", max_len: 28 },
391
+ states: null, shapes: null, bounded: false, series: null,
392
+ unknown: "dash", cost: "free", refused_reason: null, params: null,
393
+ binding: "task.name", composite: null, time_based: false, structural: false,
394
+ 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" },
395
+ },
396
+ {
397
+ id: "task-tier", group: "T", board: "subagent", label: null,
398
+ summary: "The model and effort this agent is ACTUALLY running at — observed, not derived from its name and not self-reported.",
399
+ renderers: ["bare", "plain", "label-value", "badge"],
400
+ defaults: { render: "bare" },
401
+ states: null, shapes: null, bounded: false, series: null,
402
+ unknown: "dash", cost: "free", refused_reason: null, params: null,
403
+ binding: "task.tier", composite: null, time_based: false, structural: false,
404
+ previews: { bare: "O5/low", plain: dim("tier ") + "O5/low", "label-value": dim("TIER: ") + "O5/low", badge: "▏O5/low▕" },
405
+ },
406
+ {
407
+ id: "task-tokens", group: "T", board: "subagent", label: null,
408
+ summary: "How many tokens this agent has used. THE NUMBER v1.2.0 SAID COULD NOT BE MEASURED.",
409
+ renderers: ["plain", "label-value", "bare"],
410
+ defaults: { render: "plain", compact: "si" },
411
+ states: null, shapes: null, bounded: false, series: null,
412
+ unknown: "dash", cost: "free", refused_reason: null, params: null,
413
+ binding: "task.tokens", composite: null, time_based: false, structural: false,
414
+ previews: { plain: "84K", "label-value": dim("TOKENS: ") + "84K", bare: "84K" },
415
+ },
416
+ {
417
+ id: "task-status", group: "T", board: "subagent", label: null,
418
+ summary: "What this agent is doing.",
419
+ renderers: ["word", "shape", "badge", "bare"],
420
+ defaults: { render: "word" },
421
+ states: ["pending", "running", "completed", "failed"],
422
+ shapes: { pending: "○", running: "●", completed: "✓", failed: "▲" },
423
+ bounded: false, series: null, unknown: "dash", cost: "free",
424
+ refused_reason: null, params: null, binding: "task.status",
425
+ composite: null, time_based: false, structural: false,
426
+ previews: { word: amber("running"), shape: amber("●"), badge: "▏" + amber("running") + "▕", bare: "running" },
427
+ },
428
+ ],
429
+ renderers: components.renderers,
430
+ glyph_sets: components.glyph_sets,
431
+ ramps: components.ramps,
432
+ themes: components.themes,
433
+ hide_when: components.hide_when,
434
+ formats: components.formats,
435
+ compact: components.compact,
436
+ cases: components.cases,
437
+ case_samples: components.case_samples,
438
+ label_positions: components.label_positions,
439
+ value_positions: components.value_positions,
440
+ caption_positions: components.caption_positions,
441
+ caption_aligns: components.caption_aligns,
442
+ aligns: components.aligns,
443
+ signs: components.signs,
444
+ unknowns: components.unknowns,
445
+ line_aligns: components.line_aligns,
446
+ caption_tokens: components.caption_tokens,
447
+ limits: components.limits,
448
+ truncate: components.truncate,
449
+ emphasis: components.emphasis,
450
+ refused_emphasis: components.refused_emphasis,
451
+ colors: components.colors,
452
+ separators: components.separators,
453
+ themes_about: components.themes_about,
454
+ max_per_line: 5,
455
+ // ONE LINE by construction: Claude Code renders one row per task.
456
+ lines: 1,
457
+ dense_prefix: components.dense_prefix,
458
+ };
459
+
460
+ const subShow = {
461
+ ok: true,
462
+ enabled: true,
463
+ saved: true,
464
+ preset: "agent-default",
465
+ theme: "terminal",
466
+ glyphs: "blocks",
467
+ ansi: "auto",
468
+ align_columns: false,
469
+ lines: [
470
+ {
471
+ line: 1, separator: " · ", theme: null, max_width: 0, count: 4, counted: 4, full: false, align: null, sep_color: null, prefix: "",
472
+ items: [
473
+ { 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 },
474
+ { 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 },
475
+ { 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 },
476
+ { 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 },
477
+ ],
478
+ },
479
+ ],
480
+ errors: [],
481
+ refresh_interval: null,
482
+ needs_refresh: null,
483
+ animated: false,
484
+ // A layout can be perfectly valid and still worth a caution.
485
+ warnings: ["task-tokens is a FLOOR: an agent that finishes between two redraws is never counted"],
486
+ preview: amber("●") + " orc-executor-opus-5-low · " + dim("O5/low") + " · 84K",
487
+ dense_prefix: components.dense_prefix,
488
+ };
489
+
490
+ const subPresets = {
491
+ ok: true,
492
+ presets: [
493
+ { 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" },
494
+ { 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" },
495
+ { 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-5 · low · " + amber("running") },
496
+ ],
497
+ };
498
+
499
+ // v2.0.3 — the hook block (C7) and one `sample` per item: that item rendered
500
+ // alone with its SAVED design. Both boards run this layout, so `match` is true.
501
+ for (const s of [show, subShow]) {
502
+ s.hook = { path: ".claude/hooks/orc-statusline.js", version: "2.0.3", catalog_hash: components.catalog_hash, cli_version: "2.0.3", match: true, fallback: null, fix: null };
503
+ for (const l of s.lines) for (const it of l.items) it.sample = it.label ? dim(it.label + " ") + it.type : it.type;
504
+ }
505
+
506
+ module.exports = { show, components, presets, preview, explain, subShow, subComponents, subPresets };