@azure-id/orc 1.9.2 → 2.1.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.
Files changed (228) hide show
  1. package/CHANGELOG.md +722 -0
  2. package/README-id.md +56 -42
  3. package/README.md +58 -41
  4. package/bin/build-agents.js +125 -29
  5. package/bin/clear-logs.js +620 -0
  6. package/bin/cli.js +1873 -180
  7. package/bin/fix.js +459 -0
  8. package/bin/gotcha-import.js +1081 -0
  9. package/bin/gotcha.js +1566 -0
  10. package/bin/graph-query.js +1 -1
  11. package/bin/graph.js +717 -717
  12. package/bin/habit.js +1538 -0
  13. package/bin/mockrun-catalog.js +284 -276
  14. package/bin/onboarding-content.js +2 -1
  15. package/bin/pricing.json +28 -21
  16. package/bin/run-undo.js +398 -0
  17. package/bin/trace-write.js +869 -0
  18. package/bin/verify-contracts.js +627 -100
  19. package/bin/verify-package.js +68 -10
  20. package/bin/webui/api.js +151 -6
  21. package/bin/webui/app.html +239 -232
  22. package/bin/webui/css/00-tokens.css +110 -92
  23. package/bin/webui/css/04-motion.css +87 -0
  24. package/bin/webui/css/06-responsive.css +203 -178
  25. package/bin/webui/css/panels/behaviour.css +205 -0
  26. package/bin/webui/css/panels/hookui.css +79 -0
  27. package/bin/webui/fixtures/behaviour.js +562 -0
  28. package/bin/webui/fixtures/extra.js +9 -9
  29. package/bin/webui/fixtures/flow.js +81 -81
  30. package/bin/webui/fixtures/hookui.js +506 -431
  31. package/bin/webui/fixtures/index.js +66 -3
  32. package/bin/webui/fixtures/knowledge.js +9 -3
  33. package/bin/webui/fixtures/maintenance.js +123 -42
  34. package/bin/webui/fixtures/rules.js +1007 -1002
  35. package/bin/webui/fixtures/settings.js +6 -7
  36. package/bin/webui/fixtures/stats.js +25 -6
  37. package/bin/webui/fixtures/wait.js +98 -97
  38. package/bin/webui/i18n/en/behaviour.json +156 -0
  39. package/bin/webui/i18n/en/hookui.json +290 -194
  40. package/bin/webui/i18n/en/maintenance.json +71 -52
  41. package/bin/webui/i18n/en/nav.json +25 -24
  42. package/bin/webui/i18n/en/settings.json +60 -60
  43. package/bin/webui/i18n/en/tour.json +37 -35
  44. package/bin/webui/i18n/id/behaviour.json +156 -0
  45. package/bin/webui/i18n/id/hookui.json +290 -194
  46. package/bin/webui/i18n/id/maintenance.json +71 -52
  47. package/bin/webui/i18n/id/nav.json +25 -24
  48. package/bin/webui/i18n/id/settings.json +60 -60
  49. package/bin/webui/i18n/id/tour.json +37 -35
  50. package/bin/webui/js/01-i18n.js +155 -154
  51. package/bin/webui/js/05-banners.js +181 -172
  52. package/bin/webui/js/06-edit.js +193 -183
  53. package/bin/webui/js/90-tour.js +498 -494
  54. package/bin/webui/js/91-shortcuts.js +126 -126
  55. package/bin/webui/js/99-boot.js +121 -118
  56. package/bin/webui/js/panels/behaviour.js +1087 -0
  57. package/bin/webui/js/panels/hookui.js +2196 -1691
  58. package/bin/webui/js/panels/maintenance.js +336 -235
  59. package/bin/webui/js/panels/settings.js +726 -719
  60. package/mock-run/INDEX.md +110 -107
  61. package/mock-run/extra-slots.md +1 -1
  62. package/mock-run/gotcha-import.md +118 -0
  63. package/mock-run/habits.md +129 -0
  64. package/mock-run/orc-aftermath.md +392 -392
  65. package/mock-run/orc-budget.md +29 -33
  66. package/mock-run/orc-cli.md +200 -200
  67. package/mock-run/orc-explain.md +86 -86
  68. package/mock-run/orc-extra.md +389 -392
  69. package/mock-run/orc-fix.md +87 -0
  70. package/mock-run/orc-pattern.md +112 -112
  71. package/mock-run/orc-quick.md +6 -1
  72. package/mock-run/orc.md +157 -157
  73. package/package.json +1 -1
  74. package/templates/agents/MODEL-MAPPING.md +37 -34
  75. package/templates/agents/orc-advisor-opus-5-xhigh.md +1 -7
  76. package/templates/agents/orc-analyze-mini-opus-5-med.md +1 -6
  77. package/templates/agents/orc-analyze-mini-sonnet-5-high.md +2 -5
  78. package/templates/agents/{orc-claude-writer-opus-4-8-high.md → orc-claude-writer-opus-5-low.md} +48 -53
  79. package/templates/agents/orc-context-combiner-opus-5-high.md +1 -11
  80. package/templates/agents/orc-executor-haiku-4-5.md +14 -6
  81. package/templates/agents/orc-executor-opus-4-7-high.md +14 -6
  82. package/templates/agents/orc-executor-opus-4-7-med.md +14 -6
  83. package/templates/agents/orc-executor-opus-4-8-high.md +14 -6
  84. package/templates/agents/orc-executor-opus-5-high.md +14 -6
  85. package/templates/agents/orc-executor-opus-5-low.md +14 -6
  86. package/templates/agents/orc-executor-opus-5-med.md +14 -6
  87. package/templates/agents/orc-executor-sonnet-4-6-high.md +14 -6
  88. package/templates/agents/orc-executor-sonnet-4-6-med.md +14 -6
  89. package/templates/agents/orc-executor-sonnet-5-high.md +15 -7
  90. package/templates/agents/orc-executor-sonnet-5-low.md +155 -0
  91. package/templates/agents/orc-executor-sonnet-5-med.md +155 -0
  92. package/templates/agents/orc-graph-noter-sonnet-4-6-med.md +1 -10
  93. package/templates/agents/orc-judge-opus-5-xhigh.md +5 -9
  94. package/templates/agents/orc-learn-writer-opus-5-low.md +1 -7
  95. package/templates/agents/orc-pattern-codifier-opus-5-med.md +1 -8
  96. package/templates/agents/orc-pattern-codifier-sonnet-5-high.md +58 -63
  97. package/templates/agents/orc-planner-mini-opus-5-med.md +1 -4
  98. package/templates/agents/orc-planner-mini-sonnet-5-high.md +2 -3
  99. package/templates/agents/orc-planner-opus-5-med.md +1 -4
  100. package/templates/agents/orc-recon-opus-5-low.md +1 -8
  101. package/templates/agents/orc-recon-sonnet-4-6-med.md +1 -8
  102. package/templates/agents/orc-retro-opus-5-med.md +6 -8
  103. package/templates/agents/orc-retro-sonnet-5-high.md +7 -8
  104. package/templates/agents/orc-reviewer-opus-5-low.md +96 -0
  105. package/templates/agents/orc-scout-opus-5-low.md +1 -6
  106. package/templates/agents/orc-scout-sonnet-4-6-high.md +35 -39
  107. package/templates/agents/orc-system-analyst-opus-5-high.md +1 -6
  108. package/templates/agents/orc-test-author-opus-5-med.md +4 -5
  109. package/templates/agents/orc-trace-writer-haiku-4-5.md +3 -7
  110. package/templates/agents/orc-verifier-opus-5-med.md +16 -8
  111. package/templates/agents/{orc-wiki-scanner-opus-4-8-high.md → orc-wiki-scanner-opus-5-low.md} +74 -79
  112. package/templates/agents/orc-wiki-scanner-sonnet-5-high.md +97 -106
  113. package/templates/commands/orc-analyze.md +13 -21
  114. package/templates/commands/orc-fast.md +10 -15
  115. package/templates/commands/orc-fix.md +18 -0
  116. package/templates/commands/orc-poly.md +12 -21
  117. package/templates/commands/orc-pr-driver.md +11 -30
  118. package/templates/commands/orc-pr-setup.md +10 -31
  119. package/templates/commands/orc-route.md +11 -41
  120. package/templates/commands/orc-test.md +5 -60
  121. package/templates/commands/orc-wiki.md +64 -64
  122. package/templates/hooks/README.md +109 -7
  123. package/templates/hooks/orc-session-hook.js +339 -0
  124. package/templates/hooks/orc-statusline-render.js +317 -23
  125. package/templates/hooks/orc-statusline.js +165 -50
  126. package/templates/hooks/orc-subagent-line.js +23 -5
  127. package/templates/hooks/orc-weather-fetch.js +123 -0
  128. package/templates/skills/_shared/README.md +9 -0
  129. package/templates/skills/_shared/code-graph.md +47 -55
  130. package/templates/skills/_shared/config-precedence.md +3 -1
  131. package/templates/skills/_shared/extra-dispatch.md +78 -93
  132. package/templates/skills/_shared/gotchas.md +248 -177
  133. package/templates/skills/_shared/habits.md +101 -0
  134. package/templates/skills/_shared/lane-contract.md +84 -0
  135. package/templates/skills/_shared/opus5-only.md +14 -14
  136. package/templates/skills/_shared/phases/README.md +142 -83
  137. package/templates/skills/_shared/phases/analyst-gates.md +10 -21
  138. package/templates/skills/_shared/phases/execution.md +8 -14
  139. package/templates/skills/_shared/phases/house-rules.md +27 -32
  140. package/templates/skills/_shared/phases/intake.md +127 -133
  141. package/templates/skills/_shared/phases/mock-example.md +46 -56
  142. package/templates/skills/_shared/phases/plan-handoff.md +91 -97
  143. package/templates/skills/_shared/phases/planning.md +7 -17
  144. package/templates/skills/_shared/phases/preflight.md +19 -42
  145. package/templates/skills/_shared/phases/review.md +24 -28
  146. package/templates/skills/_shared/phases/rules.md +18 -42
  147. package/templates/skills/_shared/phases/scoring.md +55 -65
  148. package/templates/skills/_shared/phases/security-checklist.md +46 -50
  149. package/templates/skills/_shared/phases/security.md +45 -55
  150. package/templates/skills/_shared/phases/ship.md +6 -15
  151. package/templates/skills/_shared/phases/stop-resume.md +2 -5
  152. package/templates/skills/_shared/phases/summary.md +73 -48
  153. package/templates/skills/_shared/phases/testgen.md +41 -51
  154. package/templates/skills/_shared/phases/trace-verbs.md +447 -0
  155. package/templates/skills/_shared/phases/trace.md +66 -297
  156. package/templates/skills/_shared/phases/verify.md +62 -70
  157. package/templates/skills/_shared/phases/wave-grouping.md +128 -133
  158. package/templates/skills/_shared/phases/wiki-consult.md +10 -6
  159. package/templates/skills/_shared/read-ladder.md +2 -55
  160. package/templates/skills/_shared/return-validation.md +17 -70
  161. package/templates/skills/_shared/review-slice.md +106 -0
  162. package/templates/skills/_shared/smoke-gate.md +46 -28
  163. package/templates/skills/_shared/wait.md +1 -0
  164. package/templates/skills/context-combiner/SKILL.md +15 -44
  165. package/templates/skills/orc/README.md +2 -2
  166. package/templates/skills/orc/SKILL.md +35 -63
  167. package/templates/skills/orc/config.md +25 -27
  168. package/templates/skills/orc/examples/full-run-mock.md +2 -1
  169. package/templates/skills/orc/references/effort-and-mode.md +17 -17
  170. package/templates/skills/orc/references/pattern-gate.md +89 -89
  171. package/templates/skills/orc/references/phases/intake.md +41 -47
  172. package/templates/skills/orc/references/phases/integration.md +13 -19
  173. package/templates/skills/orc/references/preflight-report.md +11 -12
  174. package/templates/skills/orc/references/ultra-mode.md +9 -7
  175. package/templates/skills/orc/schemas/checkpoint.md +122 -122
  176. package/templates/skills/orc/subskills/orc-execution/SKILL.md +27 -73
  177. package/templates/skills/orc/subskills/orc-execution/core.md +12 -99
  178. package/templates/skills/orc/subskills/orc-execution/subagent.md +14 -13
  179. package/templates/skills/orc/subskills/orc-review-verify/SKILL.md +12 -53
  180. package/templates/skills/orc/subskills/orc-review-verify/core.md +52 -135
  181. package/templates/skills/orc/subskills/orc-review-verify/subagent.md +7 -7
  182. package/templates/skills/orc/subskills/orc-testgen/SKILL.md +11 -22
  183. package/templates/skills/orc/subskills/orc-testgen/core.md +20 -59
  184. package/templates/skills/orc/subskills/orc-testgen/subagent.md +7 -7
  185. package/templates/skills/orc-advisor/SKILL.md +56 -60
  186. package/templates/skills/orc-analyze/SKILL.md +33 -67
  187. package/templates/skills/orc-analyze/schemas/report-audit.md +2 -1
  188. package/templates/skills/orc-analyze/schemas/report-prose.md +2 -1
  189. package/templates/skills/orc-analyze-mini/SKILL.md +35 -70
  190. package/templates/skills/orc-claude/SKILL.md +14 -14
  191. package/templates/skills/orc-claude/examples/claude-run-mock.md +65 -65
  192. package/templates/skills/orc-diy/README.md +31 -0
  193. package/templates/skills/orc-diy/SKILL.md +27 -78
  194. package/templates/skills/orc-diy/references/blocks/pattern.md +18 -18
  195. package/templates/skills/orc-fast/SKILL.md +49 -75
  196. package/templates/skills/orc-fix/SKILL.md +110 -0
  197. package/templates/skills/orc-judge/SKILL.md +77 -82
  198. package/templates/skills/orc-mini/SKILL.md +64 -112
  199. package/templates/skills/orc-mini/examples/mini-run-mock.md +4 -2
  200. package/templates/skills/orc-pattern/SKILL.md +27 -48
  201. package/templates/skills/orc-poly/SKILL.md +32 -61
  202. package/templates/skills/orc-pr-driver/SKILL.md +25 -51
  203. package/templates/skills/orc-pr-driver/references/green-gate.md +113 -105
  204. package/templates/skills/orc-pr-setup/SKILL.md +20 -45
  205. package/templates/skills/orc-quick/README.md +44 -3
  206. package/templates/skills/orc-quick/SKILL.md +77 -108
  207. package/templates/skills/orc-quick/references/dispatch-gate.md +18 -6
  208. package/templates/skills/orc-quick/references/gh-mode.md +50 -1
  209. package/templates/skills/orc-quick/references/look.md +3 -1
  210. package/templates/skills/orc-retro/SKILL.md +20 -19
  211. package/templates/skills/orc-retro/examples/retro-mock.md +17 -17
  212. package/templates/skills/orc-route/SKILL.md +25 -45
  213. package/templates/skills/orc-test/SKILL.md +16 -37
  214. package/templates/skills/orc-verify/SKILL.md +14 -32
  215. package/templates/skills/orc-wait/SKILL.md +156 -163
  216. package/templates/skills/orc-wiki/README.md +325 -325
  217. package/templates/skills/orc-wiki/SKILL.md +195 -195
  218. package/templates/skills/orc-wiki/examples/wiki-run-mock.md +37 -37
  219. package/templates/skills/orc-wiki/references/extra.md +2 -2
  220. package/templates/skills/orc-wiki/references/partial-refresh.md +276 -271
  221. package/templates/skills/orc-wiki/references/phases/phase-0.md +2 -7
  222. package/templates/skills/orc-wiki/references/phases/phase-1.md +1 -6
  223. package/templates/skills/orc-wiki/references/phases/phase-2.md +4 -9
  224. package/templates/skills/orc-wiki/references/phases/phase-3.md +1 -6
  225. package/templates/skills/orc-wiki/references/phases/phase-3c.md +4 -8
  226. package/templates/agents/orc-claude-writer-opus-5-med.md +0 -55
  227. package/templates/agents/orc-reviewer-opus-5-med.md +0 -60
  228. package/templates/agents/orc-wiki-scanner-opus-5-med.md +0 -81
@@ -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 };