@sean.holung/minicode 0.3.2 → 0.3.3

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.
Files changed (107) hide show
  1. package/README.md +48 -43
  2. package/dist/scripts/run-benchmarks.js +147 -0
  3. package/dist/src/agent/config.js +149 -40
  4. package/dist/src/agent/editable-config.js +314 -0
  5. package/dist/src/analysis/structural-analysis.js +379 -0
  6. package/dist/src/benchmark/evaluator.js +79 -0
  7. package/dist/src/benchmark/index.js +4 -0
  8. package/dist/src/benchmark/reporter.js +177 -0
  9. package/dist/src/benchmark/runner.js +100 -0
  10. package/dist/src/benchmark/task-loader.js +78 -0
  11. package/dist/src/benchmark/types.js +5 -0
  12. package/dist/src/cli/args.js +10 -0
  13. package/dist/src/cli/config-slash-command.js +135 -0
  14. package/dist/src/cli/plugin-install.js +69 -0
  15. package/dist/src/index.js +76 -6
  16. package/dist/src/indexer/cache.js +6 -4
  17. package/dist/src/indexer/code-map.js +41 -13
  18. package/dist/src/indexer/plugins/typescript.js +70 -23
  19. package/dist/src/indexer/project-index.js +175 -36
  20. package/dist/src/indexer/symbol-names.js +92 -0
  21. package/dist/src/model-utils.js +18 -0
  22. package/dist/src/serve/agent-bridge.js +203 -24
  23. package/dist/src/serve/mcp-server.js +405 -0
  24. package/dist/src/serve/server.js +165 -10
  25. package/dist/src/serve/websocket.js +8 -0
  26. package/dist/src/shared/graph-styles.js +119 -0
  27. package/dist/src/tools/find-path.js +75 -0
  28. package/dist/src/tools/find-references.js +7 -2
  29. package/dist/src/tools/get-dependencies.js +3 -2
  30. package/dist/src/tools/read-symbol.js +12 -5
  31. package/dist/src/tools/registry.js +3 -1
  32. package/dist/src/tools/search-code-map.js +4 -2
  33. package/dist/src/ui/app.js +1 -1
  34. package/dist/src/ui/cli-ink.js +79 -4
  35. package/dist/src/ui/components/header-bar.js +6 -2
  36. package/dist/src/ui/state/ui-store.js +5 -0
  37. package/dist/src/web/app.js +1124 -176
  38. package/dist/src/web/index.html +113 -3
  39. package/dist/src/web/style.css +973 -55
  40. package/dist/tests/agent.test.js +31 -0
  41. package/dist/tests/analysis-helpers.test.js +89 -0
  42. package/dist/tests/analysis-ui.test.js +29 -0
  43. package/dist/tests/benchmark-harness.test.js +527 -0
  44. package/dist/tests/config-api.test.js +143 -0
  45. package/dist/tests/config-integration.test.js +751 -0
  46. package/dist/tests/config-slash-command.test.js +106 -0
  47. package/dist/tests/config.test.js +42 -1
  48. package/dist/tests/context-indicator.test.js +220 -0
  49. package/dist/tests/editable-config.test.js +109 -0
  50. package/dist/tests/find-path.test.js +183 -0
  51. package/dist/tests/focus-tracker.test.js +62 -0
  52. package/dist/tests/graph-onboarding.test.js +55 -0
  53. package/dist/tests/graph-styles.test.js +65 -0
  54. package/dist/tests/indexer.test.js +137 -0
  55. package/dist/tests/mcp-and-plugin.test.js +186 -0
  56. package/dist/tests/model-client-openai.test.js +29 -0
  57. package/dist/tests/model-selection.test.js +136 -0
  58. package/dist/tests/model-utils.test.js +22 -0
  59. package/dist/tests/reasoning-effort.test.js +264 -0
  60. package/dist/tests/run-benchmarks.test.js +161 -0
  61. package/dist/tests/search-code-map.test.js +18 -0
  62. package/dist/tests/serve.integration.test.js +218 -2
  63. package/dist/tests/session-ui.test.js +21 -0
  64. package/dist/tests/session.test.js +50 -0
  65. package/dist/tests/settings-ui.test.js +30 -0
  66. package/dist/tests/structural-analysis.test.js +218 -0
  67. package/node_modules/@minicode/agent-sdk/README.md +80 -51
  68. package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.d.ts +16 -5
  69. package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.d.ts.map +1 -1
  70. package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.js +51 -33
  71. package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.js.map +1 -1
  72. package/node_modules/@minicode/agent-sdk/dist/src/agent/types.d.ts +14 -0
  73. package/node_modules/@minicode/agent-sdk/dist/src/agent/types.d.ts.map +1 -1
  74. package/node_modules/@minicode/agent-sdk/dist/src/index.d.ts +3 -2
  75. package/node_modules/@minicode/agent-sdk/dist/src/index.d.ts.map +1 -1
  76. package/node_modules/@minicode/agent-sdk/dist/src/index.js +2 -0
  77. package/node_modules/@minicode/agent-sdk/dist/src/index.js.map +1 -1
  78. package/node_modules/@minicode/agent-sdk/dist/src/indexer/focus-tracker.d.ts +35 -0
  79. package/node_modules/@minicode/agent-sdk/dist/src/indexer/focus-tracker.d.ts.map +1 -0
  80. package/node_modules/@minicode/agent-sdk/dist/src/indexer/focus-tracker.js +64 -0
  81. package/node_modules/@minicode/agent-sdk/dist/src/indexer/focus-tracker.js.map +1 -0
  82. package/node_modules/@minicode/agent-sdk/dist/src/indexer/types.d.ts +7 -0
  83. package/node_modules/@minicode/agent-sdk/dist/src/indexer/types.d.ts.map +1 -1
  84. package/node_modules/@minicode/agent-sdk/dist/src/model/client.d.ts +5 -1
  85. package/node_modules/@minicode/agent-sdk/dist/src/model/client.d.ts.map +1 -1
  86. package/node_modules/@minicode/agent-sdk/dist/src/model/client.js +83 -11
  87. package/node_modules/@minicode/agent-sdk/dist/src/model/client.js.map +1 -1
  88. package/node_modules/@minicode/agent-sdk/dist/src/safety/guardrails.d.ts +1 -0
  89. package/node_modules/@minicode/agent-sdk/dist/src/safety/guardrails.d.ts.map +1 -1
  90. package/node_modules/@minicode/agent-sdk/dist/src/safety/guardrails.js +8 -1
  91. package/node_modules/@minicode/agent-sdk/dist/src/safety/guardrails.js.map +1 -1
  92. package/node_modules/@minicode/agent-sdk/dist/src/session/session.d.ts.map +1 -1
  93. package/node_modules/@minicode/agent-sdk/dist/src/session/session.js +4 -1
  94. package/node_modules/@minicode/agent-sdk/dist/src/session/session.js.map +1 -1
  95. package/node_modules/@minicode/agent-sdk/dist/tests/agent.test.js +3 -1
  96. package/node_modules/@minicode/agent-sdk/dist/tests/agent.test.js.map +1 -1
  97. package/node_modules/@minicode/agent-sdk/dist/tests/guardrails.test.js +8 -2
  98. package/node_modules/@minicode/agent-sdk/dist/tests/guardrails.test.js.map +1 -1
  99. package/node_modules/@minicode/agent-sdk/dist/tsconfig.tsbuildinfo +1 -1
  100. package/package.json +9 -5
  101. package/plugin/.claude-plugin/plugin.json +12 -0
  102. package/plugin/.mcp.json +8 -0
  103. package/plugin/CLAUDE.md +26 -0
  104. package/plugin/skills/analyze/SKILL.md +12 -0
  105. package/plugin/skills/focus/SKILL.md +20 -0
  106. package/plugin/skills/graph/SKILL.md +13 -0
  107. package/plugin/skills/symbols/SKILL.md +13 -0
