@in-the-loop-labs/pair-review 3.1.3 → 3.2.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 (39) hide show
  1. package/package.json +1 -1
  2. package/plugin/.claude-plugin/plugin.json +1 -1
  3. package/plugin-code-critic/.claude-plugin/plugin.json +1 -1
  4. package/public/css/pr.css +980 -3
  5. package/public/js/components/AIPanel.js +7 -4
  6. package/public/js/components/ChatPanel.js +34 -4
  7. package/public/js/components/CouncilProgressModal.js +11 -0
  8. package/public/js/components/NotificationDropdown.js +257 -0
  9. package/public/js/components/StackAnalysisDialog.js +313 -0
  10. package/public/js/components/StackProgressModal.js +475 -0
  11. package/public/js/components/StatusIndicator.js +1 -0
  12. package/public/js/components/SuggestionNavigator.js +2 -0
  13. package/public/js/modules/comment-manager.js +7 -0
  14. package/public/js/modules/comment-minimizer.js +151 -4
  15. package/public/js/modules/file-comment-manager.js +66 -2
  16. package/public/js/modules/suggestion-manager.js +2 -1
  17. package/public/js/pr.js +433 -2
  18. package/public/js/utils/notification-sounds.js +62 -0
  19. package/public/local.html +10 -0
  20. package/public/pr.html +12 -0
  21. package/public/setup.html +4 -0
  22. package/src/ai/claude-provider.js +1 -11
  23. package/src/ai/codex-provider.js +18 -16
  24. package/src/ai/copilot-provider.js +21 -21
  25. package/src/ai/gemini-provider.js +10 -0
  26. package/src/ai/pi-provider.js +22 -25
  27. package/src/ai/provider.js +26 -3
  28. package/src/chat/pi-bridge.js +8 -0
  29. package/src/chat/session-manager.js +1 -0
  30. package/src/git/base-branch.js +1 -51
  31. package/src/git/worktree-lock.js +88 -0
  32. package/src/git/worktree.js +64 -0
  33. package/src/github/stack-walker.js +196 -0
  34. package/src/routes/local.js +12 -8
  35. package/src/routes/pr.js +139 -26
  36. package/src/routes/sound.js +49 -0
  37. package/src/routes/stack-analysis.js +886 -0
  38. package/src/server.js +4 -0
  39. package/src/setup/stack-setup.js +77 -0
