@uniqbit/mate-core 0.15.5 → 0.16.0-canary.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 (183) hide show
  1. package/claude-plugin/.claude-plugin/plugin.json +2 -2
  2. package/claude-plugin/hooks/hooks.json +3 -6
  3. package/claude-plugin/hooks/session-guidance.mjs +8 -0
  4. package/claude-plugin/hooks/ts-loader.mjs +19 -0
  5. package/package.json +6 -4
  6. package/src/cli/commands/artifact/artifact.ts +19 -3
  7. package/src/cli/commands/artifact/finish/command.ts +183 -57
  8. package/src/cli/commands/artifact/finish/engine.ts +80 -91
  9. package/src/cli/commands/artifact/finish/finisher.ts +26 -33
  10. package/src/cli/commands/artifact/finish/git.ts +34 -23
  11. package/src/cli/commands/artifact/finish/index.ts +9 -3
  12. package/src/cli/commands/artifact/finish/openspec.ts +225 -97
  13. package/src/cli/commands/artifact/pending/command.ts +175 -0
  14. package/src/cli/commands/artifact/pending/discovery.ts +249 -0
  15. package/src/cli/commands/artifact/pending/index.ts +17 -0
  16. package/src/cli/commands/cap/index-cmd.ts +9 -1
  17. package/src/cli/commands/cap/index.ts +2 -6
  18. package/src/cli/commands/companion/companion.ts +5 -1
  19. package/src/cli/commands/companion/link.ts +2 -2
  20. package/src/cli/commands/companion/sync.ts +92 -0
  21. package/src/cli/commands/doctor.ts +0 -3
  22. package/src/cli/commands/launch/shared.ts +23 -5
  23. package/src/cli/commands/report/collector.ts +72 -78
  24. package/src/cli/commands/report/contract.ts +40 -1
  25. package/src/cli/commands/report/highlight.ts +27 -0
  26. package/src/cli/commands/report/index.ts +11 -18
  27. package/src/cli/commands/report/renderer.ts +199 -2
  28. package/src/cli/commands/report/types.ts +26 -1
  29. package/src/cli/commands/shared/companion-selection.ts +107 -10
  30. package/src/cli/commands/studio/areas.ts +68 -0
  31. package/src/cli/commands/studio/index.ts +69 -0
  32. package/src/cli/commands/studio/inventory.ts +55 -0
  33. package/src/cli/commands/studio/mate-inventory.ts +43 -0
  34. package/src/cli/commands/studio/openspec-cli.ts +198 -0
  35. package/src/cli/commands/studio/payload.ts +184 -0
  36. package/src/cli/commands/studio/routes.ts +2 -0
  37. package/src/cli/commands/studio/selection.ts +61 -0
  38. package/src/cli/commands/studio/server.ts +201 -0
  39. package/src/cli/commands/studio/snapshot.ts +63 -0
  40. package/src/cli/commands/studio/topology.ts +199 -0
  41. package/src/cli/commands/studio/views/client.ts +197 -0
  42. package/src/cli/commands/studio/views/companion-picker.tsx +91 -0
  43. package/src/cli/commands/studio/views/companion-selector.tsx +90 -0
  44. package/src/cli/commands/studio/views/dashboard/changes.tsx +107 -0
  45. package/src/cli/commands/studio/views/dashboard/index.tsx +19 -0
  46. package/src/cli/commands/studio/views/document.tsx +256 -0
  47. package/src/cli/commands/studio/views/error.tsx +20 -0
  48. package/src/cli/commands/studio/views/model.ts +34 -0
  49. package/src/cli/commands/studio/views/pairings.tsx +38 -0
  50. package/src/cli/commands/studio/views/skills/index.tsx +87 -0
  51. package/src/cli/commands/studio/views/specs/index.tsx +101 -0
  52. package/src/cli/commands/studio/views/styles.ts +389 -0
  53. package/src/cli/commands/studio/views/warnings.tsx +21 -0
  54. package/src/cli/commands/studio/views/workflow/index.tsx +21 -0
  55. package/src/cli/commands/studio/views/workflow/steps.ts +329 -0
  56. package/src/cli/commands/studio/views/workflow/transcript.tsx +190 -0
  57. package/src/cli/commands/unwrap.ts +70 -0
  58. package/src/cli/commands/wrap.ts +164 -0
  59. package/src/cli/main.ts +68 -19
  60. package/src/cli/parse-flags.ts +36 -11
  61. package/src/cli/usage.ts +12 -3
  62. package/src/framework.ts +1 -7
  63. package/src/hooks/session-banner.ts +64 -11
  64. package/src/hooks/session-guidance.ts +40 -0
  65. package/src/hooks/validate-artifact-path.ts +108 -35
  66. package/src/lib/fs-utils.ts +9 -0
  67. package/src/lib/install.ts +33 -0
  68. package/src/lib/orchestrator/adapters/base.ts +14 -125
  69. package/src/lib/orchestrator/adapters/claude.ts +0 -11
  70. package/src/lib/orchestrator/adapters/opencode.ts +2 -32
  71. package/src/lib/orchestrator/companion-git-sync.ts +94 -84
  72. package/src/lib/orchestrator/config-store.ts +2 -21
  73. package/src/lib/orchestrator/editor.ts +12 -22
  74. package/src/lib/orchestrator/framework-context.ts +17 -6
  75. package/src/lib/orchestrator/global-config-store.ts +1 -1
  76. package/src/lib/orchestrator/launcher.ts +97 -7
  77. package/src/lib/orchestrator/opencode-guidance.ts +4 -56
  78. package/src/lib/orchestrator/projection-claude-entry.ts +198 -0
  79. package/src/lib/orchestrator/projection-claude-skills.ts +120 -0
  80. package/src/lib/orchestrator/projection-companion-link.ts +62 -0
  81. package/src/lib/orchestrator/projection-entries.ts +377 -0
  82. package/src/lib/orchestrator/projection-record.ts +56 -0
  83. package/src/lib/orchestrator/projection-runtime-documents.ts +424 -0
  84. package/src/lib/orchestrator/projection-types.ts +169 -0
  85. package/src/lib/orchestrator/repo-local-registry.ts +37 -133
  86. package/src/lib/orchestrator/repo-local-store.ts +96 -0
  87. package/src/lib/orchestrator/setup-compatibilities.ts +1 -9
  88. package/src/lib/orchestrator/types.ts +1 -0
  89. package/src/lib/orchestrator/working-repo-projection.ts +366 -0
  90. package/src/lib/orchestrator/workspace-inventory.ts +1 -1
  91. package/src/lib/package-paths.ts +11 -1
  92. package/src/opencode/companion-hooks.ts +89 -245
  93. package/src/opencode/companion-policy.ts +35 -10
  94. package/src/opencode/index.ts +1 -0
  95. package/src/opencode/projected-guidance.ts +56 -0
  96. package/src/opencode/tui.tsx +13 -4
  97. package/src/playbooks/companion-guidance.ts +32 -116
  98. package/src/plugins.ts +0 -1
  99. package/src/runtime/companion-git-state.ts +156 -0
  100. package/src/runtime/companion-git.ts +203 -0
  101. package/src/runtime/companion-guidance.ts +222 -0
  102. package/src/runtime/companion-sync.ts +298 -0
  103. package/src/runtime/env-names.ts +30 -0
  104. package/src/runtime/env.ts +67 -35
  105. package/src/runtime/framework.ts +10 -0
  106. package/src/runtime/freshness.ts +58 -0
  107. package/src/runtime/index.ts +104 -0
  108. package/src/runtime/install.ts +30 -0
  109. package/src/runtime/policy.ts +66 -0
  110. package/src/runtime/projected-guidance.ts +45 -0
  111. package/src/runtime/projection.ts +224 -0
  112. package/src/runtime/repo-local.ts +64 -0
  113. package/src/templates/capabilities/openspec-cap/mate-minimal/schema.yaml +56 -0
  114. package/src/templates/capabilities/openspec-cap/mate-minimal/templates/spec.md +48 -0
  115. package/src/templates/capabilities/openspec-cap/mate-minimal/templates/tasks.md +22 -0
  116. package/src/templates/capabilities/openspec-cap/mate-v1/schema.yaml +31 -90
  117. package/src/templates/capabilities/openspec-cap/mate-v1/templates/design.md +3 -0
  118. package/src/templates/capabilities/openspec-cap/mate-v1/templates/explore-brief.md +6 -6
  119. package/src/templates/capabilities/openspec-cap/mate-v1/templates/spec.md +3 -5
  120. package/src/templates/capabilities/openspec-cap/mate-v1/templates/tasks.md +3 -0
  121. package/src/templates/capabilities/openspec-cap/openspec-conventions.yaml +30 -0
  122. package/src/templates/capabilities/react-doctor/claude/hooks/react-doctor.sh +2 -2
  123. package/src/templates/mate-skills/agents/mate-artifact-publish/SKILL.md +185 -0
  124. package/src/templates/mate-skills/agents/mate-artifact-publish/references/openspec.md +227 -0
  125. package/src/templates/mate-skills/agents/mate-domain-modeling/SKILL.md +68 -0
  126. package/src/templates/mate-skills/agents/mate-domain-modeling/references/ADR-FORMAT.md +9 -0
  127. package/src/templates/mate-skills/agents/mate-domain-modeling/references/CONTEXT-FORMAT.md +18 -0
  128. package/src/templates/mate-skills/agents/mate-grill-me/SKILL.md +14 -0
  129. package/src/templates/mate-skills/agents/mate-grill-with-docs/SKILL.md +29 -0
  130. package/src/templates/mate-skills/agents/mate-grilling/SKILL.md +49 -0
  131. package/src/templates/mate-skills/agents/mate-interview-me/SKILL.md +147 -0
  132. package/src/templates/{capabilities/openspec-cap/mate-skills → mate-skills}/agents/mate-openspec-backfill/SKILL.md +4 -2
  133. package/src/templates/mate-skills/agents/mate-show-me/SKILL.md +139 -0
  134. package/src/templates/mate-skills/agents/mate-simplify-code/SKILL.md +503 -0
  135. package/src/templates/mate-skills/claude/mate-artifact-publish/SKILL.md +185 -0
  136. package/src/templates/mate-skills/claude/mate-artifact-publish/references/openspec.md +227 -0
  137. package/src/templates/mate-skills/claude/mate-domain-modeling/SKILL.md +68 -0
  138. package/src/templates/mate-skills/claude/mate-domain-modeling/references/ADR-FORMAT.md +9 -0
  139. package/src/templates/mate-skills/claude/mate-domain-modeling/references/CONTEXT-FORMAT.md +18 -0
  140. package/src/templates/mate-skills/claude/mate-grill-me/SKILL.md +14 -0
  141. package/src/templates/mate-skills/claude/mate-grill-with-docs/SKILL.md +29 -0
  142. package/src/templates/mate-skills/claude/mate-grilling/SKILL.md +49 -0
  143. package/src/templates/mate-skills/claude/mate-interview-me/SKILL.md +147 -0
  144. package/src/templates/mate-skills/claude/mate-openspec-backfill/SKILL.md +67 -0
  145. package/src/templates/mate-skills/claude/mate-show-me/SKILL.md +139 -0
  146. package/src/templates/mate-skills/claude/mate-simplify-code/SKILL.md +503 -0
  147. package/src/templates/report-assets/README.md +32 -0
  148. package/src/templates/report-assets/mermaid.LICENSE +21 -0
  149. package/src/templates/report-assets/mermaid.min.js +4376 -0
  150. package/src/templates/root/TEMPLATE_CLAUDE.md +1 -9
  151. package/src/tools/setup/__snapshots__/runtime-surface-golden.test.ts.snap +1476 -197
  152. package/src/tools/setup/capabilities/graphify.ts +16 -7
  153. package/src/tools/setup/capabilities/openspec.ts +63 -56
  154. package/src/tools/setup/capabilities/tokensave.ts +47 -0
  155. package/src/tools/setup/engine.ts +34 -6
  156. package/src/tools/setup/mate.ts +42 -13
  157. package/src/tools/setup/plugin.ts +9 -0
  158. package/src/tools/setup/plugins/guidance.ts +11 -1
  159. package/src/tools/setup/providers/claude-format.ts +49 -4
  160. package/src/tools/setup/providers/claude-plugin-hooks.ts +117 -0
  161. package/src/tools/setup/providers/claude.ts +55 -220
  162. package/src/tools/setup/providers/opencode.ts +41 -14
  163. package/src/tools/setup/runtime-documents.ts +174 -0
  164. package/src/tools/setup/surface-target.ts +50 -0
  165. package/src/tools/setup/working-repo-cleanup.ts +33 -26
  166. package/src/tools/setup/working-repo-local-state.ts +21 -1
  167. package/src/tools/setup.ts +25 -3
  168. package/wrappers/bin/graphify +57 -8
  169. package/wrappers/bin/openspec +50 -3
  170. package/claude-plugin/hooks/artifact-finish-nudge.mjs +0 -8
  171. package/src/cli/commands/cap/headroom.ts +0 -52
  172. package/src/cli/commands/workspace/list.ts +0 -25
  173. package/src/cli/commands/workspace/materialize.ts +0 -46
  174. package/src/cli/commands/workspace/workspace.ts +0 -22
  175. package/src/hooks/artifact-finish-nudge.ts +0 -244
  176. package/src/lib/orchestrator/headroom/proxy.ts +0 -116
  177. package/src/lib/orchestrator/workspace-materialize.ts +0 -80
  178. package/src/templates/capabilities/openspec-cap/mate-skills/agents/mate-artifact-finish/SKILL.md +0 -51
  179. package/src/templates/capabilities/openspec-cap/mate-skills/agents/mate-artifact-finish/references/openspec.md +0 -134
  180. package/src/templates/capabilities/openspec-cap/mate-skills/claude/mate-artifact-finish/SKILL.md +0 -58
  181. package/src/templates/capabilities/openspec-cap/mate-skills/claude/mate-artifact-finish/references/openspec.md +0 -139
  182. package/src/tools/setup/capabilities/headroom.ts +0 -57
  183. /package/src/cli/commands/{workspace → companion}/open.ts +0 -0