@@ -29,6 +29,10 @@ html, body {
29
29
  line-height: 1.6;
30
30
  }
31
31
 
32
+ body.modal-open {
33
+ overflow: hidden;
34
+ }
35
+
32
36
  #app {
33
37
  display: flex;
34
38
  flex-direction: column;
@@ -68,6 +72,53 @@ h1 {
68
72
  color: var(--text-dim);
69
73
  }
70
74
 
75
+ #model-info.placeholder {
76
+ color: var(--text-dim);
77
+ opacity: 0.5;
78
+ font-style: italic;
79
+ }
80
+
81
+ /* Model menu */
82
+ .model-menu {
83
+ position: relative;
84
+ }
85
+
86
+ #model-btn {
87
+ display: flex;
88
+ align-items: center;
89
+ gap: 4px;
90
+ }
91
+
92
+ #model-dropdown {
93
+ max-height: 320px;
94
+ }
95
+
96
+ #model-list {
97
+ max-height: 280px;
98
+ overflow-y: auto;
99
+ }
100
+
101
+ .model-item {
102
+ padding: 6px 8px;
103
+ border-radius: 4px;
104
+ cursor: pointer;
105
+ font-size: 12px;
106
+ transition: background 0.15s;
107
+ color: var(--text);
108
+ overflow: hidden;
109
+ text-overflow: ellipsis;
110
+ white-space: nowrap;
111
+ }
112
+
113
+ .model-item:hover {
114
+ background: var(--bg-hover);
115
+ }
116
+
117
+ .model-item.active {
118
+ color: var(--accent);
119
+ font-weight: 600;
120
+ }
121
+
71
122
  /* Session menu */
