@youtyan/code-viewer 0.5.5 → 0.6.1

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/web/index.html CHANGED
@@ -31,12 +31,14 @@
31
31
  <a class="app-menu-item" data-route="database" href="/database">Datastores</a>
32
32
  </nav>
33
33
  <div class="global-actions">
34
- <button id="annotations-toggle" class="global-icon-action" title="code annotations" aria-label="code annotations">💬<span id="annotations-count" hidden></span></button>
34
+ <button id="annotations-toggle" class="global-icon-action" title="code annotations" aria-label="code annotations"><span class="goi-icon" aria-hidden="true"></span><span id="annotations-count" hidden></span></button>
35
35
  <button id="viewer-settings" class="global-icon-action" title="viewer settings" aria-label="viewer settings"></button>
36
- <button id="doctor-btn" class="global-icon-action" title="environment doctor" aria-label="environment doctor">🩺<span id="doctor-badge" class="doctor-badge" hidden></span></button>
36
+ <button id="doctor-btn" class="global-icon-action" title="environment doctor" aria-label="environment doctor"><span class="goi-icon" aria-hidden="true"></span><span id="doctor-badge" class="doctor-badge" hidden></span></button>
37
+ <button id="copy-ai-context" class="global-icon-action" title="Copy AI context" aria-label="Copy AI context"></button>
38
+ <span id="copy-ai-context-feedback" class="goi-feedback" role="status" hidden></span>
37
39
  <button id="auto-update" class="global-icon-action active" title="auto update on file change">auto</button>
38
40
  <button id="cancel-requests" class="global-icon-action" title="no in-flight requests" aria-label="cancel in-flight requests" disabled>stop</button>
39
- <button id="theme" title="toggle theme">🌗</button>
41
+ <button id="theme" title="toggle theme" aria-label="toggle theme"></button>
40
42
  <span id="status" class="status"></span>
41
43
  <a id="repo-web-link" class="global-help-link" href="#" target="_blank" rel="noopener" hidden>GitHub</a>
42
44
  <a class="global-help-link" data-route="help" href="/help">Help</a>
@@ -116,7 +118,7 @@
116
118
  </div>
117
119
  </div>
118
120
  <div class="sb-filter-wrap">
119
- <input id="sb-filter" type="search" placeholder="filter files… (/)" title="Use /pattern/ for regex. Cmd/Ctrl+K focuses this field." autocomplete="off" />
121
+ <input id="sb-filter" type="search" placeholder="filter files… / ⌘K" title="Use /pattern/ for regex. Press / to focus this field, Cmd/Ctrl+K for the full-file palette, Ctrl+G for grep, ? for help." autocomplete="off" />
120
122
  </div>
121
123
  <ul id="filelist"></ul>
122
124
  <div id="sidebar-resizer" aria-hidden="true"></div>
@@ -201,6 +203,7 @@
201
203
  </div>
202
204
 
203
205
  <aside id="annotation-panel" hidden>
206
+ <div id="annotation-panel-resizer" aria-hidden="true"></div>
204
207
  <div class="annotation-panel-head">
205
208
  <strong>Code annotations</strong>
206
209
  <label class="annotation-follow-label" title="jump to new annotations as they arrive">
@@ -233,6 +236,7 @@
233
236
  <div id="annotation-detail" hidden>
234
237
  <div class="annotation-detail-head">
235
238
  <span id="annotation-detail-session"></span>
239
+ <span id="annotation-detail-time"></span>
236
240
  <span id="annotation-detail-step"></span>
237
241
  <button id="annotation-detail-prev" type="button" title="previous annotation">‹</button>
238
242
  <button id="annotation-detail-next" type="button" title="next annotation">›</button>
package/web/style.css CHANGED
@@ -52,6 +52,7 @@
52
52
  --sidebar-w: 308px;
53
53
  --history-w: 320px;
54
54
  --sidebar-restore-rail-w: 44px;
55
+ --annotation-panel-w: 380px;
55
56
  /* shadows */
56
57
  --shadow-sm: 0 1px 0 rgba(31,35,40,0.04);
57
58
  --shadow-md: 0 3px 6px rgba(140,149,159,0.15);
@@ -397,6 +398,7 @@ body[data-code-font-size="xlarge"] { --code-font-size: 15px; }
397
398
  }
