agent-control-plane 0.4.9 → 0.7.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 (87) hide show
  1. package/README.md +109 -13
  2. package/npm/bin/agent-control-plane.js +1 -1
  3. package/package.json +39 -33
  4. package/tools/bin/debug-session.sh +106 -0
  5. package/tools/bin/flow-config-lib.sh +13 -3508
  6. package/tools/bin/flow-execution-lib.sh +243 -0
  7. package/tools/bin/flow-forge-lib.sh +1770 -0
  8. package/tools/bin/flow-profile-lib.sh +335 -0
  9. package/tools/bin/flow-provider-lib.sh +981 -0
  10. package/tools/bin/flow-runtime-doctor-linux.sh +136 -0
  11. package/tools/bin/flow-runtime-doctor.sh +5 -1
  12. package/tools/bin/flow-session-lib.sh +317 -0
  13. package/tools/bin/install-project-systemd.sh +255 -0
  14. package/tools/bin/project-runtimectl.sh +45 -0
  15. package/tools/bin/project-systemd-bootstrap.sh +74 -0
  16. package/tools/bin/uninstall-project-systemd.sh +87 -0
  17. package/tools/dashboard/app.js +238 -8
  18. package/tools/dashboard/issue_queue_state.py +101 -0
  19. package/tools/dashboard/requirements.txt +3 -0
  20. package/tools/dashboard/server.py +250 -30
  21. package/tools/dashboard/styles.css +526 -455
  22. package/tools/bin/agent-cleanup-worktree +0 -247
  23. package/tools/bin/agent-github-update-labels +0 -105
  24. package/tools/bin/agent-init-worktree +0 -216
  25. package/tools/bin/agent-project-archive-run +0 -52
  26. package/tools/bin/agent-project-capture-worker +0 -46
  27. package/tools/bin/agent-project-catch-up-issue-pr-links +0 -118
  28. package/tools/bin/agent-project-catch-up-merged-prs +0 -195
  29. package/tools/bin/agent-project-catch-up-scheduled-issue-retries +0 -123
  30. package/tools/bin/agent-project-cleanup-session +0 -513
  31. package/tools/bin/agent-project-detached-launch +0 -127
  32. package/tools/bin/agent-project-heartbeat-loop +0 -1029
  33. package/tools/bin/agent-project-open-issue-worktree +0 -89
  34. package/tools/bin/agent-project-open-pr-worktree +0 -80
  35. package/tools/bin/agent-project-publish-issue-pr +0 -468
  36. package/tools/bin/agent-project-reconcile-issue-session +0 -1409
  37. package/tools/bin/agent-project-reconcile-pr-session +0 -1288
  38. package/tools/bin/agent-project-retry-state +0 -158
  39. package/tools/bin/agent-project-run-claude-session +0 -805
  40. package/tools/bin/agent-project-run-codex-resilient +0 -963
  41. package/tools/bin/agent-project-run-codex-session +0 -435
  42. package/tools/bin/agent-project-run-kilo-session +0 -369
  43. package/tools/bin/agent-project-run-ollama-session +0 -658
  44. package/tools/bin/agent-project-run-openclaw-session +0 -1309
  45. package/tools/bin/agent-project-run-opencode-session +0 -377
  46. package/tools/bin/agent-project-run-pi-session +0 -479
  47. package/tools/bin/agent-project-sync-anchor-repo +0 -139
  48. package/tools/bin/agent-project-sync-source-repo-main +0 -163
  49. package/tools/bin/agent-project-worker-status +0 -188
  50. package/tools/bin/branch-verification-guard.sh +0 -364
  51. package/tools/bin/capture-worker.sh +0 -18
  52. package/tools/bin/cleanup-worktree.sh +0 -52
  53. package/tools/bin/codex-quota +0 -31
  54. package/tools/bin/create-follow-up-issue.sh +0 -114
  55. package/tools/bin/dashboard-launchd-bootstrap.sh +0 -50
  56. package/tools/bin/issue-publish-localization-guard.sh +0 -142
  57. package/tools/bin/issue-publish-scope-guard.sh +0 -242
  58. package/tools/bin/issue-requires-local-workspace-install.sh +0 -31
  59. package/tools/bin/issue-resource-class.sh +0 -12
  60. package/tools/bin/kick-scheduler.sh +0 -75
  61. package/tools/bin/label-follow-up-issues.sh +0 -14
  62. package/tools/bin/new-pr-worktree.sh +0 -50
  63. package/tools/bin/new-worktree.sh +0 -49
  64. package/tools/bin/pr-risk.sh +0 -12
  65. package/tools/bin/prepare-worktree.sh +0 -142
  66. package/tools/bin/provider-cooldown-state.sh +0 -204
  67. package/tools/bin/publish-issue-worker.sh +0 -31
  68. package/tools/bin/reconcile-bootstrap-lib.sh +0 -113
  69. package/tools/bin/reconcile-issue-worker.sh +0 -34
  70. package/tools/bin/reconcile-pr-worker.sh +0 -34
  71. package/tools/bin/record-verification.sh +0 -71
  72. package/tools/bin/render-flow-config.sh +0 -98
  73. package/tools/bin/resident-issue-controller-lib.sh +0 -448
  74. package/tools/bin/retry-state.sh +0 -31
  75. package/tools/bin/reuse-issue-worktree.sh +0 -121
  76. package/tools/bin/run-codex-bypass.sh +0 -3
  77. package/tools/bin/run-codex-safe.sh +0 -3
  78. package/tools/bin/run-codex-task.sh +0 -280
  79. package/tools/bin/serve-dashboard.sh +0 -5
  80. package/tools/bin/start-issue-worker.sh +0 -943
  81. package/tools/bin/start-pr-fix-worker.sh +0 -528
  82. package/tools/bin/start-pr-merge-repair-worker.sh +0 -8
  83. package/tools/bin/start-pr-review-worker.sh +0 -261
  84. package/tools/bin/start-resident-issue-loop.sh +0 -499
  85. package/tools/bin/update-github-labels.sh +0 -14
  86. package/tools/bin/worker-status.sh +0 -19
  87. package/tools/bin/workflow-catalog.sh +0 -77
