prreviewbuddy 0.45.0 → 0.46.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prreviewbuddy",
3
- "version": "0.45.0",
3
+ "version": "0.46.0",
4
4
  "description": "Review a branch or pull request in an isolated checkout, from your terminal, with the coding agent you already have installed.",
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://prreviewbuddy.com",
package/static/shell.css CHANGED
@@ -1529,6 +1529,9 @@ a.prb-rail-item { text-decoration: none; }
1529
1529
  }
1530
1530
  .prb-bank-add:hover { border-color: var(--border-strong); color: var(--text-primary); }
1531
1531
  .prb-bank-list { display: flex; flex-wrap: wrap; gap: 6px; }
1532
+ /* Folded. The `display` above outranks the browser's own rule for `hidden`, so without this the
1533
+ fold flips the attribute and the chips stay on screen. */
1534
+ .prb-bank-list[hidden] { display: none; }
1532
1535
  /* The pair reads as one chip: the label inserts, the pencil edits. They share a border so the
1533
1536
  edit affordance is visibly part of the prompt it edits rather than a control floating beside it. */
1534
1537
  .prb-bank-item {
@@ -3704,6 +3707,320 @@ a.prb-rail-item { text-decoration: none; }
3704
3707
  .prb-diagram-source > summary::before { content: '\25B8 '; }
3705
3708
  .prb-diagram-source[open] > summary::before { content: '\25BE '; }
3706
3709
 
3710
+ /* ── The two diagram tabs ──
3711
+ Each says what question it answers, so the reviewer never has to open both to learn they differ.
3712
+ A segmented strip rather than the rail's style: these are two views of one place, not two places. */
3713
+ .prb-diagram-modes {
3714
+ display: inline-flex;
3715
+ gap: 2px;
3716
+ margin: 0 0 18px;
3717
+ padding: 4px;
3718
+ border: 1px solid rgba(15, 23, 42, 0.12);
3719
+ border-radius: 10px;
3720
+ background: #f6f8fa;
3721
+ }
3722
+ .prb-diagram-mode {
3723
+ display: flex;
3724
+ flex-direction: column;
3725
+ align-items: flex-start;
3726
+ gap: 2px;
3727
+ min-width: 190px;
3728
+ padding: 8px 18px 9px;
3729
+ border: 0;
3730
+ border-radius: 8px;
3731
+ background: transparent;
3732
+ color: #57606a;
3733
+ font: inherit;
3734
+ text-align: left;
3735
+ cursor: pointer;
3736
+ }
3737
+ .prb-diagram-mode:hover { color: #1f2328; }
3738
+ .prb-diagram-mode[aria-selected='true'] {
3739
+ background: #fff;
3740
+ color: #1f2328;
3741
+ box-shadow: 0 1px 2px rgba(15, 23, 42, 0.12);
3742
+ }
3743
+ .prb-diagram-mode:focus-visible { outline: 2px solid #9333ea; outline-offset: 1px; }
3744
+ .prb-diagram-mode-title { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-body); font-weight: 600; }
3745
+ /* The picture on this tab already exists: switching to it costs nothing. Passive, and a word for
3746
+ assistive technology rather than colour alone. */
3747
+ .prb-diagram-mode-ready {
3748
+ display: inline-flex;
3749
+ align-items: center;
3750
+ justify-content: center;
3751
+ width: 15px;
3752
+ height: 15px;
3753
+ border-radius: 50%;
3754
+ background: rgba(26, 127, 55, 0.12);
3755
+ color: #1a7f37;
3756
+ font-size: 10px;
3757
+ font-weight: 700;
3758
+ }
3759
+ .prb-diagram-mode-ready[hidden] { display: none; }
3760
+ .prb-diagram-mode-subtitle { font-size: var(--t-micro); color: #8c959f; }
3761
+
3762
+ /* ── Before anything is drawn ──
3763
+ Says what the view is for and offers the one action that spends a run. Not a dead end, and not a
3764
+ button that pretends to be free. */
3765
+ .prb-map-empty {
3766
+ max-width: 560px;
3767
+ margin: 8px 0 20px;
3768
+ padding: 18px 20px;
3769
+ border: 1px dashed rgba(15, 23, 42, 0.2);
3770
+ border-radius: 10px;
3771
+ background: #fff;
3772
+ font-size: var(--t-body);
3773
+ line-height: var(--lh-body);
3774
+ color: #57606a;
3775
+ }
3776
+ .prb-map-empty p { margin: 0 0 10px; }
3777
+ .prb-map-empty-title { margin: 0 0 6px; font-size: var(--t-section); font-weight: 600; color: #1f2328; }
3778
+ .prb-map-empty-note { font-size: var(--t-meta); color: #8c959f; }
3779
+ .prb-map-stale {
3780
+ padding: 7px 10px;
3781
+ border-radius: 7px;
3782
+ background: rgba(251, 191, 36, 0.12);
3783
+ font-size: var(--t-meta);
3784
+ color: #6b5514;
3785
+ }
3786
+ .prb-map-generate {
3787
+ margin-top: 4px;
3788
+ padding: 7px 14px;
3789
+ border: 1px solid #9333ea;
3790
+ border-radius: 6px;
3791
+ background: #9333ea;
3792
+ color: #fff;
3793
+ font: inherit;
3794
+ font-size: var(--t-meta);
3795
+ font-weight: 600;
3796
+ cursor: pointer;
3797
+ }
3798
+ .prb-map-generate:hover { background: #7e22ce; }
3799
+ .prb-map-generate[disabled] { opacity: 0.55; cursor: default; }
3800
+ /* While a map is being made there is one state on screen, the work and its Stop: the button that
3801
+ would start it again goes, whether this page asked or came back to a run already going. */
3802
+ .prb-view[data-map-running] .prb-map-generate { display: none; }
3803
+ /* The implementation tab's own empty state goes the moment its first card is in the pane. */
3804
+ .prb-view[data-diagram-pane]:has([data-diagram-card]) [data-diagram-empty] { display: none; }
3805
+
3806
+ /* ── The change map ── */
3807
+ .prb-map-body { container-type: inline-size; }
3808
+ .prb-map {
3809
+ margin: 0 0 20px;
3810
+ border: 1px solid rgba(15, 23, 42, 0.12);
3811
+ border-radius: 10px;
3812
+ background: #fff;
3813
+ }
3814
+ .prb-map-head {
3815
+ display: flex;
3816
+ flex-wrap: wrap;
3817
+ align-items: flex-start;
3818
+ gap: 12px;
3819
+ padding: 14px 16px 12px;
3820
+ border-bottom: 1px solid rgba(15, 23, 42, 0.08);
3821
+ }
3822
+ .prb-map-heading { flex: 1 1 280px; min-width: 0; }
3823
+ .prb-map-title { margin: 0; font-size: var(--t-section); font-weight: 600; color: #1f2328; }
3824
+ .prb-map-intent { margin: 4px 0 0; font-size: var(--t-body); line-height: var(--lh-body); color: #57606a; }
3825
+ .prb-map-tools { display: flex; align-items: center; gap: 8px; margin-left: auto; }
3826
+ .prb-map-registers {
3827
+ display: inline-flex;
3828
+ padding: 2px;
3829
+ border: 1px solid rgba(15, 23, 42, 0.15);
3830
+ border-radius: 7px;
3831
+ background: #f6f8fa;
3832
+ }
3833
+ .prb-map-register {
3834
+ padding: 3px 10px;
3835
+ border: 0;
3836
+ border-radius: 5px;
3837
+ background: transparent;
3838
+ color: #57606a;
3839
+ font: inherit;
3840
+ font-size: var(--t-micro);
3841
+ cursor: pointer;
3842
+ }
3843
+ .prb-map-register[aria-pressed='true'] { background: #fff; color: #1f2328; font-weight: 600; box-shadow: 0 1px 2px rgba(15, 23, 42, 0.12); }
3844
+ .prb-map-register:focus-visible { outline: 2px solid #9333ea; outline-offset: 1px; }
3845
+ .prb-map-hint { margin: 10px 16px 0; font-size: var(--t-micro); color: #8c959f; }
3846
+
3847
+ /* One graph in the page, two sets of words; the board says which to show. */
3848
+ .prb-map[data-register='simple'] [data-reg='technical'],
3849
+ .prb-map[data-register='technical'] [data-reg='simple'] { display: none; }
3850
+
3851
+ /* Stages as columns, read left to right. The gaps are wide on purpose: the relationship labels sit
3852
+ in them, and a label is the point of a line. */
3853
+ .prb-map-board {
3854
+ position: relative;
3855
+ display: grid;
3856
+ grid-template-columns: repeat(var(--prb-map-stages, 5), minmax(180px, 1fr));
3857
+ column-gap: 112px;
3858
+ padding: 14px 16px 22px;
3859
+ overflow-x: auto;
3860
+ }
3861
+ .prb-map-stage {
3862
+ position: relative;
3863
+ z-index: 1;
3864
+ display: flex;
3865
+ flex-direction: column;
3866
+ gap: 22px;
3867
+ }
3868
+ .prb-map-stage-title {
3869
+ align-self: flex-start;
3870
+ margin: 0 0 -8px;
3871
+ font-size: var(--t-micro);
3872
+ font-weight: 600;
3873
+ text-transform: uppercase;
3874
+ letter-spacing: 0.05em;
3875
+ color: #8c959f;
3876
+ }
3877
+
3878
+ .prb-map-node {
3879
+ --role: #8250df;
3880
+ position: relative;
3881
+ padding: 9px 11px 10px;
3882
+ border: 1px solid rgba(15, 23, 42, 0.14);
3883
+ border-left: 4px solid var(--role);
3884
+ border-radius: 8px;
3885
+ background: #fff;
3886
+ font-size: var(--t-meta);
3887
+ line-height: 1.45;
3888
+ color: #424a53;
3889
+ transition: opacity 0.15s ease, box-shadow 0.15s ease;
3890
+ cursor: pointer;
3891
+ }
3892
+ .prb-map-node:focus-visible { outline: 2px solid #9333ea; outline-offset: 2px; }
3893
+ .prb-map-node[data-role='intent'] { --role: #0969da; }
3894
+ .prb-map-node[data-role='actor'] { --role: #6e7781; }
3895
+ .prb-map-node[data-role='concept'] { --role: #8250df; }
3896
+ .prb-map-node[data-role='state'] { --role: #0f766e; }
3897
+ .prb-map-node[data-role='constraint'] { --role: #9a6700; }
3898
+ .prb-map-node[data-role='risk'] { --role: #cf222e; }
3899
+ .prb-map-node[data-role='outcome'] { --role: #1a7f37; }
3900
+ /* Importance is prominence: a heavier frame and a larger name, never a score. */
3901
+ .prb-map-node[data-weight='primary'] {
3902
+ border-width: 2px 2px 2px 5px;
3903
+ border-color: var(--role);
3904
+ box-shadow: 0 2px 8px rgba(15, 23, 42, 0.08);
3905
+ }
3906
+ .prb-map-node[data-weight='primary'] .prb-map-node-title { font-size: calc(var(--t-body) + 1px); }
3907
+ .prb-map-role {
3908
+ margin: 0 0 3px;
3909
+ font-size: var(--t-micro);
3910
+ font-weight: 600;
3911
+ text-transform: uppercase;
3912
+ letter-spacing: 0.04em;
3913
+ color: var(--role);
3914
+ }
3915
+ .prb-map-core { color: #57606a; font-weight: 500; }
3916
+ .prb-map-node-title { margin: 0 0 4px; font-size: var(--t-body); font-weight: 600; line-height: 1.3; color: #1f2328; }
3917
+ .prb-map-node-body { margin: 0; }
3918
+ .prb-map code:not(.prb-map-anchor) {
3919
+ padding: 0 3px;
3920
+ border-radius: 3px;
3921
+ background: #f6f8fa;
3922
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
3923
+ font-size: var(--t-code);
3924
+ }
3925
+ .prb-map-why { margin: 6px 0 0; color: #57606a; }
3926
+ .prb-map-why-lead { font-weight: 600; color: #1f2328; }
3927
+ .prb-map-anchor {
3928
+ display: inline-block;
3929
+ max-width: 100%;
3930
+ margin-top: 6px;
3931
+ padding: 1px 5px;
3932
+ border-radius: 4px;
3933
+ background: #f6f8fa;
3934
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
3935
+ font-size: var(--t-code);
3936
+ color: #57606a;
3937
+ overflow-wrap: anywhere;
3938
+ }
3939
+ /* Relationships the board could not draw cleanly, said in the idea they leave from. */
3940
+ .prb-map-inline {
3941
+ margin: 7px 0 0;
3942
+ padding: 6px 0 0;
3943
+ border-top: 1px dashed rgba(15, 23, 42, 0.14);
3944
+ list-style: none;
3945
+ font-size: var(--t-micro);
3946
+ color: #57606a;
3947
+ }
3948
+ .prb-map-inline:not(:has(li:not([hidden]))) { display: none; }
3949
+ .prb-map-inline li + li { margin-top: 2px; }
3950
+ .prb-map-inline em { color: #1f2328; }
3951
+ .prb-map-goto {
3952
+ display: block;
3953
+ margin-top: 8px;
3954
+ padding: 0;
3955
+ border: 0;
3956
+ background: none;
3957
+ color: #8250df;
3958
+ font: inherit;
3959
+ font-size: var(--t-micro);
3960
+ font-weight: 600;
3961
+ text-align: left;
3962
+ cursor: pointer;
3963
+ }
3964
+ .prb-map-goto:hover { text-decoration: underline; }
3965
+
3966
+ .prb-map-edges {
3967
+ position: absolute;
3968
+ top: 0;
3969
+ left: 0;
3970
+ z-index: 0;
3971
+ overflow: visible;
3972
+ pointer-events: none;
3973
+ }
3974
+ .prb-map-edge { fill: none; stroke: #8c959f; stroke-width: 1.5; transition: opacity 0.15s ease; }
3975
+ .prb-map-arrow { fill: #8c959f; }
3976
+ .prb-map-labels { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
3977
+ .prb-map-board:not([data-laid-out]) .prb-map-labels { visibility: hidden; }
3978
+ .prb-map-label {
3979
+ position: absolute;
3980
+ max-width: 100px;
3981
+ padding: 1px 6px;
3982
+ border: 1px solid rgba(15, 23, 42, 0.12);
3983
+ border-radius: 10px;
3984
+ background: #fff;
3985
+ font-size: var(--t-micro);
3986
+ font-style: italic;
3987
+ line-height: 1.35;
3988
+ text-align: center;
3989
+ color: #424a53;
3990
+ transition: opacity 0.15s ease;
3991
+ }
3992
+ .prb-map-label[hidden] { display: none; }
3993
+
3994
+ /* Selecting an idea keeps it, its neighbours and the lines between them, and quiets the rest. */
3995
+ .prb-map-board[data-selecting] .prb-map-node:not([data-active]):not([data-near]) { opacity: 0.35; }
3996
+ .prb-map-board[data-selecting] .prb-map-edge:not([data-active]) { opacity: 0.15; }
3997
+ .prb-map-board[data-selecting] .prb-map-label:not([data-active]) { opacity: 0.2; }
3998
+ .prb-map-board .prb-map-edge[data-active] { stroke: #1f2328; stroke-width: 2; }
3999
+ .prb-map-board .prb-map-label[data-active] { border-color: #1f2328; color: #1f2328; }
4000
+ .prb-map-node[data-active] { box-shadow: 0 0 0 3px rgba(147, 51, 234, 0.25); }
4001
+
4002
+ .prb-map-list { margin: 0 16px 14px; font-size: var(--t-meta); color: #57606a; }
4003
+ .prb-map-list > summary { cursor: pointer; }
4004
+ .prb-map-list ol { margin: 8px 0 0; padding-left: 20px; line-height: var(--lh-body); }
4005
+ .prb-map-list li { margin-bottom: 4px; }
4006
+ .prb-map-list strong { color: #1f2328; font-weight: 600; }
4007
+ .prb-map-note { color: #57606a; }
4008
+
4009
+ /* Five stages side by side, with room between them for the words on the lines, need about 1360px:
4010
+ the expanded pane, not the one between the rail and Buddy AI. Narrower than that the stages stack, top to bottom, in the same reading order,
4011
+ and the lines follow them down. A board that scrolled sideways would hide the half of every line
4012
+ that explains it. */
4013
+ @container (max-width: 1360px) {
4014
+ .prb-map-board { grid-template-columns: minmax(0, 1fr); row-gap: 58px; overflow-x: visible; }
4015
+ .prb-map-stage { flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: stretch; gap: 28px 36px; }
4016
+ .prb-map-stage-title { flex-basis: 100%; margin: 0; }
4017
+ .prb-map-node { flex: 1 1 210px; max-width: 300px; }
4018
+ }
4019
+
4020
+ @media (prefers-reduced-motion: reduce) {
4021
+ .prb-map-node, .prb-map-edge, .prb-map-label { transition: none; }
4022
+ }
4023
+
3707
4024
  /* ── The Overview's stat cards ──
3708
4025
  The drawer stacks each card as a centred column: number, then label, then an optional note. At
3709
4026
  460px that is the only thing that fits. Here it produced two faults at once. Every card is as
@@ -3797,6 +4114,21 @@ a.prb-rail-item { text-decoration: none; }
3797
4114
  }
3798
4115
  .pr-helper-diagram-button:hover { background: rgba(147, 51, 234, 0.08); }
3799
4116
  .pr-helper-diagram-button[disabled] { opacity: 0.55; cursor: default; }
4117
+ /* The Overview's way to the diagrams: the main visual path through the change, so a step above its
4118
+ neighbour with a tinted ground, yet no run behind it, so not the filled treatment Generate has. */
4119
+ .pr-helper-map-button {
4120
+ margin: 0 0 14px;
4121
+ padding: 7px 16px;
4122
+ border: 1px solid #9333ea;
4123
+ border-radius: 6px;
4124
+ background: rgba(147, 51, 234, 0.1);
4125
+ color: #7e22ce;
4126
+ font-family: inherit;
4127
+ font-size: var(--t-meta);
4128
+ font-weight: 600;
4129
+ cursor: pointer;
4130
+ }
4131
+ .pr-helper-map-button:hover { background: rgba(147, 51, 234, 0.16); }
3800
4132
  /* In a theme card the button stands alone in the actions row, whose other occupant — the guided
3801
4133
  review CTA — is hidden in this client. That CTA carried the gap below the review checklist, so
3802
4134
  with it gone the row has to carry it, or the button sits flush against the checklist box: the
@@ -4544,14 +4876,17 @@ a.prb-notification-open:focus-visible { outline: 2px solid var(--brand-hover); o
4544
4876
  body .prb-body[data-focus] { grid-template-columns: minmax(0, 1fr); }
4545
4877
  body .prb-body[data-focus] .prb-rail { display: none; }
4546
4878
 
4547
- /* A document surface: the review pane takes the width, and gets more room to use it. Issues and
4548
- Questions stay a readable measure; a diff is the one thing here that genuinely wants the width. */
4549
- body .prb-body:is([data-focus='issues'], [data-focus='questions'], [data-focus='files'], [data-focus='guide']) .prb-ask { display: none; }
4550
- body .prb-body:is([data-focus='issues'], [data-focus='questions'], [data-focus='guide']) .pr-helper-sidebar.prb-pane { max-width: 1080px; }
4879
+ /* A document surface, which is every view but the assistant: the review pane takes the width, and
4880
+ gets more room to use it. Prose stays a readable measure; a diff and a drawing are the things here
4881
+ that genuinely want the width. */
4882
+ body .prb-body[data-focus]:not([data-focus='buddy']) .prb-ask { display: none; }
4883
+ body .prb-body[data-focus]:not([data-focus='buddy']) .pr-helper-sidebar.prb-pane { max-width: 1080px; }
4884
+ body .prb-body:is([data-focus='files'], [data-focus='diagram']) .pr-helper-sidebar.prb-pane { max-width: 1600px; }
4551
4885
  /* The rail is where the themes are listed, and it is hidden here, so the picker it stands in for
4552
4886
  below 860px stands in for it now. */
4553
4887
  body .prb-body[data-focus='guide'] .prb-guide-picker { display: flex; }
4554
- body .prb-body[data-focus='files'] .pr-helper-sidebar.prb-pane { max-width: 1600px; }
4888
+ /* An expanded map has room for every stage side by side, which is the point of expanding it. */
4889
+ body .prb-body[data-focus='map']:not([data-focus='buddy']) .pr-helper-sidebar.prb-pane { max-width: 1560px; }
4555
4890
 
4556
4891
  /* The assistant: the review pane goes, and the assistant is a column in the grid again at every
4557
4892
  width. Below 860px it is otherwise a fixed overlay, and an overlay as the whole workspace would
@@ -4606,6 +4941,10 @@ body .prb-body[data-focus='buddy'] .prb-msg-user { max-width: min(90%, 78ch); }
4606
4941
  /* The title row is baseline-aligned for the disclosure's text; an icon has no baseline worth
4607
4942
  aligning, so it centres on the title instead. */
4608
4943
  .prb-doc .prb-doc-head .prb-focus-toggle { align-self: center; margin-left: auto; }
4944
+ /* Beside Analysis details the pair sits together at the right: the disclosure takes the free space,
4945
+ and the toggle follows it rather than splitting the row in two. */
4946
+ .prb-doc .prb-doc-head .prb-doc-provenance { margin-left: auto; }
4947
+ .prb-doc .prb-doc-head .prb-doc-provenance + .prb-focus-toggle { margin-left: -8px; }
4609
4948
 
4610
4949
  /* ── Your prompts, folded ──
4611
4950
  The heading is the toggle. Folded, it keeps a count, so a reviewer knows what is behind it