@@ -0,0 +1,389 @@
1
+ /**
2
+ * Theme-aware by tokens: the Workflow palette is the default, light mode is
3
+ * applied through the system preference or the inline toggle, and explicit
4
+ * theme attributes win over media queries.
5
+ */
6
+ export const STUDIO_STYLES = `
7
+ :root {
8
+ color-scheme: dark;
9
+ --bg: #0e1116;
10
+ --bg-rail: #12171e;
11
+ --panel: #171d26;
12
+ --panel-soft: #1e2631;
13
+ --border: #303b4a;
14
+ --border-soft: #25303c;
15
+ --text: #f3f6fa;
16
+ --muted: #9aa8b8;
17
+ --accent: #8cc7ff;
18
+ --accent-soft: rgb(140 199 255 / 11%);
19
+ --done: #9ee493;
20
+ --done-soft: rgb(158 228 147 / 12%);
21
+ --warn: #f6c56e;
22
+ --warn-soft: rgb(246 197 110 / 12%);
23
+ --bad: #ff8d87;
24
+ --bad-soft: rgb(255 141 135 / 12%);
25
+ --what: #74d3d8;
26
+ --what-soft: rgb(116 211 216 / 12%);
27
+ --why: #caa8ff;
28
+ --why-soft: rgb(202 168 255 / 14%);
29
+ --prompt-bg: #0a0d12;
30
+ --prompt-text: #dce5f0;
31
+ --shadow: 0 14px 36px rgb(0 0 0 / 22%);
32
+ --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
33
+ }
34
+ @media (prefers-color-scheme: light) {
35
+ :root:not([data-theme="dark"]) {
36
+ color-scheme: light;
37
+ --bg: #f3f6fa;
38
+ --bg-rail: #f8fafc;
39
+ --panel: #ffffff;
40
+ --panel-soft: #eef4fa;
41
+ --border: #cbd5e1;
42
+ --border-soft: #e3eaf2;
43
+ --text: #18212b;
44
+ --muted: #637083;
45
+ --accent: #1f66a6;
46
+ --accent-soft: #e8f3fd;
47
+ --done: #287b3b;
48
+ --done-soft: #e7f5e9;
49
+ --warn: #946300;
50
+ --warn-soft: #fff4d9;
51
+ --bad: #b42318;
52
+ --bad-soft: #ffebe9;
53
+ --what: #176b75;
54
+ --what-soft: #e2f5f6;
55
+ --why: #6346a5;
56
+ --why-soft: #f0ebff;
57
+ --prompt-bg: #17212b;
58
+ --prompt-text: #edf4fb;
59
+ --shadow: 0 12px 32px rgb(30 55 80 / 10%);
60
+ }
61
+ }
62
+ @media (prefers-color-scheme: dark) {
63
+ :root:not([data-theme="light"]) { color-scheme: dark; }
64
+ }
65
+ :root[data-theme="light"] {
66
+ color-scheme: light;
67
+ --bg: #f3f6fa;
68
+ --bg-rail: #f8fafc;
69
+ --panel: #ffffff;
70
+ --panel-soft: #eef4fa;
71
+ --border: #cbd5e1;
72
+ --border-soft: #e3eaf2;
73
+ --text: #18212b;
74
+ --muted: #637083;
75
+ --accent: #1f66a6;
76
+ --accent-soft: #e8f3fd;
77
+ --done: #287b3b;
78
+ --done-soft: #e7f5e9;
79
+ --warn: #946300;
80
+ --warn-soft: #fff4d9;
81
+ --bad: #b42318;
82
+ --bad-soft: #ffebe9;
83
+ --what: #176b75;
84
+ --what-soft: #e2f5f6;
85
+ --why: #6346a5;
86
+ --why-soft: #f0ebff;
87
+ --prompt-bg: #17212b;
88
+ --prompt-text: #edf4fb;
89
+ --shadow: 0 12px 32px rgb(30 55 80 / 10%);
90
+ }
91
+ :root[data-theme="dark"] {
92
+ color-scheme: dark;
93
+ }
94
+
95
+ * { box-sizing: border-box; }
96
+ body {
97
+ margin: 0;
98
+ background: var(--bg);
99
+ color: var(--text);
100
+ font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
101
+ font-size: 14px;
102
+ line-height: 1.5;
103
+ }
104
+ .shell { display: grid; grid-template-columns: 260px minmax(0, 1fr); min-height: 100vh; }
105
+ @media (max-width: 900px) { .shell { grid-template-columns: 1fr; } }
106
+
107
+ .rail {
108
+ background: var(--bg-rail);
109
+ border-right: 1px solid var(--border);
110
+ padding: 22px 18px 24px;
111
+ display: flex;
112
+ flex-direction: column;
113
+ gap: 24px;
114
+ }
115
+ .pairings li { padding: 6px 0; font-size: .84rem; }
116
+ select, button {
117
+ font: inherit;
118
+ color: inherit;
119
+ background: var(--panel);
120
+ border: 1px solid var(--border);
121
+ border-radius: 8px;
122
+ padding: 9px 11px;
123
+ max-width: 100%;
124
+ }
125
+ select { width: 100%; }
126
+ button { cursor: pointer; text-align: left; transition: border-color .15s, background .15s, color .15s; }
127
+ button:hover { border-color: var(--accent); background: var(--accent-soft); }
128
+ button:focus-visible, select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
129
+ .main { padding: 40px clamp(22px, 4vw, 64px) 72px; min-width: 0; background: var(--bg); }
130
+ .main > * { width: min(100%, 1180px); margin-right: auto; margin-left: auto; }
131
+ .panel {
132
+ background: var(--panel);
133
+ border: 1px solid var(--border);
134
+ border-radius: 12px;
135
+ padding: 24px;
136
+ margin-bottom: 16px;
137
+ box-shadow: var(--shadow);
138
+ }
139
+ h1 { margin: 0; font-size: clamp(1.75rem, 3vw, 2.25rem); line-height: 1.1; letter-spacing: -.04em; }
140
+ h3 { color: var(--text); font-size: 1.05rem; font-weight: 700; margin: 0; letter-spacing: -.02em; }
141
+ h4 { font-size: .86rem; margin: 0 0 6px; font-family: var(--mono); }
142
+ .note { color: var(--muted); font-size: .82rem; margin: 5px 0 14px; }
143
+ .muted { color: var(--muted); font-size: .84rem; }
144
+ .mono { font-family: var(--mono); font-size: .86rem; }
145
+ code { font-family: var(--mono); font-size: .82rem; }
146
+ .empty { color: var(--muted); font-style: italic; margin: 0; }
147
+ .unready { color: var(--warn); }
148
+ option.unready { color: var(--warn); font-style: italic; }
149
+ option.placeholder { color: var(--muted); font-style: italic; }
150
+ .scroll { overflow-x: auto; }
151
+
152
+ .page-header { display: flex; align-items: stretch; justify-content: space-between; gap: 32px; padding-bottom: 24px; margin-bottom: 18px; border-bottom: 1px solid var(--border-soft); }
153
+ .page-heading { min-width: 0; }
154
+ .page-eyebrow { margin: 0 0 8px; color: var(--accent); font-family: var(--mono); font-size: .68rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
155
+ .page-context { display: grid; align-content: start; gap: 6px; min-width: min(100%, 300px); max-width: 380px; padding: 0; border: 0; border-radius: 0; background: transparent; }
156
+ .page-context-label { color: var(--muted); font-size: .64rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
157
+ .page-context code { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
158
+ .snapshot-status { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: .75rem; }
159
+ .snapshot-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--done); }
160
+ .section-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; margin-bottom: 18px; }
161
+ .section-note { margin: 4px 0 0; color: var(--muted); font-size: .8rem; }
162
+ .section-count { flex: none; color: var(--muted); font-family: var(--mono); font-size: .72rem; }
163
+
164
+ table { border-collapse: collapse; width: 100%; font-size: .88rem; }
165
+ th, td { text-align: left; padding: 12px 10px; border-bottom: 1px solid var(--border-soft); vertical-align: top; }
166
+ th:first-child, td:first-child { padding-left: 0; }
167
+ th:last-child, td:last-child { padding-right: 0; }
168
+ th { font-size: .7rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
169
+ tbody tr:hover td { background: var(--accent-soft); }
170
+ td.numeric { font-variant-numeric: tabular-nums; white-space: nowrap; }
171
+ .lookup-table td:first-child { min-width: 180px; }
172
+ .change-cell { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 8px; }
173
+ .change-cell .mono { min-width: 0; overflow-wrap: anywhere; }
174
+ .progress-label { display: block; }
175
+ .bar { display: block; margin-top: 7px; width: 120px; height: 5px; border-radius: 999px; background: var(--border); overflow: hidden; }
176
+ .bar-fill { display: block; height: 100%; background: var(--done); }
177
+ .artifact-list { display: flex; flex-wrap: wrap; gap: 5px 6px; }
178
+ .lookup-table .chip { margin: 0; padding: 2px 7px; font-size: .68rem; }
179
+ .status-chip { display: inline-block; padding: 3px 8px; border: 1px solid var(--border); border-radius: 999px; background: var(--panel-soft); color: var(--muted); font-family: var(--mono); font-size: .68rem; white-space: nowrap; }
180
+ .status-chip[data-status="complete"] { border-color: var(--done); background: var(--done-soft); color: var(--done); }
181
+ .status-chip[data-status="active"] { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
182
+
183
+ ul.plain { margin: 0; padding: 0; list-style: none; }
184
+ ul.plain li { padding: 3px 0; border-bottom: 1px solid var(--border-soft); }
185
+ ul.plain li:last-child { border-bottom: 0; }
186
+ .chip {
187
+ display: inline-block;
188
+ font-size: .7rem;
189
+ font-family: var(--mono);
190
+ padding: 2px 8px;
191
+ margin: 0 5px 4px 0;
192
+ border-radius: 999px;
193
+ border: 1px solid var(--border);
194
+ background: var(--panel-soft);
195
+ }
196
+ .chip-done { background: var(--done-soft); border-color: var(--done); color: var(--done); }
197
+ .chip-invalid { background: var(--bad-soft); border-color: var(--bad); color: var(--bad); }
198
+ .toast {
199
+ position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
200
+ background: var(--done); color: #0e1116; border-radius: 8px;
201
+ padding: 6px 14px; font-size: .8rem;
202
+ opacity: 0; transition: opacity .16s; pointer-events: none; z-index: 20;
203
+ }
204
+ .toast[data-shown="true"] { opacity: 1; }
205
+
206
+ .warnings { border-color: var(--warn); }
207
+ .error { border-color: var(--bad); }
208
+
209
+ .runway-step-badge { padding: 1px 5px; border: 1px solid var(--badge); background: var(--badge-soft); color: var(--badge); font-size: .62rem; font-style: normal; font-weight: 750; letter-spacing: .08em; text-transform: uppercase; }
210
+ .runway-step-badge-optional { --badge: var(--warn); --badge-soft: var(--warn-soft); }
211
+ .runway-step-badge-skill { --badge: var(--what); --badge-soft: var(--what-soft); }
212
+ .runway-step-badge-openspec { --badge: var(--accent); --badge-soft: var(--accent-soft); }
213
+ .runway-step-badge-human-in-loop { --badge: var(--why); --badge-soft: var(--why-soft); }
214
+ .runway-step-copy { align-self: start; padding: 5px 8px; border-color: var(--border); background: transparent; color: var(--muted); font-size: .68rem; white-space: nowrap; }
215
+ .runway-step-copy:hover { background: var(--accent-soft); color: var(--text); }
216
+ .workflow-session-break { display: grid; grid-template-columns: minmax(20px, 1fr) auto minmax(20px, 1fr); align-items: center; gap: 10px; padding: 9px 0; color: var(--muted); font-family: var(--mono); font-size: .63rem; letter-spacing: .04em; text-align: center; }
217
+ .workflow-session-break::before, .workflow-session-break::after { height: 1px; background: var(--border); content: ""; }
218
+
219
+ /** The compact navigation rail keeps scope, navigation, and status visible together. */
220
+ .studio-sidebar {
221
+ position: sticky;
222
+ top: 0;
223
+ height: 100vh;
224
+ min-width: 0;
225
+ padding: 22px 18px 24px;
226
+ gap: 26px;
227
+ overflow-y: auto;
228
+ }
229
+ .sidebar-brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
230
+ .sidebar-brand-mark { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 8px; background: var(--accent); color: var(--bg-rail); font-size: .72rem; font-weight: 800; }
231
+ .sidebar-brand-copy { display: grid; gap: 1px; min-width: 0; }
232
+ .sidebar-brand-copy strong { font-size: .9rem; letter-spacing: -.02em; }
233
+ .sidebar-brand-copy span { color: var(--muted); font-size: .68rem; }
234
+ .sidebar-label { color: var(--muted); font-size: .62rem; font-weight: 750; letter-spacing: .1em; text-transform: uppercase; }
235
+ .sidebar-scope { display: grid; gap: 7px; }
236
+ .sidebar-scope select { padding: 8px 9px; font-family: var(--mono); font-size: .72rem; }
237
+ .sidebar-pairings { color: var(--muted); font-family: var(--mono); font-size: .67rem; line-height: 1.45; }
238
+ .sidebar-pairings .plain li { padding: 4px 0; }
239
+ .sidebar-pairings .muted { font-size: .67rem; }
240
+ .sidebar-nav { display: grid; gap: 3px; }
241
+ .sidebar-nav-list { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
242
+ .sidebar-nav button { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 8px 10px; border-color: transparent; border-radius: 7px; background: transparent; font-size: .8rem; }
243
+ .sidebar-nav button:hover, .sidebar-nav button[aria-pressed="true"] { border-color: var(--border); background: var(--accent-soft); }
244
+ .sidebar-nav button[aria-pressed="true"] { color: var(--accent); font-weight: 700; }
245
+ .sidebar-metrics { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; }
246
+ .sidebar-metric { display: grid; gap: 1px; padding: 8px 6px; border: 1px solid var(--border-soft); border-radius: 7px; background: var(--panel-soft); }
247
+ .sidebar-metric strong { font-size: .9rem; font-variant-numeric: tabular-nums; }
248
+ .sidebar-metric span { color: var(--muted); font-size: .58rem; letter-spacing: .06em; text-transform: uppercase; }
249
+ .sidebar-footer { display: grid; gap: 6px; margin-top: auto; }
250
+ .sidebar-footer-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
251
+ .sidebar-footer button { width: 100%; padding: 7px 8px; font-size: .72rem; }
252
+
253
+ /** Specs uses the same full-bleed content treatment as Workflow. */
254
+ .specs-eyebrow { color: var(--accent); font-size: .68rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
255
+ .specs-intro { display: flex; align-items: flex-end; justify-content: space-between; gap: 28px; margin-bottom: 26px; }
256
+ .specs-intro-copy { max-width: 54ch; }
257
+ .specs-intro-copy p { margin: 0; color: var(--muted); }
258
+ .specs-summary { display: grid; grid-template-columns: repeat(3, minmax(84px, 1fr)); min-width: 290px; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
259
+ .specs-summary-item { display: grid; gap: 1px; padding: 12px 10px; border-right: 1px solid var(--border); }
260
+ .specs-summary-item:last-child { border-right: 0; }
261
+ .specs-summary-item strong { font-size: 1.25rem; font-variant-numeric: tabular-nums; }
262
+ .specs-summary-item span { color: var(--muted); font-size: .62rem; text-transform: uppercase; letter-spacing: .08em; }
263
+ .picker-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(252px, 1fr)); gap: 12px; }
264
+ .picker-card { display: grid; align-content: start; gap: 5px; padding: 16px; }
265
+ .picker-card[data-unready="true"] { border-color: var(--warn); }
266
+ .picker-card-name { overflow: hidden; font-family: var(--mono); font-size: .9rem; font-weight: 750; text-overflow: ellipsis; white-space: nowrap; }
267
+ .picker-card-path { color: var(--muted); font-size: .72rem; overflow-wrap: anywhere; }
268
+ .picker-card-meta { display: flex; flex-wrap: wrap; margin-top: 5px; }
269
+
270
+ .specs-area-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 14px; }
271
+ .specs-area-card { padding: 18px; border: 1px solid var(--border); border-radius: 10px; background: var(--panel); }
272
+ .specs-area-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; min-height: 58px; padding-bottom: 16px; border-bottom: 1px solid var(--border-soft); }
273
+ .specs-area-number { color: var(--muted); font-family: var(--mono); font-size: .68rem; }
274
+ .specs-area-name { display: flex; align-items: baseline; gap: 9px; min-width: 0; }
275
+ .specs-area-name h4 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
276
+ .specs-area-count { color: var(--muted); font-family: var(--mono); font-size: .7rem; white-space: nowrap; }
277
+ .specs-card-list { display: grid; gap: 7px; margin-top: 14px; }
278
+ .spec-card-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--border-soft); }
279
+ .spec-card-row:last-child { border-bottom: 0; padding-bottom: 0; }
280
+ .spec-card-row:first-child { padding-top: 0; }
281
+ .spec-card-row strong { overflow: hidden; font-family: var(--mono); font-size: .78rem; text-overflow: ellipsis; white-space: nowrap; }
282
+ .spec-card-meta { display: flex; align-items: center; gap: 7px; color: var(--muted); font-size: .7rem; }
283
+ .spec-status { padding: 2px 5px; border: 1px solid var(--done); background: var(--done-soft); color: var(--done); font-family: var(--mono); font-size: .61rem; text-transform: uppercase; }
284
+ .spec-status-invalid { border-color: var(--bad); background: var(--bad-soft); color: var(--bad); }
285
+
286
+ .skills-tab-list { display: flex; gap: 5px; border-bottom: 1px solid var(--border); }
287
+ .skills-tab-list button { display: grid; gap: 3px; min-width: 150px; padding: 10px 12px; border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: transparent; color: var(--muted); }
288
+ .skills-tab-list button:hover { background: var(--accent-soft); }
289
+ .skills-tab-list button[aria-selected="true"] { border-bottom-color: var(--accent); background: var(--panel-soft); color: var(--text); }
290
+ .skills-tab-list button strong { font-family: var(--mono); font-size: .74rem; text-align: left; }
291
+ .skills-tab-list button span { font-size: .68rem; text-align: left; }
292
+ .skills-panels { padding-top: 18px; }
293
+ .skills-panels > [data-active="false"] { display: none; }
294
+ .skills-panel-description { margin: 0 0 16px; color: var(--muted); font-size: .8rem; }
295
+ .skills-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; }
296
+ .skill-card { display: grid; gap: 4px; min-width: 0; padding: 13px 14px; border: 1px solid var(--border-soft); border-radius: 8px; background: var(--panel-soft); }
297
+ .skill-card code { overflow: hidden; font-size: .78rem; font-weight: 700; text-overflow: ellipsis; white-space: nowrap; }
298
+ .skill-card span { overflow: hidden; color: var(--muted); font-family: var(--mono); font-size: .65rem; text-overflow: ellipsis; white-space: nowrap; }
299
+
300
+ @media (max-width: 600px) {
301
+ .main { padding-right: 18px; padding-left: 18px; }
302
+ .page-header { display: grid; gap: 18px; }
303
+ .page-context { min-width: 0; max-width: none; }
304
+ .section-header { gap: 10px; }
305
+ .skills-tab-list button { min-width: 0; flex: 1; }
306
+ }
307
+
308
+ @media (min-width: 901px) {
309
+ .shell:has(.studio-sidebar) { grid-template-columns: 260px minmax(0, 1fr); }
310
+ }
311
+ @media (max-width: 900px) {
312
+ .studio-sidebar { position: relative; height: auto; max-height: none; }
313
+ }
314
+
315
+ /** Production Workflow transcript. */
316
+ .workflow-view { margin: 0 auto; }
317
+ .workflow-eyebrow { margin: 0 0 10px; color: var(--muted); font-family: var(--mono); font-size: .68rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
318
+ .workflow-console { width: 100%; overflow: hidden; border: 1px solid var(--border); border-radius: 12px; background: var(--panel); color: var(--text); box-shadow: none; }
319
+ .workflow-console-header { display: grid; grid-template-columns: 1fr auto; gap: 16px; align-items: center; padding: 14px 18px; border-bottom: 1px solid var(--border); background: var(--panel-soft); color: var(--muted); font-family: system-ui, sans-serif; font-size: .68rem; }
320
+ .workflow-console-header-title { display: grid; gap: 2px; }
321
+ .workflow-console-header-title > span { color: var(--accent); font-family: var(--mono); font-size: .62rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
322
+ .workflow-console-header-title strong { color: var(--text); font-size: .84rem; }
323
+ .workflow-console-header > span:last-child { text-align: right; }
324
+ .workflow-console-body { padding: 22px clamp(14px, 3vw, 34px) 26px; }
325
+ .workflow-console-context { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px 18px; align-items: start; margin: 4px 0 18px 55px; padding: 11px 0 15px; border-bottom: 1px solid var(--border); }
326
+ .workflow-console-context > span { color: var(--why); font-family: var(--mono); font-size: .62rem; text-transform: uppercase; }
327
+ .workflow-console-context > div { display: grid; gap: 3px; }
328
+ .workflow-console-context p { margin: 0; color: var(--text); font-family: system-ui, sans-serif; font-size: .72rem; line-height: 1.35; }
329
+ .workflow-console-context small { color: var(--muted); font-family: system-ui, sans-serif; font-size: .68rem; line-height: 1.35; }
330
+ .workflow-console-tabs { display: flex; gap: 5px; margin-left: 55px; border-bottom: 1px solid var(--border); }
331
+ .workflow-console-tabs button { display: grid; gap: 3px; min-width: 150px; padding: 10px 12px; border: 0; border-bottom: 2px solid transparent; background: transparent; color: var(--muted); }
332
+ .workflow-console-tabs button:hover { background: var(--panel); }
333
+ .workflow-console-tabs button[aria-selected="true"] { border-bottom-color: var(--accent); background: var(--panel); color: var(--text); }
334
+ .workflow-console-tabs button strong { font-family: var(--mono); font-size: .72rem; text-align: left; }
335
+ .workflow-console-tabs button small { font-size: .65rem; text-align: left; }
336
+ .workflow-console-panels { margin-left: 20px; padding-left: 35px; border-left: 1px dashed var(--border); }
337
+ .workflow-console-panels > [data-active="false"] { display: none; }
338
+ .workflow-console-branch-rule { display: grid; gap: 4px; padding: 16px 0 6px; }
339
+ .workflow-console-branch-rule-description { max-width: 70ch; margin: 0; color: var(--muted); font-family: system-ui, sans-serif; font-size: .73rem; line-height: 1.4; }
340
+ .workflow-console-line { display: grid; grid-template-columns: 42px minmax(0, 1fr); gap: 13px; padding: 12px 0; }
341
+ .workflow-console-gutter { color: var(--muted); font-family: var(--mono); font-size: .66rem; opacity: .7; }
342
+ .workflow-console-line-body { min-width: 0; }
343
+ .workflow-console-step-title { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; margin-bottom: 7px; }
344
+ .workflow-console-step-title strong { color: var(--text); font-family: var(--mono); font-size: .71rem; }
345
+ .workflow-console-command { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 9px; align-items: center; padding: 9px 10px; border: 1px solid var(--border-soft); border-radius: 7px; background: var(--panel-soft); }
346
+ .workflow-console-command-label { color: var(--accent); font-family: var(--mono); font-size: .62rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
347
+ .workflow-console-command code { color: var(--text); font-family: var(--mono); font-size: .78rem; overflow-wrap: anywhere; }
348
+ .workflow-console-command .runway-step-copy { border-color: var(--border); }
349
+ .workflow-console-explanation { display: grid; gap: 6px; margin-top: 10px; }
350
+ .workflow-console-detail { display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: 10px; align-items: baseline; }
351
+ .workflow-console-detail > span { color: var(--muted); font-family: var(--mono); font-size: .6rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
352
+ .workflow-badges { display: inline-flex; flex-wrap: wrap; gap: 4px; }
353
+ .workflow-badges .runway-step-badge { font-size: .56rem; }
354
+ .workflow-console-explanation p, .workflow-console-explanation small { margin: 0; color: var(--muted); font-family: system-ui, sans-serif; font-size: .73rem; line-height: 1.4; }
355
+ .workflow-console-explanation p { color: var(--text); }
356
+ .workflow-console-divider { display: flex; align-items: center; gap: 12px; padding: 16px 0 4px 55px; color: var(--accent); font-family: var(--mono); font-size: .63rem; text-transform: uppercase; }
357
+ .workflow-console-divider::after { flex: 1; height: 1px; background: var(--border); content: ""; }
358
+ .workflow-option-list { display: grid; gap: 3px; margin: 8px 0 0 18px; }
359
+ .workflow-option { display: grid; gap: 1px; padding-left: 8px; }
360
+ .workflow-option small { color: var(--muted); font-size: .65rem; line-height: 1.35; }
361
+ .workflow-option .runway-step-copy { justify-self: start; }
362
+
363
+ @media (max-width: 650px) {
364
+ .workflow-console-header { grid-template-columns: 1fr auto; }
365
+ .workflow-console-context, .workflow-console-tabs { margin-left: 0; }
366
+ .workflow-console-context { grid-template-columns: minmax(0, 1fr); }
367
+ .workflow-console-context > span { margin-bottom: 2px; }
368
+ .workflow-console-tabs button { min-width: 0; flex: 1; padding-right: 8px; padding-left: 8px; }
369
+ .workflow-console-panels { margin-left: 0; padding-left: 10px; }
370
+ .workflow-console-command { grid-template-columns: auto minmax(0, 1fr); }
371
+ .workflow-console-command .runway-step-copy { grid-column: 2; justify-self: start; }
372
+ .workflow-console-divider, .workflow-console .workflow-session-break { padding-left: 0; margin-left: 0; }
373
+ }
374
+
375
+ @media (max-width: 760px) {
376
+ .lookup-panel .scroll { overflow: visible; }
377
+ .lookup-table { display: block; }
378
+ .lookup-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
379
+ .lookup-table tbody { display: grid; gap: 0; }
380
+ .lookup-table tr { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 18px; padding: 16px 0; border-bottom: 1px solid var(--border-soft); }
381
+ .lookup-table tr:last-child { border-bottom: 0; }
382
+ .lookup-table td, .lookup-table td:first-child, .lookup-table td:last-child { display: grid; gap: 5px; min-width: 0; padding: 0; border: 0; }
383
+ .lookup-table td::before { color: var(--muted); content: attr(data-label); font-size: .62rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
384
+ .lookup-table td:first-child, .lookup-table td:last-child { grid-column: 1 / -1; }
385
+ .lookup-table td:first-child::before { display: none; }
386
+ .lookup-table tbody tr:hover td { background: transparent; }
387
+ .lookup-table .bar { width: 100%; max-width: 180px; }
388
+ }
389
+ `;
@@ -0,0 +1,21 @@
1
+ /** @jsxImportSource hono/jsx */
2
+
3
+ interface WarningsProps {
4
+ warnings: string[];
5
+ }
6
+
7
+ /** Degraded collection is reported without costing the rest of the page. */
8
+ export function Warnings({ warnings }: WarningsProps) {
9
+ if (warnings.length === 0) return null;
10
+
11
+ return (
12
+ <section className="panel warnings">
13
+ <h3>Warnings</h3>
14
+ <ul className="plain">
15
+ {warnings.map((warning) => (
16
+ <li key={warning}>{warning}</li>
17
+ ))}
18
+ </ul>
19
+ </section>
20
+ );
21
+ }
@@ -0,0 +1,21 @@
1
+ /** @jsxImportSource hono/jsx */
2
+
3
+ import type { StudioCompanionPayload } from "../../payload";
4
+ import { Warnings } from "../warnings";
5
+ import { WorkflowTranscript } from "./transcript";
6
+
7
+ interface WorkflowProps {
8
+ payload: StudioCompanionPayload;
9
+ }
10
+
11
+ export function Workflow({ payload }: WorkflowProps) {
12
+ return (
13
+ <>
14
+ <div className="workflow-view">
15
+ <div className="workflow-eyebrow">Workflow</div>
16
+ <WorkflowTranscript payload={payload} />
17
+ </div>
18
+ <Warnings warnings={payload.warnings} />
19
+ </>
20
+ );
21
+ }