398
399
 
399
400
  .global-actions {
401
+ position: relative;
400
402
  margin-left: auto;
401
403
  display: inline-flex;
402
404
  align-items: center;
@@ -425,6 +427,7 @@ body[data-code-font-size="xlarge"] { --code-font-size: 15px; }
425
427
  font-size: 13px;
426
428
  transition: background 0.12s, border-color 0.12s;
427
429
  }
430
+ .global-actions #theme svg,
428
431
  .global-icon-action svg {
429
432
  display: block;
430
433
  }
@@ -433,10 +436,55 @@ body[data-code-font-size="xlarge"] { --code-font-size: 15px; }
433
436
  background: var(--bg-mute);
434
437
  border-color: var(--border-strong);
435
438
  }
439
+ .global-actions #theme:focus-visible,
436
440
  .global-icon-action:focus-visible {
437
441
  outline: 2px solid var(--accent);
438
442
  outline-offset: 1px;
439
443
  }
444
+ .global-icon-action.copied {
445
+ color: var(--success);
446
+ border-color: var(--success);
447
+ }
448
+ .global-icon-action.failed {
449
+ color: var(--danger);
450
+ border-color: var(--danger);
451
+ }
452
+ .global-icon-action.warn {
453
+ color: var(--attn);
454
+ border-color: var(--attn);
455
+ }
456
+ .goi-feedback {
457
+ position: absolute;
458
+ top: 100%;
459
+ right: 0;
460
+ margin-top: 12px;
461
+ z-index: 70;
462
+ padding: 4px 10px;
463
+ border: 1px solid var(--border);
464
+ border-radius: 6px;
465
+ background: var(--bg);
466
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
467
+ font-size: 12px;
468
+ font-weight: 600;
469
+ white-space: nowrap;
470
+ pointer-events: none;
471
+ animation: gdp-banner-slide 0.15s ease;
472
+ }
473
+ .goi-feedback[hidden] {
474
+ display: none;
475
+ }
476
+ .goi-feedback.copied {
477
+ color: var(--success);
478
+ border-color: var(--success);
479
+ }
480
+ .goi-feedback.failed {
481
+ color: var(--danger);
482
+ border-color: var(--danger);
483
+ }
484
+ .goi-feedback.warn {
485
+ color: var(--attn);
486
+ border-color: var(--attn);
487
+ }
440
488
  #auto-update {
441
489
  width: auto;
442
490
  padding: 0 8px;
@@ -528,6 +576,10 @@ body[data-code-font-size="xlarge"] { --code-font-size: 15px; }
528
576
  cursor: pointer;
529
577
  transition: border-color 0.12s, background 0.12s, box-shadow 0.12s;
530
578
  }
579
+ .ref-selector[hidden],
580
+ #repo-target-wrap {
581
+ display: none !important;
582
+ }
531
583
  [data-theme="dark"] .ref-selector {
532
584
  border-color: var(--border);
533
585
  background: var(--bg-soft);
@@ -573,6 +625,14 @@ body[data-code-font-size="xlarge"] { --code-font-size: 15px; }
573
625
  border-color: transparent;
574
626
  box-shadow: none;
575
627
  }
628
+ body.gdp-repo-page #repo-target-wrap:not([hidden]),
629
+ body.gdp-file-detail-page.gdp-repo-blob-page #repo-target-wrap:not([hidden]) {
630
+ display: flex !important;
631
+ }
632
+ body.gdp-diff-page #repo-target-wrap:not([hidden]),
633
+ body.gdp-diff-page #repo-target-wrap {
634
+ display: none !important;
635
+ }
576
636
  .ref-dots {
577
637
  color: var(--fg-subtle);
578
638
  font-size: 14px;
@@ -2606,7 +2666,9 @@ table.d2h-diff-table td.d2h-code-side-linenumber {
2606
2666
  user-select: none;
2607
2667
  }
2608
2668
 
2609
- /* Floating "copy @path#start-end" pill shown while lines are selected. */
2669
+ /* Floating "copy @path#start-end" pill shown while lines are selected. Root
2670
+ is a plain div (see line-ref-pill.ts) hosting two buttons: the copy
2671
+ action fills the capsule, the close (×) button overlays its corner. */
2610
2672
  #line-ref-pill {
2611
2673
  position: fixed;
2612
2674
  left: 50%;
@@ -2626,12 +2688,45 @@ table.d2h-diff-table td.d2h-code-side-linenumber {
2626
2688
  font: inherit;
2627
2689
  font-size: 13px;
2628
2690
  font-weight: 600;
2629
- cursor: pointer;
2630
2691
  box-shadow: 0 8px 28px rgba(31, 35, 40, 0.35);
2631
2692
  }
2632
2693
  #line-ref-pill:hover {
2633
2694
  filter: brightness(1.1);
2634
2695
  }
