prreviewbuddy 0.87.2 → 0.90.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.
package/static/shell.css CHANGED
@@ -90,6 +90,22 @@
90
90
  --neutral-subtle: light-dark(rgba(15, 23, 42, 0.06), rgba(139, 148, 158, 0.16));
91
91
  --merged-subtle: light-dark(#f3e8ff, rgba(163, 113, 247, 0.18));
92
92
  --merged-ink: light-dark(#6b21a8, #d2a8ff);
93
+ /* A review's own lifecycle, what happens next with it: Active, Waiting, Done. Named apart from
94
+ --lifecycle-*, which is a pull request's, so the two cannot be swapped by accident. Done is a
95
+ muted slate rather than purple, because purple already means the brand, Merged and branch news. */
96
+ --state-active-subtle: light-dark(#eaf2fd, rgba(56, 139, 253, 0.14));
97
+ --state-active-ink: light-dark(#0b4fae, #9cc4ff);
98
+ --state-active-border: light-dark(rgba(11, 79, 174, 0.3), rgba(56, 139, 253, 0.45));
99
+ --state-waiting-subtle: light-dark(#fff5d6, rgba(210, 153, 34, 0.16));
100
+ --state-waiting-ink: light-dark(#7a5200, #ffd18a);
101
+ --state-waiting-border: light-dark(rgba(138, 92, 0, 0.32), rgba(210, 153, 34, 0.5));
102
+ --state-done-subtle: light-dark(#e8ecf1, rgba(148, 163, 184, 0.16));
103
+ --state-done-ink: light-dark(#334155, #cbd5e1);
104
+ --state-done-border: light-dark(rgba(51, 65, 85, 0.32), rgba(148, 163, 184, 0.45));
105
+ /* The pills' widths, the widest of their words (NOT REVIEWED, WAITING): a press never moves what
106
+ is beside them, and a card can reserve exactly the room its controls take. */
107
+ --status-pill-width: 104px;
108
+ --lifecycle-pill-width: 70px;
93
109
  /* A pull request's lifecycle in Activity: merged, closed, reopened. Blue because purple there
94
110
  means unread, and a merged tile must never be read as a new one. */
95
111
  --lifecycle-subtle: light-dark(#e7f0fd, rgba(56, 139, 253, 0.16));
@@ -408,6 +424,8 @@ body > * { flex: 0 0 auto; }
408
424
  a fixed-width box hanging below the header, and its items have to wrap inside it. */
409
425
  .prb-header-stats > :not(.prb-menu) { white-space: nowrap; }
410
426
  .prb-header-stats .prb-add { color: var(--success); }
427
+ /* The two pills and the change chip read as one pair of facts, closer to each other than to the stats. */
428
+ .prb-state-pills { display: inline-flex; align-items: center; gap: 6px; }
411
429
  .prb-header-stats .prb-del { color: var(--danger); }
412
430
 
413
431
  /* The build, and where to complain about it. Quieter than the change stats — it is provenance,
@@ -2830,6 +2848,18 @@ a.prb-rail-item { text-decoration: none; }
2830
2848
  /* A notice the reviewer can put away: the sentence, then its Dismiss at the end of the same row. */
2831
2849
  .prb-job[data-notice] { flex-direction: row; align-items: center; justify-content: space-between; gap: 16px; }
2832
2850
  .prb-job p { margin: 0; }
2851
+ /* The AI integrations notice: an invitation rather than a status, so it carries the brand edge and
2852
+ its link sits before Not now, both at the end of the row. */
2853
+ .prb-integrations-notice { border-left-color: var(--brand); }
2854
+ .prb-integrations-notice p { flex: 1; }
2855
+ .prb-integrations-notice-link {
2856
+ flex: none;
2857
+ color: var(--brand-ink);
2858
+ font-size: var(--t-meta);
2859
+ font-weight: 600;
2860
+ text-decoration: none;
2861
+ }
2862
+ .prb-integrations-notice-link:hover { opacity: 0.8; }
2833
2863
  .prb-job strong { color: var(--text-primary); font-weight: 600; }
2834
2864
  .prb-job-progress { color: var(--text-muted); }
2835
2865
  .prb-job-elapsed, .prb-job-note { color: var(--text-muted); font-size: var(--t-micro); }
@@ -3519,12 +3549,17 @@ a.prb-guide-pick { text-decoration: none; }
3519
3549
  .prb-index-more[hidden] { display: none; }
3520
3550
  .prb-index-more:hover { color: var(--text-primary); border-color: var(--border-strong); }
3521
3551
  .prb-card {
3552
+ /* What the controls over the top-right corner take: two pills, the menu and the star, and the
3553
+ gaps between them. The head reserves exactly this, so the title is cut only where they are. */
3554
+ --card-controls-width: calc(var(--status-pill-width) + var(--lifecycle-pill-width) + 26px + 26px + 3 * 6px);
3522
3555
  position: relative;
3556
+ container-type: inline-size;
3523
3557
  border: 1px solid var(--border);
3524
3558
  border-radius: 12px;
3525
3559
  background: var(--surface-raised);
3526
3560
  }
3527
- .prb-card:hover { border-color: var(--border-strong); }
3561
+ /* A stronger edge and the faintest change of ground, and nothing that moves. */
3562
+ .prb-card:hover { border-color: var(--border-strong); background: color-mix(in srgb, var(--surface-raised), var(--text-primary) 2%); }
3528
3563
  .prb-card[hidden] { display: none; }
3529
3564
 
3530
3565
  /* ── Selecting ──
@@ -3768,10 +3803,9 @@ a.prb-guide-pick { text-decoration: none; }
3768
3803
  align-items: baseline;
3769
3804
  justify-content: space-between;
3770
3805
  gap: 12px;
3771
- /* Room for the pin and the menu, both positioned over the card's top-right corner. Reserved
3772
- here rather than left to chance: the status badge is the last thing in this row, and without
3773
- the space it is what the controls sit on top of. */
3774
- padding-right: 56px;
3806
+ /* Room for the controls positioned over the card's top-right corner. Reserved here rather than
3807
+ left to chance: without it the PR state and the change chip are what the controls sit on. */
3808
+ padding-right: calc(var(--card-controls-width) + 6px);
3775
3809
  }
3776
3810
  .prb-card-head h2 {
3777
3811
  /* The auto margin takes the free space, so the status and the PR state sit together at the end
@@ -3847,12 +3881,26 @@ a.prb-guide-pick { text-decoration: none; }
3847
3881
 
3848
3882
  /* News about the change rather than a verdict on it: tinted like the brand, never like a risk.
3849
3883
  It sits in the meta line with the other facts, because that is what it is. */
3850
- .prb-card-moved {
3851
- color: var(--brand);
3884
+ .prb-card-moved,
3885
+ .prb-card-badge {
3886
+ padding: 1px 7px;
3887
+ border-radius: 999px;
3852
3888
  font-weight: 600;
3889
+ white-space: nowrap;
3853
3890
  }
3891
+ .prb-card-moved { background: var(--brand-muted); color: var(--brand-ink); }
3854
3892
  .prb-card-diffstat { font-variant-numeric: tabular-nums; }
3855
- .prb-card-left { color: var(--text-secondary); }
3893
+ /* What is left, as facts: a badge only where there is an outcome to see at a glance (resolved and
3894
+ answered, or still open), plain words for the rest, "Nothing flagged" among them. */
3895
+ .prb-card-left {
3896
+ display: inline-flex;
3897
+ flex-wrap: wrap;
3898
+ align-items: baseline;
3899
+ gap: 8px;
3900
+ color: var(--text-secondary);
3901
+ }
3902
+ .prb-card-badge[data-tone="success"] { background: var(--success-subtle); color: var(--success-ink); }
3903
+ .prb-card-badge[data-tone="attention"] { background: var(--warning-subtle); color: var(--warning-ink); }
3856
3904
 
3857
3905
  /* What is happening to this review right now.
3858
3906
  A dot that breathes, because the one thing this line has to communicate before it is read is
@@ -4045,6 +4093,51 @@ a.prb-guide-pick { text-decoration: none; }
4045
4093
  .prb-card-status { border: 1px solid var(--border); color: var(--text-tertiary, var(--text-secondary)); }
4046
4094
  .prb-card-status[data-status="new"] { border-color: var(--brand); color: var(--brand-ink); }
4047
4095
  .prb-card-status[data-status="complete"] { border-color: var(--success-border); color: var(--success-ink); }
4096
+
4097
+ /* ── Status and lifecycle pills ──
4098
+ Where a review stands, on a card and in the review's header, and the control that changes it
4099
+ (state_pills.ts). Outlined on a faint tint of their own colour, where the facts beside them
4100
+ (Merged, risk, branch news) are filled and borderless, so a control and a fact never look alike.
4101
+ Each kind has one width whatever its words, so pressing one never moves what is beside it. */
4102
+ .prb-state-pill {
4103
+ box-sizing: border-box;
4104
+ display: inline-flex;
4105
+ align-items: center;
4106
+ justify-content: center;
4107
+ gap: 4px;
4108
+ flex: none;
4109
+ padding: 2px 8px;
4110
+ border: 1px solid var(--border-strong);
4111
+ border-radius: 999px;
4112
+ background: var(--neutral-subtle);
4113
+ color: var(--text-secondary);
4114
+ font: inherit;
4115
+ font-size: var(--t-pill);
4116
+ font-weight: 700;
4117
+ line-height: 1.4;
4118
+ letter-spacing: 0.04em;
4119
+ text-transform: uppercase;
4120
+ white-space: nowrap;
4121
+ }
4122
+ .prb-state-pill.prb-card-status { min-width: var(--status-pill-width); }
4123
+ .prb-lifecycle-pill { min-width: var(--lifecycle-pill-width); }
4124
+ .prb-state-pill[data-status="new"] { border-color: var(--brand-border); background: var(--brand-muted); color: var(--brand-ink); }
4125
+ .prb-state-pill[data-status="complete"] { border-color: var(--success-border); background: var(--success-subtle); color: var(--success-ink); }
4126
+ /* A mark as well as a colour, so Reviewed is not told apart by colour alone. Silent to a screen
4127
+ reader, which hears the word. */
4128
+ .prb-state-pill[data-status="complete"]::before { content: '✓' / ''; }
4129
+ .prb-lifecycle-pill[data-lifecycle-pill="active"] { border-color: var(--state-active-border); background: var(--state-active-subtle); color: var(--state-active-ink); }
4130
+ .prb-lifecycle-pill[data-lifecycle-pill="waiting"] { border-color: var(--state-waiting-border); background: var(--state-waiting-subtle); color: var(--state-waiting-ink); }
4131
+ .prb-lifecycle-pill[data-lifecycle-pill="done"] { border-color: var(--state-done-border); background: var(--state-done-subtle); color: var(--state-done-ink); }
4132
+ button.prb-state-pill { cursor: pointer; }
4133
+ /* Pressable, said quietly: the outline takes the word's colour and the ground darkens a step. */
4134
+ button.prb-state-pill:not([aria-busy="true"]):hover {
4135
+ border-color: color-mix(in srgb, currentColor 55%, transparent);
4136
+ box-shadow: inset 0 0 0 999px var(--wash-strong);
4137
+ }
4138
+ button.prb-state-pill:focus-visible { outline: 2px solid var(--brand-hover); outline-offset: 2px; }
4139
+ button.prb-state-pill[aria-busy="true"] { opacity: 0.6; cursor: progress; }
4140
+ .prb-pill-menu .prb-menu-panel { top: 28px; width: 200px; }
4048
4141
  /* The upstream's state, beside the reviewer's. Filled where the status is outlined, so the two read
4049
4142
  as different kinds of fact. Merged takes the forge's own purple; closed is muted rather than red,
4050
4143
  because red on this card already means high risk. */
@@ -4061,19 +4154,42 @@ a.prb-guide-pick { text-decoration: none; }
4061
4154
  padding: 2px 7px;
4062
4155
  border-radius: 999px;
4063
4156
  font-size: var(--t-meta);
4064
- font-weight: 600;
4157
+ font-weight: 700;
4065
4158
  white-space: nowrap;
4066
4159
  background: var(--brand-muted);
4067
4160
  color: var(--brand-ink);
4161
+ /* A step louder than Branch updated, because a parked review that moved is the thing to find when
4162
+ scanning a long list. An inset edge, so it is no bigger than the pills beside it. */
4163
+ box-shadow: inset 0 0 0 1px var(--brand-border);
4068
4164
  }
4069
4165
  .prb-card-lifecycle[hidden] { display: none; }
4070
4166
 
4071
- /* Over the card rather than inside its link, so pinning cannot be a mis-click into the review. */
4072
- .prb-card-pin {
4167
+ /* The card's controls, over its top-right corner rather than inside its link, so no press on them
4168
+ can be a mis-click into the review. No z-index of its own: each control keeps the layer it had
4169
+ when the pin and the menu sat here alone, the pin and the pills under any open panel above them
4170
+ (a collection's menu, the card's above), the menu over them. Waiting's items rise while open. */
4171
+ .prb-card-controls {
4073
4172
  position: absolute;
4074
4173
  top: 10px;
4075
4174
  right: 10px;
4076
- z-index: 1;
4175
+ display: flex;
4176
+ align-items: center;
4177
+ gap: 6px;
4178
+ }
4179
+ .prb-card-controls > .prb-state-pill,
4180
+ .prb-card-controls > .prb-card-pin { position: relative; z-index: 1; }
4181
+ .prb-card-controls > .prb-menu { position: relative; top: auto; right: auto; }
4182
+ .prb-card-controls > .prb-pill-menu { z-index: 1; }
4183
+ .prb-card-controls > .prb-pill-menu:has(> [aria-expanded="true"]) { z-index: 3; }
4184
+ /* Where the title would be cut short, the controls take a line of their own under it instead, at
4185
+ the title's own left edge. The title is one line, so the line it leaves is a fixed height. */
4186
+ @container (max-width: 560px) {
4187
+ .prb-card[data-card] .prb-card-head { padding-right: 0; margin-bottom: 38px; }
4188
+ .prb-card-controls { top: 42px; right: auto; left: 16px; }
4189
+ .prb-index[data-selecting] .prb-card-controls { left: 42px; }
4190
+ }
4191
+
4192
+ .prb-card-pin {
4077
4193
  width: 26px;
4078
4194
  height: 26px;
4079
4195
  border: 0;
@@ -4222,18 +4338,6 @@ a.prb-guide-pick { text-decoration: none; }
4222
4338
  line-height: var(--lh-body);
4223
4339
  }
4224
4340
 
4225
- /* The review page's lifecycle pill is the status pill's shape. Changed since it was parked, it
4226
- reads as the card's chip does: a sentence, tinted like news. */
4227
- .prb-page-lifecycle[data-changed] {
4228
- border-color: transparent;
4229
- background: var(--brand-muted);
4230
- color: var(--brand-ink);
4231
- font-size: var(--t-meta);
4232
- font-weight: 600;
4233
- letter-spacing: 0;
4234
- text-transform: none;
4235
- }
4236
- .prb-page-lifecycle[hidden] { display: none; }
4237
4341
 
4238
4342
  /* ── Diagrams ──
4239
4343
  *
@@ -5791,6 +5895,89 @@ select.prb-addreview-control {
5791
5895
  }
5792
5896
  .prb-settings-help code { font-size: var(--t-code); color: var(--text-primary); }
5793
5897
 
5898
+ /* ── AI integrations ──
5899
+ A list inside Settings, one row per coding agent. Each row's state is a word in a pill and the
5900
+ colour only agrees with it, as the save line does. Buttons here act at once, so the primary one
5901
+ is filled and the rest are outlined like Stop server, never the danger red: Disconnect is
5902
+ recoverable with one press of Connect. */
5903
+ #ai-integrations { scroll-margin-top: 96px; }
5904
+ .prb-integrations > .prb-settings-help + .prb-settings-help { margin-top: 10px; }
5905
+ .prb-integrations-list { list-style: none; margin: 14px 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
5906
+ .prb-integration {
5907
+ padding: 14px 16px;
5908
+ border: 1px solid var(--border);
5909
+ border-radius: 10px;
5910
+ background: var(--surface-2);
5911
+ display: flex;
5912
+ flex-direction: column;
5913
+ gap: 8px;
5914
+ }
5915
+ .prb-integration[aria-busy='true'] { opacity: 0.8; }
5916
+ .prb-integration-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
5917
+ .prb-integration-name { font-size: var(--t-body); font-weight: 600; color: var(--text-primary); }
5918
+ .prb-integration-state {
5919
+ padding: 2px 9px;
5920
+ border: 1px solid var(--border);
5921
+ border-radius: 999px;
5922
+ font-size: var(--t-meta);
5923
+ color: var(--text-secondary);
5924
+ }
5925
+ .prb-integration-state[data-state='connected'] { color: var(--success); border-color: var(--success); }
5926
+ .prb-integration-state[data-state='connected-elsewhere'],
5927
+ .prb-integration-state[data-state='disabled'],
5928
+ .prb-integration-state[data-state='unknown'] { color: var(--warning); border-color: var(--warning); }
5929
+ .prb-integration-actions { display: flex; flex-wrap: wrap; gap: 8px; }
5930
+ .prb-integration-actions:empty { display: none; }
5931
+ .prb-integration-button,
5932
+ .prb-integration-primary {
5933
+ padding: 7px 14px;
5934
+ border: 1px solid var(--border);
5935
+ border-radius: 8px;
5936
+ background: transparent;
5937
+ color: var(--text-primary);
5938
+ font: inherit;
5939
+ font-size: var(--t-body);
5940
+ cursor: pointer;
5941
+ }
5942
+ .prb-integration-button:hover { border-color: var(--border-strong); }
5943
+ .prb-integration-primary { border-color: var(--brand); background: var(--brand); color: var(--on-brand); }
5944
+ .prb-integration-primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
5945
+ .prb-integration-button:disabled,
5946
+ .prb-integration-primary:disabled { opacity: 0.6; cursor: default; }
5947
+ .prb-integration-button:focus-visible,
5948
+ .prb-integration-primary:focus-visible { outline: 2px solid var(--brand-hover); outline-offset: 2px; }
5949
+ .prb-integration-result { margin: 0; font-size: var(--t-meta); line-height: var(--lh-body); color: var(--text-secondary); }
5950
+ .prb-integration-result:empty { display: none; }
5951
+ .prb-integration-result[data-kind='ok'] { color: var(--success); }
5952
+ .prb-integration-result[data-kind='error'] { color: var(--danger); }
5953
+ .prb-integration pre,
5954
+ .prb-integration-dialog pre {
5955
+ margin: 6px 0;
5956
+ padding: 8px 10px;
5957
+ border: 1px solid var(--border);
5958
+ border-radius: 8px;
5959
+ background: var(--surface);
5960
+ white-space: pre-wrap;
5961
+ word-break: break-all;
5962
+ font-size: var(--t-code);
5963
+ color: var(--text-primary);
5964
+ }
5965
+ .prb-integration-manual > summary,
5966
+ .prb-integrations-scope > summary {
5967
+ cursor: pointer;
5968
+ font-size: var(--t-meta);
5969
+ color: var(--text-secondary);
5970
+ }
5971
+ .prb-integration-manual > summary:hover,
5972
+ .prb-integrations-scope > summary:hover { color: var(--text-primary); }
5973
+ .prb-integration-manual[open] > summary,
5974
+ .prb-integrations-scope[open] > summary { margin-bottom: 6px; }
5975
+ .prb-integration-manual .prb-settings-field { margin: 8px 0; }
5976
+ .prb-integrations-scope { margin-top: 6px; }
5977
+ .prb-integrations-scope a { color: var(--brand-ink); text-decoration: none; }
5978
+ .prb-integrations-scope a:hover { opacity: 0.8; }
5979
+ .prb-integration-dialog { max-width: 560px; }
5980
+
5794
5981
  /* ── Help ──
5795
5982
  Reading, not settings: prose at a readable measure, one topic per section, each with an anchor a
5796
5983
  place elsewhere in the product can link to. */