package/public/css/pr.css CHANGED
@@ -5983,7 +5983,6 @@ body::before {
5983
5983
  .header-center {
5984
5984
  flex: 1;
5985
5985
  min-width: 0;
5986
- overflow: hidden;
5987
5986
  text-align: center;
5988
5987
  }
5989
5988
 
@@ -7452,6 +7451,31 @@ body.resizing * {
7452
7451
  background: rgba(88, 166, 255, 0.15);
7453
7452
  }
7454
7453
 
7454
+ /* ── Notification Sounds Popover ───────────────────────────────────────── */
7455
+ .notification-popover {
7456
+ background: var(--color-bg-primary, #ffffff);
7457
+ border: 1px solid var(--color-border-primary, #d0d7de);
7458
+ border-radius: 8px;
7459
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08), 0 8px 24px rgba(0, 0, 0, 0.12);
7460
+ min-width: 180px;
7461
+ }
7462
+
7463
+ .notification-popover label:hover {
7464
+ background: var(--color-bg-tertiary);
7465
+ }
7466
+
7467
+ /* Dark theme */
7468
+ [data-theme="dark"] .notification-popover {
7469
+ background: var(--color-bg-secondary);
7470
+ border-color: var(--color-border-secondary);
7471
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.4);
7472
+ }
7473
+
7474
+ [data-theme="dark"] .notification-popover label:hover {
7475
+ background: var(--color-bg-tertiary);
7476
+ }
7477
+
7478
+
7455
7479
  /* --------------------------------------------------------------------------
7456
7480
  Comment Minimize Mode
7457
7481
  -------------------------------------------------------------------------- */
@@ -7468,6 +7492,90 @@ body.resizing * {
7468
7492
  display: table-row;
7469
7493
  }
7470
7494
 
7495
+ /* When minimize mode is active, hide file-level comment cards */
7496
+ .comments-minimized .file-comment-card {
7497
+ display: none;
7498
+ }
7499
+
7500
+ /* Per-file expansion override — clicking a file-header indicator reveals that file's cards */
7501
+ .comments-minimized .file-comments-zone.file-comments-expanded .file-comment-card {
7502
+ display: block;
7503
+ }
7504
+
7505
+ /* File-header comment indicator — matches header button sizing, only visible when minimized */
7506
+ .file-comment-indicator {
7507
+ display: none;
7508
+ }
7509
+
7510
+ .comments-minimized .file-comment-indicator {
7511
+ display: inline-flex;
7512
+ align-items: center;
7513
+ justify-content: center;
7514
+ gap: 3px;
7515
+ width: 28px;
7516
+ height: 28px;
7517
+ padding: 0;
7518
+ background: transparent;
7519
+ border: 1px solid transparent;
7520
+ border-radius: 6px;
7521
+ cursor: pointer;
7522
+ color: var(--color-text-secondary, #656d76);
7523
+ transition: background-color 0.15s, color 0.15s, border-color 0.15s;
7524
+ flex-shrink: 0;
7525
+ font-size: 11px;
7526
+ line-height: 1;
7527
+ }
7528
+
7529
+ .comments-minimized .file-comment-indicator:has(.indicator-user):hover,
7530
+ .comments-minimized .file-comment-indicator:has(.indicator-adopted):hover {
7531
+ background-color: rgba(130, 80, 223, 0.1);
7532
+ border-color: var(--comment-primary, #8250df);
7533
+ }
7534
+
7535
+ .comments-minimized .file-comment-indicator:has(.indicator-ai):hover {
7536
+ background-color: rgba(217, 119, 6, 0.1);
7537
+ border-color: var(--color-accent-ai, #d97706);
7538
+ }
7539
+
7540
+ .comments-minimized .file-comment-indicator:has(.indicator-user),
7541
+ .comments-minimized .file-comment-indicator:has(.indicator-adopted) {
7542
+ border-color: var(--comment-primary, #8250df);
7543
+ color: var(--comment-primary, #8250df);
7544
+ }
7545
+
7546
+ .comments-minimized .file-comment-indicator:has(.indicator-ai) {
7547
+ border-color: var(--color-accent-ai, #d97706);
7548
+ color: var(--color-accent-ai, #d97706);
7549
+ }
7550
+
7551
+ .comments-minimized .file-comment-indicator.expanded {
7552
+ border-width: 2px;
7553
+ }
7554
+
7555
+ [data-theme="dark"] .comments-minimized .file-comment-indicator:has(.indicator-user),
7556
+ [data-theme="dark"] .comments-minimized .file-comment-indicator:has(.indicator-adopted) {
7557
+ border-color: var(--comment-primary, #a371f7);
7558
+ color: var(--comment-primary, #a371f7);
7559
+ }
7560
+
7561
+ [data-theme="dark"] .comments-minimized .file-comment-indicator:has(.indicator-ai) {
7562
+ border-color: var(--color-accent-ai, #fbbf24);
7563
+ color: var(--color-accent-ai, #fbbf24);
7564
+ }
7565
+
7566
+ [data-theme="dark"] .comments-minimized .file-comment-indicator:has(.indicator-user):hover,
7567
+ [data-theme="dark"] .comments-minimized .file-comment-indicator:has(.indicator-adopted):hover {
7568
+ background-color: rgba(163, 113, 247, 0.15);
7569
+ }
7570
+
7571
+ [data-theme="dark"] .comments-minimized .file-comment-indicator:has(.indicator-ai):hover {
7572
+ background-color: rgba(251, 191, 36, 0.15);
7573
+ }
7574
+
7575
+ [data-theme="dark"] .comments-minimized .file-comment-indicator.expanded {
7576
+ border-width: 2px;
7577
+ }
7578
+
7471
7579
  /* Indicator button on the right edge of diff code cells */
7472
7580
  .comment-indicator {
7473
7581
  position: absolute;
@@ -7530,11 +7638,11 @@ body.resizing * {
7530
7638
  }
7531
7639
 
7532
7640
  .comment-indicator .indicator-ai {
7533
- color: var(--ai-accent, #d97706);
7641
+ color: var(--color-accent-ai, #d97706);
7534
7642
  }
7535
7643
 
7536
7644
  .comment-indicator:has(.indicator-ai) {
7537
- border-color: var(--ai-accent, #d97706);
7645
+ border-color: var(--color-accent-ai, #d97706);
7538
7646
  background: rgba(217, 119, 6, 0.06);
7539
7647
  }
7540
7648
 
@@ -12945,3 +13053,872 @@ body.resizing * {
12945
13053
  background: rgba(56, 139, 253, 0.1);
12946
13054
  color: var(--color-text-secondary, #8b949e);
12947
13055
  }
13056
+
13057
+ /* ============================================
13058
+ Stack Review — Analyze Split Button
13059
+ ============================================ */
13060
+
13061
+ .analyze-split-container {
13062
+ display: inline-flex;
13063
+ align-items: stretch;
13064
+ position: relative;
13065
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
13066
+ border-radius: var(--radius-sm, 6px);
13067
+ }
13068
+
13069
+ .analyze-split-container:hover {
13070
+ transform: translateY(-1px);
13071
+ box-shadow: 0 0 16px rgba(245, 158, 11, 0.4), 0 0 32px rgba(245, 158, 11, 0.2);
13072
+ }
13073
+
13074
+ .analyze-split-container #analyze-btn {
13075
+ border-top-right-radius: 0;
13076
+ border-bottom-right-radius: 0;
13077
+ border-right: none;
13078
+ }
13079
+
13080
+ /* Remove per-button transform/shadow on hover — container handles it */
13081
+ .analyze-split-container #analyze-btn:hover {
13082
+ transform: none;
13083
+ box-shadow: none;
13084
+ }
13085
+
13086
+ .analyze-dropdown-toggle {
13087
+ display: flex;
13088
+ align-items: center;
13089
+ justify-content: center;
13090
+ padding: 0 8px;
13091
+ background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
13092
+ border: 1px solid #fcd34d;
13093
+ border-left: 1px solid rgba(180, 83, 9, 0.2);
13094
+ border-top-right-radius: var(--radius-sm, 6px);
13095
+ border-bottom-right-radius: var(--radius-sm, 6px);
13096
+ color: #b45309;
13097
+ cursor: pointer;
13098
+ transition: all 0.3s ease;
13099
+ font-size: 0;
13100
+ position: relative;
13101
+ overflow: hidden;
13102
+ font-weight: 600;
13103
+ }
13104
+
13105
+ .analyze-dropdown-toggle::before {
13106
+ content: '';
13107
+ position: absolute;
13108
+ top: 0;
13109
+ left: -100%;
13110
+ width: 100%;
13111
+ height: 100%;
13112
+ background: linear-gradient(
13113
+ 90deg,
13114
+ transparent 0%,
13115
+ rgba(255, 255, 255, 0.4) 50%,
13116
+ transparent 100%
13117
+ );
13118
+ transition: left 0.5s ease;
13119
+ }
13120
+
13121
+ .analyze-split-container:hover .analyze-dropdown-toggle {
13122
+ background: linear-gradient(135deg, #fde68a 0%, #fcd34d 100%);
13123
+ border-color: var(--color-accent-ai-dark);
13124
+ }
13125
+
13126
+ .analyze-split-container:hover .analyze-dropdown-toggle::before {
13127
+ left: 100%;
13128
+ }
13129
+
13130
+ .analyze-dropdown-toggle svg {
13131
+ width: 12px;
13132
+ height: 12px;
13133
+ fill: currentColor;
13134
+ transition: transform 0.15s ease;
13135
+ }
13136
+
13137
+ .analyze-split-container.open .analyze-dropdown-toggle svg {
13138
+ transform: rotate(180deg);
13139
+ }
13140
+
13141
+ .analyze-dropdown-menu {
13142
+ display: none;
13143
+ position: absolute;
13144
+ top: 100%;
13145
+ right: 0;
13146
+ margin-top: 4px;
13147
+ min-width: 200px;
13148
+ background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
13149
+ border: 1px solid #fcd34d;
13150
+ border-radius: var(--radius-sm, 6px);
13151
+ box-shadow: 0 4px 16px rgba(245, 158, 11, 0.2), 0 8px 24px rgba(0, 0, 0, 0.08);
13152
+ z-index: 100;
13153
+ padding: 0;
13154
+ overflow: hidden;
13155
+ }
13156
+
13157
+ .analyze-split-container.open .analyze-dropdown-menu {
13158
+ display: block;
13159
+ }
13160
+
13161
+ .analyze-dropdown-item {
13162
+ display: block;
13163
+ width: 100%;
13164
+ padding: 8px 12px;
13165
+ background: none;
13166
+ border: none;
13167
+ color: #92400e;
13168
+ font-size: 13px;
13169
+ font-weight: 500;
13170
+ text-align: left;
13171
+ cursor: pointer;
13172
+ white-space: nowrap;
13173
+ transition: background 0.15s ease, color 0.15s ease;
13174
+ }
13175
+
13176
+ .analyze-dropdown-item:hover {
13177
+ background: rgba(251, 191, 36, 0.25);
13178
+ color: #b45309;
13179
+ }
13180
+
13181
+ /* Dark theme — container hover */
13182
+ [data-theme="dark"] .analyze-split-container:hover {
13183
+ box-shadow: 0 0 20px rgba(251, 191, 36, 0.3), 0 0 40px rgba(245, 158, 11, 0.15);
13184
+ }
13185
+
13186
+ [data-theme="dark"] .analyze-dropdown-toggle {
13187
+ background: linear-gradient(135deg, rgba(251, 191, 36, 0.15) 0%, rgba(245, 158, 11, 0.25) 100%);
13188
+ border-color: rgba(251, 191, 36, 0.4);
13189
+ border-left-color: rgba(251, 191, 36, 0.2);
13190
+ color: var(--color-accent-ai, #fbbf24);
13191
+ }
13192
+
13193
+ [data-theme="dark"] .analyze-split-container:hover .analyze-dropdown-toggle {
13194
+ background: linear-gradient(135deg, rgba(251, 191, 36, 0.25) 0%, rgba(245, 158, 11, 0.35) 100%);
13195
+ border-color: var(--color-accent-ai-dark);
13196
+ }
13197
+
13198
+ [data-theme="dark"] .analyze-dropdown-menu {
13199
+ background: linear-gradient(135deg, rgba(251, 191, 36, 0.08) 0%, rgba(245, 158, 11, 0.12) 100%);
13200
+ background-color: var(--color-bg-elevated, #1e2329);
13201
+ border-color: rgba(251, 191, 36, 0.4);
13202
+ box-shadow: 0 4px 16px rgba(251, 191, 36, 0.1), 0 8px 24px rgba(0, 0, 0, 0.4);
13203
+ }
13204
+
13205
+ [data-theme="dark"] .analyze-dropdown-item {
13206
+ color: var(--color-accent-ai, #fbbf24);
13207
+ }
13208
+
13209
+ [data-theme="dark"] .analyze-dropdown-item:hover {
13210
+ background: rgba(251, 191, 36, 0.15);
13211
+ color: #fcd34d;
13212
+ }
13213
+
13214
+ /* Analyzing state — toggle matches the main button */
13215
+ .analyze-split-container .analyze-dropdown-toggle.btn-analyzing {
13216
+ background: linear-gradient(135deg, var(--color-accent-ai-dark, #d97706) 0%, #d97706 100%);
13217
+ border-color: #b45309;
13218
+ color: #ffffff;
13219
+ box-shadow: 0 0 20px rgba(245, 158, 11, 0.5), 0 0 40px rgba(217, 119, 6, 0.3);
13220
+ }
13221
+
13222
+ [data-theme="dark"] .analyze-split-container .analyze-dropdown-toggle.btn-analyzing {
13223
+ background: linear-gradient(135deg, var(--color-accent-ai, #fbbf24) 0%, var(--color-accent-ai-dark, #d97706) 100%);
13224
+ border-color: var(--color-accent-ai-dark, #d97706);
13225
+ color: #1c1917;
13226
+ box-shadow: 0 0 24px rgba(251, 191, 36, 0.6), 0 0 48px rgba(245, 158, 11, 0.3);
13227
+ }
13228
+
13229
+ /* ============================================
13230
+ Stack Review — PR Title Navigation Dropdown
13231
+ ============================================ */
13232
+
13233
+ .stack-nav-dropdown {
13234
+ position: relative;
13235
+ display: inline-flex;
13236
+ align-items: center;
13237
+ max-width: 100%;
13238
+ }
13239
+
13240
+ .stack-nav-trigger {
13241
+ display: inline-flex;
13242
+ align-items: center;
13243
+ gap: 4px;
13244
+ background: none;
13245
+ border: none;
13246
+ padding: 0;
13247
+ cursor: pointer;
13248
+ max-width: 100%;
13249
+ color: inherit;
13250
+ font: inherit;
13251
+ }
13252
+
13253
+ .stack-nav-trigger:hover .stack-nav-chevron {
13254
+ opacity: 1;
13255
+ }
13256
+
13257
+ .stack-nav-trigger h1 {
13258
+ margin: 0;
13259
+ }
13260
+
13261
+ .stack-nav-chevron {
13262
+ flex-shrink: 0;
13263
+ width: 14px;
13264
+ height: 14px;
13265
+ opacity: 0.5;
13266
+ transition: opacity 0.15s ease, transform 0.15s ease;
13267
+ fill: currentColor;
13268
+ color: var(--color-text-tertiary, #656d76);
13269
+ }
13270
+
13271
+ .stack-nav-dropdown.open .stack-nav-chevron {
13272
+ transform: rotate(180deg);
13273
+ opacity: 1;
13274
+ }
13275
+
13276
+ .stack-nav-menu {
13277
+ display: none;
13278
+ position: absolute;
13279
+ top: 100%;
13280
+ left: 50%;
13281
+ transform: translateX(-50%);
13282
+ margin-top: 8px;
13283
+ width: max(420px, min(600px, 50vw));
13284
+ background: var(--color-bg-elevated, #fff);
13285
+ border: 1px solid var(--color-border-primary, #d1d9e0);
13286
+ border-radius: var(--radius-sm, 6px);
13287
+ box-shadow: 0 4px 16px var(--color-shadow, rgba(0, 0, 0, 0.12));
13288
+ z-index: 100;
13289
+ padding: 6px 0;
13290
+ max-height: 420px;
13291
+ overflow-y: auto;
13292
+ }
13293
+
13294
+ .stack-nav-dropdown.open .stack-nav-menu {
13295
+ display: block;
13296
+ }
13297
+
13298
+ .stack-nav-item {
13299
+ display: flex;
13300
+ align-items: flex-start;
13301
+ padding: 10px 16px 10px 36px;
13302
+ cursor: pointer;
13303
+ text-decoration: none;
13304
+ color: var(--color-text-primary, #1f2328);
13305
+ transition: background 0.1s ease;
13306
+ font-size: 14px;
13307
+ position: relative;
13308
+ }
13309
+
13310
+ .stack-nav-item:hover {
13311
+ background: var(--color-accent-lighter, rgba(88, 166, 255, 0.08));
13312
+ }
13313
+
13314
+ .stack-nav-item.current {
13315
+ background: var(--color-accent-lighter, rgba(88, 166, 255, 0.08));
13316
+ }
13317
+
13318
+ /* Star indicator for current PR — absolutely positioned, outside flex flow */
13319
+ .stack-nav-item.current::before {
13320
+ content: '\2605';
13321
+ position: absolute;
13322
+ left: 12px;
13323
+ top: 50%;
13324
+ transform: translateY(-50%);
13325
+ color: var(--color-accent-ai, #f59e0b);
13326
+ font-size: 14px;
13327
+ line-height: 1;
13328
+ }
13329
+
13330
+ /* Text column: two rows */
13331
+ .stack-nav-text {
13332
+ flex: 1;
13333
+ min-width: 0;
13334
+ display: flex;
13335
+ flex-direction: column;
13336
+ gap: 2px;
13337
+ }
13338
+
13339
+ /* Primary row: PR number + title inline */
13340
+ .stack-nav-primary {
13341
+ display: flex;
13342
+ align-items: baseline;
13343
+ gap: 6px;
13344
+ min-width: 0;
13345
+ }
13346
+
13347
+ .stack-nav-number {
13348
+ color: var(--color-accent-ai, #f59e0b);
13349
+ font-weight: 600;
13350
+ font-size: 13px;
13351
+ font-variant-numeric: tabular-nums;
13352
+ }
13353
+
13354
+ .stack-nav-title {
13355
+ overflow: hidden;
13356
+ text-overflow: ellipsis;
13357
+ white-space: nowrap;
13358
+ font-weight: 600;
13359
+ font-size: 14px;
13360
+ color: var(--color-text-primary, #1f2328);
13361
+ }
13362
+
13363
+ /* Secondary row: branch name */
13364
+ .stack-nav-branch {
13365
+ display: flex;
13366
+ align-items: center;
13367
+ gap: 4px;
13368
+ font-size: 12px;
13369
+ color: var(--color-text-tertiary, #656d76);
13370
+ overflow: hidden;
13371
+ }
13372
+
13373
+ .stack-nav-branch span {
13374
+ overflow: hidden;
13375
+ text-overflow: ellipsis;
13376
+ white-space: nowrap;
13377
+ }
13378
+
13379
+ .stack-nav-branch-icon {
13380
+ flex-shrink: 0;
13381
+ width: 12px;
13382
+ height: 12px;
13383
+ fill: currentColor;
13384
+ opacity: 0.7;
13385
+ }
13386
+
13387
+ [data-theme="dark"] .stack-nav-menu {
13388
+ background: var(--color-bg-elevated, #1e2329);
13389
+ border-color: var(--color-border-primary, #30363d);
13390
+ box-shadow: 0 4px 16px var(--color-shadow-large, rgba(0, 0, 0, 0.5));
13391
+ }
13392
+
13393
+ [data-theme="dark"] .stack-nav-item {
13394
+ color: var(--color-text-primary, #c9d1d9);
13395
+ }
13396
+
13397
+ [data-theme="dark"] .stack-nav-item:hover {
13398
+ background: var(--color-accent-lighter, rgba(88, 166, 255, 0.08));
13399
+ }
13400
+
13401
+ [data-theme="dark"] .stack-nav-item.current {
13402
+ background: var(--color-accent-lighter, rgba(88, 166, 255, 0.08));
13403
+ }
13404
+
13405
+ [data-theme="dark"] .stack-nav-title {
13406
+ color: var(--color-text-primary, #c9d1d9);
13407
+ }
13408
+
13409
+ [data-theme="dark"] .stack-nav-chevron {
13410
+ color: var(--color-text-tertiary, #6e7681);
13411
+ }
13412
+
13413
+ [data-theme="dark"] .stack-nav-branch {
13414
+ color: var(--color-text-tertiary, #6e7681);
13415
+ }
13416
+
13417
+ /* ============================================
13418
+ Stack Review — Stack Analysis Dialog
13419
+ ============================================ */
13420
+
13421
+ .stack-dialog-overlay {
13422
+ position: fixed;
13423
+ inset: 0;
13424
+ background: var(--color-bg-overlay, rgba(0, 0, 0, 0.5));
13425
+ display: flex;
13426
+ align-items: center;
13427
+ justify-content: center;
13428
+ z-index: 1000;
13429
+ }
13430
+
13431
+ .stack-dialog-backdrop {
13432
+ position: absolute;
13433
+ inset: 0;
13434
+ }
13435
+
13436
+ .stack-dialog {
13437
+ position: relative;
13438
+ z-index: 1;
13439
+ background: var(--color-bg-elevated, #fff);
13440
+ border: 1px solid var(--color-border-primary, #d1d9e0);
13441
+ border-radius: 12px;
13442
+ box-shadow: 0 8px 32px var(--color-shadow-large, rgba(0, 0, 0, 0.2));
13443
+ width: 680px;
13444
+ max-width: 90vw;
13445
+ max-height: 80vh;
13446
+ display: flex;
13447
+ flex-direction: column;
13448
+ overflow: hidden;
13449
+ }
13450
+
13451
+ .stack-dialog-header {
13452
+ display: flex;
13453
+ align-items: center;
13454
+ justify-content: space-between;
13455
+ padding: 16px 20px;
13456
+ border-bottom: 1px solid var(--color-border-primary, #d1d9e0);
13457
+ font-size: 15px;
13458
+ font-weight: 600;
13459
+ color: var(--color-text-primary, #1f2328);
13460
+ }
13461
+
13462
+ .stack-dialog-header button {
13463
+ background: none;
13464
+ border: none;
13465
+ color: var(--color-text-tertiary, #656d76);
13466
+ cursor: pointer;
13467
+ padding: 4px;
13468
+ border-radius: 4px;
13469
+ transition: color 0.15s ease;
13470
+ }
13471
+
13472
+ .stack-dialog-header button:hover {
13473
+ color: var(--color-text-primary, #1f2328);
13474
+ }
13475
+
13476
+ .stack-dialog-body {
13477
+ flex: 1;
13478
+ overflow-y: auto;
13479
+ padding: 16px 20px;
13480
+ }
13481
+
13482
+ .stack-dialog-footer {
13483
+ display: flex;
13484
+ align-items: center;
13485
+ justify-content: flex-end;
13486
+ gap: 8px;
13487
+ padding: 12px 20px;
13488
+ border-top: 1px solid var(--color-border-primary, #d1d9e0);
13489
+ }
13490
+
13491
+ .stack-dialog-pr-item {
13492
+ display: flex;
13493
+ align-items: flex-start;
13494
+ gap: 10px;
13495
+ padding: 10px 4px;
13496
+ border-bottom: 1px solid var(--color-border-subtle, rgba(0, 0, 0, 0.06));
13497
+ font-size: 13px;
13498
+ color: var(--color-text-primary, #1f2328);
13499
+ }
13500
+
13501
+ .stack-dialog-pr-item:last-child {
13502
+ border-bottom: none;
13503
+ }
13504
+
13505
+ .stack-dialog-pr-checkbox {
13506
+ flex-shrink: 0;
13507
+ width: 16px;
13508
+ height: 16px;
13509
+ accent-color: var(--color-accent-primary, #0969da);
13510
+ cursor: pointer;
13511
+ }
13512
+
13513
+ .stack-dialog-pr-current {
13514
+ font-weight: 600;
13515
+ }
13516
+
13517
+ .stack-dialog-current-badge {
13518
+ flex-shrink: 0;
13519
+ width: 16px;
13520
+ text-align: center;
13521
+ color: var(--color-accent-ai, #f59e0b);
13522
+ font-size: 14px;
13523
+ }
13524
+
13525
+ .stack-dialog-pr-info {
13526
+ flex: 1;
13527
+ min-width: 0;
13528
+ display: flex;
13529
+ flex-direction: column;
13530
+ gap: 2px;
13531
+ }
13532
+
13533
+ .stack-dialog-pr-title-row {
13534
+ display: flex;
13535
+ align-items: center;
13536
+ gap: 8px;
13537
+ min-width: 0;
13538
+ }
13539
+
13540
+ .stack-dialog-loading {
13541
+ display: flex;
13542
+ align-items: center;
13543
+ justify-content: center;
13544
+ padding: 32px 16px;
13545
+ color: var(--color-text-secondary, #656d76);
13546
+ font-size: 13px;
13547
+ gap: 8px;
13548
+ }
13549
+
13550
+ .stack-dialog-loading .loading-spinner {
13551
+ width: 18px;
13552
+ height: 18px;
13553
+ margin-bottom: 0;
13554
+ }
13555
+
13556
+ .stack-dialog-pr-list {
13557
+ max-height: 50vh;
13558
+ overflow-y: auto;
13559
+ }
13560
+
13561
+ .stack-dialog-pr-number {
13562
+ flex-shrink: 0;
13563
+ font-family: var(--font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace);
13564
+ color: var(--color-text-secondary, #656d76);
13565
+ }
13566
+
13567
+ .stack-dialog-pr-title {
13568
+ flex: 1;
13569
+ min-width: 0;
13570
+ overflow: hidden;
13571
+ text-overflow: ellipsis;
13572
+ white-space: nowrap;
13573
+ }
13574
+
13575
+ .stack-dialog-pr-branch {
13576
+ display: flex;
13577
+ align-items: center;
13578
+ gap: 4px;
13579
+ color: var(--color-text-secondary, #656d76);
13580
+ font-size: 12px;
13581
+ }
13582
+
13583
+ .stack-dialog-branch-name {
13584
+ overflow: hidden;
13585
+ text-overflow: ellipsis;
13586
+ white-space: nowrap;
13587
+ min-width: 0;
13588
+ }
13589
+
13590
+ .stack-dialog-branch-icon {
13591
+ flex-shrink: 0;
13592
+ opacity: 0.7;
13593
+ }
13594
+
13595
+ .stack-dialog-analyzed-badge {
13596
+ flex-shrink: 0;
13597
+ color: var(--color-accent-primary, #0969da);
13598
+ font-size: 11px;
13599
+ }
13600
+
13601
+ .stack-dialog-note {
13602
+ color: var(--color-text-secondary, #656d76);
13603
+ font-size: 12px;
13604
+ padding: 8px 16px;
13605
+ border-top: 1px solid var(--color-border-subtle, rgba(0, 0, 0, 0.06));
13606
+ display: flex;
13607
+ flex-direction: column;
13608
+ gap: 4px;
13609
+ }
13610
+
13611
+ .stack-dialog-note-info {
13612
+ display: flex;
13613
+ align-items: flex-start;
13614
+ gap: 4px;
13615
+ color: var(--color-text-tertiary, #8c959f);
13616
+ }
13617
+
13618
+ .stack-dialog-info-icon {
13619
+ flex-shrink: 0;
13620
+ margin-top: 2px;
13621
+ opacity: 0.7;
13622
+ }
13623
+
13624
+ .stack-dialog-error {
13625
+ padding: 16px;
13626
+ color: var(--color-danger, #cf222e);
13627
+ }
13628
+
13629
+ .stack-dialog-controls {
13630
+ display: flex;
13631
+ gap: 8px;
13632
+ margin-bottom: 12px;
13633
+ }
13634
+
13635
+ .stack-dialog-controls button {
13636
+ background: none;
13637
+ border: none;
13638
+ color: var(--color-accent-primary, #0969da);
13639
+ cursor: pointer;
13640
+ font-size: 12px;
13641
+ padding: 2px 4px;
13642
+ }
13643
+
13644
+ .stack-dialog-controls button:hover {
13645
+ text-decoration: underline;
13646
+ }
13647
+
13648
+ [data-theme="dark"] .stack-dialog {
13649
+ background: var(--color-bg-elevated, #1e2329);
13650
+ border-color: var(--color-border-primary, #30363d);
13651
+ box-shadow: 0 8px 32px var(--color-shadow-large, rgba(0, 0, 0, 0.5));
13652
+ }
13653
+
13654
+ [data-theme="dark"] .stack-dialog-header {
13655
+ border-color: var(--color-border-primary, #30363d);
13656
+ color: var(--color-text-primary, #c9d1d9);
13657
+ }
13658
+
13659
+ [data-theme="dark"] .stack-dialog-header button:hover {
13660
+ color: var(--color-text-primary, #c9d1d9);
13661
+ }
13662
+
13663
+ [data-theme="dark"] .stack-dialog-body {
13664
+ color: var(--color-text-primary, #c9d1d9);
13665
+ }
13666
+
13667
+ [data-theme="dark"] .stack-dialog-footer {
13668
+ border-color: var(--color-border-primary, #30363d);
13669
+ }
13670
+
13671
+ [data-theme="dark"] .stack-dialog-pr-item {
13672
+ border-color: var(--color-border-subtle, rgba(255, 255, 255, 0.06));
13673
+ color: var(--color-text-primary, #c9d1d9);
13674
+ }
13675
+
13676
+ [data-theme="dark"] .stack-dialog-loading {
13677
+ color: var(--color-text-secondary, #8b949e);
13678
+ }
13679
+
13680
+ [data-theme="dark"] .stack-dialog-controls button {
13681
+ color: var(--color-accent-primary, #58a6ff);
13682
+ }
13683
+
13684
+ [data-theme="dark"] .stack-dialog-pr-number {
13685
+ color: var(--color-text-secondary, #8b949e);
13686
+ }
13687
+
13688
+ [data-theme="dark"] .stack-dialog-pr-branch {
13689
+ color: var(--color-text-secondary, #8b949e);
13690
+ }
13691
+
13692
+ [data-theme="dark"] .stack-dialog-analyzed-badge {
13693
+ color: var(--color-accent-primary, #58a6ff);
13694
+ }
13695
+
13696
+ [data-theme="dark"] .stack-dialog-note {
13697
+ color: var(--color-text-secondary, #8b949e);
13698
+ border-color: var(--color-border-subtle, rgba(255, 255, 255, 0.06));
13699
+ }
13700
+
13701
+ [data-theme="dark"] .stack-dialog-note-info {
13702
+ color: var(--color-text-tertiary, #6e7681);
13703
+ }
13704
+
13705
+ [data-theme="dark"] .stack-dialog-error {
13706
+ color: var(--color-danger, #f85149);
13707
+ }
13708
+
13709
+ /* ============================================
13710
+ Stack Review — Stack Progress Modal
13711
+ ============================================ */
13712
+
13713
+ .stack-progress-overlay {
13714
+ position: fixed;
13715
+ inset: 0;
13716
+ background: var(--color-bg-overlay, rgba(0, 0, 0, 0.5));
13717
+ display: flex;
13718
+ align-items: center;
13719
+ justify-content: center;
13720
+ z-index: 1000;
13721
+ }
13722
+
13723
+ .stack-progress-backdrop {
13724
+ position: absolute;
13725
+ inset: 0;
13726
+ }
13727
+
13728
+ .stack-progress-modal {
13729
+ background: var(--color-bg-elevated, #fff);
13730
+ border: 1px solid var(--color-border-primary, #d1d9e0);
13731
+ border-radius: 12px;
13732
+ box-shadow: 0 8px 32px var(--color-shadow-large, rgba(0, 0, 0, 0.2));
13733
+ width: 520px;
13734
+ max-width: 90vw;
13735
+ max-height: 80vh;
13736
+ display: flex;
13737
+ flex-direction: column;
13738
+ overflow: hidden;
13739
+ }
13740
+
13741
+ .stack-progress-header {
13742
+ display: flex;
13743
+ align-items: center;
13744
+ justify-content: space-between;
13745
+ padding: 16px 20px;
13746
+ border-bottom: 1px solid var(--color-border-primary, #d1d9e0);
13747
+ font-size: 15px;
13748
+ font-weight: 600;
13749
+ color: var(--color-text-primary, #1f2328);
13750
+ }
13751
+
13752
+ .stack-progress-header button {
13753
+ background: none;
13754
+ border: none;
13755
+ color: var(--color-text-tertiary, #656d76);
13756
+ cursor: pointer;
13757
+ padding: 4px;
13758
+ border-radius: 4px;
13759
+ transition: color 0.15s ease;
13760
+ }
13761
+
13762
+ .stack-progress-header button:hover {
13763
+ color: var(--color-text-primary, #1f2328);
13764
+ }
13765
+
13766
+ .stack-progress-body {
13767
+ flex: 1;
13768
+ overflow-y: auto;
13769
+ padding: 16px 20px;
13770
+ }
13771
+
13772
+ .stack-progress-footer {
13773
+ display: flex;
13774
+ align-items: center;
13775
+ justify-content: flex-end;
13776
+ gap: 8px;
13777
+ padding: 12px 20px;
13778
+ border-top: 1px solid var(--color-border-primary, #d1d9e0);
13779
+ }
13780
+
13781
+ .stack-progress-pr-list {
13782
+ max-height: 320px;
13783
+ overflow-y: auto;
13784
+ }
13785
+
13786
+ .stack-progress-pr-row {
13787
+ display: flex;
13788
+ align-items: center;
13789
+ gap: 12px;
13790
+ padding: 10px 4px;
13791
+ border-bottom: 1px solid var(--color-border-subtle, rgba(0, 0, 0, 0.06));
13792
+ font-size: 13px;
13793
+ }
13794
+
13795
+ .stack-progress-pr-row:last-child {
13796
+ border-bottom: none;
13797
+ }
13798
+
13799
+ .stack-progress-status-icon {
13800
+ flex-shrink: 0;
13801
+ width: 20px;
13802
+ height: 20px;
13803
+ display: flex;
13804
+ align-items: center;
13805
+ justify-content: center;
13806
+ font-size: 14px;
13807
+ }
13808
+
13809
+ .stack-progress-pr-label {
13810
+ flex: 1;
13811
+ min-width: 0;
13812
+ overflow: hidden;
13813
+ text-overflow: ellipsis;
13814
+ white-space: nowrap;
13815
+ color: var(--color-text-primary, #1f2328);
13816
+ }
13817
+
13818
+ .stack-progress-pr-link {
13819
+ cursor: pointer;
13820
+ color: var(--color-accent-primary, #0969da);
13821
+ }
13822
+
13823
+ .stack-progress-pr-link:hover {
13824
+ text-decoration: underline;
13825
+ }
13826
+
13827
+ .stack-progress-pr-detail {
13828
+ flex-shrink: 0;
13829
+ color: var(--color-text-secondary, #656d76);
13830
+ }
13831
+
13832
+ .stack-progress-pr-detail a {
13833
+ color: var(--color-accent-primary, #0969da);
13834
+ text-decoration: none;
13835
+ }
13836
+
13837
+ .stack-progress-pr-detail a:hover {
13838
+ text-decoration: underline;
13839
+ }
13840
+
13841
+ .status-completed .stack-progress-status-icon {
13842
+ color: var(--color-accent-emphasis, #1a7f37);
13843
+ }
13844
+
13845
+ .status-running .stack-progress-status-icon {
13846
+ color: var(--color-accent-ai, #f59e0b);
13847
+ animation: pulse-dot 1.2s ease-in-out infinite;
13848
+ }
13849
+
13850
+ .status-setting_up .stack-progress-status-icon {
13851
+ color: var(--color-text-secondary, #656d76);
13852
+ animation: pulse-dot 1.2s ease-in-out infinite;
13853
+ }
13854
+
13855
+ .status-pending .stack-progress-status-icon {
13856
+ color: var(--color-text-muted, #d1d9e0);
13857
+ }
13858
+
13859
+ .status-failed .stack-progress-status-icon {
13860
+ color: var(--color-danger, #cf222e);
13861
+ }
13862
+
13863
+ [data-theme="dark"] .stack-progress-modal {
13864
+ background: var(--color-bg-elevated, #1e2329);
13865
+ border-color: var(--color-border-primary, #30363d);
13866
+ box-shadow: 0 8px 32px var(--color-shadow-large, rgba(0, 0, 0, 0.5));
13867
+ }
13868
+
13869
+ [data-theme="dark"] .stack-progress-header {
13870
+ border-color: var(--color-border-primary, #30363d);
13871
+ color: var(--color-text-primary, #c9d1d9);
13872
+ }
13873
+
13874
+ [data-theme="dark"] .stack-progress-header button:hover {
13875
+ color: var(--color-text-primary, #c9d1d9);
13876
+ }
13877
+
13878
+ [data-theme="dark"] .stack-progress-body {
13879
+ color: var(--color-text-primary, #c9d1d9);
13880
+ }
13881
+
13882
+ [data-theme="dark"] .stack-progress-footer {
13883
+ border-color: var(--color-border-primary, #30363d);
13884
+ }
13885
+
13886
+ [data-theme="dark"] .stack-progress-pr-row {
13887
+ border-color: var(--color-border-subtle, rgba(255, 255, 255, 0.06));
13888
+ }
13889
+
13890
+ [data-theme="dark"] .stack-progress-pr-label {
13891
+ color: var(--color-text-primary, #c9d1d9);
13892
+ }
13893
+
13894
+ [data-theme="dark"] .stack-progress-pr-link {
13895
+ color: var(--color-accent-primary, #58a6ff);
13896
+ }
13897
+
13898
+ [data-theme="dark"] .stack-progress-pr-detail {
13899
+ color: var(--color-text-secondary, #8b949e);
13900
+ }
13901
+
13902
+ [data-theme="dark"] .stack-progress-pr-detail a {
13903
+ color: var(--color-accent-primary, #58a6ff);
13904
+ }
13905
+
13906
+ [data-theme="dark"] .status-completed .stack-progress-status-icon {
13907
+ color: var(--color-accent-emphasis-hover, #2ea043);
13908
+ }
13909
+
13910
+ [data-theme="dark"] .status-running .stack-progress-status-icon {
13911
+ color: var(--color-accent-ai-dark, #f59e0b);
13912
+ }
13913
+
13914
+ [data-theme="dark"] .status-setting_up .stack-progress-status-icon {
13915
+ color: var(--color-text-secondary, #8b949e);
13916
+ }
13917
+
13918
+ [data-theme="dark"] .status-pending .stack-progress-status-icon {
13919
+ color: var(--color-text-muted, #484f58);
13920
+ }
13921
+
13922
+ [data-theme="dark"] .status-failed .stack-progress-status-icon {
13923
+ color: var(--color-danger, #f85149);
13924
+ }