2696
+ #line-ref-pill-copy {
2697
+ display: inline-flex;
2698
+ align-items: center;
2699
+ gap: 8px;
2700
+ min-width: 0;
2701
+ padding: 0;
2702
+ border: none;
2703
+ background: none;
2704
+ color: inherit;
2705
+ font: inherit;
2706
+ cursor: pointer;
2707
+ }
2708
+ #line-ref-pill-close {
2709
+ position: absolute;
2710
+ top: -6px;
2711
+ right: -6px;
2712
+ width: 16px;
2713
+ height: 16px;
2714
+ display: inline-flex;
2715
+ align-items: center;
2716
+ justify-content: center;
2717
+ padding: 0;
2718
+ border: 1px solid var(--accent);
2719
+ border-radius: 50%;
2720
+ background: var(--bg);
2721
+ color: var(--fg-muted);
2722
+ font-size: 11px;
2723
+ line-height: 1;
2724
+ cursor: pointer;
2725
+ }
2726
+ #line-ref-pill-close:hover {
2727
+ color: var(--fg);
2728
+ border-color: var(--border-strong);
2729
+ }
2635
2730
  #line-ref-pill svg {
2636
2731
  flex: 0 0 auto;
2637
2732
  }
@@ -2648,6 +2743,21 @@ table.d2h-diff-table td.d2h-code-side-linenumber {
2648
2743
  font-size: 12px;
2649
2744
  font-weight: 400;
2650
2745
  }
2746
+ /* Line count badge shown for multi-line selections. Flips to a solid
2747
+ warning chip (var(--attn)) once the selection is large enough that
2748
+ Shift+Click would paste a sizeable chunk of code into the AI prompt. */
2749
+ #line-ref-pill .lrp-count {
2750
+ flex: 0 0 auto;
2751
+ padding: 2px 6px;
2752
+ border-radius: 6px;
2753
+ background: rgba(255, 255, 255, 0.18);
2754
+ font-size: 11px;
2755
+ font-weight: 700;
2756
+ }
2757
+ #line-ref-pill .lrp-count-warn {
2758
+ background: #fff;
2759
+ color: var(--attn);
2760
+ }
2651
2761
  #line-ref-pill.copied {