72
123
  .session-menu {
73
124
  position: relative;
@@ -107,6 +158,11 @@ h1 {
107
158
  padding: 8px;
108
159
  }
109
160
 
161
+ .session-update-row {
162
+ display: flex;
163
+ margin-bottom: 8px;
164
+ }
165
+
110
166
  .dropdown-divider {
111
167
  height: 1px;
112
168
  background: var(--border);
@@ -172,6 +228,11 @@ h1 {
172
228
  background: var(--bg-hover);
173
229
  }
174
230
 
231
+ .session-item.active {
232
+ background: rgba(122, 162, 247, 0.12);
233
+ outline: 1px solid rgba(122, 162, 247, 0.35);
234
+ }
235
+
175
236
  .session-label {
176
237
  color: var(--text);
177
238
  overflow: hidden;
@@ -186,6 +247,10 @@ h1 {
186
247
  margin-left: 8px;
187
248
  }
188
249
 
250
+ .session-active-badge {
251
+ color: var(--accent);
252
+ }
253
+
189
254
  .badge {
190
255
  font-size: 11px;
191
256
  padding: 2px 8px;
@@ -203,6 +268,45 @@ h1 {
203
268
  color: var(--yellow);
204
269
  }
205
270
 
271
+ /* Context indicator */
272
+ #context-indicator {
273
+ display: flex;
274
+ align-items: center;
275
+ gap: 6px;
276
+ margin-left: 12px;
277
+ }
278
+
279
+ #context-bar {
280
+ width: 80px;
281
+ height: 8px;
282
+ background: var(--bg-surface);
283
+ border-radius: 4px;
284
+ overflow: hidden;
285
+ border: 1px solid var(--border);
286
+ }
287
+
288
+ #context-fill {
289
+ height: 100%;
290
+ width: 0%;
291
+ background: var(--accent);
292
+ border-radius: 4px;
293
+ transition: width 0.3s ease, background-color 0.3s ease;
294
+ }
295
+
296
+ #context-fill.warn {
297
+ background: var(--yellow);
298
+ }
299
+
300
+ #context-fill.critical {
301
+ background: var(--red);
302
+ }
303
+
304
+ #context-label {
305
+ font-size: 11px;
306
+ color: var(--text-dim);
307
+ min-width: 28px;
308
+ }
309
+
206
310
  .badge.error {
207
311
  background: rgba(247, 118, 142, 0.15);
208
312
  color: var(--red);
@@ -222,6 +326,92 @@ h1 {
222
326
  flex-direction: column;
223
327
  width: 33%;
224
328
  min-width: 280px;
329
+ position: relative;
330
+ }
331
+
332
+ /* Config overlay — shown when model provider is not configured */
333
+ .config-overlay {
334
+ position: absolute;
335
+ inset: 0;
336
+ z-index: 50;
337
+ display: flex;
338
+ align-items: center;
339
+ justify-content: center;
340
+ background: rgba(26, 27, 38, 0.92);
341
+ backdrop-filter: blur(4px);
342
+ padding: 24px;
343
+ overflow-y: auto;
344
+ }
345
+
346
+ .config-overlay.hidden { display: none; }
347
+
348
+ .config-overlay-content {
349
+ max-width: 520px;
350
+ width: 100%;
351
+ }
352
+
353
+ .config-overlay-content h2 {
354
+ color: var(--yellow);
355
+ font-size: 16px;
356
+ margin-bottom: 8px;
357
+ }
358
+
359
+ .config-overlay-content > p {
360
+ color: var(--text-dim);
361
+ font-size: 13px;
362
+ margin-bottom: 16px;
363
+ }
364
+
365
+ .config-missing {
366
+ color: var(--red, #f7768e);
367
+ font-size: 13px;
368
+ padding: 8px 12px;
369
+ background: rgba(247, 118, 142, 0.1);
370
+ border-radius: 4px;
371
+ margin-bottom: 12px;
372
+ }
373
+
374
+ .config-overlay-options {
375
+ display: flex;
376
+ flex-direction: column;
377
+ gap: 16px;
378
+ }
379
+
380
+ .config-overlay-option {
381
+ background: var(--bg-surface);
382
+ border: 1px solid var(--border);
383
+ border-radius: 6px;
384
+ padding: 12px 14px;
385
+ }
386
+
387
+ .config-overlay-option strong {
388
+ display: block;
389
+ color: var(--text);
390
+ font-size: 13px;
391
+ margin-bottom: 4px;
392
+ }
393
+
394
+ .config-overlay-option p {
395
+ color: var(--text-dim);
396
+ font-size: 12px;
397
+ margin-bottom: 8px;
398
+ }
399
+
400
+ .config-overlay-option pre {
401
+ background: var(--bg);
402
+ border: 1px solid var(--border);
403
+ border-radius: 4px;
404
+ padding: 8px 10px;
405
+ font-size: 12px;
406
+ color: var(--green);
407
+ white-space: pre-wrap;
408
+ word-break: break-all;
409
+ }
410
+
411
+ .config-overlay-footer {
412
+ margin-top: 16px;
413
+ color: var(--text-dim);
414
+ font-size: 12px;
225
415
  }
226
416
 
227
417
  /* Pane divider (draggable) */
@@ -553,96 +743,737 @@ footer {
553
743
  display: none !important;
554
744
  }
555
745
 
556
- /* Scrollbar */
557
- main::-webkit-scrollbar {
558
- width: 6px;
746
+ /* Settings modal */
747
+ .modal {
748
+ position: fixed;
749
+ inset: 0;
750
+ z-index: 500;
559
751
  }
560
752
 
561
- main::-webkit-scrollbar-track {
562
- background: transparent;
753
+ .modal-backdrop {
754
+ position: absolute;
755
+ inset: 0;
756
+ background: rgba(10, 10, 18, 0.72);
757
+ backdrop-filter: blur(4px);
563
758
  }
564
759
 
565
- main::-webkit-scrollbar-thumb {
566
- background: var(--border);
567
- border-radius: 3px;
760
+ .modal-panel {
761
+ position: absolute;
762
+ top: 50%;
763
+ left: 50%;
764
+ width: min(960px, calc(100vw - 32px));
765
+ max-height: calc(100vh - 48px);
766
+ transform: translate(-50%, -50%);
767
+ display: flex;
768
+ flex-direction: column;
769
+ background: var(--bg-surface);
770
+ border: 1px solid var(--border);
771
+ border-radius: 12px;
772
+ box-shadow: 0 24px 64px rgba(0, 0, 0, 0.45);
773
+ overflow: hidden;
568
774
  }
569
775
 
570
- /* ── Graph pane ── */
776
+ .modal-header,
777
+ .modal-footer,
778
+ .settings-toolbar {
779
+ padding: 18px 20px;
780
+ }
571
781
 
572
- #graph-toolbar {
782
+ .modal-header {
573
783
  display: flex;
574
- align-items: center;
575
- gap: 10px;
576
- padding: 8px 16px;
784
+ align-items: flex-start;
785
+ justify-content: space-between;
786
+ gap: 16px;
577
787
  border-bottom: 1px solid var(--border);
578
- flex-shrink: 0;
579
- flex-wrap: wrap;
580
788
  }
581
789
 
582
- #graph-search {
583
- background: var(--bg-surface);
790
+ .modal-header h2 {
791
+ font-size: 16px;
792
+ color: var(--text);
793
+ margin-bottom: 4px;
794
+ }
795
+
796
+ .modal-subtitle {
797
+ font-size: 12px;
798
+ color: var(--text-dim);
799
+ }
800
+
801
+ .settings-toolbar {
802
+ display: flex;
803
+ align-items: flex-end;
804
+ justify-content: space-between;
805
+ gap: 16px;
806
+ border-bottom: 1px solid var(--border);
807
+ background: rgba(26, 27, 38, 0.55);
808
+ }
809
+
810
+ .settings-scope-picker {
811
+ display: flex;
812
+ flex-direction: column;
813
+ gap: 6px;
814
+ font-size: 12px;
815
+ color: var(--text-dim);
816
+ }
817
+
818
+ .settings-scope-picker select,
819
+ .settings-control,
820
+ .settings-select {
821
+ background: var(--bg);
584
822
  border: 1px solid var(--border);
585
- border-radius: 4px;
823
+ border-radius: 6px;
586
824
  color: var(--text);
587
825
  font-family: var(--font-mono);
588
826
  font-size: 12px;
589
- padding: 5px 10px;
590
- width: 200px;
591
827
  }
592
828
 
593
- #graph-search:focus {
829
+ .settings-scope-picker select,
830
+ .settings-select {
831
+ padding: 8px 10px;
832
+ }
833
+
834
+ .settings-control {
835
+ width: 100%;
836
+ padding: 9px 11px;
837
+ }
838
+
839
+ .settings-control:disabled,
840
+ .settings-select:disabled {
841
+ cursor: not-allowed;
842
+ opacity: 0.65;
843
+ background: rgba(17, 19, 29, 0.9);
844
+ }
845
+
846
+ .settings-scope-picker select:focus,
847
+ .settings-control:focus,
848
+ .settings-select:focus {
594
849
  outline: none;
595
850
  border-color: var(--accent);
596
851
  }
597
852
 
598
- /* Search dropdown */
599
- .search-dropdown {
600
- position: absolute;
601
- top: 100%;
602
- left: 0;
603
- width: 300px;
604
- max-height: 320px;
605
- overflow-y: auto;
606
- background: var(--bg-surface);
607
- border: 1px solid var(--border);
608
- border-radius: 6px;
609
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
610
- z-index: 200;
611
- margin-top: 4px;
853
+ .settings-path-group {
854
+ display: flex;
855
+ flex-direction: column;
856
+ align-items: flex-end;
857
+ gap: 6px;
858
+ min-width: 0;
612
859
  }
613
860
 
614
- .search-result {
615
- display: flex;
616
- align-items: center;
617
- justify-content: space-between;
618
- padding: 6px 10px;
619
- cursor: pointer;
620
- font-size: 12px;
621
- transition: background 0.1s;
861
+ .settings-path-label {
862
+ font-size: 11px;
863
+ color: var(--text-dim);
864
+ text-transform: uppercase;
865
+ letter-spacing: 0.08em;
622
866
  }
623
867
 
624
- .search-result:hover {
625
- background: var(--bg-hover);
868
+ .settings-path {
869
+ max-width: min(100%, 500px);
870
+ overflow-x: auto;
871
+ white-space: nowrap;
872
+ color: var(--accent);
873
+ background: rgba(122, 162, 247, 0.08);
874
+ border: 1px solid rgba(122, 162, 247, 0.18);
875
+ border-radius: 999px;
876
+ padding: 4px 10px;
626
877
  }
627
878
 
628
- .search-result-name {
879
+ .settings-banner {
880
+ margin: 14px 20px 0;
881
+ padding: 10px 12px;
882
+ border-radius: 8px;
883
+ font-size: 12px;
884
+ border: 1px solid transparent;
885
+ }
886
+
887
+ .settings-banner.info {
888
+ background: rgba(122, 162, 247, 0.12);
889
+ border-color: rgba(122, 162, 247, 0.24);
629
890
  color: var(--text);
630
- font-weight: 500;
631
891
  }
632
892
 
633
- .search-result-kind {
634
- font-size: 11px;
635
- opacity: 0.7;
893
+ .settings-banner.success {
894
+ background: rgba(158, 206, 106, 0.12);
895
+ border-color: rgba(158, 206, 106, 0.26);
896
+ color: var(--green);
636
897
  }
637
898
 
638
- #cy {
899
+ .settings-banner.error {
900
+ background: rgba(247, 118, 142, 0.12);
901
+ border-color: rgba(247, 118, 142, 0.26);
902
+ color: var(--red);
903
+ }
904
+
905
+ .settings-list {
639
906
  flex: 1;
640
907
  min-height: 0;
641
- background: var(--bg);
908
+ overflow-y: auto;
909
+ padding: 18px 20px 20px;
910
+ display: flex;
911
+ flex-direction: column;
912
+ gap: 14px;
642
913
  }
643
914
 
644
- .graph-empty {
645
- display: flex;
915
+ .settings-item {
916
+ background: rgba(26, 27, 38, 0.72);
917
+ border: 1px solid var(--border);
918
+ border-radius: 10px;
919
+ padding: 16px;
920
+ }
921
+
922
+ .settings-item.is-disabled {
923
+ border-color: rgba(122, 162, 247, 0.24);
924
+ background: rgba(26, 27, 38, 0.6);
925
+ }
926
+
927
+ .settings-item-header {
928
+ display: flex;
929
+ align-items: flex-start;
930
+ justify-content: space-between;
931
+ gap: 16px;
932
+ margin-bottom: 8px;
933
+ }
934
+
935
+ .settings-item-title {
936
+ font-size: 13px;
937
+ font-weight: 600;
938
+ color: var(--text);
939
+ margin-bottom: 4px;
940
+ }
941
+
942
+ .settings-item-description {
943
+ font-size: 12px;
944
+ color: var(--text-dim);
945
+ }
946
+
947
+ .settings-item-badges {
948
+ display: flex;
949
+ flex-wrap: wrap;
950
+ justify-content: flex-end;
951
+ gap: 6px;
952
+ }
953
+
954
+ .settings-badge {
955
+ display: inline-flex;
956
+ align-items: center;
957
+ padding: 2px 8px;
958
+ border-radius: 999px;
959
+ font-size: 11px;
960
+ border: 1px solid transparent;
961
+ white-space: nowrap;
962
+ }
963
+
964
+ .settings-badge.env {
965
+ color: var(--accent);
966
+ background: rgba(122, 162, 247, 0.12);
967
+ border-color: rgba(122, 162, 247, 0.24);
968
+ }
969
+
970
+ .settings-badge.override {
971
+ color: var(--yellow);
972
+ background: rgba(224, 175, 104, 0.14);
973
+ border-color: rgba(224, 175, 104, 0.24);
974
+ }
975
+
976
+ .settings-item-meta {
977
+ display: grid;
978
+ grid-template-columns: repeat(3, minmax(0, 1fr));
979
+ gap: 10px;
980
+ margin-bottom: 12px;
981
+ }
982
+
983
+ .settings-meta-block {
984
+ background: var(--bg);
985
+ border: 1px solid rgba(51, 53, 74, 0.8);
986
+ border-radius: 8px;
987
+ padding: 10px;
988
+ min-width: 0;
989
+ }
990
+
991
+ .settings-meta-label {
992
+ display: block;
993
+ font-size: 10px;
994
+ color: var(--text-dim);
995
+ text-transform: uppercase;
996
+ letter-spacing: 0.08em;
997
+ margin-bottom: 4px;
998
+ }
999
+
1000
+ .settings-meta-value {
1001
+ font-size: 12px;
1002
+ color: var(--text);
1003
+ overflow-wrap: anywhere;
1004
+ }
1005
+
1006
+ .settings-item-controls {
1007
+ display: flex;
1008
+ flex-direction: column;
1009
+ gap: 8px;
1010
+ }
1011
+
1012
+ .settings-help {
1013
+ font-size: 11px;
1014
+ color: var(--text-dim);
1015
+ }
1016
+
1017
+ .settings-help-warning {
1018
+ color: var(--red);
1019
+ font-weight: 600;
1020
+ }
1021
+
1022
+ .modal-footer {
1023
+ display: flex;
1024
+ align-items: center;
1025
+ justify-content: space-between;
1026
+ gap: 16px;
1027
+ border-top: 1px solid var(--border);
1028
+ }
1029
+
1030
+ .settings-footnote {
1031
+ font-size: 12px;
1032
+ color: var(--text-dim);
1033
+ max-width: 560px;
1034
+ }
1035
+
1036
+ .settings-actions {
1037
+ display: flex;
1038
+ align-items: center;
1039
+ gap: 8px;
1040
+ flex-shrink: 0;
1041
+ }
1042
+
1043
+ .settings-list::-webkit-scrollbar,
1044
+ .settings-path::-webkit-scrollbar {
1045
+ width: 6px;
1046
+ height: 6px;
1047
+ }
1048
+
1049
+ .settings-list::-webkit-scrollbar-track,
1050
+ .settings-path::-webkit-scrollbar-track {
1051
+ background: transparent;
1052
+ }
1053
+
1054
+ .settings-list::-webkit-scrollbar-thumb,
1055
+ .settings-path::-webkit-scrollbar-thumb {
1056
+ background: var(--border);
1057
+ border-radius: 999px;
1058
+ }
1059
+
1060
+ /* Scrollbar */
1061
+ main::-webkit-scrollbar {
1062
+ width: 6px;
1063
+ }
1064
+
1065
+ main::-webkit-scrollbar-track {
1066
+ background: transparent;
1067
+ }
1068
+
1069
+ main::-webkit-scrollbar-thumb {
1070
+ background: var(--border);
1071
+ border-radius: 3px;
1072
+ }
1073
+
1074
+ /* ── Graph pane ── */
1075
+
1076
+ #graph-toolbar {
1077
+ display: flex;
1078
+ align-items: center;
1079
+ gap: 10px;
1080
+ padding: 8px 16px;
1081
+ border-bottom: 1px solid var(--border);
1082
+ flex-shrink: 0;
1083
+ flex-wrap: wrap;
1084
+ }
1085
+
1086
+ #graph-stage {
1087
+ position: relative;
1088
+ flex: 1;
1089
+ min-height: 0;
1090
+ background: var(--bg);
1091
+ }
1092
+
1093
+ #graph-search {
1094
+ background: var(--bg-surface);
1095
+ border: 1px solid var(--border);
1096
+ border-radius: 4px;
1097
+ color: var(--text);
1098
+ font-family: var(--font-mono);
1099
+ font-size: 12px;
1100
+ padding: 5px 10px;
1101
+ width: 200px;
1102
+ }
1103
+
1104
+ #graph-search:focus {
1105
+ outline: none;
1106
+ border-color: var(--accent);
1107
+ }
1108
+
1109
+ /* Search dropdown */
1110
+ .search-dropdown {
1111
+ position: absolute;
1112
+ top: 100%;
1113
+ left: 0;
1114
+ width: 300px;
1115
+ max-height: 320px;
1116
+ overflow-y: auto;
1117
+ background: var(--bg-surface);
1118
+ border: 1px solid var(--border);
1119
+ border-radius: 6px;
1120
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
1121
+ z-index: 200;
1122
+ margin-top: 4px;
1123
+ }
1124
+
1125
+ .search-result {
1126
+ display: flex;
1127
+ align-items: center;
1128
+ justify-content: space-between;
1129
+ padding: 6px 10px;
1130
+ cursor: pointer;
1131
+ font-size: 12px;
1132
+ transition: background 0.1s;
1133
+ }
1134
+
1135
+ .search-result:hover {
1136
+ background: var(--bg-hover);
1137
+ }
1138
+
1139
+ .search-result-name {
1140
+ color: var(--text);
1141
+ font-weight: 500;
1142
+ }
1143
+
1144
+ .search-result-kind {
1145
+ font-size: 11px;
1146
+ opacity: 0.7;
1147
+ }
1148
+
1149
+ #cy {
1150
+ width: 100%;
1151
+ height: 100%;
1152
+ background: var(--bg);
1153
+ position: relative;
1154
+ }
1155
+
1156
+ #analysis-panel {
1157
+ position: absolute;
1158
+ top: 16px;
1159
+ left: 16px;
1160
+ bottom: 16px;
1161
+ width: min(380px, calc(100% - 32px));
1162
+ background: rgba(17, 19, 29, 0.96);
1163
+ border: 1px solid rgba(122, 162, 247, 0.22);
1164
+ border-radius: 16px;
1165
+ box-shadow: 0 24px 60px rgba(0, 0, 0, 0.4);
1166
+ backdrop-filter: blur(16px);
1167
+ z-index: 40;
1168
+ display: flex;
1169
+ flex-direction: column;
1170
+ overflow: hidden;
1171
+ }
1172
+
1173
+ .analysis-panel-header {
1174
+ padding: 18px 18px 14px;
1175
+ border-bottom: 1px solid rgba(122, 162, 247, 0.14);
1176
+ display: flex;
1177
+ align-items: flex-start;
1178
+ justify-content: space-between;
1179
+ gap: 16px;
1180
+ }
1181
+
1182
+ .analysis-kicker {
1183
+ font-size: 11px;
1184
+ text-transform: uppercase;
1185
+ letter-spacing: 0.08em;
1186
+ color: var(--accent);
1187
+ margin-bottom: 6px;
1188
+ }
1189
+
1190
+ .analysis-title-row {
1191
+ display: flex;
1192
+ align-items: center;
1193
+ gap: 10px;
1194
+ flex-wrap: wrap;
1195
+ }
1196
+
1197
+ .analysis-title-row h2 {
1198
+ margin: 0;
1199
+ font-size: 17px;
1200
+ color: var(--text);
1201
+ }
1202
+
1203
+ .analysis-pill {
1204
+ border: 1px solid rgba(122, 162, 247, 0.3);
1205
+ border-radius: 999px;
1206
+ padding: 3px 8px;
1207
+ font-size: 11px;
1208
+ color: var(--text-dim);
1209
+ }
1210
+
1211
+ .analysis-subtitle {
1212
+ margin: 10px 0 0;
1213
+ font-size: 12px;
1214
+ line-height: 1.5;
1215
+ color: var(--text-dim);
1216
+ max-width: 48ch;
1217
+ }
1218
+
1219
+ .analysis-panel-actions {
1220
+ display: flex;
1221
+ align-items: center;
1222
+ gap: 8px;
1223
+ flex-shrink: 0;
1224
+ }
1225
+
1226
+ .analysis-status {
1227
+ margin: 12px 18px 0;
1228
+ padding: 10px 12px;
1229
+ border-radius: 10px;
1230
+ border: 1px solid rgba(122, 162, 247, 0.18);
1231
+ background: rgba(122, 162, 247, 0.08);
1232
+ color: var(--text-dim);
1233
+ font-size: 12px;
1234
+ }
1235
+
1236
+ .analysis-status.error {
1237
+ border-color: rgba(247, 118, 142, 0.28);
1238
+ background: rgba(247, 118, 142, 0.1);
1239
+ color: #f4b1ba;
1240
+ }
1241
+
1242
+ .analysis-summary {
1243
+ padding: 14px 18px 10px;
1244
+ display: grid;
1245
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1246
+ gap: 10px;
1247
+ }
1248
+
1249
+ .analysis-summary-card {
1250
+ appearance: none;
1251
+ width: 100%;
1252
+ text-align: left;
1253
+ border: 1px solid rgba(122, 162, 247, 0.14);
1254
+ border-radius: 12px;
1255
+ background: rgba(31, 35, 53, 0.72);
1256
+ padding: 12px;
1257
+ cursor: pointer;
1258
+ transition: border-color 0.15s ease, transform 0.15s ease, background 0.15s ease;
1259
+ }
1260
+
1261
+ .analysis-summary-card:hover {
1262
+ border-color: rgba(122, 162, 247, 0.3);
1263
+ background: rgba(36, 40, 60, 0.82);
1264
+ transform: translateY(-1px);
1265
+ }
1266
+
1267
+ .analysis-summary-card.active {
1268
+ border-color: rgba(122, 162, 247, 0.38);
1269
+ background: rgba(34, 41, 67, 0.92);
1270
+ box-shadow: 0 0 0 1px rgba(122, 162, 247, 0.16);
1271
+ }
1272
+
1273
+ .analysis-summary-value {
1274
+ display: block;
1275
+ font-size: 17px;
1276
+ font-weight: 600;
1277
+ color: var(--text);
1278
+ }
1279
+
1280
+ .analysis-summary-label {
1281
+ display: block;
1282
+ margin-top: 4px;
1283
+ font-size: 11px;
1284
+ color: var(--text-dim);
1285
+ text-transform: uppercase;
1286
+ letter-spacing: 0.05em;
1287
+ }
1288
+
1289
+ .analysis-findings {
1290
+ flex: 1;
1291
+ overflow-y: auto;
1292
+ padding: 6px 18px 18px;
1293
+ display: flex;
1294
+ flex-direction: column;
1295
+ gap: 10px;
1296
+ }
1297
+
1298
+ .analysis-findings::-webkit-scrollbar {
1299
+ width: 6px;
1300
+ }
1301
+
1302
+ .analysis-findings::-webkit-scrollbar-track {
1303
+ background: transparent;
1304
+ }
1305
+
1306
+ .analysis-findings::-webkit-scrollbar-thumb {
1307
+ background: var(--border);
1308
+ border-radius: 999px;
1309
+ }
1310
+
1311
+ .analysis-empty {
1312
+ border: 1px dashed rgba(122, 162, 247, 0.2);
1313
+ border-radius: 12px;
1314
+ padding: 16px;
1315
+ color: var(--text-dim);
1316
+ font-size: 13px;
1317
+ line-height: 1.6;
1318
+ }
1319
+
1320
+ .analysis-finding {
1321
+ border: 1px solid rgba(122, 162, 247, 0.14);
1322
+ border-radius: 14px;
1323
+ background: rgba(31, 35, 53, 0.78);
1324
+ padding: 14px;
1325
+ cursor: pointer;
1326
+ transition: border-color 0.15s ease, transform 0.15s ease, background 0.15s ease;
1327
+ }
1328
+
1329
+ .analysis-finding:hover {
1330
+ border-color: rgba(122, 162, 247, 0.32);
1331
+ background: rgba(36, 40, 60, 0.86);
1332
+ transform: translateY(-1px);
1333
+ }
1334
+
1335
+ .analysis-finding.active {
1336
+ border-color: rgba(247, 118, 142, 0.4);
1337
+ box-shadow: 0 0 0 1px rgba(247, 118, 142, 0.2);
1338
+ }
1339
+
1340
+ .analysis-finding-header {
1341
+ display: flex;
1342
+ align-items: flex-start;
1343
+ justify-content: space-between;
1344
+ gap: 12px;
1345
+ margin-bottom: 8px;
1346
+ }
1347
+
1348
+ .analysis-finding-title {
1349
+ margin: 0;
1350
+ font-size: 14px;
1351
+ line-height: 1.4;
1352
+ color: var(--text);
1353
+ }
1354
+
1355
+ .analysis-finding-meta {
1356
+ display: flex;
1357
+ flex-wrap: wrap;
1358
+ align-items: center;
1359
+ gap: 6px;
1360
+ flex-shrink: 0;
1361
+ }
1362
+
1363
+ .analysis-type-badge,
1364
+ .analysis-severity-badge,
1365
+ .analysis-metric-chip,
1366
+ .analysis-file-badge {
1367
+ border-radius: 999px;
1368
+ font-size: 11px;
1369
+ padding: 3px 8px;
1370
+ }
1371
+
1372
+ .analysis-type-badge {
1373
+ color: var(--accent);
1374
+ background: rgba(122, 162, 247, 0.12);
1375
+ border: 1px solid rgba(122, 162, 247, 0.2);
1376
+ }
1377
+
1378
+ .analysis-severity-badge {
1379
+ border: 1px solid transparent;
1380
+ }
1381
+
1382
+ .analysis-severity-badge.info {
1383
+ color: #7dcfff;
1384
+ background: rgba(125, 207, 255, 0.12);
1385
+ border-color: rgba(125, 207, 255, 0.18);
1386
+ }
1387
+
1388
+ .analysis-severity-badge.warning {
1389
+ color: #e0af68;
1390
+ background: rgba(224, 175, 104, 0.12);
1391
+ border-color: rgba(224, 175, 104, 0.2);
1392
+ }
1393
+
1394
+ .analysis-severity-badge.high {
1395
+ color: #f7768e;
1396
+ background: rgba(247, 118, 142, 0.12);
1397
+ border-color: rgba(247, 118, 142, 0.24);
1398
+ }
1399
+
1400
+ .analysis-finding-summary {
1401
+ margin: 0 0 10px;
1402
+ font-size: 12px;
1403
+ line-height: 1.6;
1404
+ color: var(--text-dim);
1405
+ }
1406
+
1407
+ .analysis-chip-row,
1408
+ .analysis-file-row {
1409
+ display: flex;
1410
+ flex-wrap: wrap;
1411
+ gap: 6px;
1412
+ margin-bottom: 8px;
1413
+ }
1414
+
1415
+ .analysis-metric-chip {
1416
+ color: var(--text);
1417
+ background: rgba(17, 19, 29, 0.75);
1418
+ border: 1px solid rgba(122, 162, 247, 0.12);
1419
+ }
1420
+
1421
+ .analysis-file-badge {
1422
+ color: var(--text-dim);
1423
+ background: rgba(17, 19, 29, 0.75);
1424
+ border: 1px solid rgba(86, 95, 137, 0.32);
1425
+ }
1426
+
1427
+ .analysis-rationale {
1428
+ margin: 0;
1429
+ padding-left: 18px;
1430
+ color: var(--text-dim);
1431
+ font-size: 12px;
1432
+ line-height: 1.5;
1433
+ }
1434
+
1435
+ .analysis-rationale li + li {
1436
+ margin-top: 4px;
1437
+ }
1438
+
1439
+ .analysis-finding-actions {
1440
+ display: flex;
1441
+ gap: 8px;
1442
+ margin-top: 12px;
1443
+ }
1444
+
1445
+ .analysis-finding-actions .header-btn {
1446
+ flex: 1;
1447
+ text-align: center;
1448
+ }
1449
+
1450
+ .analysis-explanation {
1451
+ margin-top: 12px;
1452
+ padding-top: 12px;
1453
+ border-top: 1px solid rgba(122, 162, 247, 0.12);
1454
+ }
1455
+
1456
+ .analysis-explanation-label {
1457
+ font-size: 11px;
1458
+ text-transform: uppercase;
1459
+ letter-spacing: 0.06em;
1460
+ color: #7dcfff;
1461
+ margin-bottom: 4px;
1462
+ }
1463
+
1464
+ .analysis-explanation-note {
1465
+ font-size: 12px;
1466
+ line-height: 1.5;
1467
+ color: var(--text-dim);
1468
+ margin-bottom: 10px;
1469
+ }
1470
+
1471
+ .analysis-explanation-content {
1472
+ max-height: 280px;
1473
+ }
1474
+
1475
+ .graph-empty {
1476
+ display: flex;
646
1477
  align-items: center;
647
1478
  justify-content: center;
648
1479
  height: 100%;
@@ -652,12 +1483,46 @@ main::-webkit-scrollbar-thumb {
652
1483
  text-align: center;
653
1484
  }
654
1485
 
1486
+ .graph-onboarding {
1487
+ position: absolute;
1488
+ inset: 0;
1489
+ display: flex;
1490
+ flex-direction: column;
1491
+ align-items: center;
1492
+ justify-content: center;
1493
+ gap: 8px;
1494
+ pointer-events: none;
1495
+ z-index: 10;
1496
+ color: var(--text-dim);
1497
+ text-align: center;
1498
+ padding: 40px;
1499
+ }
1500
+
1501
+ .graph-onboarding-icon {
1502
+ font-size: 28px;
1503
+ opacity: 0.25;
1504
+ letter-spacing: 4px;
1505
+ margin-bottom: 4px;
1506
+ }
1507
+
1508
+ .graph-onboarding-title {
1509
+ font-size: 15px;
1510
+ font-weight: 600;
1511
+ opacity: 0.5;
1512
+ }
1513
+
1514
+ .graph-onboarding-subtitle {
1515
+ font-size: 13px;
1516
+ opacity: 0.4;
1517
+ line-height: 1.5;
1518
+ }
1519
+
655
1520
  /* Symbol detail panel */
656
1521
  #symbol-detail {
657
1522
  position: absolute;
658
1523
  top: 0;
659
1524
  right: 0;
660
- width: 320px;
1525
+ width: 380px;
661
1526
  min-width: 200px;
662
1527
  max-width: 80%;
663
1528
  height: 100%;
@@ -920,3 +1785,56 @@ main::-webkit-scrollbar-thumb {
920
1785
  @keyframes spin {
921
1786
  to { transform: rotate(360deg); }
922
1787
  }
1788
+
1789
+ @media (max-width: 900px) {
1790
+ .modal-panel {
1791
+ width: calc(100vw - 20px);
1792
+ max-height: calc(100vh - 20px);
1793
+ }
1794
+
1795
+ .settings-toolbar,
1796
+ .modal-footer,
1797
+ .settings-item-header {
1798
+ flex-direction: column;
1799
+ align-items: stretch;
1800
+ }
1801
+
1802
+ .settings-path-group {
1803
+ align-items: flex-start;
1804
+ }
1805
+
1806
+ .settings-item-badges {
1807
+ justify-content: flex-start;
1808
+ }
1809
+
1810
+ .settings-item-meta {
1811
+ grid-template-columns: 1fr;
1812
+ }
1813
+
1814
+ .settings-actions {
1815
+ width: 100%;
1816
+ justify-content: flex-end;
1817
+ }
1818
+
1819
+ #analysis-panel {
1820
+ top: auto;
1821
+ left: 12px;
1822
+ right: 12px;
1823
+ bottom: 12px;
1824
+ width: auto;
1825
+ max-height: min(70vh, 560px);
1826
+ }
1827
+
1828
+ .analysis-panel-header {
1829
+ flex-direction: column;
1830
+ align-items: stretch;
1831
+ }
1832
+
1833
+ .analysis-panel-actions {
1834
+ justify-content: flex-end;
1835
+ }
1836
+
1837
+ .analysis-summary {
1838
+ grid-template-columns: 1fr 1fr;
1839
+ }
1840
+ }