@vintasoftware/pr-review-canvas 0.2.0 → 0.4.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/README.md +61 -26
- package/docs/reference.md +231 -121
- package/package.json +18 -4
- package/pr-review.config.example.yml +10 -4
- package/prompts/chat-seed.md +3 -0
- package/prompts/generation-format.md +3 -0
- package/skills/pr-review-canvas/SKILL.md +77 -40
- package/src/acpx/acpx.ts +21 -4
- package/src/acpx/events.ts +5 -1
- package/src/acpx/ndjson.ts +3 -1
- package/src/acpx/preflight.ts +5 -1
- package/src/canvas/comment.ts +24 -0
- package/src/canvas/export.ts +11 -2
- package/src/canvas/import.ts +30 -9
- package/src/canvas/name.ts +1 -0
- package/src/canvas/zip.ts +25 -2
- package/src/chat/chat-manager.ts +55 -41
- package/src/chat/context.ts +10 -3
- package/src/chat/seed.ts +3 -1
- package/src/chat/threads.ts +27 -26
- package/src/cli.ts +24 -9
- package/src/commands.ts +86 -25
- package/src/config.ts +24 -24
- package/src/contract/api.ts +32 -1
- package/src/contract/canvas-manifest.ts +2 -0
- package/src/contract/comments.ts +8 -1
- package/src/contract/discovery.ts +5 -2
- package/src/contract/generation-context.ts +27 -2
- package/src/contract/review-artifact.ts +14 -8
- package/src/contract/review-key.ts +51 -0
- package/src/contract/reviews.ts +17 -0
- package/src/contract/settings.ts +2 -0
- package/src/contract/state.ts +41 -19
- package/src/git/diff-collector.ts +2 -1
- package/src/git/environment.mjs +27 -0
- package/src/git/git.ts +117 -12
- package/src/git/local-target.ts +138 -0
- package/src/git/patch-lines.ts +34 -2
- package/src/git/pr-refs.ts +36 -0
- package/src/github/attachments.ts +9 -257
- package/src/github/canvas-comment.ts +22 -0
- package/src/github/capabilities.ts +3 -37
- package/src/github/comments.ts +9 -27
- package/src/github/post-comment.ts +7 -37
- package/src/github/post-review.ts +4 -19
- package/src/github/pr.ts +6 -84
- package/src/github/threads.ts +6 -2
- package/src/gitlab/attachments.ts +40 -0
- package/src/gitlab/canvas-comment.ts +26 -0
- package/src/gitlab/capabilities.ts +64 -0
- package/src/gitlab/comments.ts +164 -0
- package/src/gitlab/mr.ts +115 -0
- package/src/gitlab/post-comment.ts +111 -0
- package/src/gitlab/post-review.ts +54 -0
- package/src/gitlab/project.ts +13 -0
- package/src/host/attachments.ts +293 -0
- package/src/host/capabilities.ts +38 -0
- package/src/host/client.ts +245 -0
- package/src/host/host.ts +136 -0
- package/src/host/pr.ts +51 -0
- package/src/host/remote.ts +42 -0
- package/src/project-config.ts +25 -9
- package/src/prompt-files.ts +4 -3
- package/src/review/carry-over.ts +79 -0
- package/src/review/doctor.ts +31 -14
- package/src/review/normalize.ts +3 -1
- package/src/review/prepare.ts +87 -17
- package/src/review/prompt.ts +8 -2
- package/src/review/publish.ts +76 -13
- package/src/{github → review}/review-body.ts +17 -5
- package/src/review/skill-command.ts +5 -3
- package/src/review/trim-caps.ts +10 -6
- package/src/review/validate-folds.ts +2 -2
- package/src/review/validate.ts +67 -15
- package/src/server/app.ts +12 -4
- package/src/server/bundle.ts +320 -106
- package/src/server/context.ts +24 -10
- package/src/server/errors.ts +56 -10
- package/src/server/html.ts +36 -12
- package/src/server/node-server.ts +4 -2
- package/src/server/routes/api.ts +92 -31
- package/src/server/routes/chat-routes.ts +105 -46
- package/src/server/routes/pages.ts +25 -9
- package/src/server/routes/review-routes.ts +101 -35
- package/src/server/sse.ts +3 -1
- package/src/store/atomic-json.ts +5 -1
- package/src/store/canvas-store.ts +95 -46
- package/src/store/data-dir.ts +2 -1
- package/src/store/derived-store.ts +41 -23
- package/src/store/pr-store.ts +25 -15
- package/src/store/state-store.ts +42 -37
- package/static/brand.svg +19 -0
- package/static/js/api.js +47 -27
- package/static/js/app.js +27 -7
- package/static/js/chat-panel.js +93 -0
- package/static/js/chat.js +41 -17
- package/static/js/composer.js +30 -17
- package/static/js/contract-types.d.ts +3 -0
- package/static/js/diagram.js +2 -1
- package/static/js/diff-decorations.js +5 -3
- package/static/js/diff-renderer.js +7 -2
- package/static/js/dom.js +5 -7
- package/static/js/download.js +1 -1
- package/static/js/empty-state.js +85 -16
- package/static/js/errors.js +22 -6
- package/static/js/header.js +32 -9
- package/static/js/host.js +40 -0
- package/static/js/import-zone.js +1 -1
- package/static/js/interactions.js +56 -17
- package/static/js/keyboard.js +7 -2
- package/static/js/layers.js +26 -14
- package/static/js/links.js +9 -3
- package/static/js/markdown.js +28 -1
- package/static/js/nav.js +5 -2
- package/static/js/overview.js +32 -4
- package/static/js/points.js +5 -3
- package/static/js/progress.js +2 -1
- package/static/js/proposed-comment.js +4 -1
- package/static/js/quick-questions.js +2 -1
- package/static/js/regenerate.js +4 -1
- package/static/js/review-session.js +7 -2
- package/static/js/settings.js +2 -1
- package/static/js/signoff.js +9 -6
- package/static/styles/base.css +16 -6
- package/static/styles/chat-panel.css +81 -0
- package/static/styles/chat-tools.css +28 -0
- package/static/styles/chat.css +1 -1
- package/static/styles/commands.css +10 -4
- package/static/styles/diff.css +1 -1
- package/static/styles/header.css +18 -4
- package/static/styles/layout.css +4 -4
- package/static/styles/panels.css +4 -0
- package/static/styles/responsive.css +1 -15
- package/static/styles/review-actions.css +1 -0
- package/static/styles/review.css +24 -3
- package/static/styles/skin-github.css +99 -100
- package/static/styles.css +13 -12
- package/src/github/gh.ts +0 -196
package/static/styles/base.css
CHANGED
|
@@ -22,8 +22,10 @@
|
|
|
22
22
|
--s4: var(--v4);
|
|
23
23
|
--s5: var(--v5);
|
|
24
24
|
--s6: var(--v6);
|
|
25
|
-
--sans:
|
|
26
|
-
|
|
25
|
+
--sans:
|
|
26
|
+
-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif,
|
|
27
|
+
'Apple Color Emoji', 'Segoe UI Emoji';
|
|
28
|
+
--mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
|
|
27
29
|
|
|
28
30
|
--v1: light-dark(#ffd43b, #ffe066);
|
|
29
31
|
--v2: light-dark(#ffa94d, #ffc078);
|
|
@@ -31,7 +33,15 @@
|
|
|
31
33
|
--v4: light-dark(#da77f2, #e599f7);
|
|
32
34
|
--v5: light-dark(#9775fa, #b197fc);
|
|
33
35
|
--v6: light-dark(#748ffc, #91a7ff);
|
|
34
|
-
--stripe-y: linear-gradient(
|
|
36
|
+
--stripe-y: linear-gradient(
|
|
37
|
+
180deg,
|
|
38
|
+
var(--v1) 0 1px,
|
|
39
|
+
var(--v2) 1px 2px,
|
|
40
|
+
var(--v3) 2px 3px,
|
|
41
|
+
var(--v4) 3px 4px,
|
|
42
|
+
var(--v5) 4px 5px,
|
|
43
|
+
var(--v6) 5px 6px
|
|
44
|
+
);
|
|
35
45
|
|
|
36
46
|
--bg: light-dark(#ffffff, #1e1f2b);
|
|
37
47
|
--panel: light-dark(#ffffff, #282a3a);
|
|
@@ -80,10 +90,10 @@
|
|
|
80
90
|
|
|
81
91
|
/* The server writes `data-theme` for every load. `auto` matches neither rule, which leaves the
|
|
82
92
|
`color-scheme: light dark` above to follow the operating system. */
|
|
83
|
-
:root[data-theme=
|
|
93
|
+
:root[data-theme='dark'] {
|
|
84
94
|
color-scheme: dark;
|
|
85
95
|
}
|
|
86
|
-
:root[data-theme=
|
|
96
|
+
:root[data-theme='light'] {
|
|
87
97
|
color-scheme: light;
|
|
88
98
|
}
|
|
89
99
|
|
|
@@ -218,6 +228,6 @@ strong {
|
|
|
218
228
|
}
|
|
219
229
|
|
|
220
230
|
/* The hidden attribute takes priority over component layout styles. */
|
|
221
|
-
[hidden]:not([hidden=
|
|
231
|
+
[hidden]:not([hidden='until-found']) {
|
|
222
232
|
display: none !important;
|
|
223
233
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
.chat-launcher,
|
|
2
|
+
.chat-minimize {
|
|
3
|
+
display: none;
|
|
4
|
+
}
|
|
5
|
+
@media (max-width: 1360px) {
|
|
6
|
+
.chat-launcher {
|
|
7
|
+
display: block;
|
|
8
|
+
position: fixed;
|
|
9
|
+
right: 20px;
|
|
10
|
+
bottom: 20px;
|
|
11
|
+
z-index: 10;
|
|
12
|
+
padding: 14px 20px;
|
|
13
|
+
border: 1px solid var(--ink);
|
|
14
|
+
border-radius: 999px;
|
|
15
|
+
background: var(--accent);
|
|
16
|
+
color: var(--bg);
|
|
17
|
+
box-shadow: 0 4px 20px #0003;
|
|
18
|
+
font: inherit;
|
|
19
|
+
font-weight: 600;
|
|
20
|
+
cursor: pointer;
|
|
21
|
+
}
|
|
22
|
+
.chat-launcher[hidden] {
|
|
23
|
+
display: none;
|
|
24
|
+
}
|
|
25
|
+
.chat-minimize {
|
|
26
|
+
display: inline-block;
|
|
27
|
+
}
|
|
28
|
+
dialog.chat-dialog {
|
|
29
|
+
position: fixed;
|
|
30
|
+
inset: auto 20px 20px auto;
|
|
31
|
+
width: min(420px, calc(100vw - 40px));
|
|
32
|
+
height: min(680px, calc(100dvh - 40px));
|
|
33
|
+
max-width: none;
|
|
34
|
+
max-height: none;
|
|
35
|
+
margin: 0;
|
|
36
|
+
padding: 0;
|
|
37
|
+
border: 1px solid var(--ink);
|
|
38
|
+
border-radius: 12px;
|
|
39
|
+
background: var(--panel);
|
|
40
|
+
color: var(--fg);
|
|
41
|
+
box-shadow: 0 8px 32px #0004;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
z-index: 11;
|
|
44
|
+
}
|
|
45
|
+
.chat-dialog .chat {
|
|
46
|
+
position: relative;
|
|
47
|
+
top: auto;
|
|
48
|
+
height: 100%;
|
|
49
|
+
padding: 0;
|
|
50
|
+
}
|
|
51
|
+
.chat-dialog .chat-h,
|
|
52
|
+
.chat-dialog .ctx-line,
|
|
53
|
+
.chat-dialog .chat-composer {
|
|
54
|
+
flex-shrink: 0;
|
|
55
|
+
}
|
|
56
|
+
.chat-dialog .chat-h h2 {
|
|
57
|
+
margin-bottom: 0;
|
|
58
|
+
}
|
|
59
|
+
.chat-dialog .chat-composer {
|
|
60
|
+
margin: 0;
|
|
61
|
+
padding: 12px 14px;
|
|
62
|
+
gap: 8px;
|
|
63
|
+
}
|
|
64
|
+
.chat-dialog textarea {
|
|
65
|
+
max-height: 25dvh;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
@media (max-width: 600px) {
|
|
69
|
+
dialog.chat-dialog {
|
|
70
|
+
inset: auto 8px max(8px, env(safe-area-inset-bottom)) 8px;
|
|
71
|
+
width: auto;
|
|
72
|
+
height: calc(100dvh - 24px - env(safe-area-inset-bottom));
|
|
73
|
+
}
|
|
74
|
+
.chat-launcher {
|
|
75
|
+
right: 16px;
|
|
76
|
+
bottom: max(16px, env(safe-area-inset-bottom));
|
|
77
|
+
}
|
|
78
|
+
html:has(.chat-dialog:modal) {
|
|
79
|
+
overflow: hidden;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -1,4 +1,32 @@
|
|
|
1
1
|
/* Chat context, proposed comments, quick questions, and settings. */
|
|
2
|
+
.chat-tool-calls > summary {
|
|
3
|
+
padding: 4px 0;
|
|
4
|
+
gap: 8px;
|
|
5
|
+
align-items: baseline;
|
|
6
|
+
overflow-wrap: anywhere;
|
|
7
|
+
cursor: pointer;
|
|
8
|
+
}
|
|
9
|
+
.chat-tool-calls > summary::before {
|
|
10
|
+
content: '';
|
|
11
|
+
width: 6px;
|
|
12
|
+
height: 6px;
|
|
13
|
+
flex: 0 0 6px;
|
|
14
|
+
border-right: 1.5px solid currentColor;
|
|
15
|
+
border-bottom: 1.5px solid currentColor;
|
|
16
|
+
transform: rotate(-45deg);
|
|
17
|
+
}
|
|
18
|
+
.chat-tool-calls[open] > summary::before {
|
|
19
|
+
transform: rotate(45deg);
|
|
20
|
+
}
|
|
21
|
+
.chat-tool-calls > ul {
|
|
22
|
+
margin: 4px 0 8px;
|
|
23
|
+
padding-left: 14px;
|
|
24
|
+
list-style: none;
|
|
25
|
+
}
|
|
26
|
+
.chat-tool-calls > ul > li {
|
|
27
|
+
margin: 4px 0;
|
|
28
|
+
overflow-wrap: anywhere;
|
|
29
|
+
}
|
|
2
30
|
.ctx-line {
|
|
3
31
|
display: flex;
|
|
4
32
|
align-items: baseline;
|
package/static/styles/chat.css
CHANGED
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
line-height: inherit;
|
|
15
15
|
}
|
|
16
16
|
.cmd::before {
|
|
17
|
-
content:
|
|
17
|
+
content: '[ ';
|
|
18
18
|
}
|
|
19
19
|
.cmd::after {
|
|
20
|
-
content:
|
|
20
|
+
content: ' ]';
|
|
21
21
|
}
|
|
22
22
|
.cmd:hover {
|
|
23
23
|
text-decoration: underline;
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
text-decoration-thickness: 2px;
|
|
26
26
|
}
|
|
27
27
|
.cmd:disabled,
|
|
28
|
-
.cmd[aria-disabled=
|
|
28
|
+
.cmd[aria-disabled='true'] {
|
|
29
29
|
color: var(--fg-dim);
|
|
30
30
|
cursor: not-allowed;
|
|
31
31
|
text-decoration: none;
|
|
32
32
|
}
|
|
33
|
-
.cmd[aria-busy=
|
|
33
|
+
.cmd[aria-busy='true'] {
|
|
34
34
|
color: var(--fg-muted);
|
|
35
35
|
cursor: progress;
|
|
36
36
|
}
|
|
@@ -116,6 +116,12 @@
|
|
|
116
116
|
color: var(--purple);
|
|
117
117
|
border-color: currentColor;
|
|
118
118
|
}
|
|
119
|
+
/* The two local reviews: work with no pull request, so neither open nor closed. */
|
|
120
|
+
.pill.branch,
|
|
121
|
+
.pill.uncommitted {
|
|
122
|
+
color: var(--accent);
|
|
123
|
+
border-color: currentColor;
|
|
124
|
+
}
|
|
119
125
|
.pill.agent {
|
|
120
126
|
color: var(--fg);
|
|
121
127
|
border-color: var(--ink);
|
package/static/styles/diff.css
CHANGED
package/static/styles/header.css
CHANGED
|
@@ -20,12 +20,26 @@
|
|
|
20
20
|
text-transform: uppercase;
|
|
21
21
|
font-size: 12px;
|
|
22
22
|
}
|
|
23
|
-
.brand
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
.brand-wordmark {
|
|
24
|
+
position: relative;
|
|
25
|
+
display: inline-flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
min-height: 32px;
|
|
28
|
+
padding-left: 40px;
|
|
29
|
+
white-space: nowrap;
|
|
27
30
|
color: var(--fg);
|
|
28
31
|
}
|
|
32
|
+
.brand-icon {
|
|
33
|
+
position: absolute;
|
|
34
|
+
left: 0;
|
|
35
|
+
top: 50%;
|
|
36
|
+
transform: translateY(-50%);
|
|
37
|
+
width: 32px;
|
|
38
|
+
height: 32px;
|
|
39
|
+
}
|
|
40
|
+
.brand {
|
|
41
|
+
flex-wrap: wrap;
|
|
42
|
+
}
|
|
29
43
|
.hdr-actions {
|
|
30
44
|
display: flex;
|
|
31
45
|
flex-wrap: wrap;
|
package/static/styles/layout.css
CHANGED
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
display: grid;
|
|
32
32
|
grid-template-columns: auto auto minmax(0, 1fr);
|
|
33
33
|
grid-template-areas:
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
'd n t'
|
|
35
|
+
'd n m';
|
|
36
36
|
column-gap: 8px;
|
|
37
37
|
padding: 6px 14px 6px 12px;
|
|
38
38
|
color: var(--fg);
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
.tree a:not(:has(.dot)) {
|
|
45
45
|
grid-template-columns: minmax(0, 1fr);
|
|
46
46
|
grid-template-areas:
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
't'
|
|
48
|
+
'm';
|
|
49
49
|
}
|
|
50
50
|
.tree a:hover {
|
|
51
51
|
background: var(--panel-2);
|
package/static/styles/panels.css
CHANGED
|
@@ -88,6 +88,10 @@
|
|
|
88
88
|
box-shadow: 2px 2px 0 var(--shadow);
|
|
89
89
|
font-size: 13px;
|
|
90
90
|
}
|
|
91
|
+
/* The same bar for a canvas that still applies: a note, not a warning. */
|
|
92
|
+
.stale-bar.carried-over-bar {
|
|
93
|
+
background: var(--bg);
|
|
94
|
+
}
|
|
91
95
|
.notice {
|
|
92
96
|
margin: 10px 0 0;
|
|
93
97
|
padding: 6px 10px;
|
|
@@ -4,25 +4,11 @@
|
|
|
4
4
|
grid-template-columns: var(--rail-w) minmax(0, 1fr);
|
|
5
5
|
background: linear-gradient(var(--ink), var(--ink)) calc(var(--rail-w) - 1px) 0 / 1px 100% no-repeat;
|
|
6
6
|
}
|
|
7
|
-
.chat {
|
|
8
|
-
grid-column: 2;
|
|
9
|
-
position: static;
|
|
10
|
-
align-self: auto;
|
|
11
|
-
height: auto;
|
|
12
|
-
border-top: 2px solid var(--ink);
|
|
13
|
-
padding: 0;
|
|
14
|
-
}
|
|
15
|
-
.transcript {
|
|
16
|
-
max-height: 50vh;
|
|
17
|
-
}
|
|
18
7
|
.handle {
|
|
19
8
|
display: none;
|
|
20
9
|
}
|
|
21
10
|
}
|
|
22
11
|
@media (max-width: 1000px) {
|
|
23
|
-
.chat {
|
|
24
|
-
grid-column: 1 / -1;
|
|
25
|
-
}
|
|
26
12
|
.layout,
|
|
27
13
|
.layout.no-chat {
|
|
28
14
|
grid-template-columns: minmax(0, 1fr);
|
|
@@ -53,7 +39,7 @@
|
|
|
53
39
|
}
|
|
54
40
|
.tree a,
|
|
55
41
|
.tree a:not(:has(.dot)) {
|
|
56
|
-
grid-template-areas:
|
|
42
|
+
grid-template-areas: 'd n t';
|
|
57
43
|
grid-template-columns: auto auto minmax(0, 1fr);
|
|
58
44
|
align-items: center;
|
|
59
45
|
border: 1px solid var(--ink);
|
package/static/styles/review.css
CHANGED
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
cursor: pointer;
|
|
53
53
|
transition: transform 0.12s ease-out;
|
|
54
54
|
}
|
|
55
|
-
.chev[aria-expanded=
|
|
55
|
+
.chev[aria-expanded='true'] {
|
|
56
56
|
transform: rotate(90deg);
|
|
57
57
|
}
|
|
58
58
|
.body {
|
|
@@ -323,6 +323,21 @@
|
|
|
323
323
|
.pr-desc {
|
|
324
324
|
border-top: 1px solid var(--ink);
|
|
325
325
|
}
|
|
326
|
+
.review-history {
|
|
327
|
+
border-top: 1px solid var(--line);
|
|
328
|
+
}
|
|
329
|
+
.review-entry > .pill {
|
|
330
|
+
margin-bottom: 10px;
|
|
331
|
+
}
|
|
332
|
+
.review-entry .cmt {
|
|
333
|
+
row-gap: 8px;
|
|
334
|
+
}
|
|
335
|
+
.review-entry .who {
|
|
336
|
+
display: flex;
|
|
337
|
+
flex-wrap: wrap;
|
|
338
|
+
align-items: baseline;
|
|
339
|
+
gap: 4px 10px;
|
|
340
|
+
}
|
|
326
341
|
/* A <details> summary reads like a card header: the chevron before the title is its toggle. The row
|
|
327
342
|
itself keeps the default cursor and no hover background; the native <details> handles the click. */
|
|
328
343
|
summary {
|
|
@@ -469,5 +484,11 @@ details[open] > summary .chev {
|
|
|
469
484
|
margin: 0;
|
|
470
485
|
}
|
|
471
486
|
|
|
472
|
-
.prose img {
|
|
473
|
-
|
|
487
|
+
.prose img {
|
|
488
|
+
max-width: 100%;
|
|
489
|
+
height: auto;
|
|
490
|
+
}
|
|
491
|
+
img.av {
|
|
492
|
+
object-fit: cover;
|
|
493
|
+
border-radius: 50%;
|
|
494
|
+
}
|