@@ -1,471 +1,542 @@
1
- :root {
2
- --bg: #f4f3ee;
3
- --panel: #fffdf7;
4
- --panel-strong: #f8f4e6;
5
- --ink: #192126;
6
- --muted: #5a6872;
7
- --line: #d7d0c0;
8
- --accent: #0f766e;
9
- --accent-soft: #d8f1ec;
10
- --warn: #a16207;
11
- --warn-soft: #fce7b2;
12
- --danger: #b42318;
13
- --danger-soft: #fdd8d2;
14
- --shadow: 0 18px 50px rgba(25, 33, 38, 0.08);
15
- --button-bg: var(--ink);
16
- --button-ink: #ffffff;
17
- --button-hover: #0f1720;
18
- --hero-bg: rgba(255, 253, 247, 0.92);
19
- --profile-bg: rgba(255, 253, 247, 0.94);
20
- --body-gradient-top: rgba(15, 118, 110, 0.08);
21
- --body-gradient-bottom: #faf7ef;
22
- --theme-toggle-bg: var(--panel);
23
- --theme-toggle-ink: var(--ink);
24
- --theme-toggle-line: var(--line);
25
- --theme-toggle-hover: var(--panel-strong);
26
- --reported-soft: #dbeafe;
27
- --reported-ink: #1d4ed8;
28
- --implemented-soft: #dcfce7;
29
- --implemented-ink: #166534;
30
- --blocked-soft: #fef3c7;
31
- --blocked-ink: #92400e;
32
- }
33
-
34
- :root[data-theme="dark"] {
35
- --bg: #0d1418;
36
- --panel: #142026;
37
- --panel-strong: #1a2a31;
38
- --ink: #ebf1f3;
39
- --muted: #9ab0bb;
40
- --line: #2a3c44;
41
- --accent: #5ad4c7;
42
- --accent-soft: #183d3a;
43
- --warn: #f4c35f;
44
- --warn-soft: #4d3a12;
45
- --danger: #ff8a80;
46
- --danger-soft: #4a2220;
47
- --shadow: 0 24px 60px rgba(0, 0, 0, 0.32);
48
- --button-bg: #ebf1f3;
49
- --button-ink: #0d1418;
50
- --button-hover: #d7e2e6;
51
- --hero-bg: rgba(20, 32, 38, 0.92);
52
- --profile-bg: rgba(20, 32, 38, 0.94);
53
- --body-gradient-top: rgba(90, 212, 199, 0.12);
54
- --body-gradient-bottom: #10181d;
55
- --theme-toggle-bg: #1d2d35;
56
- --theme-toggle-ink: #ebf1f3;
57
- --theme-toggle-line: #35505b;
58
- --theme-toggle-hover: #23363f;
59
- --reported-soft: #1b3552;
60
- --reported-ink: #9fc8ff;
61
- --implemented-soft: #173a2b;
62
- --implemented-ink: #85ddb1;
63
- --blocked-soft: #4a3711;
64
- --blocked-ink: #f4c35f;
65
- }
66
-
67
- * {
68
- box-sizing: border-box;
69
- }
70
-
71
- body {
72
- margin: 0;
73
- font-family: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", serif;
74
- background:
75
- radial-gradient(circle at top right, var(--body-gradient-top), transparent 34%),
76
- linear-gradient(180deg, var(--body-gradient-bottom) 0%, var(--bg) 100%);
77
- color: var(--ink);
78
- }
79
-
80
- .page {
81
- max-width: 1440px;
82
- margin: 0 auto;
83
- padding: 32px 20px 48px;
84
- }
85
-
86
- .hero {
1
+ 1| 1|:root {
2
+ 2| 2| --bg: #f4f3ee;
3
+ 3| 3| --panel: #fffdf7;
4
+ 4| 4| --panel-strong: #f8f4e6;
5
+ 5| 5| --ink: #192126;
6
+ 6| 6| --muted: #5a6872;
7
+ 7| 7| --line: #d7d0c0;
8
+ 8| 8| --accent: #0f766e;
9
+ 9| 9| --accent-soft: #d8f1ec;
10
+ 10| 10| --warn: #a16207;
11
+ 11| 11| --warn-soft: #fce7b2;
12
+ 12| 12| --danger: #b42318;
13
+ 13| 13| --danger-soft: #fdd8d2;
14
+ 14| 14| --shadow: 0 18px 50px rgba(25, 33, 38, 0.08);
15
+ 15| 15| --button-bg: var(--ink);
16
+ 16| 16| --button-ink: #ffffff;
17
+ 17| 17| --button-hover: #0f1720;
18
+ 18| 18| --hero-bg: rgba(255, 253, 247, 0.92);
19
+ 19| 19| --profile-bg: rgba(255, 253, 247, 0.94);
20
+ 20| 20| --body-gradient-top: rgba(15, 118, 110, 0.08);
21
+ 21| 21| --body-gradient-bottom: #faf7ef;
22
+ 22| 22| --theme-toggle-bg: var(--panel);
23
+ 23| 23| --theme-toggle-ink: var(--ink);
24
+ 24| 24| --theme-toggle-line: var(--line);
25
+ 25| 25| --theme-toggle-hover: var(--panel-strong);
26
+ 26| 26| --reported-soft: #dbeafe;
27
+ 27| 27| --reported-ink: #1d4ed8;
28
+ 28| 28| --implemented-soft: #dcfce7;
29
+ 29| 29| --implemented-ink: #166534;
30
+ 30| 30| --blocked-soft: #fef3c7;
31
+ 31| 31| --blocked-ink: #92400e;
32
+ 32| 32|}
33
+ 33| 33|
34
+ 34| 34|:root[data-theme="dark"] {
35
+ 35| 35| --bg: #0d1418;
36
+ 36| 36| --panel: #142026;
37
+ 37| 37| --panel-strong: #1a2a31;
38
+ 38| 38| --ink: #ebf1f3;
39
+ 39| 39| --muted: #9ab0bb;
40
+ 40| 40| --line: #2a3c44;
41
+ 41| 41| --accent: #5ad4c7;
42
+ 42| 42| --accent-soft: #183d3a;
43
+ 43| 43| --warn: #f4c35f;
44
+ 44| 44| --warn-soft: #4d3a12;
45
+ 45| 45| --danger: #ff8a80;
46
+ 46| 46| --danger-soft: #4a2220;
47
+ 47| 47| --shadow: 0 24px 60px rgba(0, 0, 0, 0.32);
48
+ 48| 48| --button-bg: #ebf1f3;
49
+ 49| 49| --button-ink: #0d1418;
50
+ 50| 50| --button-hover: #d7e2e6;
51
+ 51| 51| --hero-bg: rgba(20, 32, 38, 0.92);
52
+ 52| 52| --profile-bg: rgba(20, 32, 38, 0.94);
53
+ 53| 53| --body-gradient-top: rgba(90, 212, 199, 0.12);
54
+ 54| 54| --body-gradient-bottom: #10181d;
55
+ 55| 55| --theme-toggle-bg: #1d2d35;
56
+ 56| 56| --theme-toggle-ink: #ebf1f3;
57
+ 57| 57| --theme-toggle-line: #35505b;
58
+ 58| 58| --theme-toggle-hover: #23363f;
59
+ 59| 59| --reported-soft: #1b3552;
60
+ 60| 60| --reported-ink: #9fc8ff;
61
+ 61| 61| --implemented-soft: #173a2b;
62
+ 62| 62| --implemented-ink: #85ddb1;
63
+ 63| 63| --blocked-soft: #4a3711;
64
+ 64| 64| --blocked-ink: #f4c35f;
65
+ 65| 65|}
66
+ 66| 66|
67
+ 67| 67|* {
68
+ 68| 68| box-sizing: border-box;
69
+ 69| 69|}
70
+ 70| 70|
71
+ 71| 71|body {
72
+ 72| 72| margin: 0;
73
+ 73| 73| font-family: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", serif;
74
+ 74| 74| background:
75
+ 75| 75| radial-gradient(circle at top right, var(--body-gradient-top), transparent 34%),
76
+ 76| 76| linear-gradient(180deg, var(--body-gradient-bottom) 0%, var(--bg) 100%);
77
+ 77| 77| color: var(--ink);
78
+ 78| 78|}
79
+ 79| 79|
80
+ 80| 80|.page {
81
+ 81| 81| max-width: 1440px;
82
+ 82| 82| margin: 0 auto;
83
+ 83| 83| padding: 32px 20px 48px;
84
+ 84| 84|}
85
+ 85| 85|
86
+ 86| 86|.hero {
87
+ 87| 87| display: flex;
88
+ 88| 88| justify-content: space-between;
89
+ 89| 89| gap: 24px;
90
+ 90| 90| align-items: flex-start;
91
+ 91| 91| padding: 24px;
92
+ 92| 92| border: 1px solid var(--line);
93
+ 93| 93| border-radius: 28px;
94
+ 94| 94| background: var(--hero-bg);
95
+ 95| 95| box-shadow: var(--shadow);
96
+ 96| 96|}
97
+ 97| 97|
98
+ 98| 98|.eyebrow {
99
+ 99| 99| margin: 0 0 8px;
100
+ 100| 100| text-transform: uppercase;
101
+ 101| 101| letter-spacing: 0.08em;
102
+ 102| 102| font-size: 12px;
103
+ 103| 103| color: var(--accent);
104
+ 104| 104|}
105
+ 105| 105|
106
+ 106| 106|.hero h1 {
107
+ 107| 107| margin: 0;
108
+ 108| 108| font-size: clamp(34px, 5vw, 56px);
109
+ 109| 109| line-height: 0.95;
110
+ 110| 110|}
111
+ 111| 111|
112
+ 112| 112|.subtitle {
113
+ 113| 113| max-width: 760px;
114
+ 114| 114| margin: 16px 0 0;
115
+ 115| 115| color: var(--muted);
116
+ 116| 116| font-size: 18px;
117
+ 117| 117| line-height: 1.45;
118
+ 118| 118|}
119
+ 119| 119|
120
+ 120| 120|.hero-actions {
121
+ 121| 121| min-width: 220px;
122
+ 122| 122| display: flex;
123
+ 123| 123| flex-direction: column;
124
+ 124| 124| gap: 14px;
125
+ 125| 125| align-items: flex-end;
126
+ 126| 126|}
127
+ 127| 127|
128
+ 128| 128|.hero-controls {
129
+ 129| 129| display: flex;
130
+ 130| 130| gap: 10px;
131
+ 131| 131| align-items: center;
132
+ 132| 132| flex-wrap: wrap;
133
+ 133| 133| justify-content: flex-end;
134
+ 134| 134|}
135
+ 135| 135|
136
+ 136| 136|button {
137
+ 137| 137| appearance: none;
138
+ 138| 138| border: 0;
139
+ 139| 139| border-radius: 999px;
140
+ 140| 140| padding: 12px 18px;
141
+ 141| 141| font: inherit;
142
+ 142| 142| background: var(--button-bg);
143
+ 143| 143| color: var(--button-ink);
144
+ 144| 144| cursor: pointer;
145
+ 145| 145| transition: background 140ms ease, color 140ms ease, border-color 140ms ease, transform 140ms ease;
146
+ 146| 146|}
147
+ 147| 147|
148
+ 148| 148|button:hover {
149
+ 149| 149| background: var(--button-hover);
150
+ 150| 150|}
151
+ 151| 151|
152
+ 152| 152|button:active {
153
+ 153| 153| transform: translateY(1px);
154
+ 154| 154|}
155
+ 155| 155|
156
+ 156| 156|#theme-toggle {
157
+ 157| 157| background: var(--theme-toggle-bg);
158
+ 158| 158| color: var(--theme-toggle-ink);
159
+ 159| 159| border: 1px solid var(--theme-toggle-line);
160
+ 160| 160|}
161
+ 161| 161|
162
+ 162| 162|#theme-toggle:hover {
163
+ 163| 163| background: var(--theme-toggle-hover);
164
+ 164| 164|}
165
+ 165| 165|
166
+ 166| 166|.meta {
167
+ 167| 167| text-align: right;
168
+ 168| 168| color: var(--muted);
169
+ 169| 169| font-size: 14px;
170
+ 170| 170|}
171
+ 171| 171|
172
+ 172| 172|.overview {
173
+ 173| 173| margin-top: 24px;
174
+ 174| 174| display: grid;
175
+ 175| 175| grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
176
+ 176| 176| gap: 14px;
177
+ 177| 177|}
178
+ 178| 178|
179
+ 179| 179|.card {
180
+ 180| 180| padding: 18px;
181
+ 181| 181| border-radius: 22px;
182
+ 182| 182| border: 1px solid var(--line);
183
+ 183| 183| background: var(--panel);
184
+ 184| 184| box-shadow: var(--shadow);
185
+ 185| 185|}
186
+ 186| 186|
187
+ 187| 187|.stat-label {
188
+ 188| 188| color: var(--muted);
189
+ 189| 189| font-size: 13px;
190
+ 190| 190| text-transform: uppercase;
191
+ 191| 191| letter-spacing: 0.06em;
192
+ 192| 192|}
193
+ 193| 193|
194
+ 194| 194|.stat-value {
195
+ 195| 195| margin-top: 8px;
196
+ 196| 196| font-size: 34px;
197
+ 197| 197| font-weight: 700;
198
+ 198| 198|}
199
+ 199| 199|
200
+ 200| 200|.profiles {
201
+ 201| 201| margin-top: 28px;
202
+ 202| 202| display: flex;
203
+ 203| 203| flex-direction: column;
204
+ 204| 204| gap: 22px;
205
+ 205| 205|}
206
+ 206| 206|
207
+ 207| 207|.profile {
208
+ 208| 208| padding: 22px;
209
+ 209| 209| border-radius: 28px;
210
+ 210| 210| border: 1px solid var(--line);
211
+ 211| 211| background: var(--profile-bg);
212
+ 212| 212| box-shadow: var(--shadow);
213
+ 213| 213|}
214
+ 214| 214|
215
+ 215| 215|.profile-header {
216
+ 216| 216| display: flex;
217
+ 217| 217| justify-content: space-between;
218
+ 218| 218| gap: 16px;
219
+ 219| 219| align-items: flex-start;
220
+ 220| 220|}
221
+ 221| 221|
222
+ 222| 222|.profile-title {
223
+ 223| 223| display: flex;
224
+ 224| 224| flex-wrap: wrap;
225
+ 225| 225| gap: 10px;
226
+ 226| 226| align-items: center;
227
+ 227| 227|}
228
+ 228| 228|
229
+ 229| 229|.profile-title h2 {
230
+ 230| 230| margin: 0;
231
+ 231| 231| font-size: 28px;
232
+ 232| 232|}
233
+ 233| 233|
234
+ 234| 234|.profile-subtitle {
235
+ 235| 235| margin-top: 8px;
236
+ 236| 236| color: var(--muted);
237
+ 237| 237|}
238
+ 238| 238|
239
+ 239| 239|.badge-row {
240
+ 240| 240| display: flex;
241
+ 241| 241| flex-wrap: wrap;
242
+ 242| 242| gap: 8px;
243
+ 243| 243| justify-content: flex-end;
244
+ 244| 244|}
245
+ 245| 245|
246
+ 246| 246|.badge {
247
+ 247| 247| display: inline-flex;
248
+ 248| 248| align-items: center;
249
+ 249| 249| gap: 6px;
250
+ 250| 250| padding: 7px 10px;
251
+ 251| 251| border-radius: 999px;
252
+ 252| 252| font-size: 13px;
253
+ 253| 253| border: 1px solid transparent;
254
+ 254| 254| background: var(--panel-strong);
255
+ 255| 255|}
256
+ 256| 256|
257
+ 257| 257|.badge.good {
258
+ 258| 258| background: var(--accent-soft);
259
+ 259| 259| color: var(--accent);
260
+ 260| 260|}
261
+ 261| 261|
262
+ 262| 262|.badge.warn {
263
+ 263| 263| background: var(--warn-soft);
264
+ 264| 264| color: var(--warn);
265
+ 265| 265|}
266
+ 266| 266|
267
+ 267| 267|.badge.danger {
268
+ 268| 268| background: var(--danger-soft);
269
+ 269| 269| color: var(--danger);
270
+ 270| 270|}
271
+ 271| 271|
272
+ 272| 272|.profile-grid {
273
+ 273| 273| margin-top: 18px;
274
+ 274| 274| display: grid;
275
+ 275| 275| grid-template-columns: repeat(12, minmax(0, 1fr));
276
+ 276| 276| gap: 14px;
277
+ 277| 277|}
278
+ 278| 278|
279
+ 279| 279|.panel {
280
+ 280| 280| grid-column: span 12;
281
+ 281| 281| padding: 16px;
282
+ 282| 282| border-radius: 22px;
283
+ 283| 283| border: 1px solid var(--line);
284
+ 284| 284| background: var(--panel);
285
+ 285| 285|}
286
+ 286| 286|
287
+ 287| 287|.panel.half {
288
+ 288| 288| grid-column: span 6;
289
+ 289| 289|}
290
+ 290| 290|
291
+ 291| 291|.panel.third {
292
+ 292| 292| grid-column: span 4;
293
+ 293| 293|}
294
+ 294| 294|
295
+ 295| 295|.panel h3 {
296
+ 296| 296| margin: 0 0 12px;
297
+ 297| 297| font-size: 18px;
298
+ 298| 298|}
299
+ 299| 299|
300
+ 300| 300|.panel-subtitle {
301
+ 301| 301| margin: -6px 0 12px;
302
+ 302| 302| color: var(--muted);
303
+ 303| 303| font-size: 14px;
304
+ 304| 304|}
305
+ 305| 305|
306
+ 306| 306|.alert-list {
307
+ 307| 307| display: grid;
308
+ 308| 308| gap: 12px;
309
+ 309| 309|}
310
+ 310| 310|
311
+ 311| 311|.alert-card {
312
+ 312| 312| padding: 14px 16px;
313
+ 313| 313| border-radius: 18px;
314
+ 314| 314| border: 1px solid var(--line);
315
+ 315| 315| background: var(--panel-strong);
316
+ 316| 316|}
317
+ 317| 317|
318
+ 318| 318|.alert-card.warn {
319
+ 319| 319| border-color: color-mix(in srgb, var(--warn) 45%, var(--line));
320
+ 320| 320| background: color-mix(in srgb, var(--warn-soft) 82%, var(--panel) 18%);
321
+ 321| 321|}
322
+ 322| 322|
323
+ 323| 323|.alert-card h4 {
324
+ 324| 324| margin: 0;
325
+ 325| 325| font-size: 17px;
326
+ 326| 326|}
327
+ 327| 327|
328
+ 328| 328|.alert-card p {
329
+ 329| 329| margin: 10px 0 0;
330
+ 330| 330| line-height: 1.5;
331
+ 331| 331|}
332
+ 332| 332|
333
+ 333| 333|.alert-header {
334
+ 334| 334| display: flex;
335
+ 335| 335| gap: 12px;
336
+ 336| 336| justify-content: space-between;
337
+ 337| 337| align-items: flex-start;
338
+ 338| 338|}
339
+ 339| 339|
340
+ 340| 340|.alert-meta {
341
+ 341| 341| margin-top: 10px;
342
+ 342| 342| display: flex;
343
+ 343| 343| flex-wrap: wrap;
344
+ 344| 344| gap: 12px;
345
+ 345| 345| color: var(--muted);
346
+ 346| 346| font-size: 13px;
347
+ 347| 347|}
348
+ 348| 348|
349
+ 349| 349|.table-wrap {
350
+ 350| 350| overflow-x: auto;
351
+ 351| 351|}
352
+ 352| 352|
353
+ 353| 353|table {
354
+ 354| 354| width: 100%;
355
+ 355| 355| border-collapse: collapse;
356
+ 356| 356| font-size: 14px;
357
+ 357| 357|}
358
+ 358| 358|
359
+ 359| 359|th,
360
+ 360| 360|td {
361
+ 361| 361| padding: 10px 8px;
362
+ 362| 362| text-align: left;
363
+ 363| 363| vertical-align: top;
364
+ 364| 364| border-top: 1px solid var(--line);
365
+ 365| 365|}
366
+ 366| 366|
367
+ 367| 367|th {
368
+ 368| 368| color: var(--muted);
369
+ 369| 369| font-size: 12px;
370
+ 370| 370| text-transform: uppercase;
371
+ 371| 371| letter-spacing: 0.06em;
372
+ 372| 372| border-top: 0;
373
+ 373| 373|}
374
+ 374| 374|
375
+ 375| 375|.mono {
376
+ 376| 376| font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
377
+ 377| 377| font-size: 12px;
378
+ 378| 378|}
379
+ 379| 379|
380
+ 380| 380|.muted {
381
+ 381| 381| color: var(--muted);
382
+ 382| 382|}
383
+ 383| 383|
384
+ 384| 384|.status-pill {
385
+ 385| 385| display: inline-flex;
386
+ 386| 386| align-items: center;
387
+ 387| 387| padding: 4px 8px;
388
+ 388| 388| border-radius: 999px;
389
+ 389| 389| font-size: 12px;
390
+ 390| 390| font-weight: 700;
391
+ 391| 391| background: var(--panel-strong);
392
+ 392| 392|}
393
+ 393| 393|
394
+ 394| 394|.status-pill.RUNNING,
395
+ 395| 395|.status-pill.waiting-worker,
396
+ 396| 396|.status-pill.launching,
397
+ 397| 397|.status-pill.reconciling {
398
+ 398| 398| background: var(--accent-soft);
399
+ 399| 399| color: var(--accent);
400
+ 400| 400|}
401
+ 401| 401|
402
+ 402| 402|.status-pill.waiting-provider,
403
+ 403| 403|.status-pill.waiting-due,
404
+ 404| 404|.status-pill.waiting-open-pr,
405
+ 405| 405|.status-pill.idle,
406
+ 406| 406|.status-pill.sleeping {
407
+ 407| 407| background: var(--warn-soft);
408
+ 408| 408| color: var(--warn);
409
+ 409| 409|}
410
+ 410| 410|
411
+ 411| 411|.status-pill.FAILED,
412
+ 412| 412|.status-pill.stopped,
413
+ 413| 413|.status-pill.launch-failed {
414
+ 414| 414| background: var(--danger-soft);
415
+ 415| 415| color: var(--danger);
416
+ 416| 416|}
417
+ 417| 417|
418
+ 418| 418|.status-pill.implemented {
419
+ 419| 419| background: var(--implemented-soft);
420
+ 420| 420| color: var(--implemented-ink);
421
+ 421| 421|}
422
+ 422| 422|
423
+ 423| 423|.status-pill.reported,
424
+ 424| 424|.status-pill.completed {
425
+ 425| 425| background: var(--reported-soft);
426
+ 426| 426| color: var(--reported-ink);
427
+ 427| 427|}
428
+ 428| 428|
429
+ 429| 429|.status-pill.blocked {
430
+ 430| 430| background: var(--blocked-soft);
431
+ 431| 431| color: var(--blocked-ink);
432
+ 432| 432|}
433
+ 433| 433|
434
+ 434| 434|.status-pill.failed,
435
+ 435| 435|.status-pill.unknown {
436
+ 436| 436| background: var(--danger-soft);
437
+ 437| 437| color: var(--danger);
438
+ 438| 438|}
439
+ 439| 439|
440
+ 440| 440|.status-pill.running {
441
+ 441| 441| background: var(--accent-soft);
442
+ 442| 442| color: var(--accent);
443
+ 443| 443|}
444
+ 444| 444|
445
+ 445| 445|.empty-state {
446
+ 446| 446| color: var(--muted);
447
+ 447| 447| padding: 10px 4px;
448
+ 448| 448|}
449
+ 449| 449|
450
+ 450| 450|@media (max-width: 960px) {
451
+ 451| 451| .hero,
452
+ 452| 452| .profile-header {
453
+ 453| 453| flex-direction: column;
454
+ 454| 454| }
455
+ 455| 455|
456
+ 456| 456| .hero-actions,
457
+ 457| 457| .badge-row {
458
+ 458| 458| align-items: flex-start;
459
+ 459| 459| justify-content: flex-start;
460
+ 460| 460| text-align: left;
461
+ 461| 461| }
462
+ 462| 462|
463
+ 463| 463| .hero-controls {
464
+ 464| 464| justify-content: flex-start;
465
+ 465| 465| }
466
+ 466| 466|
467
+ 467| 467| .panel.half,
468
+ 468| 468| .panel.third {
469
+ 469| 469| grid-column: span 12;
470
+ 470| 470| }
471
+ 471| 471|}
472
+ 472| 472|
473
+ 473|
474
+ 474|/* Filter bar */
475
+ 475|.filter-bar {
476
+ 476| display: flex;
477
+ 477| gap: 8px;
478
+ 478| margin-bottom: 12px;
479
+ 479| flex-wrap: wrap;
480
+ 480| align-items: center;
481
+ 481|}
482
+ 482|
483
+ 483|.filter-search {
484
+ 484| flex: 1;
485
+ 485| min-width: 200px;
486
+ 486| padding: 6px 10px;
487
+ 487| border: 1px solid var(--line);
488
+ 488| border-radius: 6px;
489
+ 489| background: var(--panel);
490
+ 490| color: var(--ink);
491
+ 491| font-size: 13px;
492
+ 492|}
493
+ 493|
494
+ 494|.filter-search:focus {
495
+ 495| outline: none;
496
+ 496| border-color: var(--accent);
497
+ 497| box-shadow: 0 0 0 2px var(--accent-soft);
498
+ 498|}
499
+ 499|
500
+ 500|.filter-btn {
501
+ 501|
502
+
503
+ /* Action bar */
504
+ .action-bar {
87
505
  display: flex;
88
- justify-content: space-between;
89
- gap: 24px;
90
- align-items: flex-start;
91
- padding: 24px;
92
- border: 1px solid var(--line);
93
- border-radius: 28px;
94
- background: var(--hero-bg);
95
- box-shadow: var(--shadow);
96
- }
97
-
98
- .eyebrow {
99
- margin: 0 0 8px;
100
- text-transform: uppercase;
101
- letter-spacing: 0.08em;
102
- font-size: 12px;
103
- color: var(--accent);
104
- }
105
-
106
- .hero h1 {
107
- margin: 0;
108
- font-size: clamp(34px, 5vw, 56px);
109
- line-height: 0.95;
110
- }
111
-
112
- .subtitle {
113
- max-width: 760px;
114
- margin: 16px 0 0;
115
- color: var(--muted);
116
- font-size: 18px;
117
- line-height: 1.45;
118
- }
119
-
120
- .hero-actions {
121
- min-width: 220px;
122
- display: flex;
123
- flex-direction: column;
124
- gap: 14px;
125
- align-items: flex-end;
126
- }
127
-
128
- .hero-controls {
129
- display: flex;
130
- gap: 10px;
506
+ gap: 8px;
131
507
  align-items: center;
132
- flex-wrap: wrap;
133
- justify-content: flex-end;
508
+ margin-bottom: 12px;
134
509
  }
135
510
 
136
- button {
137
- appearance: none;
138
- border: 0;
139
- border-radius: 999px;
140
- padding: 12px 18px;
141
- font: inherit;
142
- background: var(--button-bg);
143
- color: var(--button-ink);
511
+ .action-btn {
512
+ padding: 6px 16px;
513
+ border: 1px solid var(--accent);
514
+ border-radius: 6px;
515
+ background: var(--accent);
516
+ color: #fff;
517
+ font-size: 13px;
144
518
  cursor: pointer;
145
- transition: background 140ms ease, color 140ms ease, border-color 140ms ease, transform 140ms ease;
519
+ transition: all 0.15s ease;
146
520
  }
147
521
 
148
- button:hover {
522
+ .action-btn:hover {
149
523
  background: var(--button-hover);
524
+ border-color: var(--button-hover);
150
525
  }
151
526
 
152
- button:active {
153
- transform: translateY(1px);
154
- }
155
-
156
- #theme-toggle {
157
- background: var(--theme-toggle-bg);
158
- color: var(--theme-toggle-ink);
159
- border: 1px solid var(--theme-toggle-line);
160
- }
161
-
162
- #theme-toggle:hover {
163
- background: var(--theme-toggle-hover);
164
- }
165
-
166
- .meta {
167
- text-align: right;
168
- color: var(--muted);
169
- font-size: 14px;
527
+ .action-btn:active {
528
+ transform: scale(0.98);
170
529
  }
171
530
 
172
- .overview {
173
- margin-top: 24px;
174
- display: grid;
175
- grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
176
- gap: 14px;
177
- }
178
-
179
- .card {
180
- padding: 18px;
181
- border-radius: 22px;
531
+ .doctor-output {
532
+ margin-top: 12px;
533
+ padding: 12px;
182
534
  border: 1px solid var(--line);
183
- background: var(--panel);
184
- box-shadow: var(--shadow);
185
- }
186
-
187
- .stat-label {
188
- color: var(--muted);
189
- font-size: 13px;
190
- text-transform: uppercase;
191
- letter-spacing: 0.06em;
192
- }
193
-
194
- .stat-value {
195
- margin-top: 8px;
196
- font-size: 34px;
197
- font-weight: 700;
198
- }
199
-
200
- .profiles {
201
- margin-top: 28px;
202
- display: flex;
203
- flex-direction: column;
204
- gap: 22px;
205
- }
206
-
207
- .profile {
208
- padding: 22px;
209
- border-radius: 28px;
210
- border: 1px solid var(--line);
211
- background: var(--profile-bg);
212
- box-shadow: var(--shadow);
213
- }
214
-
215
- .profile-header {
216
- display: flex;
217
- justify-content: space-between;
218
- gap: 16px;
219
- align-items: flex-start;
220
- }
221
-
222
- .profile-title {
223
- display: flex;
224
- flex-wrap: wrap;
225
- gap: 10px;
226
- align-items: center;
227
- }
228
-
229
- .profile-title h2 {
230
- margin: 0;
231
- font-size: 28px;
232
- }
233
-
234
- .profile-subtitle {
235
- margin-top: 8px;
236
- color: var(--muted);
237
- }
238
-
239
- .badge-row {
240
- display: flex;
241
- flex-wrap: wrap;
242
- gap: 8px;
243
- justify-content: flex-end;
244
- }
245
-
246
- .badge {
247
- display: inline-flex;
248
- align-items: center;
249
- gap: 6px;
250
- padding: 7px 10px;
251
- border-radius: 999px;
252
- font-size: 13px;
253
- border: 1px solid transparent;
535
+ border-radius: 6px;
254
536
  background: var(--panel-strong);
255
- }
256
-
257
- .badge.good {
258
- background: var(--accent-soft);
259
- color: var(--accent);
260
- }
261
-
262
- .badge.warn {
263
- background: var(--warn-soft);
264
- color: var(--warn);
265
- }
266
-
267
- .badge.danger {
268
- background: var(--danger-soft);
269
- color: var(--danger);
270
- }
271
-
272
- .profile-grid {
273
- margin-top: 18px;
274
- display: grid;
275
- grid-template-columns: repeat(12, minmax(0, 1fr));
276
- gap: 14px;
277
- }
278
-
279
- .panel {
280
- grid-column: span 12;
281
- padding: 16px;
282
- border-radius: 22px;
283
- border: 1px solid var(--line);
284
- background: var(--panel);
285
- }
286
-
287
- .panel.half {
288
- grid-column: span 6;
289
- }
290
-
291
- .panel.third {
292
- grid-column: span 4;
293
- }
294
-
295
- .panel h3 {
296
- margin: 0 0 12px;
297
- font-size: 18px;
298
- }
299
-
300
- .panel-subtitle {
301
- margin: -6px 0 12px;
302
- color: var(--muted);
303
- font-size: 14px;
304
- }
305
-
306
- .alert-list {
307
- display: grid;
308
- gap: 12px;
309
- }
310
-
311
- .alert-card {
312
- padding: 14px 16px;
313
- border-radius: 18px;
314
- border: 1px solid var(--line);
315
- background: var(--panel-strong);
316
- }
317
-
318
- .alert-card.warn {
319
- border-color: color-mix(in srgb, var(--warn) 45%, var(--line));
320
- background: color-mix(in srgb, var(--warn-soft) 82%, var(--panel) 18%);
321
- }
322
-
323
- .alert-card h4 {
324
- margin: 0;
325
- font-size: 17px;
326
- }
327
-
328
- .alert-card p {
329
- margin: 10px 0 0;
330
- line-height: 1.5;
331
- }
332
-
333
- .alert-header {
334
- display: flex;
335
- gap: 12px;
336
- justify-content: space-between;
337
- align-items: flex-start;
338
- }
339
-
340
- .alert-meta {
341
- margin-top: 10px;
342
- display: flex;
343
- flex-wrap: wrap;
344
- gap: 12px;
345
- color: var(--muted);
346
- font-size: 13px;
347
- }
348
-
349
- .table-wrap {
350
- overflow-x: auto;
351
- }
352
-
353
- table {
354
- width: 100%;
355
- border-collapse: collapse;
356
- font-size: 14px;
357
- }
358
-
359
- th,
360
- td {
361
- padding: 10px 8px;
362
- text-align: left;
363
- vertical-align: top;
364
- border-top: 1px solid var(--line);
365
- }
366
-
367
- th {
368
- color: var(--muted);
369
- font-size: 12px;
370
- text-transform: uppercase;
371
- letter-spacing: 0.06em;
372
- border-top: 0;
373
- }
374
-
375
- .mono {
376
- font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
377
- font-size: 12px;
378
- }
379
-
380
- .muted {
381
- color: var(--muted);
382
- }
383
-
384
- .status-pill {
385
- display: inline-flex;
386
- align-items: center;
387
- padding: 4px 8px;
388
- border-radius: 999px;
537
+ color: var(--ink);
389
538
  font-size: 12px;
390
- font-weight: 700;
391
- background: var(--panel-strong);
392
- }
393
-
394
- .status-pill.RUNNING,
395
- .status-pill.waiting-worker,
396
- .status-pill.launching,
397
- .status-pill.reconciling {
398
- background: var(--accent-soft);
399
- color: var(--accent);
400
- }
401
-
402
- .status-pill.waiting-provider,
403
- .status-pill.waiting-due,
404
- .status-pill.waiting-open-pr,
405
- .status-pill.idle,
406
- .status-pill.sleeping {
407
- background: var(--warn-soft);
408
- color: var(--warn);
409
- }
410
-
411
- .status-pill.FAILED,
412
- .status-pill.stopped,
413
- .status-pill.launch-failed {
414
- background: var(--danger-soft);
415
- color: var(--danger);
416
- }
417
-
418
- .status-pill.implemented {
419
- background: var(--implemented-soft);
420
- color: var(--implemented-ink);
421
- }
422
-
423
- .status-pill.reported,
424
- .status-pill.completed {
425
- background: var(--reported-soft);
426
- color: var(--reported-ink);
427
- }
428
-
429
- .status-pill.blocked {
430
- background: var(--blocked-soft);
431
- color: var(--blocked-ink);
432
- }
433
-
434
- .status-pill.failed,
435
- .status-pill.unknown {
436
- background: var(--danger-soft);
437
- color: var(--danger);
438
- }
439
-
440
- .status-pill.running {
441
- background: var(--accent-soft);
442
- color: var(--accent);
443
- }
444
-
445
- .empty-state {
446
- color: var(--muted);
447
- padding: 10px 4px;
448
- }
449
-
450
- @media (max-width: 960px) {
451
- .hero,
452
- .profile-header {
453
- flex-direction: column;
454
- }
455
-
456
- .hero-actions,
457
- .badge-row {
458
- align-items: flex-start;
459
- justify-content: flex-start;
460
- text-align: left;
461
- }
462
-
463
- .hero-controls {
464
- justify-content: flex-start;
465
- }
466
-
467
- .panel.half,
468
- .panel.third {
469
- grid-column: span 12;
470
- }
539
+ max-height: 400px;
540
+ overflow-y: auto;
541
+ white-space: pre-wrap;
471
542
  }