@erdemtuna/doc-review 0.7.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/LICENSE +21 -0
- package/README.md +117 -0
- package/package.json +57 -0
- package/src/SKILL.md +143 -0
- package/src/anchor-text.js +115 -0
- package/src/chrome-client.js +986 -0
- package/src/chrome-session.js +15 -0
- package/src/chrome.css +458 -0
- package/src/chrome.html +83 -0
- package/src/cli.js +341 -0
- package/src/click-target.js +26 -0
- package/src/editing.js +99 -0
- package/src/frame-channel.js +44 -0
- package/src/frame-policy.js +16 -0
- package/src/html-transform.js +62 -0
- package/src/markdown.js +87 -0
- package/src/paths.js +87 -0
- package/src/sdk.js +1520 -0
- package/src/serialize.js +46 -0
- package/src/server-entry.js +26 -0
- package/src/server-lock.js +101 -0
- package/src/server.js +1268 -0
- package/src/setup.js +117 -0
- package/src/state.js +491 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function pageUrl(key, sessionId) {
|
|
2
|
+
return `/api/page/${key}?session=${encodeURIComponent(sessionId)}`;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function replacePage(state, page) {
|
|
6
|
+
state.page = page;
|
|
7
|
+
state.others = page.others || [];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** New and newly revised feedback belongs where the reviewer can see it. */
|
|
11
|
+
export function newestComments(comments) {
|
|
12
|
+
return [...(comments || [])].sort(
|
|
13
|
+
(a, b) => (b.updatedAt || b.createdAt || 0) - (a.updatedAt || a.createdAt || 0)
|
|
14
|
+
);
|
|
15
|
+
}
|
package/src/chrome.css
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
/* Chrome palette. The artifact never sees any of this. */
|
|
2
|
+
:root {
|
|
3
|
+
--canvas: #eceae4;
|
|
4
|
+
--rail: #fbfaf7;
|
|
5
|
+
--card: #ffffff;
|
|
6
|
+
--card-border: #e9e7e0;
|
|
7
|
+
--hair: #e4e2db;
|
|
8
|
+
--hair-2: #eceae4;
|
|
9
|
+
--dash: #e0ddd4;
|
|
10
|
+
--strong-border: #d9d5c9;
|
|
11
|
+
--txt: #26241e;
|
|
12
|
+
--strong-txt: #1b1a16;
|
|
13
|
+
--mute: #8b877d;
|
|
14
|
+
--mute-2: #6b6862;
|
|
15
|
+
--faint: #b6b2a8;
|
|
16
|
+
--faint-2: #a8a49a;
|
|
17
|
+
--soft: #f2f0ea;
|
|
18
|
+
--chip: #f4f2ec;
|
|
19
|
+
--input-bg: #fdfcfa;
|
|
20
|
+
--focus: #c2beb4;
|
|
21
|
+
--danger: #b23b2e;
|
|
22
|
+
--danger-soft: #f6ecea;
|
|
23
|
+
--amber: #c99500;
|
|
24
|
+
--green: #7d9370;
|
|
25
|
+
--btn-bg: #1b1a16;
|
|
26
|
+
--btn-fg: #fbfaf7;
|
|
27
|
+
--rail-w: 352px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
:root[data-theme="dark"] {
|
|
31
|
+
--canvas: #171614;
|
|
32
|
+
--rail: #1f1e1b;
|
|
33
|
+
--card: #262420;
|
|
34
|
+
--card-border: #34322d;
|
|
35
|
+
--hair: #2f2d29;
|
|
36
|
+
--hair-2: #2a2825;
|
|
37
|
+
--dash: #3a3833;
|
|
38
|
+
--strong-border: #403d37;
|
|
39
|
+
--txt: #eae7e0;
|
|
40
|
+
--strong-txt: #f4f1ea;
|
|
41
|
+
--mute: #9c968a;
|
|
42
|
+
--mute-2: #a8a29a;
|
|
43
|
+
--faint: #6e6961;
|
|
44
|
+
--faint-2: #837d74;
|
|
45
|
+
--soft: #2c2a26;
|
|
46
|
+
--chip: #2e2c27;
|
|
47
|
+
--input-bg: #1c1b18;
|
|
48
|
+
--focus: #4d4941;
|
|
49
|
+
--danger: #d9705f;
|
|
50
|
+
--danger-soft: #3a2320;
|
|
51
|
+
--amber: #d9a520;
|
|
52
|
+
--green: #8ea37f;
|
|
53
|
+
--btn-bg: #f0ede6;
|
|
54
|
+
--btn-fg: #1b1a16;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
* { box-sizing: border-box; }
|
|
58
|
+
|
|
59
|
+
/* Author display rules beat the UA rule for [hidden], so restate it. */
|
|
60
|
+
[hidden] { display: none !important; }
|
|
61
|
+
|
|
62
|
+
html, body {
|
|
63
|
+
height: 100%;
|
|
64
|
+
margin: 0;
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
body {
|
|
69
|
+
background: var(--canvas);
|
|
70
|
+
color: var(--txt);
|
|
71
|
+
font: 13px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif;
|
|
72
|
+
-webkit-font-smoothing: antialiased;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
button, textarea { font: inherit; color: inherit; }
|
|
76
|
+
|
|
77
|
+
.app { display: flex; height: 100vh; }
|
|
78
|
+
|
|
79
|
+
/* The artifact takes all remaining width and styles itself. */
|
|
80
|
+
.stage { flex: 1; min-width: 0; background: var(--canvas); }
|
|
81
|
+
#frame { width: 100%; height: 100%; border: 0; display: block; background: #fff; }
|
|
82
|
+
|
|
83
|
+
.handle {
|
|
84
|
+
position: fixed;
|
|
85
|
+
top: 50%;
|
|
86
|
+
right: var(--rail-w);
|
|
87
|
+
z-index: 40;
|
|
88
|
+
width: 22px;
|
|
89
|
+
height: 46px;
|
|
90
|
+
margin-top: -23px;
|
|
91
|
+
display: flex;
|
|
92
|
+
align-items: center;
|
|
93
|
+
justify-content: center;
|
|
94
|
+
border: 1px solid var(--hair);
|
|
95
|
+
border-right: 0;
|
|
96
|
+
border-radius: 7px 0 0 7px;
|
|
97
|
+
background: var(--rail);
|
|
98
|
+
color: var(--mute);
|
|
99
|
+
font-size: 11px;
|
|
100
|
+
line-height: 1;
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
box-shadow: -2px 0 8px -6px rgba(0, 0, 0, 0.28);
|
|
103
|
+
transition: right 140ms ease-out;
|
|
104
|
+
}
|
|
105
|
+
.handle:hover { color: var(--strong-txt); background: var(--soft); }
|
|
106
|
+
|
|
107
|
+
.rail {
|
|
108
|
+
flex: none;
|
|
109
|
+
width: var(--rail-w);
|
|
110
|
+
display: flex;
|
|
111
|
+
flex-direction: column;
|
|
112
|
+
overflow: hidden;
|
|
113
|
+
border-left: 1px solid var(--hair);
|
|
114
|
+
background: var(--rail);
|
|
115
|
+
transition: width 140ms ease-out;
|
|
116
|
+
}
|
|
117
|
+
body.collapsed .rail { width: 0; border-left-width: 0; }
|
|
118
|
+
body.collapsed .handle { right: 0; }
|
|
119
|
+
|
|
120
|
+
.rail-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 12px 12px; }
|
|
121
|
+
|
|
122
|
+
.rail-head { display: flex; align-items: baseline; gap: 7px; padding: 0 4px 9px; }
|
|
123
|
+
.rail-head.tight { padding-top: 0; }
|
|
124
|
+
.section {
|
|
125
|
+
font-size: 11px;
|
|
126
|
+
font-weight: 600;
|
|
127
|
+
letter-spacing: 0.08em;
|
|
128
|
+
text-transform: uppercase;
|
|
129
|
+
color: var(--mute);
|
|
130
|
+
}
|
|
131
|
+
.dim { color: var(--faint); font-size: 11px; }
|
|
132
|
+
|
|
133
|
+
.icon-btn {
|
|
134
|
+
margin-left: auto;
|
|
135
|
+
width: 26px;
|
|
136
|
+
height: 26px;
|
|
137
|
+
display: flex;
|
|
138
|
+
align-items: center;
|
|
139
|
+
justify-content: center;
|
|
140
|
+
border: 1px solid var(--hair);
|
|
141
|
+
border-radius: 7px;
|
|
142
|
+
background: var(--soft);
|
|
143
|
+
font-size: 12.5px;
|
|
144
|
+
line-height: 1;
|
|
145
|
+
cursor: pointer;
|
|
146
|
+
}
|
|
147
|
+
.icon-btn:hover { border-color: var(--strong-border); color: var(--strong-txt); }
|
|
148
|
+
|
|
149
|
+
.link-btn {
|
|
150
|
+
margin-left: auto;
|
|
151
|
+
border: 0;
|
|
152
|
+
padding: 0;
|
|
153
|
+
background: none;
|
|
154
|
+
color: var(--faint-2);
|
|
155
|
+
font-size: 11px;
|
|
156
|
+
cursor: pointer;
|
|
157
|
+
}
|
|
158
|
+
.link-btn:hover { color: var(--strong-txt); }
|
|
159
|
+
.danger-hover:hover { color: var(--danger); }
|
|
160
|
+
|
|
161
|
+
/* Compose card — always in the rail, never floating over the artifact. */
|
|
162
|
+
.compose {
|
|
163
|
+
margin-bottom: 8px;
|
|
164
|
+
padding: 13px 14px;
|
|
165
|
+
border: 1px solid var(--strong-border);
|
|
166
|
+
border-radius: 8px;
|
|
167
|
+
background: var(--card);
|
|
168
|
+
box-shadow: 0 4px 14px -8px rgba(27, 26, 22, 0.3);
|
|
169
|
+
animation: rise 130ms ease-out;
|
|
170
|
+
}
|
|
171
|
+
.compose-head { display: flex; align-items: center; gap: 7px; margin-bottom: 9px; }
|
|
172
|
+
.chip {
|
|
173
|
+
padding: 2px 8px;
|
|
174
|
+
border-radius: 999px;
|
|
175
|
+
background: var(--chip);
|
|
176
|
+
color: var(--mute);
|
|
177
|
+
font-size: 10px;
|
|
178
|
+
font-weight: 600;
|
|
179
|
+
}
|
|
180
|
+
.quote {
|
|
181
|
+
margin: 0 0 10px;
|
|
182
|
+
padding-left: 9px;
|
|
183
|
+
border-left: 2px solid rgba(245, 196, 0, 0.7);
|
|
184
|
+
color: var(--mute);
|
|
185
|
+
font-size: 12px;
|
|
186
|
+
font-style: italic;
|
|
187
|
+
line-height: 1.45;
|
|
188
|
+
overflow: hidden;
|
|
189
|
+
display: -webkit-box;
|
|
190
|
+
-webkit-line-clamp: 3;
|
|
191
|
+
-webkit-box-orient: vertical;
|
|
192
|
+
}
|
|
193
|
+
.compose textarea, .rail-foot textarea {
|
|
194
|
+
width: 100%;
|
|
195
|
+
padding: 8px 10px;
|
|
196
|
+
border: 1px solid var(--hair);
|
|
197
|
+
border-radius: 6px;
|
|
198
|
+
background: var(--input-bg);
|
|
199
|
+
font-size: 13px;
|
|
200
|
+
line-height: 1.5;
|
|
201
|
+
resize: none;
|
|
202
|
+
outline: none;
|
|
203
|
+
}
|
|
204
|
+
.compose textarea:focus, .rail-foot textarea:focus { border-color: var(--focus); background: var(--card); }
|
|
205
|
+
.compose-actions { margin-top: 9px; display: flex; align-items: center; gap: 8px; }
|
|
206
|
+
|
|
207
|
+
.btn-primary {
|
|
208
|
+
display: flex;
|
|
209
|
+
align-items: center;
|
|
210
|
+
gap: 7px;
|
|
211
|
+
padding: 6px 11px;
|
|
212
|
+
border: 1px solid var(--btn-bg);
|
|
213
|
+
border-radius: 6px;
|
|
214
|
+
background: var(--btn-bg);
|
|
215
|
+
color: var(--btn-fg);
|
|
216
|
+
font-size: 12px;
|
|
217
|
+
font-weight: 500;
|
|
218
|
+
cursor: pointer;
|
|
219
|
+
}
|
|
220
|
+
.btn-ghost {
|
|
221
|
+
padding: 6px 10px;
|
|
222
|
+
border: 0;
|
|
223
|
+
border-radius: 6px;
|
|
224
|
+
background: transparent;
|
|
225
|
+
color: var(--mute);
|
|
226
|
+
font-size: 12px;
|
|
227
|
+
cursor: pointer;
|
|
228
|
+
}
|
|
229
|
+
.btn-ghost:hover { background: var(--soft); color: var(--strong-txt); }
|
|
230
|
+
.key { font-size: 10.5px; opacity: 0.55; }
|
|
231
|
+
|
|
232
|
+
.cards { display: flex; flex-direction: column; gap: 8px; }
|
|
233
|
+
.comment {
|
|
234
|
+
padding: 13px 14px;
|
|
235
|
+
border: 1px solid var(--card-border);
|
|
236
|
+
border-radius: 8px;
|
|
237
|
+
background: var(--card);
|
|
238
|
+
box-shadow: inset 2px 0 0 transparent;
|
|
239
|
+
cursor: pointer;
|
|
240
|
+
}
|
|
241
|
+
.comment.active { box-shadow: inset 2px 0 0 #e0a800; }
|
|
242
|
+
.comment-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
|
|
243
|
+
.who { color: var(--mute-2); font-size: 11px; font-weight: 500; }
|
|
244
|
+
.who .sep { color: var(--focus); margin: 0 4px; }
|
|
245
|
+
.who .when { color: var(--faint-2); }
|
|
246
|
+
.jump {
|
|
247
|
+
margin-left: auto;
|
|
248
|
+
border: 0;
|
|
249
|
+
padding: 0;
|
|
250
|
+
background: none;
|
|
251
|
+
color: var(--faint-2);
|
|
252
|
+
font-size: 11px;
|
|
253
|
+
white-space: nowrap;
|
|
254
|
+
cursor: pointer;
|
|
255
|
+
}
|
|
256
|
+
.jump:hover { color: var(--strong-txt); }
|
|
257
|
+
.edit-comment { margin-left: 0; }
|
|
258
|
+
.remove {
|
|
259
|
+
width: 18px;
|
|
260
|
+
height: 18px;
|
|
261
|
+
display: flex;
|
|
262
|
+
align-items: center;
|
|
263
|
+
justify-content: center;
|
|
264
|
+
border: 0;
|
|
265
|
+
border-radius: 4px;
|
|
266
|
+
background: transparent;
|
|
267
|
+
color: var(--faint);
|
|
268
|
+
font-size: 10px;
|
|
269
|
+
line-height: 1;
|
|
270
|
+
cursor: pointer;
|
|
271
|
+
}
|
|
272
|
+
.remove:hover { background: var(--danger-soft); color: var(--danger); }
|
|
273
|
+
.end-review {
|
|
274
|
+
margin-top: 9px;
|
|
275
|
+
width: 100%;
|
|
276
|
+
padding: 6px;
|
|
277
|
+
background: none;
|
|
278
|
+
border: none;
|
|
279
|
+
color: var(--faint-2);
|
|
280
|
+
font-size: 12px;
|
|
281
|
+
cursor: pointer;
|
|
282
|
+
border-radius: 6px;
|
|
283
|
+
}
|
|
284
|
+
.end-review:hover { color: var(--danger); background: var(--danger-soft); }
|
|
285
|
+
|
|
286
|
+
.ended {
|
|
287
|
+
position: fixed;
|
|
288
|
+
inset: 0;
|
|
289
|
+
z-index: 100;
|
|
290
|
+
display: flex;
|
|
291
|
+
flex-direction: column;
|
|
292
|
+
align-items: center;
|
|
293
|
+
justify-content: center;
|
|
294
|
+
gap: 4px;
|
|
295
|
+
background: var(--rail);
|
|
296
|
+
color: var(--txt);
|
|
297
|
+
}
|
|
298
|
+
.ended h2 { margin: 0; font-size: 17px; color: var(--strong-txt); }
|
|
299
|
+
.ended p { margin: 0; font-size: 13px; color: var(--mute-2); }
|
|
300
|
+
|
|
301
|
+
.comment .quote { -webkit-line-clamp: 2; margin-bottom: 8px; }
|
|
302
|
+
.comment .body { margin: 0; font-size: 13px; line-height: 1.5; cursor: text; border-radius: 4px; }
|
|
303
|
+
.comment .body:hover { background: var(--input-bg); box-shadow: 0 0 0 4px var(--input-bg); }
|
|
304
|
+
.comment .body-edit {
|
|
305
|
+
width: 100%;
|
|
306
|
+
padding: 6px 8px;
|
|
307
|
+
border: 1px solid var(--focus);
|
|
308
|
+
border-radius: 6px;
|
|
309
|
+
background: var(--card);
|
|
310
|
+
font-size: 13px;
|
|
311
|
+
line-height: 1.5;
|
|
312
|
+
resize: none;
|
|
313
|
+
outline: none;
|
|
314
|
+
}
|
|
315
|
+
.badge {
|
|
316
|
+
display: inline-block;
|
|
317
|
+
margin-left: 6px;
|
|
318
|
+
padding: 1px 7px;
|
|
319
|
+
border-radius: 999px;
|
|
320
|
+
background: var(--chip);
|
|
321
|
+
color: var(--faint-2);
|
|
322
|
+
font-size: 10px;
|
|
323
|
+
font-weight: 600;
|
|
324
|
+
}
|
|
325
|
+
.badge.correction { background: var(--danger-soft); color: var(--danger); }
|
|
326
|
+
|
|
327
|
+
.empty {
|
|
328
|
+
padding: 16px 14px;
|
|
329
|
+
border: 1px dashed var(--dash);
|
|
330
|
+
border-radius: 8px;
|
|
331
|
+
color: var(--faint);
|
|
332
|
+
font-size: 11.5px;
|
|
333
|
+
line-height: 1.5;
|
|
334
|
+
text-align: center;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
#editsBox { margin-top: 20px; animation: rise 140ms ease-out; }
|
|
338
|
+
.save-line { display: flex; align-items: center; gap: 7px; padding: 0 4px 9px; color: var(--faint-2); font-size: 11px; }
|
|
339
|
+
.save-line.saving { color: var(--mute); }
|
|
340
|
+
.save-line.failed { color: var(--danger); }
|
|
341
|
+
.save-line.dynamic { color: var(--mute); }
|
|
342
|
+
.save-line.dynamic .dot { background: var(--amber); }
|
|
343
|
+
.dot { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--green); }
|
|
344
|
+
.save-line.saving .dot { background: var(--amber); }
|
|
345
|
+
.save-line.failed .dot { background: var(--danger); }
|
|
346
|
+
.dot.amber { background: var(--amber); }
|
|
347
|
+
|
|
348
|
+
.edit-list { border: 1px solid var(--card-border); border-radius: 8px; background: var(--card); overflow: hidden; }
|
|
349
|
+
.edit-row { display: flex; align-items: center; gap: 9px; padding: 9px 12px; border-top: 1px solid var(--hair-2); }
|
|
350
|
+
.edit-row:first-child { border-top: 0; }
|
|
351
|
+
.edit-row .pip { width: 5px; height: 5px; flex: none; border-radius: 50%; background: var(--amber); }
|
|
352
|
+
.edit-row.deleted .pip { background: var(--danger); }
|
|
353
|
+
.edit-row .label { font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
354
|
+
.edit-row .kind { margin-left: auto; color: var(--faint-2); font-size: 11px; white-space: nowrap; }
|
|
355
|
+
|
|
356
|
+
.edit-more {
|
|
357
|
+
width: 100%;
|
|
358
|
+
padding: 8px 12px;
|
|
359
|
+
border: 0;
|
|
360
|
+
border-top: 1px solid var(--hair-2);
|
|
361
|
+
background: transparent;
|
|
362
|
+
color: var(--faint-2);
|
|
363
|
+
font-size: 11.5px;
|
|
364
|
+
text-align: left;
|
|
365
|
+
cursor: pointer;
|
|
366
|
+
}
|
|
367
|
+
.edit-more:hover { background: var(--soft); color: var(--strong-txt); }
|
|
368
|
+
|
|
369
|
+
.other-row {
|
|
370
|
+
width: 100%;
|
|
371
|
+
border: 0;
|
|
372
|
+
background: transparent;
|
|
373
|
+
text-align: left;
|
|
374
|
+
cursor: pointer;
|
|
375
|
+
color: inherit;
|
|
376
|
+
}
|
|
377
|
+
.other-row:hover { background: var(--soft); }
|
|
378
|
+
|
|
379
|
+
.rail-foot { flex: none; padding: 12px; border-top: 1px solid var(--hair-2); }
|
|
380
|
+
.rail-foot textarea { min-height: 58px; max-height: 40vh; margin-bottom: 9px; font-size: 12.5px; overflow-y: auto; resize: vertical; }
|
|
381
|
+
|
|
382
|
+
.send {
|
|
383
|
+
width: 100%;
|
|
384
|
+
padding: 10px 12px;
|
|
385
|
+
display: flex;
|
|
386
|
+
align-items: center;
|
|
387
|
+
justify-content: center;
|
|
388
|
+
gap: 8px;
|
|
389
|
+
border: 1px solid var(--btn-bg);
|
|
390
|
+
border-radius: 6px;
|
|
391
|
+
background: var(--btn-bg);
|
|
392
|
+
color: var(--btn-fg);
|
|
393
|
+
font-size: 12.5px;
|
|
394
|
+
font-weight: 500;
|
|
395
|
+
cursor: pointer;
|
|
396
|
+
}
|
|
397
|
+
.send:disabled { border-color: var(--hair); background: var(--soft); color: var(--faint); cursor: default; }
|
|
398
|
+
|
|
399
|
+
.agent-line {
|
|
400
|
+
margin: 10px 2px 2px;
|
|
401
|
+
display: flex;
|
|
402
|
+
align-items: center;
|
|
403
|
+
justify-content: center;
|
|
404
|
+
gap: 6px;
|
|
405
|
+
color: var(--faint);
|
|
406
|
+
font-size: 11px;
|
|
407
|
+
line-height: 1.4;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/* Shown after Send when nothing is polling, so the loop never dead-ends. */
|
|
411
|
+
.handoff {
|
|
412
|
+
margin-top: 10px;
|
|
413
|
+
padding: 11px 12px;
|
|
414
|
+
border: 1px solid var(--strong-border);
|
|
415
|
+
border-radius: 8px;
|
|
416
|
+
background: var(--card);
|
|
417
|
+
animation: rise 140ms ease-out;
|
|
418
|
+
}
|
|
419
|
+
.handoff-title { margin: 0 0 4px; font-size: 12px; font-weight: 600; }
|
|
420
|
+
.handoff-body { margin: 0 0 8px; color: var(--mute); font-size: 11.5px; line-height: 1.45; }
|
|
421
|
+
.handoff-cmd {
|
|
422
|
+
margin-bottom: 8px;
|
|
423
|
+
padding: 8px 9px;
|
|
424
|
+
border-radius: 6px;
|
|
425
|
+
background: var(--input-bg);
|
|
426
|
+
border: 1px solid var(--hair);
|
|
427
|
+
overflow-x: auto;
|
|
428
|
+
}
|
|
429
|
+
.handoff-cmd code {
|
|
430
|
+
font: 11.5px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
431
|
+
white-space: pre-wrap;
|
|
432
|
+
word-break: break-word;
|
|
433
|
+
}
|
|
434
|
+
.handoff .btn-ghost { padding: 5px 9px; font-size: 11.5px; }
|
|
435
|
+
|
|
436
|
+
.toast {
|
|
437
|
+
position: fixed;
|
|
438
|
+
left: 50%;
|
|
439
|
+
bottom: 22px;
|
|
440
|
+
transform: translateX(-50%);
|
|
441
|
+
z-index: 60;
|
|
442
|
+
padding: 8px 14px;
|
|
443
|
+
border-radius: 8px;
|
|
444
|
+
background: var(--btn-bg);
|
|
445
|
+
color: var(--btn-fg);
|
|
446
|
+
font-size: 12px;
|
|
447
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
|
|
448
|
+
animation: rise 140ms ease-out;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
@keyframes rise {
|
|
452
|
+
from { opacity: 0; transform: translateY(4px); }
|
|
453
|
+
to { opacity: 1; transform: none; }
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
@media (prefers-reduced-motion: reduce) {
|
|
457
|
+
*, .rail, .handle { animation: none !important; transition: none !important; }
|
|
458
|
+
}
|
package/src/chrome.html
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>doc-review</title>
|
|
7
|
+
<link rel="stylesheet" href="/chrome.css">
|
|
8
|
+
</head>
|
|
9
|
+
<body data-session="__SESSION_ID__" data-token="__TOKEN__">
|
|
10
|
+
<div class="app">
|
|
11
|
+
<main class="stage">
|
|
12
|
+
<iframe
|
|
13
|
+
id="frame"
|
|
14
|
+
title="Artifact under review"
|
|
15
|
+
sandbox="allow-scripts allow-forms allow-modals"></iframe>
|
|
16
|
+
</main>
|
|
17
|
+
|
|
18
|
+
<button type="button" id="handle" class="handle" title="Hide comments panel" aria-label="Hide comments panel">›</button>
|
|
19
|
+
|
|
20
|
+
<aside class="rail" id="rail">
|
|
21
|
+
<div class="rail-scroll">
|
|
22
|
+
<div class="rail-head">
|
|
23
|
+
<span class="section">Feedback</span>
|
|
24
|
+
<span class="dim" id="count">0</span>
|
|
25
|
+
<button type="button" id="theme" class="icon-btn" title="Switch chrome to dark" aria-label="Switch chrome to dark">☾</button>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div id="compose" hidden>
|
|
29
|
+
<div class="compose">
|
|
30
|
+
<div class="compose-head">
|
|
31
|
+
<span class="chip" id="composeKind">Selection</span>
|
|
32
|
+
<span class="dim">Click to write · Esc to dismiss</span>
|
|
33
|
+
</div>
|
|
34
|
+
<p class="quote" id="composeQuote"></p>
|
|
35
|
+
<textarea id="composeText" rows="3" placeholder="What should change?"></textarea>
|
|
36
|
+
<div class="compose-actions">
|
|
37
|
+
<button type="button" id="composeAdd" class="btn-primary">Add comment <span class="key">⏎</span></button>
|
|
38
|
+
<button type="button" id="composeCancel" class="btn-ghost">Cancel</button>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div id="cards" class="cards"></div>
|
|
44
|
+
|
|
45
|
+
<div id="empty" class="empty">Select text or click an element to comment on it</div>
|
|
46
|
+
|
|
47
|
+
<section id="othersBox" hidden>
|
|
48
|
+
<div class="rail-head tight">
|
|
49
|
+
<span class="section">Other pages</span>
|
|
50
|
+
<span class="dim" id="othersCount">0</span>
|
|
51
|
+
</div>
|
|
52
|
+
<div class="edit-list" id="othersList"></div>
|
|
53
|
+
</section>
|
|
54
|
+
|
|
55
|
+
<section id="editsBox" hidden>
|
|
56
|
+
<div class="rail-head tight">
|
|
57
|
+
<span class="section">Your edits</span>
|
|
58
|
+
<span class="dim" id="editCount">0</span>
|
|
59
|
+
<button type="button" id="revert" class="link-btn danger-hover">Revert all</button>
|
|
60
|
+
</div>
|
|
61
|
+
<div class="save-line" id="saveLine"><span class="dot"></span><span id="saveText"></span></div>
|
|
62
|
+
<div class="edit-list" id="editList"></div>
|
|
63
|
+
</section>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<div class="rail-foot">
|
|
67
|
+
<textarea id="note" rows="2" placeholder="Overall note…"></textarea>
|
|
68
|
+
<button type="button" id="send" class="send" disabled>Nothing to send yet</button>
|
|
69
|
+
<div class="agent-line" id="agentLine" hidden><span class="dot amber"></span><span id="agentText"></span></div>
|
|
70
|
+
<div class="handoff" id="handoff" hidden>
|
|
71
|
+
<p class="handoff-title">Sent — but no agent is listening yet.</p>
|
|
72
|
+
<p class="handoff-body">Paste this into your agent — Claude Code, Codex, or Cursor:</p>
|
|
73
|
+
<div class="handoff-cmd"><code id="handoffCmd"></code></div>
|
|
74
|
+
<button type="button" id="handoffCopy" class="btn-ghost">Copy prompt</button>
|
|
75
|
+
</div>
|
|
76
|
+
<button type="button" id="endReview" class="end-review" title="Stop this review and release the waiting agent">End review</button>
|
|
77
|
+
</div>
|
|
78
|
+
</aside>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<script type="module" src="/chrome.js"></script>
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|