2652
2762
  background: var(--success, #2ea043);
2653
2763
  border-color: var(--success, #2ea043);
@@ -2848,10 +2958,21 @@ table.d2h-diff-table td.d2h-code-side-linenumber {
2848
2958
  }
2849
2959
  .gdp-source-loading-content {
2850
2960
  display: flex;
2961
+ flex-wrap: wrap;
2851
2962
  align-items: center;
2852
2963
  gap: 10px;
2853
2964
  min-width: 0;
2854
2965
  }
2966
+ .gdp-source-loading-spinner {
2967
+ display: inline-block;
2968
+ width: 14px;
2969
+ height: 14px;
2970
+ border: 2px solid var(--border);
2971
+ border-top-color: var(--accent);
2972
+ border-radius: 50%;
2973
+ flex: 0 0 auto;
2974
+ animation: gdp-spin 0.8s linear infinite;
2975
+ }
2855
2976
  .gdp-source-loading-title {
2856
2977
  color: var(--fg);
2857
2978
  font-weight: 600;
@@ -2862,6 +2983,12 @@ table.d2h-diff-table td.d2h-code-side-linenumber {
2862
2983
  text-overflow: ellipsis;
2863
2984
  white-space: nowrap;
2864
2985
  }
2986
+ .gdp-source-loading-slow-note {
2987
+ flex-basis: 100%;
2988
+ color: var(--fg-subtle);
2989
+ font-size: 12px;
2990
+ font-style: italic;
2991
+ }
2865
2992
  .gdp-source-cancel {
2866
2993
  margin-left: auto;
2867
2994
  }
@@ -4794,7 +4921,7 @@ body.gdp-file-detail-page #empty {
4794
4921
  right: 0;
4795
4922
  top: var(--chrome-h);
4796
4923
  bottom: 0;
4797
- width: min(380px, calc(100vw - 32px));
4924
+ width: min(var(--annotation-panel-w), calc(100vw - 32px));
4798
4925
  z-index: 45;
4799
4926
  display: flex;
4800
4927
  flex-direction: column;
@@ -4802,6 +4929,24 @@ body.gdp-file-detail-page #empty {
4802
4929
  background: var(--bg);
4803
4930
  box-shadow: var(--shadow-md);
4804
4931
  }
4932
+ #annotation-panel-resizer {
4933
+ position: absolute;
4934
+ left: -4px;
4935
+ top: 0;
4936
+ bottom: 0;
4937
+ width: 8px;
4938
+ cursor: col-resize;
4939
+ touch-action: none;
4940
+ z-index: 1;
4941
+ }
4942
+ #annotation-panel-resizer:hover,
4943
+ body.gdp-annotation-resizing #annotation-panel-resizer {
4944
+ background: var(--accent-muted);
4945
+ }
4946
+ body.gdp-annotation-resizing {
4947
+ cursor: col-resize !important;
4948
+ user-select: none;
4949
+ }
4805
4950
  #annotation-panel[hidden],
4806
4951
  #annotation-detail[hidden] {
4807
4952
  display: none;
@@ -4815,7 +4960,7 @@ body.gdp-database-page #annotation-panel {
4815
4960
  }
4816
4961
  /* Keep code readable next to the panel instead of underneath it. */
4817
4962
  body.annotation-panel-open #content {
4818
- margin-right: min(380px, calc(100vw - 32px));
4963
+ margin-right: min(var(--annotation-panel-w), calc(100vw - 32px));
4819
4964
  }
4820
4965
 
4821
4966
  /* ---- Query History right-panel ---- */
@@ -5419,7 +5564,9 @@ html[data-theme="dark"] .db-session-log-sql span[style] {
5419
5564
  flex: 1;
5420
5565
  display: grid;
5421
5566
  grid-template-columns: 18px minmax(0, 1fr);
5567
+ grid-template-rows: auto auto auto;
5422
5568
  column-gap: 4px;
5569
+ row-gap: 1px;
5423
5570
  text-align: left;
5424
5571
  border: 0;
5425
5572
  background: none;
@@ -5430,7 +5577,7 @@ html[data-theme="dark"] .db-session-log-sql span[style] {
5430
5577
  }
5431
5578
  .annotation-entry-open::before {
5432
5579
  content: counter(annotation-step);
5433
- grid-row: 1 / span 2;
5580
+ grid-row: 1 / span 3;
5434
5581
  color: var(--fg-subtle);
5435
5582
  font-size: 11px;
5436
5583
  line-height: 1.6;
@@ -5458,6 +5605,13 @@ html[data-theme="dark"] .db-session-log-sql span[style] {
5458
5605
  text-overflow: ellipsis;
5459
5606
  white-space: nowrap;
5460
5607
  }
5608
+ .annotation-entry-time {
5609
+ grid-column: 2;
5610
+ display: block;
5611
+ font-size: 10px;
5612
+ color: var(--fg-subtle);
5613
+ white-space: nowrap;
5614
+ }
5461
5615
  /* Per-row actions stay quiet until the row (or the panel item) is hovered,
5462
5616
  so the list reads as content, not as a wall of trash cans. */
5463
5617
  .annotation-session-head .annotation-icon-btn,
@@ -5517,6 +5671,12 @@ html[data-theme="dark"] .db-session-log-sql span[style] {
5517
5671
  font-size: 11px;
5518
5672
  color: var(--fg-subtle);
5519
5673
  }
5674
+ #annotation-detail-time {
5675
+ flex: none;
5676
+ font-size: 11px;
5677
+ color: var(--fg-subtle);
5678
+ white-space: nowrap;
5679
+ }
5520
5680
  #annotation-detail-prev,
5521
5681
  #annotation-detail-next,
5522
5682
  #annotation-detail-close {