git-reviewer 2.15.0 → 2.17.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 +93 -5
- package/bin/reviewer.js +256 -1
- package/lib/agent.js +12 -2
- package/lib/answerer.js +191 -0
- package/lib/channel.js +286 -0
- package/lib/claude-background.js +316 -0
- package/lib/claude-command.js +90 -0
- package/lib/claude-sessions.js +229 -0
- package/lib/cli.js +147 -7
- package/lib/comments.js +175 -10
- package/lib/presence.js +223 -0
- package/lib/search.js +319 -0
- package/lib/store.js +284 -9
- package/lib/threads.js +180 -0
- package/lib/watch.js +131 -0
- package/man/git-reviewer.1 +47 -0
- package/package.json +1 -1
- package/public/app.js +1118 -107
- package/public/index.html +80 -0
- package/public/style.css +383 -0
- package/server.js +431 -34
package/public/index.html
CHANGED
|
@@ -19,6 +19,19 @@
|
|
|
19
19
|
<span id="repoButtonLabel">Open a repository</span>
|
|
20
20
|
</button>
|
|
21
21
|
|
|
22
|
+
<button id="agentButton" class="agent-button hidden" onclick="openAgentDialog()"
|
|
23
|
+
title="Have the Claude Code session that wrote this code answer your comments">
|
|
24
|
+
<span class="agent-dot" aria-hidden="true"></span>
|
|
25
|
+
<span id="agentButtonLabel">Ask Claude Code</span>
|
|
26
|
+
</button>
|
|
27
|
+
|
|
28
|
+
<button id="searchButton" class="icon-button hidden" onclick="openSearch()"
|
|
29
|
+
title="Search the change (Ctrl+Shift+F)" aria-label="Search the change">
|
|
30
|
+
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
|
31
|
+
<path d="M10.68 11.74a6 6 0 01-7.92-8.98 6 6 0 018.98 7.92l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04zM11.5 7a4.5 4.5 0 10-9 0 4.5 4.5 0 009 0z"></path>
|
|
32
|
+
</svg>
|
|
33
|
+
</button>
|
|
34
|
+
|
|
22
35
|
<button id="helpButton" class="icon-button" onclick="openHelp()"
|
|
23
36
|
title="How to review" aria-label="How to review">
|
|
24
37
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
|
@@ -202,7 +215,73 @@
|
|
|
202
215
|
</div>
|
|
203
216
|
</div>
|
|
204
217
|
|
|
218
|
+
<!-- Connecting a Claude Code session to answer comments in their threads. -->
|
|
219
|
+
<div id="agentModal" class="help-modal hidden" onclick="if (event.target.id === 'agentModal') closeAgentDialog()">
|
|
220
|
+
<div class="help-card agent-card" role="dialog" aria-modal="true" aria-labelledby="agentTitle">
|
|
221
|
+
<div class="help-head">
|
|
222
|
+
<h2 id="agentTitle">Ask the session that wrote this code</h2>
|
|
223
|
+
<button class="icon-button" onclick="closeAgentDialog()" aria-label="Close">
|
|
224
|
+
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
|
225
|
+
<path d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path>
|
|
226
|
+
</svg>
|
|
227
|
+
</button>
|
|
228
|
+
</div>
|
|
229
|
+
<div class="agent-body">
|
|
230
|
+
<div id="agentConnected" class="agent-connected hidden"></div>
|
|
231
|
+
<p class="agent-intro">Pick the Claude Code session that worked on this repository. Every comment you
|
|
232
|
+
write, and every reply you add, goes to it, and its answer appears in the thread as it is written.</p>
|
|
233
|
+
<div id="agentSessions" class="agent-sessions"></div>
|
|
234
|
+
<label class="agent-fork">
|
|
235
|
+
<input type="checkbox" id="agentFork" checked>
|
|
236
|
+
Answer in a copy of the session, so the original stays exactly as it was
|
|
237
|
+
</label>
|
|
238
|
+
<p class="agent-note">In the background the session can read the repository and nothing else.
|
|
239
|
+
To have it answer live in your terminal instead, copy its command and run it there:
|
|
240
|
+
your session, your permissions, and every comment arrives as it is written.</p>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
|
|
205
245
|
<aside id="sidebar" class="sidebar hidden">
|
|
246
|
+
<!-- Find across the whole change, the way an IDE's find navigator
|
|
247
|
+
searches a project: it takes the sidebar's place while open. -->
|
|
248
|
+
<section id="searchPanel" class="search-panel hidden" aria-label="Search the change">
|
|
249
|
+
<div class="search-head">
|
|
250
|
+
<h2>Search</h2>
|
|
251
|
+
<button class="search-back" type="button" onclick="closeSearch()" title="Back to the files (Esc)">Files</button>
|
|
252
|
+
</div>
|
|
253
|
+
<div class="search-box">
|
|
254
|
+
<input id="searchInput" type="search" list="searchHistory" placeholder="Find in the change"
|
|
255
|
+
spellcheck="false" autocomplete="off" aria-label="Find in the change">
|
|
256
|
+
<datalist id="searchHistory"></datalist>
|
|
257
|
+
<button id="searchCase" class="search-toggle" type="button" aria-pressed="false" title="Match case">Aa</button>
|
|
258
|
+
<button id="searchRefs" class="search-toggle" type="button" aria-pressed="false"
|
|
259
|
+
title="Find references: the definition, and uses added, removed and left unchanged">Refs</button>
|
|
260
|
+
</div>
|
|
261
|
+
<div class="search-options">
|
|
262
|
+
<select id="searchMode" aria-label="How to match">
|
|
263
|
+
<option value="contains">Contains</option>
|
|
264
|
+
<option value="word">Whole word</option>
|
|
265
|
+
<option value="prefix">Starts with</option>
|
|
266
|
+
<option value="suffix">Ends with</option>
|
|
267
|
+
<option value="regex">Regular expression</option>
|
|
268
|
+
</select>
|
|
269
|
+
<select id="searchScope" aria-label="Where to search">
|
|
270
|
+
<option value="changes">Changed lines</option>
|
|
271
|
+
<option value="files" selected>Changed files</option>
|
|
272
|
+
<option value="repo">Whole repository</option>
|
|
273
|
+
</select>
|
|
274
|
+
</div>
|
|
275
|
+
<div class="search-sides" role="group" aria-label="Show results">
|
|
276
|
+
<button type="button" data-side="all" class="active">All</button>
|
|
277
|
+
<button type="button" data-side="added">Added</button>
|
|
278
|
+
<button type="button" data-side="deleted">Deleted</button>
|
|
279
|
+
<button type="button" data-side="unchanged">Unchanged</button>
|
|
280
|
+
</div>
|
|
281
|
+
<div id="searchSummary" class="search-summary" role="status" aria-live="polite"></div>
|
|
282
|
+
<div id="searchResults" class="search-results" role="listbox" aria-label="Search results"></div>
|
|
283
|
+
</section>
|
|
284
|
+
|
|
206
285
|
<!-- The commits a review is made of, when it is made of commits. Click
|
|
207
286
|
one to review it on its own; shift-click a second to review the run
|
|
208
287
|
between them -- the same gesture a pull request's commit picker
|
|
@@ -237,6 +316,7 @@
|
|
|
237
316
|
</button>
|
|
238
317
|
</div>
|
|
239
318
|
<div id="codeViewer" class="code-viewer"></div>
|
|
319
|
+
<div id="searchMinimap" class="search-minimap hidden" aria-hidden="true"></div>
|
|
240
320
|
</main>
|
|
241
321
|
|
|
242
322
|
<div id="commentsResizeHandle" class="resize-handle hidden"></div>
|
package/public/style.css
CHANGED
|
@@ -651,6 +651,13 @@ button:disabled {
|
|
|
651
651
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
|
652
652
|
}
|
|
653
653
|
|
|
654
|
+
/* The box keeps its right edge clear for the action buttons, which sit at
|
|
655
|
+
the top. A thread starts below them, so it can have the full width --
|
|
656
|
+
which an answer of a few paragraphs needs. */
|
|
657
|
+
.comment-box .comment-followups {
|
|
658
|
+
margin-right: -194px;
|
|
659
|
+
}
|
|
660
|
+
|
|
654
661
|
.comment-followup-item {
|
|
655
662
|
margin-bottom: 8px;
|
|
656
663
|
padding: 8px 12px;
|
|
@@ -2222,3 +2229,379 @@ button:disabled {
|
|
|
2222
2229
|
max-height: 8.5em;
|
|
2223
2230
|
overflow-y: auto;
|
|
2224
2231
|
}
|
|
2232
|
+
|
|
2233
|
+
/* Agents answering in threads
|
|
2234
|
+
*
|
|
2235
|
+
* An answer from the session that wrote the code sits in the thread like any
|
|
2236
|
+
* reply, marked with who wrote it so it is never mistaken for the reviewer's
|
|
2237
|
+
* own note. The orange is the same family Claude Code uses for itself.
|
|
2238
|
+
*/
|
|
2239
|
+
.agent-button {
|
|
2240
|
+
display: flex;
|
|
2241
|
+
align-items: center;
|
|
2242
|
+
gap: 8px;
|
|
2243
|
+
padding: 7px 12px;
|
|
2244
|
+
border: 1px solid #d1d5da;
|
|
2245
|
+
border-radius: 6px;
|
|
2246
|
+
background: white;
|
|
2247
|
+
font: inherit;
|
|
2248
|
+
font-size: 13px;
|
|
2249
|
+
font-weight: 500;
|
|
2250
|
+
color: #24292e;
|
|
2251
|
+
cursor: pointer;
|
|
2252
|
+
white-space: nowrap;
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
.agent-button:hover {
|
|
2256
|
+
background: #f6f8fa;
|
|
2257
|
+
border-color: #c6cbd1;
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
.agent-dot {
|
|
2261
|
+
flex: none;
|
|
2262
|
+
width: 8px;
|
|
2263
|
+
height: 8px;
|
|
2264
|
+
border-radius: 50%;
|
|
2265
|
+
background: #c9ced6;
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
.agent-button.connected .agent-dot,
|
|
2269
|
+
.agent-connection .agent-dot {
|
|
2270
|
+
background: #2da44e;
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
.agent-button.working .agent-dot {
|
|
2274
|
+
background: #d97757;
|
|
2275
|
+
animation: agent-pulse 1.2s ease-in-out infinite;
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
@keyframes agent-pulse {
|
|
2279
|
+
0%, 100% { opacity: 1; }
|
|
2280
|
+
50% { opacity: 0.35; }
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2283
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2284
|
+
.agent-button.working .agent-dot { animation: none; }
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
.comment-followup-item.followup-agent {
|
|
2288
|
+
border-left-color: #d97757;
|
|
2289
|
+
background: rgba(217, 119, 87, 0.08);
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2292
|
+
.followup-author {
|
|
2293
|
+
display: block;
|
|
2294
|
+
margin-bottom: 4px;
|
|
2295
|
+
font-size: 11px;
|
|
2296
|
+
font-weight: 600;
|
|
2297
|
+
color: #b0532e;
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2300
|
+
.followup-markdown code {
|
|
2301
|
+
padding: 1px 4px;
|
|
2302
|
+
border-radius: 3px;
|
|
2303
|
+
background: rgba(27, 31, 35, 0.07);
|
|
2304
|
+
font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;
|
|
2305
|
+
font-size: 11.5px;
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2308
|
+
.followup-code {
|
|
2309
|
+
margin: 6px 0;
|
|
2310
|
+
padding: 8px 10px;
|
|
2311
|
+
border-radius: 4px;
|
|
2312
|
+
background: rgba(27, 31, 35, 0.06);
|
|
2313
|
+
overflow-x: auto;
|
|
2314
|
+
white-space: pre;
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
.followup-code code {
|
|
2318
|
+
padding: 0;
|
|
2319
|
+
background: none;
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
.agent-typing {
|
|
2323
|
+
color: #8a6d5f;
|
|
2324
|
+
font-style: italic;
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
.followup-queued {
|
|
2328
|
+
margin-top: 4px;
|
|
2329
|
+
font-size: 11px;
|
|
2330
|
+
color: #8a6d5f;
|
|
2331
|
+
font-style: italic;
|
|
2332
|
+
}
|
|
2333
|
+
|
|
2334
|
+
.comment-item-thread {
|
|
2335
|
+
margin-top: 4px;
|
|
2336
|
+
font-size: 11px;
|
|
2337
|
+
color: #6a737d;
|
|
2338
|
+
}
|
|
2339
|
+
|
|
2340
|
+
.comment-item-answering {
|
|
2341
|
+
color: #b0532e;
|
|
2342
|
+
}
|
|
2343
|
+
|
|
2344
|
+
.agent-card {
|
|
2345
|
+
max-width: 640px;
|
|
2346
|
+
}
|
|
2347
|
+
|
|
2348
|
+
.agent-body {
|
|
2349
|
+
padding: 18px 22px 22px;
|
|
2350
|
+
overflow-y: auto;
|
|
2351
|
+
font-size: 13px;
|
|
2352
|
+
color: #24292e;
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
.agent-intro,
|
|
2356
|
+
.agent-note {
|
|
2357
|
+
line-height: 1.5;
|
|
2358
|
+
color: #57606a;
|
|
2359
|
+
}
|
|
2360
|
+
|
|
2361
|
+
.agent-note {
|
|
2362
|
+
margin-top: 12px;
|
|
2363
|
+
font-size: 12px;
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
.agent-sessions {
|
|
2367
|
+
display: flex;
|
|
2368
|
+
flex-direction: column;
|
|
2369
|
+
gap: 8px;
|
|
2370
|
+
margin: 14px 0;
|
|
2371
|
+
}
|
|
2372
|
+
|
|
2373
|
+
.agent-session {
|
|
2374
|
+
display: flex;
|
|
2375
|
+
align-items: center;
|
|
2376
|
+
gap: 12px;
|
|
2377
|
+
padding: 10px 12px;
|
|
2378
|
+
border: 1px solid #e1e4e8;
|
|
2379
|
+
border-radius: 6px;
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
.agent-session-copy {
|
|
2383
|
+
opacity: 0.75;
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
.agent-session-text {
|
|
2387
|
+
flex: 1;
|
|
2388
|
+
min-width: 0;
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2391
|
+
.agent-session-title {
|
|
2392
|
+
font-weight: 500;
|
|
2393
|
+
overflow: hidden;
|
|
2394
|
+
display: -webkit-box;
|
|
2395
|
+
-webkit-line-clamp: 2;
|
|
2396
|
+
-webkit-box-orient: vertical;
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
.agent-session-meta,
|
|
2400
|
+
.agent-connection-meta {
|
|
2401
|
+
margin-top: 2px;
|
|
2402
|
+
font-size: 11.5px;
|
|
2403
|
+
color: #6a737d;
|
|
2404
|
+
}
|
|
2405
|
+
|
|
2406
|
+
.agent-session-actions {
|
|
2407
|
+
display: flex;
|
|
2408
|
+
flex-direction: column;
|
|
2409
|
+
gap: 6px;
|
|
2410
|
+
flex: none;
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2413
|
+
.agent-connect,
|
|
2414
|
+
.agent-copy,
|
|
2415
|
+
.agent-disconnect {
|
|
2416
|
+
padding: 5px 10px;
|
|
2417
|
+
border-radius: 6px;
|
|
2418
|
+
font: inherit;
|
|
2419
|
+
font-size: 12px;
|
|
2420
|
+
cursor: pointer;
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
.agent-connect {
|
|
2424
|
+
border: none;
|
|
2425
|
+
background: #d97757;
|
|
2426
|
+
color: white;
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
.agent-connect:hover {
|
|
2430
|
+
background: #c4643f;
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
.agent-copy,
|
|
2434
|
+
.agent-disconnect {
|
|
2435
|
+
border: 1px solid #d1d5da;
|
|
2436
|
+
background: white;
|
|
2437
|
+
color: #24292e;
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2440
|
+
.agent-copy:hover,
|
|
2441
|
+
.agent-disconnect:hover {
|
|
2442
|
+
background: #f6f8fa;
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2445
|
+
.agent-connected {
|
|
2446
|
+
display: flex;
|
|
2447
|
+
flex-direction: column;
|
|
2448
|
+
gap: 8px;
|
|
2449
|
+
margin-bottom: 14px;
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2452
|
+
.agent-connection {
|
|
2453
|
+
display: flex;
|
|
2454
|
+
align-items: flex-start;
|
|
2455
|
+
gap: 10px;
|
|
2456
|
+
padding: 10px 12px;
|
|
2457
|
+
border-radius: 6px;
|
|
2458
|
+
background: #f0faf3;
|
|
2459
|
+
border: 1px solid #c8e6d0;
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
.agent-connection .agent-dot {
|
|
2463
|
+
margin-top: 5px;
|
|
2464
|
+
}
|
|
2465
|
+
|
|
2466
|
+
.agent-connection > div {
|
|
2467
|
+
flex: 1;
|
|
2468
|
+
min-width: 0;
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
.agent-connection-title {
|
|
2472
|
+
margin-top: 2px;
|
|
2473
|
+
overflow: hidden;
|
|
2474
|
+
text-overflow: ellipsis;
|
|
2475
|
+
white-space: nowrap;
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
.agent-fork {
|
|
2479
|
+
display: flex;
|
|
2480
|
+
align-items: center;
|
|
2481
|
+
gap: 8px;
|
|
2482
|
+
font-size: 12.5px;
|
|
2483
|
+
color: #24292e;
|
|
2484
|
+
}
|
|
2485
|
+
|
|
2486
|
+
.agent-empty {
|
|
2487
|
+
padding: 12px 0;
|
|
2488
|
+
color: #6a737d;
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2491
|
+
@media (max-width: 640px) {
|
|
2492
|
+
.agent-session { flex-direction: column; align-items: stretch; }
|
|
2493
|
+
.agent-session-actions { flex-direction: row; }
|
|
2494
|
+
.agent-button { padding: 7px 9px; }
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
/* Search across the change
|
|
2498
|
+
*
|
|
2499
|
+
* Results are code, so they are set in the diff's monospace, and each one
|
|
2500
|
+
* says which side of the change it is on with the diff's own colours.
|
|
2501
|
+
*/
|
|
2502
|
+
.code-section { position: relative; }
|
|
2503
|
+
.sidebar.searching > :not(#searchPanel):not(.resize-handle) { display: none !important; }
|
|
2504
|
+
.search-panel {
|
|
2505
|
+
display: flex;
|
|
2506
|
+
flex-direction: column;
|
|
2507
|
+
gap: 8px;
|
|
2508
|
+
padding: 12px 14px;
|
|
2509
|
+
min-height: 0;
|
|
2510
|
+
flex: 1;
|
|
2511
|
+
}
|
|
2512
|
+
.search-head { display: flex; align-items: center; justify-content: space-between; }
|
|
2513
|
+
.search-head h2 { font-size: 14px; font-weight: 600; color: #24292e; }
|
|
2514
|
+
.search-panel .search-back {
|
|
2515
|
+
padding: 3px 9px; border: 1px solid #d1d5da; border-radius: 6px;
|
|
2516
|
+
background: white; color: #24292e; font: inherit; font-size: 12px; cursor: pointer;
|
|
2517
|
+
}
|
|
2518
|
+
.search-panel .search-back:hover { background: #f3f4f6; }
|
|
2519
|
+
.search-box { display: flex; gap: 6px; }
|
|
2520
|
+
.search-box input {
|
|
2521
|
+
flex: 1; min-width: 0; padding: 7px 9px;
|
|
2522
|
+
border: 1px solid #d1d5da; border-radius: 6px; font-size: 13px;
|
|
2523
|
+
font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;
|
|
2524
|
+
}
|
|
2525
|
+
.search-box input:focus { outline: 2px solid #0366d6; outline-offset: -1px; }
|
|
2526
|
+
.search-panel .search-toggle {
|
|
2527
|
+
padding: 0 8px; border: 1px solid #d1d5da; border-radius: 6px;
|
|
2528
|
+
background: white; color: #57606a; cursor: pointer;
|
|
2529
|
+
font-family: inherit; font-size: 12px; font-weight: 600; line-height: 1;
|
|
2530
|
+
}
|
|
2531
|
+
.search-panel .search-toggle:hover { background: #f3f4f6; }
|
|
2532
|
+
.search-panel .search-toggle[aria-pressed="true"] { background: #0366d6; border-color: #0366d6; color: white; }
|
|
2533
|
+
.search-options { display: flex; gap: 6px; }
|
|
2534
|
+
.search-options select {
|
|
2535
|
+
flex: 1; min-width: 0; padding: 5px 6px; font-size: 12px;
|
|
2536
|
+
border: 1px solid #d1d5da; border-radius: 6px; background: white;
|
|
2537
|
+
}
|
|
2538
|
+
.search-sides { display: flex; gap: 4px; flex-wrap: wrap; }
|
|
2539
|
+
.search-panel .search-sides button {
|
|
2540
|
+
padding: 3px 9px; border: 1px solid #d1d5da; border-radius: 999px;
|
|
2541
|
+
background: white; color: #57606a; font-size: 11.5px; font-weight: 500; cursor: pointer;
|
|
2542
|
+
}
|
|
2543
|
+
.search-panel .search-sides button:hover { background: #f3f4f6; }
|
|
2544
|
+
.search-panel .search-sides button.active { background: #24292e; border-color: #24292e; color: white; }
|
|
2545
|
+
.search-summary { font-size: 12px; color: #57606a; line-height: 1.45; }
|
|
2546
|
+
.search-summary .search-warning { display: block; margin-top: 4px; color: #9a6700; }
|
|
2547
|
+
.search-summary .search-error { color: #cf222e; }
|
|
2548
|
+
.search-results { flex: 1; min-height: 0; overflow-y: auto; margin: 0 -14px; }
|
|
2549
|
+
.search-panel .search-file {
|
|
2550
|
+
display: flex; align-items: center; gap: 6px; width: 100%;
|
|
2551
|
+
padding: 6px 14px; border: none; border-radius: 0; background: #f6f8fa; cursor: pointer;
|
|
2552
|
+
font-family: inherit; font-size: 12px; font-weight: 600; line-height: 1.3; color: #24292e; text-align: left;
|
|
2553
|
+
white-space: normal; position: sticky; top: 0; transform: none;
|
|
2554
|
+
}
|
|
2555
|
+
.search-panel .search-file:hover { background: #eef1f4; }
|
|
2556
|
+
.search-file .count {
|
|
2557
|
+
margin-left: auto; padding: 1px 7px; border-radius: 999px;
|
|
2558
|
+
background: #e1e4e8; color: #57606a; font-weight: 500; font-size: 11px;
|
|
2559
|
+
}
|
|
2560
|
+
.search-file .elsewhere { font-weight: 400; color: #8b949e; }
|
|
2561
|
+
.search-file[aria-expanded="false"] + .search-group { display: none; }
|
|
2562
|
+
.search-hit {
|
|
2563
|
+
position: relative;
|
|
2564
|
+
display: grid; grid-template-columns: 14px 34px minmax(0, 1fr); gap: 6px; align-items: baseline;
|
|
2565
|
+
padding: 3px 14px; cursor: pointer;
|
|
2566
|
+
font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace; font-size: 11.5px;
|
|
2567
|
+
}
|
|
2568
|
+
.search-hit:hover { background: #f3f6fa; }
|
|
2569
|
+
.search-hit.selected { background: #ddf4ff; }
|
|
2570
|
+
.search-hit .side { text-align: center; font-weight: 700; }
|
|
2571
|
+
.search-hit[data-side="added"] .side { color: #1a7f37; }
|
|
2572
|
+
.search-hit[data-side="deleted"] .side { color: #cf222e; }
|
|
2573
|
+
.search-hit[data-side="context"] .side { color: #8b949e; }
|
|
2574
|
+
.search-hit[data-side="untouched"] .side { color: #0969da; }
|
|
2575
|
+
.search-hit .num { color: #8b949e; text-align: right; font-variant-numeric: tabular-nums; }
|
|
2576
|
+
.search-hit .text { white-space: pre; overflow: hidden; text-overflow: ellipsis; color: #24292e; }
|
|
2577
|
+
.search-hit[data-side="deleted"] .text { color: #82071e; }
|
|
2578
|
+
.search-hit mark { background: #fff8c5; color: inherit; border-radius: 2px; box-shadow: 0 0 0 1px #d4a72c; }
|
|
2579
|
+
.search-hit .role {
|
|
2580
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
2581
|
+
font-size: 10.5px; color: #8250df; font-weight: 600;
|
|
2582
|
+
}
|
|
2583
|
+
.search-panel .hit-comment {
|
|
2584
|
+
position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
|
|
2585
|
+
visibility: hidden; padding: 1px 6px; border: 1px solid #d1d5da; border-radius: 4px;
|
|
2586
|
+
background: white; color: #24292e; font: 11px/1.3 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; cursor: pointer;
|
|
2587
|
+
}
|
|
2588
|
+
.search-panel .hit-comment:hover { background: #f3f4f6; }
|
|
2589
|
+
.search-hit:hover .hit-comment, .search-hit.selected .hit-comment { visibility: visible; }
|
|
2590
|
+
.search-preview {
|
|
2591
|
+
margin: 2px 14px 6px 34px; padding: 6px 8px; border-left: 2px solid #0969da;
|
|
2592
|
+
background: #f6f8fa; font: 11px/1.5 SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;
|
|
2593
|
+
white-space: pre; overflow-x: auto; color: #24292e;
|
|
2594
|
+
}
|
|
2595
|
+
.search-preview .focus { background: #fff8c5; display: inline-block; min-width: 100%; }
|
|
2596
|
+
.line.search-flash { animation: search-flash 1.6s ease-out; }
|
|
2597
|
+
@keyframes search-flash { 0%, 30% { box-shadow: inset 4px 0 0 #0969da; background: #ddf4ff; } }
|
|
2598
|
+
@media (prefers-reduced-motion: reduce) { .line.search-flash { animation: none; box-shadow: inset 4px 0 0 #0969da; } }
|
|
2599
|
+
.search-minimap {
|
|
2600
|
+
position: absolute; top: 58px; right: 2px; bottom: 6px; width: 8px; pointer-events: none;
|
|
2601
|
+
}
|
|
2602
|
+
.search-minimap span {
|
|
2603
|
+
position: absolute; right: 0; width: 8px; height: 3px; border-radius: 1px;
|
|
2604
|
+
background: #d4a72c; pointer-events: auto; cursor: pointer;
|
|
2605
|
+
}
|
|
2606
|
+
.search-minimap span[data-side="added"] { background: #2da44e; }
|
|
2607
|
+
.search-minimap span[data-side="deleted"] { background: #cf222e; }
|