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,841 @@
1
+ /* ─────────────────────────────────────────────────────────────
2
+ * Sessions — Session List, Chat View, Diff Viewer styles
3
+ * ────────────────────────────────────────────────────────────── */
4
+
5
+ /* ═══ Session Layout ═══ */
6
+ .session-panel {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: var(--space-md);
10
+ }
11
+
12
+ .session-pane {
13
+ display: flex;
14
+ flex-direction: column;
15
+ gap: var(--space-md);
16
+ min-width: 0;
17
+ }
18
+
19
+ .session-detail {
20
+ display: flex;
21
+ flex-direction: column;
22
+ gap: var(--space-md);
23
+ min-width: 0;
24
+ }
25
+
26
+ @media (min-width: 769px) {
27
+ .session-split {
28
+ display: grid;
29
+ grid-template-columns: 280px 1fr;
30
+ gap: var(--space-md);
31
+ min-height: 500px;
32
+ }
33
+ }
34
+
35
+ @media (max-width: 768px) {
36
+ .session-split {
37
+ display: flex;
38
+ flex-direction: column;
39
+ gap: var(--space-md);
40
+ }
41
+ .session-list {
42
+ max-height: 300px;
43
+ }
44
+ }
45
+
46
+ /* ─── Detail tabs ─── */
47
+ .session-detail-tabs {
48
+ display: flex;
49
+ gap: 2px;
50
+ background: var(--glass-bg);
51
+ border: 1px solid var(--glass-border);
52
+ border-radius: var(--radius-md);
53
+ padding: 3px;
54
+ margin-bottom: var(--space-md);
55
+ }
56
+
57
+ .session-detail-tab {
58
+ flex: 1;
59
+ padding: 8px 12px;
60
+ border: none;
61
+ background: transparent;
62
+ color: var(--text-secondary);
63
+ font-size: 13px;
64
+ font-weight: 500;
65
+ cursor: pointer;
66
+ border-radius: var(--radius-sm);
67
+ transition: all var(--transition-fast);
68
+ font-family: inherit;
69
+ }
70
+
71
+ .session-detail-tab:hover {
72
+ color: var(--text-primary);
73
+ background: var(--glass-highlight);
74
+ }
75
+
76
+ .session-detail-tab.active {
77
+ background: var(--gradient-accent);
78
+ color: var(--accent-text);
79
+ box-shadow: var(--shadow-glow-sm);
80
+ }
81
+
82
+ /* Back button (mobile) */
83
+ .session-back-btn {
84
+ display: none;
85
+ align-items: center;
86
+ gap: 4px;
87
+ background: none;
88
+ border: none;
89
+ color: var(--accent);
90
+ font-size: 14px;
91
+ cursor: pointer;
92
+ padding: 6px 0;
93
+ margin-bottom: var(--space-sm);
94
+ font-family: inherit;
95
+ }
96
+
97
+ @media (max-width: 768px) {
98
+ .session-back-btn {
99
+ display: inline-flex;
100
+ }
101
+ }
102
+
103
+ /* ═══ Session List ═══ */
104
+ .session-list {
105
+ background: var(--glass-bg);
106
+ backdrop-filter: var(--glass-blur);
107
+ -webkit-backdrop-filter: var(--glass-blur);
108
+ border: 1px solid var(--glass-border);
109
+ border-radius: var(--radius-lg);
110
+ display: flex;
111
+ flex-direction: column;
112
+ overflow: hidden;
113
+ }
114
+
115
+ .session-list-header {
116
+ display: flex;
117
+ align-items: center;
118
+ justify-content: space-between;
119
+ padding: 12px 14px;
120
+ border-bottom: 1px solid var(--glass-border);
121
+ }
122
+
123
+ .session-list-title {
124
+ font-size: 15px;
125
+ font-weight: 600;
126
+ color: var(--text-primary);
127
+ }
128
+
129
+ .session-search {
130
+ padding: 8px 10px;
131
+ border-bottom: 1px solid var(--border);
132
+ }
133
+
134
+ .session-search-input {
135
+ width: 100%;
136
+ font-size: 13px;
137
+ padding: 6px 10px;
138
+ box-sizing: border-box;
139
+ }
140
+
141
+ .session-list-scroll {
142
+ overflow-y: auto;
143
+ flex: 1;
144
+ max-height: 460px;
145
+ }
146
+
147
+ .session-group-label {
148
+ font-size: 11px;
149
+ font-weight: 600;
150
+ text-transform: uppercase;
151
+ letter-spacing: 0.5px;
152
+ color: var(--text-hint);
153
+ padding: 10px 14px 4px;
154
+ }
155
+
156
+ .session-item {
157
+ padding: 12px 14px;
158
+ cursor: pointer;
159
+ border-bottom: 1px solid var(--border);
160
+ transition: background var(--transition-fast);
161
+ }
162
+
163
+ .session-item:hover {
164
+ background: var(--bg-card-hover);
165
+ }
166
+
167
+ .session-item.active {
168
+ background: var(--accent-subtle);
169
+ border-left: 3px solid var(--accent);
170
+ padding-left: 11px;
171
+ }
172
+
173
+ .session-item-row {
174
+ display: flex;
175
+ align-items: center;
176
+ gap: 6px;
177
+ }
178
+
179
+ .session-item-icon {
180
+ font-size: 14px;
181
+ flex-shrink: 0;
182
+ }
183
+
184
+ .session-item-title {
185
+ flex: 1;
186
+ font-size: 13px;
187
+ font-weight: 500;
188
+ color: var(--text-primary);
189
+ line-height: 1.4;
190
+ white-space: nowrap;
191
+ overflow: hidden;
192
+ text-overflow: ellipsis;
193
+ }
194
+
195
+ .session-item-status {
196
+ font-size: 12px;
197
+ flex-shrink: 0;
198
+ }
199
+
200
+ .session-item-preview {
201
+ font-size: 12px;
202
+ color: var(--text-secondary);
203
+ margin-top: 3px;
204
+ line-height: 1.4;
205
+ white-space: nowrap;
206
+ overflow: hidden;
207
+ text-overflow: ellipsis;
208
+ }
209
+
210
+ .session-item-time {
211
+ font-size: 11px;
212
+ color: var(--text-hint);
213
+ margin-top: 2px;
214
+ line-height: 1.3;
215
+ }
216
+
217
+ .session-empty {
218
+ display: flex;
219
+ flex-direction: column;
220
+ align-items: center;
221
+ justify-content: center;
222
+ padding: var(--space-lg);
223
+ gap: var(--space-sm);
224
+ }
225
+
226
+ .session-empty-icon {
227
+ font-size: 32px;
228
+ opacity: 0.6;
229
+ }
230
+
231
+ .session-empty-text {
232
+ font-size: 13px;
233
+ color: var(--text-secondary);
234
+ text-align: center;
235
+ }
236
+
237
+ .session-empty-subtext {
238
+ font-size: 11px;
239
+ color: var(--text-hint);
240
+ margin-top: 4px;
241
+ }
242
+
243
+ .session-empty-actions {
244
+ display: flex;
245
+ align-items: center;
246
+ gap: 8px;
247
+ flex-wrap: wrap;
248
+ justify-content: center;
249
+ margin-top: 4px;
250
+ }
251
+
252
+ /* ═══ Chat View ═══ */
253
+ .chat-view {
254
+ display: flex;
255
+ flex-direction: column;
256
+ background: var(--glass-bg);
257
+ backdrop-filter: var(--glass-blur);
258
+ -webkit-backdrop-filter: var(--glass-blur);
259
+ border: 1px solid var(--glass-border);
260
+ border-radius: var(--radius-lg);
261
+ min-height: 400px;
262
+ max-height: 600px;
263
+ overflow: hidden;
264
+ }
265
+
266
+ @media (min-width: 1024px) {
267
+ .chat-view {
268
+ max-height: none;
269
+ min-height: 560px;
270
+ }
271
+ }
272
+
273
+ .chat-view.chat-empty-state {
274
+ align-items: center;
275
+ justify-content: center;
276
+ }
277
+
278
+ .chat-header {
279
+ padding: 12px 16px;
280
+ border-bottom: 1px solid var(--glass-border);
281
+ flex-shrink: 0;
282
+ display: flex;
283
+ align-items: center;
284
+ justify-content: space-between;
285
+ gap: 12px;
286
+ }
287
+
288
+ .chat-toolbar {
289
+ display: flex;
290
+ flex-wrap: wrap;
291
+ align-items: center;
292
+ justify-content: space-between;
293
+ gap: 10px;
294
+ padding: 10px 16px;
295
+ border-bottom: 1px solid var(--glass-border);
296
+ background: rgba(8, 14, 24, 0.3);
297
+ }
298
+
299
+ .chat-toolbar-left {
300
+ display: flex;
301
+ flex-wrap: wrap;
302
+ align-items: center;
303
+ gap: 10px;
304
+ }
305
+
306
+ .chat-toolbar-actions {
307
+ display: flex;
308
+ flex-wrap: wrap;
309
+ align-items: center;
310
+ gap: 6px;
311
+ }
312
+
313
+ .chat-filter-group {
314
+ display: flex;
315
+ flex-wrap: wrap;
316
+ gap: 6px;
317
+ }
318
+
319
+ .chat-filter-chip {
320
+ border: 1px solid var(--glass-border);
321
+ background: var(--glass-bg);
322
+ color: var(--text-secondary);
323
+ font-size: 11px;
324
+ padding: 4px 10px;
325
+ border-radius: 999px;
326
+ display: inline-flex;
327
+ align-items: center;
328
+ gap: 6px;
329
+ cursor: pointer;
330
+ transition: all var(--transition-fast);
331
+ }
332
+
333
+ .chat-filter-chip:hover {
334
+ color: var(--text-primary);
335
+ border-color: rgba(148, 163, 184, 0.4);
336
+ }
337
+
338
+ .chat-filter-chip.active {
339
+ color: var(--text-primary);
340
+ border-color: var(--accent);
341
+ background: rgba(59, 130, 246, 0.12);
342
+ }
343
+
344
+ .chat-filter-count {
345
+ font-size: 10px;
346
+ padding: 1px 6px;
347
+ border-radius: 999px;
348
+ background: rgba(148, 163, 184, 0.15);
349
+ color: var(--text-hint);
350
+ }
351
+
352
+ .chat-paused-pill {
353
+ font-size: 11px;
354
+ padding: 3px 8px;
355
+ border-radius: 999px;
356
+ border: 1px solid rgba(248, 113, 113, 0.4);
357
+ color: var(--color-error);
358
+ background: rgba(248, 113, 113, 0.12);
359
+ }
360
+
361
+ .chat-header-info {
362
+ display: flex;
363
+ flex-direction: column;
364
+ gap: 2px;
365
+ }
366
+
367
+ .chat-header-actions {
368
+ display: flex;
369
+ align-items: center;
370
+ gap: 6px;
371
+ flex-shrink: 0;
372
+ }
373
+
374
+ .chat-header-title {
375
+ font-size: 14px;
376
+ font-weight: 600;
377
+ color: var(--text-primary);
378
+ }
379
+
380
+ .chat-header-meta {
381
+ font-size: 12px;
382
+ color: var(--text-hint);
383
+ margin-top: 2px;
384
+ line-height: 1.4;
385
+ }
386
+
387
+ .chat-messages {
388
+ flex: 1;
389
+ overflow-y: auto;
390
+ padding: var(--space-md);
391
+ display: flex;
392
+ flex-direction: column;
393
+ gap: var(--space-sm);
394
+ }
395
+
396
+ .chat-empty-state-inline {
397
+ display: flex;
398
+ flex-direction: column;
399
+ align-items: center;
400
+ justify-content: center;
401
+ padding: var(--space-lg);
402
+ gap: var(--space-sm);
403
+ border: 1px dashed var(--glass-border);
404
+ border-radius: var(--radius-md);
405
+ background: rgba(8, 12, 20, 0.35);
406
+ text-align: center;
407
+ }
408
+
409
+ .chat-loading {
410
+ text-align: center;
411
+ color: var(--text-hint);
412
+ padding: var(--space-lg);
413
+ font-size: 13px;
414
+ }
415
+
416
+ /* ─── Bubbles ─── */
417
+ .chat-bubble {
418
+ max-width: 85%;
419
+ padding: 10px 14px;
420
+ border-radius: var(--radius-md);
421
+ font-size: 13px;
422
+ line-height: 1.5;
423
+ word-wrap: break-word;
424
+ }
425
+
426
+ .chat-bubble.user {
427
+ align-self: flex-end;
428
+ background: var(--gradient-accent);
429
+ color: var(--accent-text);
430
+ border-bottom-right-radius: var(--radius-sm);
431
+ box-shadow: var(--shadow-glow-sm);
432
+ }
433
+
434
+ .chat-bubble.assistant {
435
+ align-self: flex-start;
436
+ background: var(--glass-bg);
437
+ backdrop-filter: blur(8px);
438
+ -webkit-backdrop-filter: blur(8px);
439
+ color: var(--text-primary);
440
+ border: 1px solid var(--glass-border);
441
+ border-bottom-left-radius: var(--radius-sm);
442
+ }
443
+
444
+ .chat-bubble.system {
445
+ align-self: center;
446
+ max-width: 90%;
447
+ background: transparent;
448
+ padding: 6px 12px;
449
+ }
450
+
451
+ .chat-bubble.tool {
452
+ align-self: flex-start;
453
+ background: rgba(56, 189, 248, 0.08);
454
+ border: 1px dashed rgba(56, 189, 248, 0.3);
455
+ color: var(--text-primary);
456
+ font-family: var(--font-mono);
457
+ }
458
+
459
+ .chat-bubble.error {
460
+ align-self: flex-start;
461
+ background: rgba(248, 113, 113, 0.12);
462
+ border: 1px solid rgba(248, 113, 113, 0.4);
463
+ color: var(--text-primary);
464
+ }
465
+
466
+ .chat-system-text {
467
+ font-size: 12px;
468
+ color: var(--text-hint);
469
+ text-align: center;
470
+ font-style: italic;
471
+ }
472
+
473
+ .chat-bubble-label {
474
+ font-size: 10px;
475
+ font-weight: 600;
476
+ text-transform: uppercase;
477
+ letter-spacing: 0.4px;
478
+ color: var(--text-hint);
479
+ margin-bottom: 4px;
480
+ }
481
+
482
+ .chat-bubble-content {
483
+ white-space: pre-wrap;
484
+ }
485
+
486
+ .chat-bubble-time {
487
+ font-size: 10px;
488
+ opacity: 0.6;
489
+ margin-top: 4px;
490
+ }
491
+
492
+ /* ─── Code blocks ─── */
493
+ .chat-code-block {
494
+ position: relative;
495
+ background: #1e1e2e;
496
+ border-radius: var(--radius-sm);
497
+ margin: 6px 0;
498
+ overflow: hidden;
499
+ }
500
+
501
+ .chat-code-block pre {
502
+ margin: 0;
503
+ padding: 10px 12px;
504
+ overflow-x: auto;
505
+ font-size: 12px;
506
+ line-height: 1.5;
507
+ }
508
+
509
+ .chat-code-block code {
510
+ font-family: var(--font-mono);
511
+ color: #e2e8f0;
512
+ }
513
+
514
+ .chat-code-copy {
515
+ position: absolute;
516
+ top: 6px;
517
+ right: 6px;
518
+ background: rgba(255, 255, 255, 0.1);
519
+ border: none;
520
+ color: #aaa;
521
+ font-size: 12px;
522
+ cursor: pointer;
523
+ padding: 2px 6px;
524
+ border-radius: var(--radius-sm);
525
+ transition: background var(--transition-fast);
526
+ }
527
+
528
+ .chat-code-copy:hover {
529
+ background: rgba(255, 255, 255, 0.2);
530
+ }
531
+
532
+ /* ─── Markdown rendering ─── */
533
+ .md-rendered {
534
+ white-space: normal;
535
+ word-wrap: break-word;
536
+ }
537
+
538
+ .md-heading {
539
+ font-weight: 600;
540
+ margin: 4px 0;
541
+ }
542
+
543
+ .md-h1 { font-size: 1.3em; }
544
+ .md-h2 { font-size: 1.15em; }
545
+ .md-h3 { font-size: 1.05em; }
546
+
547
+ .md-blockquote {
548
+ border-left: 3px solid var(--accent);
549
+ background: var(--glass-bg);
550
+ padding: 6px 12px;
551
+ margin: 4px 0;
552
+ border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
553
+ color: var(--text-secondary);
554
+ }
555
+
556
+ .md-list {
557
+ margin: 4px 0;
558
+ padding-left: 20px;
559
+ }
560
+
561
+ .md-list li {
562
+ margin: 2px 0;
563
+ }
564
+
565
+ ul.md-list {
566
+ list-style: none;
567
+ padding-left: 16px;
568
+ }
569
+
570
+ ul.md-list li::before {
571
+ content: "•";
572
+ color: var(--accent);
573
+ font-weight: bold;
574
+ display: inline-block;
575
+ width: 12px;
576
+ margin-left: -12px;
577
+ }
578
+
579
+ .md-link {
580
+ color: var(--accent);
581
+ text-decoration: underline;
582
+ text-underline-offset: 2px;
583
+ }
584
+
585
+ .md-link:hover {
586
+ opacity: 0.8;
587
+ }
588
+
589
+ .md-inline-code {
590
+ background: var(--glass-bg);
591
+ border: 1px solid var(--glass-border);
592
+ padding: 1px 6px;
593
+ border-radius: 10px;
594
+ font-family: "SF Mono", "Fira Code", "Consolas", monospace;
595
+ font-size: 0.9em;
596
+ }
597
+
598
+ .md-hr {
599
+ border: none;
600
+ border-top: 1px solid var(--glass-border);
601
+ margin: 8px 0;
602
+ }
603
+
604
+ /* ─── Typing indicator ─── */
605
+ .chat-typing {
606
+ display: flex;
607
+ gap: 4px;
608
+ padding: 4px 0;
609
+ }
610
+
611
+ .chat-typing-dot {
612
+ width: 7px;
613
+ height: 7px;
614
+ border-radius: 50%;
615
+ background: var(--text-hint);
616
+ animation: chat-typing-bounce 1.4s infinite ease-in-out;
617
+ }
618
+
619
+ .chat-typing-dot:nth-child(2) {
620
+ animation-delay: 0.16s;
621
+ }
622
+
623
+ .chat-typing-dot:nth-child(3) {
624
+ animation-delay: 0.32s;
625
+ }
626
+
627
+ @keyframes chat-typing-bounce {
628
+ 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
629
+ 40% { transform: scale(1); opacity: 1; }
630
+ }
631
+
632
+ /* ─── Input bar ─── */
633
+ .chat-input-bar {
634
+ border-top: 1px solid var(--border);
635
+ padding: 10px 12px;
636
+ flex-shrink: 0;
637
+ }
638
+
639
+ .chat-resume-btn {
640
+ width: 100%;
641
+ margin-bottom: var(--space-sm);
642
+ }
643
+
644
+ .chat-input-row {
645
+ display: flex;
646
+ gap: 8px;
647
+ align-items: flex-end;
648
+ }
649
+
650
+ .chat-input {
651
+ flex: 1;
652
+ resize: none;
653
+ font-size: 13px;
654
+ min-height: 36px;
655
+ max-height: 100px;
656
+ line-height: 1.4;
657
+ padding: 8px 12px;
658
+ box-sizing: border-box;
659
+ }
660
+
661
+ .chat-send-btn {
662
+ flex-shrink: 0;
663
+ width: 36px;
664
+ height: 36px;
665
+ padding: 0;
666
+ display: flex;
667
+ align-items: center;
668
+ justify-content: center;
669
+ font-size: 16px;
670
+ border-radius: var(--radius-md);
671
+ }
672
+
673
+ /* ═══ Diff Viewer ═══ */
674
+ .diff-viewer {
675
+ background: var(--glass-bg);
676
+ backdrop-filter: blur(12px);
677
+ -webkit-backdrop-filter: blur(12px);
678
+ border: 1px solid var(--glass-border);
679
+ border-radius: var(--radius-lg);
680
+ overflow: hidden;
681
+ min-height: 200px;
682
+ }
683
+
684
+ .diff-viewer.diff-empty {
685
+ display: flex;
686
+ flex-direction: column;
687
+ align-items: center;
688
+ justify-content: center;
689
+ min-height: 300px;
690
+ }
691
+
692
+ .diff-loading {
693
+ text-align: center;
694
+ color: var(--text-hint);
695
+ padding: var(--space-lg);
696
+ font-size: 13px;
697
+ }
698
+
699
+ .diff-summary {
700
+ display: flex;
701
+ align-items: center;
702
+ gap: var(--space-sm);
703
+ padding: 10px 14px;
704
+ font-size: 13px;
705
+ font-weight: 500;
706
+ color: var(--text-primary);
707
+ border-bottom: 1px solid var(--glass-border);
708
+ background: var(--glass-bg);
709
+ }
710
+
711
+ .diff-stat-add {
712
+ color: var(--color-done);
713
+ font-weight: 600;
714
+ font-size: 12px;
715
+ }
716
+
717
+ .diff-stat-del {
718
+ color: var(--color-error);
719
+ font-weight: 600;
720
+ font-size: 12px;
721
+ }
722
+
723
+ .diff-file-list {
724
+ display: flex;
725
+ flex-direction: column;
726
+ }
727
+
728
+ .diff-file-item {
729
+ border-bottom: 1px solid var(--border);
730
+ }
731
+
732
+ .diff-file-item:last-child {
733
+ border-bottom: none;
734
+ }
735
+
736
+ .diff-file-header {
737
+ display: flex;
738
+ align-items: center;
739
+ gap: 8px;
740
+ padding: 10px 14px;
741
+ cursor: pointer;
742
+ transition: background var(--transition-fast);
743
+ font-size: 13px;
744
+ }
745
+
746
+ .diff-file-header:hover {
747
+ background: var(--bg-card-hover);
748
+ }
749
+
750
+ .diff-file-header.added {
751
+ border-left: 3px solid var(--color-done);
752
+ padding-left: 11px;
753
+ }
754
+
755
+ .diff-file-header.deleted {
756
+ border-left: 3px solid var(--color-error);
757
+ padding-left: 11px;
758
+ }
759
+
760
+ .diff-file-header.modified {
761
+ border-left: 3px solid var(--color-inreview);
762
+ padding-left: 11px;
763
+ }
764
+
765
+ .diff-file-icon {
766
+ font-size: 14px;
767
+ flex-shrink: 0;
768
+ }
769
+
770
+ .diff-file-name {
771
+ flex: 1;
772
+ font-weight: 500;
773
+ color: var(--text-primary);
774
+ white-space: nowrap;
775
+ overflow: hidden;
776
+ text-overflow: ellipsis;
777
+ }
778
+
779
+ .diff-file-stats {
780
+ display: flex;
781
+ gap: 6px;
782
+ flex-shrink: 0;
783
+ }
784
+
785
+ .diff-file-toggle {
786
+ color: var(--text-hint);
787
+ font-size: 12px;
788
+ flex-shrink: 0;
789
+ }
790
+
791
+ /* ─── Diff hunks ─── */
792
+ .diff-hunk {
793
+ background: rgba(6, 8, 16, 0.9);
794
+ font-family: "SF Mono", "Fira Code", "Consolas", monospace;
795
+ font-size: 12px;
796
+ line-height: 1.6;
797
+ overflow-x: auto;
798
+ }
799
+
800
+ .diff-line {
801
+ padding: 1px 14px;
802
+ white-space: pre;
803
+ }
804
+
805
+ .diff-line.addition {
806
+ background: rgba(16, 185, 129, 0.1);
807
+ color: #6ee7b7;
808
+ }
809
+
810
+ .diff-line.deletion {
811
+ background: rgba(248, 113, 113, 0.1);
812
+ color: #fca5a5;
813
+ }
814
+
815
+ .diff-line.context {
816
+ color: #94a3b8;
817
+ }
818
+
819
+ .diff-line.hunk-header {
820
+ color: #7c3aed;
821
+ background: rgba(124, 58, 237, 0.08);
822
+ font-weight: 500;
823
+ }
824
+
825
+ .diff-line-text {
826
+ display: inline;
827
+ }
828
+
829
+ @media (min-width: 1200px) {
830
+ .app-shell[data-has-rail="true"] .session-split {
831
+ grid-template-columns: 1fr;
832
+ }
833
+
834
+ .app-shell[data-has-rail="true"] .session-split > .session-list {
835
+ display: none;
836
+ }
837
+
838
+ .app-shell[data-has-rail="true"] .session-detail {
839
+ min-height: 520px;
840
+ }
841
+ }