bosun 0.26.3

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 (122) hide show
  1. package/.env.example +918 -0
  2. package/LICENSE +190 -0
  3. package/README.md +98 -0
  4. package/agent-endpoint.mjs +918 -0
  5. package/agent-hook-bridge.mjs +230 -0
  6. package/agent-hooks.mjs +1188 -0
  7. package/agent-pool.mjs +2403 -0
  8. package/agent-prompts.mjs +689 -0
  9. package/agent-sdk.mjs +141 -0
  10. package/anomaly-detector.mjs +1195 -0
  11. package/autofix.mjs +1294 -0
  12. package/bosun.config.example.json +115 -0
  13. package/bosun.schema.json +465 -0
  14. package/claude-shell.mjs +708 -0
  15. package/cli.mjs +1028 -0
  16. package/codex-config.mjs +1274 -0
  17. package/codex-model-profiles.mjs +135 -0
  18. package/codex-shell.mjs +762 -0
  19. package/compat.mjs +286 -0
  20. package/config-doctor.mjs +613 -0
  21. package/config.mjs +1724 -0
  22. package/conflict-resolver.mjs +248 -0
  23. package/container-runner.mjs +450 -0
  24. package/copilot-shell.mjs +827 -0
  25. package/daemon-restart-policy.mjs +56 -0
  26. package/diff-stats.mjs +282 -0
  27. package/error-detector.mjs +829 -0
  28. package/fetch-runtime.mjs +34 -0
  29. package/fleet-coordinator.mjs +838 -0
  30. package/get-telegram-chat-id.mjs +71 -0
  31. package/git-safety.mjs +170 -0
  32. package/github-reconciler.mjs +403 -0
  33. package/hook-profiles.mjs +651 -0
  34. package/kanban-adapter.mjs +4491 -0
  35. package/lib/logger.mjs +645 -0
  36. package/maintenance.mjs +828 -0
  37. package/merge-strategy.mjs +1171 -0
  38. package/monitor.mjs +12237 -0
  39. package/package.json +209 -0
  40. package/postinstall.mjs +187 -0
  41. package/pr-cleanup-daemon.mjs +978 -0
  42. package/preflight.mjs +408 -0
  43. package/prepublish-check.mjs +90 -0
  44. package/presence.mjs +328 -0
  45. package/primary-agent.mjs +290 -0
  46. package/publish.mjs +241 -0
  47. package/repo-root.mjs +29 -0
  48. package/restart-controller.mjs +100 -0
  49. package/review-agent.mjs +557 -0
  50. package/rotate-agent-logs.sh +133 -0
  51. package/sdk-conflict-resolver.mjs +973 -0
  52. package/session-tracker.mjs +880 -0
  53. package/setup.mjs +3946 -0
  54. package/shared-knowledge.mjs +410 -0
  55. package/shared-state-manager.mjs +841 -0
  56. package/shared-workspace-cli.mjs +199 -0
  57. package/shared-workspace-registry.mjs +537 -0
  58. package/shared-workspaces.json +18 -0
  59. package/startup-service.mjs +1070 -0
  60. package/sync-engine.mjs +1063 -0
  61. package/task-archiver.mjs +801 -0
  62. package/task-assessment.mjs +550 -0
  63. package/task-claims.mjs +924 -0
  64. package/task-complexity.mjs +581 -0
  65. package/task-executor.mjs +5111 -0
  66. package/task-store.mjs +753 -0
  67. package/telegram-bot.mjs +9683 -0
  68. package/telegram-sentinel.mjs +2010 -0
  69. package/ui/app.js +867 -0
  70. package/ui/app.legacy.js +1464 -0
  71. package/ui/app.monolith.js +2488 -0
  72. package/ui/components/charts.js +226 -0
  73. package/ui/components/chat-view.js +567 -0
  74. package/ui/components/command-palette.js +587 -0
  75. package/ui/components/diff-viewer.js +190 -0
  76. package/ui/components/forms.js +357 -0
  77. package/ui/components/kanban-board.js +451 -0
  78. package/ui/components/session-list.js +305 -0
  79. package/ui/components/shared.js +525 -0
  80. package/ui/demo.html +640 -0
  81. package/ui/index.html +70 -0
  82. package/ui/modules/api.js +297 -0
  83. package/ui/modules/icons.js +461 -0
  84. package/ui/modules/router.js +81 -0
  85. package/ui/modules/settings-schema.js +261 -0
  86. package/ui/modules/state.js +679 -0
  87. package/ui/modules/telegram.js +331 -0
  88. package/ui/modules/utils.js +270 -0
  89. package/ui/styles/animations.css +140 -0
  90. package/ui/styles/base.css +98 -0
  91. package/ui/styles/components.css +2032 -0
  92. package/ui/styles/kanban.css +286 -0
  93. package/ui/styles/layout.css +810 -0
  94. package/ui/styles/sessions.css +841 -0
  95. package/ui/styles/variables.css +188 -0
  96. package/ui/styles.css +141 -0
  97. package/ui/styles.monolith.css +1046 -0
  98. package/ui/tabs/agents.js +1417 -0
  99. package/ui/tabs/chat.js +75 -0
  100. package/ui/tabs/control.js +892 -0
  101. package/ui/tabs/dashboard.js +515 -0
  102. package/ui/tabs/infra.js +537 -0
  103. package/ui/tabs/logs.js +783 -0
  104. package/ui/tabs/settings.js +1509 -0
  105. package/ui/tabs/tasks.js +1385 -0
  106. package/ui-server.mjs +4084 -0
  107. package/update-check.mjs +471 -0
  108. package/utils.mjs +172 -0
  109. package/ve-kanban.mjs +654 -0
  110. package/ve-kanban.ps1 +1365 -0
  111. package/ve-kanban.sh +18 -0
  112. package/ve-orchestrator.mjs +340 -0
  113. package/ve-orchestrator.ps1 +6546 -0
  114. package/ve-orchestrator.sh +18 -0
  115. package/vibe-kanban-wrapper.mjs +41 -0
  116. package/vk-error-resolver.mjs +470 -0
  117. package/vk-log-stream.mjs +914 -0
  118. package/whatsapp-channel.mjs +520 -0
  119. package/workspace-monitor.mjs +581 -0
  120. package/workspace-reaper.mjs +405 -0
  121. package/workspace-registry.mjs +238 -0
  122. package/worktree-manager.mjs +1266 -0
@@ -0,0 +1,810 @@
1
+ /* ─── Layout: Header, Main Content, Bottom Nav, FAB — Mission Control ─── */
2
+
3
+ /* ─── Header ─── */
4
+ .app-header {
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: space-between;
8
+ height: var(--header-height);
9
+ padding: 0 20px;
10
+ padding-top: var(--content-safe-top);
11
+ background: var(--bg-secondary);
12
+ border-bottom: 1px solid var(--border);
13
+ box-shadow: var(--shadow-inset);
14
+ flex-shrink: 0;
15
+ z-index: 10;
16
+ position: relative;
17
+ }
18
+
19
+ .app-header::after {
20
+ content: none;
21
+ }
22
+
23
+ .app-header-left {
24
+ display: flex;
25
+ align-items: center;
26
+ gap: 10px;
27
+ }
28
+
29
+ .app-header-titles {
30
+ display: flex;
31
+ flex-direction: column;
32
+ gap: 2px;
33
+ }
34
+
35
+ .app-header-logo {
36
+ width: 28px;
37
+ height: 28px;
38
+ border-radius: 8px;
39
+ background: var(--gradient-accent);
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: center;
43
+ box-shadow: var(--shadow-sm);
44
+ flex-shrink: 0;
45
+ }
46
+
47
+ .app-header-logo svg {
48
+ width: 16px;
49
+ height: 16px;
50
+ color: #041016;
51
+ }
52
+
53
+ .app-header-title {
54
+ font-size: 17px;
55
+ font-weight: 700;
56
+ letter-spacing: -0.03em;
57
+ color: var(--text-bright);
58
+ }
59
+
60
+ .app-header-subtitle {
61
+ font-size: 12px;
62
+ font-weight: 500;
63
+ color: var(--text-secondary);
64
+ }
65
+
66
+ .app-header-hint {
67
+ font-size: 11px;
68
+ color: var(--text-hint);
69
+ }
70
+
71
+ .app-header-user {
72
+ font-size: 12px;
73
+ color: var(--text-secondary);
74
+ }
75
+
76
+ .header-actions {
77
+ display: flex;
78
+ align-items: center;
79
+ gap: 8px;
80
+ }
81
+
82
+ /* ─── Connection Pill ─── */
83
+ .connection-pill {
84
+ display: inline-flex;
85
+ align-items: center;
86
+ gap: 6px;
87
+ padding: 4px 12px;
88
+ border-radius: var(--radius-full);
89
+ font-size: 11px;
90
+ font-weight: 600;
91
+ background: var(--bg-card);
92
+ border: 1px solid var(--border);
93
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
94
+ }
95
+
96
+ .connection-pill.connected {
97
+ border-color: rgba(46, 160, 67, 0.4);
98
+ color: var(--color-done);
99
+ box-shadow: 0 0 12px rgba(46, 160, 67, 0.2);
100
+ }
101
+
102
+ .connection-pill.disconnected {
103
+ border-color: rgba(248, 81, 73, 0.45);
104
+ color: var(--color-error);
105
+ }
106
+
107
+ .connection-dot {
108
+ width: 6px;
109
+ height: 6px;
110
+ border-radius: 50%;
111
+ background: currentColor;
112
+ animation: pulse-dot 2s infinite;
113
+ position: relative;
114
+ }
115
+
116
+ .connection-pill.connected .connection-dot::after {
117
+ content: "";
118
+ position: absolute;
119
+ inset: -3px;
120
+ border-radius: 50%;
121
+ border: 1.5px solid currentColor;
122
+ opacity: 0;
123
+ animation: pulseRing 2s ease-out infinite;
124
+ }
125
+
126
+ @keyframes pulseRing {
127
+ 0% { transform: scale(0.8); opacity: 0.6; }
128
+ 100% { transform: scale(2); opacity: 0; }
129
+ }
130
+
131
+ /* ─── Main Content ─── */
132
+ .main-content {
133
+ flex: 1;
134
+ min-height: 0;
135
+ overflow-y: auto;
136
+ overflow-x: hidden;
137
+ scrollbar-gutter: stable;
138
+ padding: 16px 16px 20px;
139
+ padding-bottom: calc(var(--nav-height) + var(--safe-bottom) + 40px);
140
+ -webkit-overflow-scrolling: touch;
141
+ scroll-behavior: smooth;
142
+ touch-action: pan-y;
143
+ position: relative;
144
+ z-index: 1;
145
+ }
146
+
147
+ /* ─── Tab Panel ─── */
148
+ .tab-panel {
149
+ display: none;
150
+ animation: fadeIn 0.25s ease;
151
+ }
152
+
153
+ .tab-panel.active {
154
+ display: block;
155
+ }
156
+
157
+ /* Staggered card entrance */
158
+ .main-content > * {
159
+ animation: cardReveal 0.25s cubic-bezier(0.4, 0, 0.2, 1) both;
160
+ }
161
+ .main-content > *:nth-child(1) { animation-delay: 0s; }
162
+ .main-content > *:nth-child(2) { animation-delay: 0.05s; }
163
+ .main-content > *:nth-child(3) { animation-delay: 0.1s; }
164
+ .main-content > *:nth-child(4) { animation-delay: 0.15s; }
165
+ .main-content > *:nth-child(5) { animation-delay: 0.2s; }
166
+ .main-content > *:nth-child(6) { animation-delay: 0.25s; }
167
+ .main-content > *:nth-child(7) { animation-delay: 0.3s; }
168
+ .main-content > *:nth-child(8) { animation-delay: 0.35s; }
169
+
170
+ @keyframes cardReveal {
171
+ from { opacity: 0; transform: translateY(10px); }
172
+ to { opacity: 1; transform: translateY(0); }
173
+ }
174
+
175
+ /* ─── Bottom Navigation — Floating Pill ─── */
176
+ .bottom-nav {
177
+ position: fixed;
178
+ bottom: calc(12px + var(--safe-bottom));
179
+ left: 16px;
180
+ right: 16px;
181
+ height: var(--nav-height);
182
+ background: var(--bg-secondary);
183
+ border: 1px solid var(--border);
184
+ border-radius: var(--radius-xl);
185
+ display: flex;
186
+ align-items: center;
187
+ justify-content: space-around;
188
+ z-index: 500;
189
+ box-shadow: var(--shadow-md);
190
+ animation: navSlideUp 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) 0.2s both;
191
+ padding-bottom: env(safe-area-inset-bottom, 0px);
192
+ }
193
+
194
+ @keyframes navSlideUp {
195
+ from { opacity: 0; transform: translateY(20px); }
196
+ to { opacity: 1; transform: translateY(0); }
197
+ }
198
+
199
+ .nav-item {
200
+ display: flex;
201
+ flex-direction: column;
202
+ align-items: center;
203
+ justify-content: center;
204
+ gap: 3px;
205
+ padding: 8px 0;
206
+ min-width: 48px;
207
+ min-height: 44px;
208
+ border: none;
209
+ background: none;
210
+ color: var(--text-hint);
211
+ font-size: 10px;
212
+ font-weight: 500;
213
+ cursor: pointer;
214
+ transition: color 0.2s ease, transform 0.15s ease;
215
+ -webkit-tap-highlight-color: transparent;
216
+ position: relative;
217
+ border-radius: var(--radius-md);
218
+ }
219
+
220
+ .nav-item:active {
221
+ transform: scale(0.9);
222
+ }
223
+
224
+ .nav-item:focus-visible {
225
+ outline: 2px solid var(--accent);
226
+ outline-offset: 2px;
227
+ }
228
+
229
+ .nav-item.active {
230
+ color: var(--accent);
231
+ }
232
+
233
+ .nav-item.active::before {
234
+ content: "";
235
+ position: absolute;
236
+ inset: 4px;
237
+ border-radius: var(--radius-md);
238
+ background: rgba(88, 166, 255, 0.18);
239
+ z-index: -1;
240
+ animation: scaleIn 0.2s ease;
241
+ }
242
+
243
+ .nav-item.active svg {
244
+ transform: scale(1.05);
245
+ filter: none;
246
+ }
247
+
248
+ .nav-item svg {
249
+ width: 22px;
250
+ height: 22px;
251
+ transition: transform 0.2s ease, filter 0.2s ease;
252
+ }
253
+
254
+ .nav-label {
255
+ line-height: 1;
256
+ }
257
+
258
+ /* ─── FAB ─── */
259
+ .fab {
260
+ position: fixed;
261
+ right: 16px;
262
+ bottom: calc(var(--nav-height) + var(--safe-bottom) + 28px);
263
+ width: 52px;
264
+ height: 52px;
265
+ border-radius: var(--radius-lg);
266
+ background: var(--accent);
267
+ color: white;
268
+ border: none;
269
+ display: flex;
270
+ align-items: center;
271
+ justify-content: center;
272
+ box-shadow: var(--shadow-lg);
273
+ cursor: pointer;
274
+ z-index: 50;
275
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
276
+ }
277
+
278
+ .fab:active {
279
+ transform: scale(0.9);
280
+ }
281
+
282
+ .fab:hover {
283
+ box-shadow: var(--shadow-xl);
284
+ }
285
+
286
+ .fab svg {
287
+ width: 24px;
288
+ height: 24px;
289
+ }
290
+
291
+ .scroll-top {
292
+ position: fixed;
293
+ left: 16px;
294
+ bottom: calc(var(--nav-height) + var(--safe-bottom) + 20px);
295
+ padding: 8px 12px;
296
+ border-radius: var(--radius-full);
297
+ border: 1px solid var(--border);
298
+ background: var(--bg-secondary);
299
+ color: var(--text-bright);
300
+ font-size: 12px;
301
+ font-weight: 600;
302
+ box-shadow: var(--shadow-md);
303
+ cursor: pointer;
304
+ z-index: 60;
305
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
306
+ }
307
+
308
+ .scroll-top:active {
309
+ transform: scale(0.95);
310
+ }
311
+
312
+ .scroll-top:hover {
313
+ box-shadow: var(--shadow-lg);
314
+ }
315
+
316
+ /* ─── Responsive ─── */
317
+ @media (max-width: 380px) {
318
+ .nav-label {
319
+ font-size: 9px;
320
+ }
321
+ }
322
+
323
+ @media (max-width: 360px) {
324
+ .app-header-hint {
325
+ display: none;
326
+ }
327
+ }
328
+
329
+ @media (min-width: 768px) {
330
+ .main-content {
331
+ max-width: 960px;
332
+ width: 100%;
333
+ margin-left: auto;
334
+ margin-right: auto;
335
+ padding: 24px;
336
+ padding-bottom: calc(var(--nav-height) + var(--safe-bottom) + 24px);
337
+ }
338
+
339
+ .app-header {
340
+ height: 60px;
341
+ }
342
+
343
+ .bottom-nav {
344
+ left: 50%;
345
+ right: auto;
346
+ width: 480px;
347
+ transform: translateX(-50%);
348
+ animation: navSlideUpDesktop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) 0.2s both;
349
+ }
350
+
351
+ @keyframes navSlideUpDesktop {
352
+ from { opacity: 0; transform: translateX(-50%) translateY(20px); }
353
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
354
+ }
355
+
356
+ .nav-item {
357
+ min-width: 64px;
358
+ gap: 4px;
359
+ }
360
+
361
+ .nav-label {
362
+ font-size: 11px;
363
+ font-weight: 600;
364
+ }
365
+ }
366
+
367
+ /* ─── Desktop Shell: Sidebar + Session Rail ─── */
368
+ .app-shell {
369
+ min-height: 100%;
370
+ display: flex;
371
+ flex-direction: column;
372
+ position: relative;
373
+ z-index: 1;
374
+ }
375
+
376
+ .app-main {
377
+ display: flex;
378
+ flex-direction: column;
379
+ min-height: 0;
380
+ flex: 1;
381
+ }
382
+
383
+ .main-panel {
384
+ display: flex;
385
+ flex-direction: column;
386
+ min-height: 0;
387
+ flex: 1;
388
+ background: var(--gradient-surface);
389
+ border: 1px solid var(--border);
390
+ border-radius: var(--radius-xl);
391
+ box-shadow: var(--shadow-lg);
392
+ overflow: hidden;
393
+ }
394
+
395
+ .sidebar,
396
+ .session-rail {
397
+ display: none;
398
+ }
399
+
400
+ .inspector {
401
+ display: none;
402
+ }
403
+
404
+ @media (min-width: 1200px) {
405
+ body {
406
+ overflow: hidden;
407
+ }
408
+
409
+ .app-shell {
410
+ display: grid;
411
+ grid-template-columns: var(--sidebar-width) var(--rail-width) minmax(0, 1fr);
412
+ grid-template-rows: 1fr;
413
+ grid-template-areas: "sidebar rail main";
414
+ gap: var(--shell-gap);
415
+ padding: var(--shell-gap);
416
+ height: var(--viewport-stable-height);
417
+ }
418
+
419
+ .app-shell[data-has-rail="false"] {
420
+ grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
421
+ grid-template-areas: "sidebar main";
422
+ }
423
+
424
+ .app-shell[data-has-inspector="true"] {
425
+ grid-template-columns: var(--sidebar-width) var(--rail-width) minmax(0, 1fr) var(--inspector-width);
426
+ grid-template-areas: "sidebar rail main inspector";
427
+ }
428
+
429
+ .app-shell[data-has-rail="false"][data-has-inspector="true"] {
430
+ grid-template-columns: var(--sidebar-width) minmax(0, 1fr) var(--inspector-width);
431
+ grid-template-areas: "sidebar main inspector";
432
+ }
433
+
434
+ .sidebar {
435
+ display: flex;
436
+ flex-direction: column;
437
+ grid-area: sidebar;
438
+ background: var(--bg-secondary);
439
+ border: 1px solid var(--border);
440
+ border-radius: var(--radius-lg);
441
+ padding: 16px 12px;
442
+ gap: 16px;
443
+ box-shadow: var(--shadow-md);
444
+ }
445
+
446
+ .session-rail {
447
+ display: flex;
448
+ flex-direction: column;
449
+ grid-area: rail;
450
+ background: var(--bg-secondary);
451
+ border: 1px solid var(--border);
452
+ border-radius: var(--radius-lg);
453
+ padding: 12px;
454
+ min-height: 0;
455
+ box-shadow: var(--shadow-md);
456
+ }
457
+
458
+ .app-main {
459
+ grid-area: main;
460
+ min-height: 0;
461
+ border-radius: var(--radius-lg);
462
+ overflow: hidden;
463
+ }
464
+
465
+ .inspector {
466
+ display: flex;
467
+ flex-direction: column;
468
+ grid-area: inspector;
469
+ background: var(--bg-secondary);
470
+ border: 1px solid var(--border);
471
+ border-radius: var(--radius-lg);
472
+ padding: 12px;
473
+ gap: 12px;
474
+ min-height: 0;
475
+ box-shadow: var(--shadow-md);
476
+ }
477
+
478
+ .app-header {
479
+ border-radius: var(--radius-lg);
480
+ border: 1px solid var(--border);
481
+ margin-bottom: var(--space-md);
482
+ position: sticky;
483
+ top: 0;
484
+ backdrop-filter: blur(12px);
485
+ z-index: 5;
486
+ }
487
+
488
+ .main-content {
489
+ padding: 20px 24px 32px;
490
+ padding-bottom: 32px;
491
+ max-width: var(--content-max);
492
+ margin: 0 auto;
493
+ }
494
+
495
+ .bottom-nav {
496
+ display: none;
497
+ }
498
+
499
+ .scroll-top {
500
+ left: auto;
501
+ right: 32px;
502
+ bottom: 32px;
503
+ }
504
+ }
505
+
506
+ /* ─── Sidebar styling ─── */
507
+ .sidebar-brand {
508
+ display: flex;
509
+ align-items: center;
510
+ gap: 10px;
511
+ }
512
+
513
+ .sidebar-logo {
514
+ width: 40px;
515
+ height: 40px;
516
+ border-radius: 14px;
517
+ background: var(--gradient-accent);
518
+ display: flex;
519
+ align-items: center;
520
+ justify-content: center;
521
+ color: #041016;
522
+ box-shadow: var(--shadow-glow-sm);
523
+ }
524
+
525
+ .sidebar-logo svg {
526
+ width: 20px;
527
+ height: 20px;
528
+ }
529
+
530
+ .sidebar-title {
531
+ font-size: 14px;
532
+ font-weight: 700;
533
+ color: var(--text-bright);
534
+ }
535
+
536
+ .sidebar-subtitle {
537
+ font-size: 11px;
538
+ color: var(--text-secondary);
539
+ }
540
+
541
+ .sidebar-actions {
542
+ display: flex;
543
+ flex-direction: column;
544
+ gap: 8px;
545
+ }
546
+
547
+ .sidebar-nav {
548
+ display: flex;
549
+ flex-direction: column;
550
+ gap: 6px;
551
+ flex: 1;
552
+ }
553
+
554
+ .sidebar-nav-item {
555
+ display: flex;
556
+ flex-direction: column;
557
+ align-items: center;
558
+ justify-content: center;
559
+ gap: 4px;
560
+ padding: 10px 6px;
561
+ border-radius: 14px;
562
+ background: transparent;
563
+ border: none;
564
+ color: var(--text-hint);
565
+ font-size: 10px;
566
+ font-weight: 600;
567
+ cursor: pointer;
568
+ transition: background var(--transition-fast), color var(--transition-fast), transform 0.2s ease;
569
+ }
570
+
571
+ .sidebar-nav-item svg {
572
+ width: 20px;
573
+ height: 20px;
574
+ }
575
+
576
+ .sidebar-nav-item span {
577
+ font-size: 10px;
578
+ letter-spacing: 0.02em;
579
+ }
580
+
581
+ .sidebar-nav-item:hover {
582
+ background: rgba(76, 201, 240, 0.12);
583
+ color: var(--text-bright);
584
+ }
585
+
586
+ .sidebar-nav-item:focus-visible {
587
+ outline: 2px solid var(--accent);
588
+ outline-offset: 2px;
589
+ }
590
+
591
+ .sidebar-nav-item.active {
592
+ background: rgba(76, 201, 240, 0.2);
593
+ color: var(--accent);
594
+ box-shadow: inset 0 0 0 1px rgba(76, 201, 240, 0.35);
595
+ }
596
+
597
+ .sidebar-footer {
598
+ border-top: 1px solid var(--border);
599
+ padding-top: 12px;
600
+ font-size: 11px;
601
+ color: var(--text-secondary);
602
+ display: flex;
603
+ flex-direction: column;
604
+ gap: 6px;
605
+ }
606
+
607
+ .sidebar-status {
608
+ display: inline-flex;
609
+ align-items: center;
610
+ gap: 6px;
611
+ }
612
+
613
+ .sidebar-status-dot {
614
+ width: 8px;
615
+ height: 8px;
616
+ border-radius: 50%;
617
+ background: var(--color-error);
618
+ box-shadow: 0 0 10px rgba(248, 113, 113, 0.4);
619
+ }
620
+
621
+ .sidebar-status.online .sidebar-status-dot {
622
+ background: var(--color-done);
623
+ box-shadow: 0 0 10px rgba(52, 211, 153, 0.4);
624
+ }
625
+
626
+ .sidebar-user {
627
+ font-size: 10px;
628
+ color: var(--text-hint);
629
+ }
630
+
631
+ /* ─── Session rail tweaks ─── */
632
+ .session-rail .session-list {
633
+ background: transparent;
634
+ border: none;
635
+ box-shadow: none;
636
+ flex: 1;
637
+ min-height: 0;
638
+ }
639
+
640
+ .session-rail .session-list-header {
641
+ padding: 8px 4px 12px;
642
+ border-bottom: 1px solid var(--border);
643
+ }
644
+
645
+ .session-rail .session-search {
646
+ padding: 8px 4px 10px;
647
+ }
648
+
649
+ .session-rail .session-list-scroll {
650
+ max-height: none;
651
+ }
652
+
653
+ .rail-header {
654
+ display: flex;
655
+ align-items: baseline;
656
+ justify-content: space-between;
657
+ gap: 8px;
658
+ padding: 4px 2px 10px;
659
+ border-bottom: 1px solid var(--border);
660
+ margin-bottom: 8px;
661
+ }
662
+
663
+ .rail-title {
664
+ font-size: 13px;
665
+ font-weight: 600;
666
+ color: var(--text-bright);
667
+ }
668
+
669
+ .rail-meta {
670
+ font-size: 11px;
671
+ color: var(--text-hint);
672
+ }
673
+
674
+ /* ─── Inspector styling ─── */
675
+ .inspector-section {
676
+ background: var(--glass-bg);
677
+ border: 1px solid var(--glass-border);
678
+ border-radius: var(--radius-lg);
679
+ padding: 12px;
680
+ display: flex;
681
+ flex-direction: column;
682
+ gap: 8px;
683
+ min-height: 0;
684
+ }
685
+
686
+ .inspector-title {
687
+ font-size: 12px;
688
+ font-weight: 600;
689
+ text-transform: uppercase;
690
+ letter-spacing: 0.08em;
691
+ color: var(--text-hint);
692
+ }
693
+
694
+ .inspector-kv {
695
+ display: flex;
696
+ justify-content: space-between;
697
+ gap: 8px;
698
+ font-size: 12px;
699
+ color: var(--text-secondary);
700
+ }
701
+
702
+ .inspector-kv strong {
703
+ color: var(--text-bright);
704
+ font-weight: 600;
705
+ }
706
+
707
+ .inspector-empty {
708
+ padding: 16px 0;
709
+ text-align: center;
710
+ color: var(--text-secondary);
711
+ font-size: 12px;
712
+ }
713
+
714
+ .inspector-scroll {
715
+ overflow-y: auto;
716
+ min-height: 120px;
717
+ max-height: 320px;
718
+ }
719
+
720
+ @media (min-width: 1200px) {
721
+ .app-shell[data-has-rail="true"] .main-content {
722
+ max-width: none;
723
+ }
724
+ }
725
+
726
+ .inspector-log-line {
727
+ font-family: var(--font-mono);
728
+ font-size: 11px;
729
+ line-height: 1.4;
730
+ padding: 6px 8px;
731
+ border-radius: 10px;
732
+ background: rgba(15, 23, 42, 0.35);
733
+ border: 1px solid rgba(148, 163, 184, 0.18);
734
+ color: var(--text-secondary);
735
+ margin-bottom: 6px;
736
+ word-break: break-word;
737
+ }
738
+
739
+ .inspector-log-line.warn {
740
+ border-color: rgba(245, 158, 11, 0.35);
741
+ color: rgba(245, 158, 11, 0.95);
742
+ background: rgba(245, 158, 11, 0.1);
743
+ }
744
+
745
+ .inspector-log-line.error {
746
+ border-color: rgba(248, 113, 113, 0.4);
747
+ color: rgba(248, 113, 113, 0.95);
748
+ background: rgba(248, 113, 113, 0.12);
749
+ }
750
+
751
+ body.is-resizing,
752
+ body.is-resizing * {
753
+ cursor: col-resize !important;
754
+ user-select: none;
755
+ }
756
+
757
+ @media (min-width: 1200px) {
758
+ .session-rail,
759
+ .inspector {
760
+ position: relative;
761
+ }
762
+
763
+ .rail-resizer,
764
+ .inspector-resizer {
765
+ position: absolute;
766
+ top: 12px;
767
+ bottom: 12px;
768
+ width: 14px;
769
+ z-index: 20;
770
+ cursor: col-resize;
771
+ }
772
+
773
+ .rail-resizer {
774
+ right: -7px;
775
+ }
776
+
777
+ .inspector-resizer {
778
+ left: -7px;
779
+ }
780
+
781
+ .rail-resizer::after,
782
+ .inspector-resizer::after {
783
+ content: "";
784
+ position: absolute;
785
+ top: 0;
786
+ bottom: 0;
787
+ width: 2px;
788
+ left: 6px;
789
+ background: rgba(148, 163, 184, 0.35);
790
+ opacity: 0;
791
+ transition: opacity var(--transition-fast), background var(--transition-fast);
792
+ }
793
+
794
+ .session-rail:hover .rail-resizer::after,
795
+ .inspector:hover .inspector-resizer::after {
796
+ opacity: 1;
797
+ }
798
+
799
+ .rail-resizer:hover::after,
800
+ .inspector-resizer:hover::after {
801
+ background: rgba(76, 201, 240, 0.7);
802
+ }
803
+ }
804
+
805
+ @media (min-width: 1200px) {
806
+ .inspector .diff-viewer {
807
+ max-height: 260px;
808
+ overflow-y: auto;
809
+ }
810
+ }