@mtharrison/loupe 1.0.0 → 1.1.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.
@@ -97,6 +97,17 @@ select {
97
97
  button {
98
98
  cursor: pointer;
99
99
  }
100
+ .sr-only {
101
+ position: absolute;
102
+ width: 1px;
103
+ height: 1px;
104
+ padding: 0;
105
+ margin: -1px;
106
+ overflow: hidden;
107
+ clip: rect(0, 0, 0, 0);
108
+ white-space: nowrap;
109
+ border: 0;
110
+ }
100
111
  pre {
101
112
  margin: 0;
102
113
  white-space: pre-wrap;
@@ -421,7 +432,12 @@ pre {
421
432
  align-items: center;
422
433
  justify-content: space-between;
423
434
  gap: 0.75rem;
424
- padding: 0.95rem 0.95rem 0;
435
+ margin: 0.4rem 0.4rem 0;
436
+ padding: 0.88rem 0.92rem;
437
+ border: 1px solid var(--line);
438
+ border-radius: 16px;
439
+ background: rgba(250, 252, 255, 0.9);
440
+ box-shadow: 0 8px 22px rgba(32, 50, 76, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.7);
425
441
  }
426
442
  .session-sidebar-toolbar-copy {
427
443
  display: flex;
@@ -551,10 +567,10 @@ pre {
551
567
  .theme-switch {
552
568
  display: inline-flex;
553
569
  align-items: center;
554
- gap: 0.28rem;
555
- min-height: 2.75rem;
556
- padding: 0.18rem;
557
- border-radius: 14px;
570
+ gap: 0.18rem;
571
+ min-height: 2.5rem;
572
+ padding: 0.14rem;
573
+ border-radius: 999px;
558
574
  border: 1px solid var(--line);
559
575
  background: rgba(245, 249, 253, 0.92);
560
576
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
@@ -563,13 +579,15 @@ pre {
563
579
  .theme-switch-button {
564
580
  display: inline-flex;
565
581
  align-items: center;
566
- gap: 0.5rem;
582
+ justify-content: center;
583
+ gap: 0;
567
584
  border: 0;
568
585
  background: transparent;
569
586
  color: var(--muted-foreground);
570
- border-radius: 10px;
571
- min-height: 2.35rem;
572
- padding: 0.5rem 0.92rem;
587
+ border-radius: 999px;
588
+ width: 2.2rem;
589
+ min-height: 2.2rem;
590
+ padding: 0;
573
591
  font-weight: 650;
574
592
  line-height: 1;
575
593
  }
@@ -578,6 +596,11 @@ pre {
578
596
  color: var(--primary-strong);
579
597
  box-shadow: inset 0 0 0 1px rgba(40, 93, 168, 0.2), 0 1px 2px rgba(19, 46, 72, 0.08);
580
598
  }
599
+ .tag-filter-toggle.is-active {
600
+ border-color: rgba(40, 93, 168, 0.2);
601
+ background: rgba(40, 93, 168, 0.08);
602
+ color: var(--primary-strong);
603
+ }
581
604
  .clear-traces-button.is-confirming {
582
605
  border-color: rgba(181, 82, 93, 0.34);
583
606
  background: rgba(181, 82, 93, 0.08);
@@ -620,6 +643,21 @@ pre {
620
643
  .ui-badge[data-semantic=call] {
621
644
  --semantic-badge-color: rgba(61, 108, 225, 0.9);
622
645
  }
646
+ .ui-badge[data-semantic=system] {
647
+ --semantic-badge-color: rgba(40, 93, 168, 0.92);
648
+ }
649
+ .ui-badge[data-semantic=assistant] {
650
+ --semantic-badge-color: rgba(91, 108, 168, 0.88);
651
+ }
652
+ .ui-badge[data-semantic=user] {
653
+ --semantic-badge-color: rgba(46, 181, 129, 0.92);
654
+ }
655
+ .ui-badge[data-semantic=tool] {
656
+ --semantic-badge-color: rgba(59, 146, 111, 0.9);
657
+ }
658
+ .ui-badge[data-semantic=tool-call] {
659
+ --semantic-badge-color: rgba(219, 150, 58, 0.92);
660
+ }
623
661
  .ui-badge-outline {
624
662
  border: 1px solid rgba(40, 93, 168, 0.16);
625
663
  background: rgba(40, 93, 168, 0.08);
@@ -1017,13 +1055,16 @@ pre {
1017
1055
  line-height: 1.4;
1018
1056
  }
1019
1057
  .hierarchy-timeline-axis {
1058
+ --timeline-time-column: 4.75rem;
1059
+ --timeline-column-gap: 0.45rem;
1020
1060
  display: grid;
1021
- grid-template-columns: 4.75rem minmax(0, 1fr) minmax(13rem, 19rem);
1022
- gap: 0.75rem;
1061
+ grid-template-columns: var(--timeline-time-column) minmax(0, 1fr) minmax(13rem, 19rem);
1062
+ gap: var(--timeline-column-gap);
1023
1063
  align-items: end;
1024
1064
  }
1025
1065
  .hierarchy-timeline-axis-track,
1026
1066
  .hierarchy-timeline-row-track {
1067
+ box-sizing: border-box;
1027
1068
  background-image:
1028
1069
  linear-gradient(
1029
1070
  90deg,
@@ -1036,6 +1077,7 @@ pre {
1036
1077
  .hierarchy-timeline-axis-track {
1037
1078
  position: relative;
1038
1079
  height: 1.6rem;
1080
+ padding: 0 0.82rem 0 0.18rem;
1039
1081
  }
1040
1082
  .hierarchy-timeline-axis-track::before {
1041
1083
  content: "";
@@ -1085,22 +1127,28 @@ pre {
1085
1127
  .hierarchy-timeline-list {
1086
1128
  display: flex;
1087
1129
  flex-direction: column;
1088
- gap: 0.22rem;
1130
+ gap: 0;
1089
1131
  max-height: 28rem;
1090
1132
  overflow: auto;
1091
1133
  padding-right: 0.2rem;
1092
1134
  }
1093
1135
  .hierarchy-timeline-row {
1136
+ --timeline-time-column: 4.75rem;
1137
+ --timeline-column-gap: 0.45rem;
1138
+ --timeline-indent: 0.94rem;
1139
+ --timeline-gutter-base: 1.16rem;
1140
+ --timeline-gutter-width: calc( var(--timeline-depth, 0) * var(--timeline-indent) + var(--timeline-gutter-base) );
1141
+ --timeline-branch-offset: calc( var(--timeline-depth, 0) * var(--timeline-indent) + 0.12rem );
1094
1142
  --timeline-row-color: rgba(69, 104, 222, 0.88);
1143
+ position: relative;
1095
1144
  display: grid;
1096
- grid-template-columns: 4.75rem minmax(0, 1fr) minmax(13rem, 19rem);
1097
- gap: 0.75rem;
1145
+ grid-template-columns: var(--timeline-time-column) minmax(0, 1fr) minmax(13rem, 19rem);
1146
+ gap: var(--timeline-column-gap);
1098
1147
  align-items: center;
1099
1148
  width: 100%;
1100
- padding: 0.44rem 0.55rem;
1101
- border-radius: 12px;
1102
- border: 1px solid transparent;
1103
- background: rgba(255, 255, 255, 0.42);
1149
+ border: 0;
1150
+ background: transparent;
1151
+ padding: 0.12rem 0.55rem;
1104
1152
  color: inherit;
1105
1153
  cursor: default;
1106
1154
  font: inherit;
@@ -1109,38 +1157,59 @@ pre {
1109
1157
  content-visibility: auto;
1110
1158
  contain-intrinsic-size: 3rem;
1111
1159
  }
1160
+ .hierarchy-timeline-row::before {
1161
+ content: "";
1162
+ position: absolute;
1163
+ top: 0.14rem;
1164
+ right: 0.55rem;
1165
+ bottom: 0.14rem;
1166
+ left: calc(0.55rem + var(--timeline-time-column) + var(--timeline-column-gap) + var(--timeline-gutter-width));
1167
+ border-radius: 12px;
1168
+ border: 1px solid transparent;
1169
+ background: rgba(255, 255, 255, 0.42);
1170
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), 0 4px 12px rgba(32, 50, 76, 0.03);
1171
+ pointer-events: none;
1172
+ z-index: 0;
1173
+ }
1174
+ .hierarchy-timeline-row > * {
1175
+ position: relative;
1176
+ z-index: 1;
1177
+ }
1112
1178
  .hierarchy-timeline-row.is-clickable {
1113
1179
  cursor: pointer;
1180
+ }
1181
+ .hierarchy-timeline-row.is-clickable::before {
1114
1182
  border-color: rgba(40, 93, 168, 0.08);
1115
- background: rgba(255, 255, 255, 0.7);
1183
+ background: rgba(255, 255, 255, 0.72);
1116
1184
  box-shadow: 0 6px 18px rgba(32, 50, 76, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.72);
1117
1185
  }
1118
- .hierarchy-timeline-row.is-clickable:hover {
1186
+ .hierarchy-timeline-row.is-clickable:hover::before {
1119
1187
  border-color: rgba(40, 93, 168, 0.14);
1120
1188
  background: rgba(242, 248, 255, 0.86);
1121
1189
  }
1122
1190
  .hierarchy-timeline-row.is-structure {
1123
- border-style: dashed;
1124
- border-color: rgba(84, 100, 125, 0.08);
1125
- background: rgba(255, 255, 255, 0.24);
1126
- box-shadow: none;
1191
+ }
1192
+ .hierarchy-timeline-row.is-structure::before {
1193
+ border-color: color-mix(in srgb, var(--timeline-row-color) 12%, rgba(84, 100, 125, 0.08));
1194
+ background: color-mix(in srgb, var(--timeline-row-color) 5%, rgba(255, 255, 255, 0.56));
1195
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), 0 4px 12px rgba(32, 50, 76, 0.02);
1127
1196
  }
1128
1197
  .hierarchy-timeline-row:focus-visible {
1129
1198
  outline: 2px solid rgba(40, 93, 168, 0.22);
1130
1199
  outline-offset: 2px;
1131
1200
  }
1132
- .hierarchy-timeline-row.is-in-path {
1201
+ .hierarchy-timeline-row.is-in-path::before {
1133
1202
  background: rgba(240, 246, 255, 0.54);
1134
1203
  }
1135
- .hierarchy-timeline-row.is-structure.is-in-path {
1204
+ .hierarchy-timeline-row.is-structure.is-in-path::before {
1136
1205
  background: rgba(240, 246, 255, 0.38);
1137
1206
  }
1138
- .hierarchy-timeline-row.is-detail-trace:not(.is-active) {
1207
+ .hierarchy-timeline-row.is-detail-trace:not(.is-active)::before {
1139
1208
  border-color: rgba(40, 93, 168, 0.16);
1140
1209
  background: rgba(238, 246, 255, 0.76);
1141
1210
  box-shadow: inset 2px 0 0 rgba(40, 93, 168, 0.58), 0 8px 18px rgba(32, 50, 76, 0.05);
1142
1211
  }
1143
- .hierarchy-timeline-row.is-active {
1212
+ .hierarchy-timeline-row.is-active::before {
1144
1213
  border-color: rgba(40, 93, 168, 0.18);
1145
1214
  background: rgba(234, 243, 255, 0.82);
1146
1215
  box-shadow: inset 3px 0 0 rgba(40, 93, 168, 0.74), 0 8px 20px rgba(32, 50, 76, 0.06);
@@ -1162,6 +1231,10 @@ pre {
1162
1231
  --timeline-row-color: rgba(61, 108, 225, 0.9);
1163
1232
  }
1164
1233
  .hierarchy-timeline-row-time {
1234
+ align-self: stretch;
1235
+ display: flex;
1236
+ align-items: center;
1237
+ justify-content: flex-end;
1165
1238
  color: var(--muted-foreground);
1166
1239
  font-family:
1167
1240
  ui-monospace,
@@ -1174,26 +1247,47 @@ pre {
1174
1247
  text-align: right;
1175
1248
  white-space: nowrap;
1176
1249
  }
1177
- .hierarchy-timeline-row-labels {
1250
+ .hierarchy-timeline-row-branch {
1251
+ display: grid;
1252
+ grid-template-columns: var(--timeline-gutter-width) minmax(0, 1fr);
1253
+ align-items: stretch;
1254
+ min-width: 0;
1255
+ }
1256
+ .hierarchy-timeline-row-gutter {
1178
1257
  position: relative;
1179
- display: flex;
1180
1258
  min-width: 0;
1181
- flex-direction: column;
1182
- gap: 0.15rem;
1183
- padding-left: calc(var(--timeline-depth, 0) * 0.95rem);
1184
1259
  }
1185
- .hierarchy-timeline-row-labels::before {
1260
+ .hierarchy-timeline-row-gutter::before {
1186
1261
  content: "";
1187
1262
  position: absolute;
1188
- left: calc(var(--timeline-depth, 0) * 0.95rem - 0.42rem);
1189
- top: 0.2rem;
1190
- bottom: 0.2rem;
1263
+ top: -0.14rem;
1264
+ left: var(--timeline-branch-offset);
1265
+ bottom: -0.14rem;
1191
1266
  width: 1px;
1192
- background: rgba(84, 100, 125, 0.12);
1267
+ background: color-mix(in srgb, var(--timeline-row-color) 18%, rgba(84, 100, 125, 0.12));
1268
+ }
1269
+ .hierarchy-timeline-row-gutter::after {
1270
+ content: "";
1271
+ position: absolute;
1272
+ top: 50%;
1273
+ left: var(--timeline-branch-offset);
1274
+ right: 0.08rem;
1275
+ height: 1px;
1276
+ background: color-mix(in srgb, var(--timeline-row-color) 18%, rgba(84, 100, 125, 0.12));
1277
+ transform: translateY(-50%);
1193
1278
  }
1194
- .hierarchy-timeline-row.is-root .hierarchy-timeline-row-labels::before {
1279
+ .hierarchy-timeline-row.is-root .hierarchy-timeline-row-gutter::before,
1280
+ .hierarchy-timeline-row.is-root .hierarchy-timeline-row-gutter::after {
1195
1281
  display: none;
1196
1282
  }
1283
+ .hierarchy-timeline-row-labels {
1284
+ position: relative;
1285
+ display: flex;
1286
+ min-width: 0;
1287
+ flex-direction: column;
1288
+ gap: 0.18rem;
1289
+ padding: 0.58rem 0 0.58rem 0.82rem;
1290
+ }
1197
1291
  .hierarchy-timeline-row-title {
1198
1292
  display: flex;
1199
1293
  align-items: center;
@@ -1218,6 +1312,7 @@ pre {
1218
1312
  .hierarchy-timeline-row.is-structure .hierarchy-timeline-row-title-text {
1219
1313
  font-size: 0.88rem;
1220
1314
  font-weight: 600;
1315
+ color: color-mix(in srgb, var(--timeline-row-color) 42%, var(--foreground));
1221
1316
  }
1222
1317
  .hierarchy-timeline-row.is-structure .hierarchy-timeline-row-meta {
1223
1318
  font-size: 0.74rem;
@@ -1229,6 +1324,7 @@ pre {
1229
1324
  column-gap: 0.65rem;
1230
1325
  row-gap: 0.45rem;
1231
1326
  align-items: center;
1327
+ padding: 0.58rem 0.82rem 0.58rem 0.18rem;
1232
1328
  }
1233
1329
  .hierarchy-timeline-row-track {
1234
1330
  grid-area: track;
@@ -1330,7 +1426,31 @@ pre {
1330
1426
  min-width: 0;
1331
1427
  flex: 1;
1332
1428
  flex-direction: column;
1333
- gap: 0.45rem;
1429
+ gap: 0.55rem;
1430
+ }
1431
+ .trace-detail-breadcrumb {
1432
+ display: flex;
1433
+ align-items: center;
1434
+ flex-wrap: wrap;
1435
+ gap: 0.28rem 0.4rem;
1436
+ color: var(--muted-foreground);
1437
+ font-size: 0.8rem;
1438
+ font-weight: 650;
1439
+ line-height: 1.4;
1440
+ }
1441
+ .trace-detail-breadcrumb-separator {
1442
+ width: 0.9rem;
1443
+ height: 0.9rem;
1444
+ color: rgba(84, 100, 125, 0.5);
1445
+ }
1446
+ .trace-detail-breadcrumb-segment {
1447
+ white-space: nowrap;
1448
+ }
1449
+ .trace-detail-breadcrumb-segment.is-current {
1450
+ border-radius: 999px;
1451
+ padding: 0.18rem 0.56rem;
1452
+ background: rgba(40, 93, 168, 0.08);
1453
+ color: var(--primary-strong);
1334
1454
  }
1335
1455
  .trace-detail-title-row {
1336
1456
  display: flex;
@@ -1341,7 +1461,7 @@ pre {
1341
1461
  }
1342
1462
  .trace-detail-title-row h2 {
1343
1463
  margin: 0;
1344
- font-size: 1.24rem;
1464
+ font-size: 1.34rem;
1345
1465
  letter-spacing: -0.02em;
1346
1466
  }
1347
1467
  .trace-detail-heading p {
@@ -1351,7 +1471,8 @@ pre {
1351
1471
  }
1352
1472
  .trace-detail-subtitle {
1353
1473
  color: var(--muted-foreground);
1354
- font-size: 0.84rem;
1474
+ font-size: 0.82rem;
1475
+ line-height: 1.45;
1355
1476
  }
1356
1477
  .trace-detail-meta {
1357
1478
  display: flex;
@@ -1454,6 +1575,11 @@ pre {
1454
1575
  justify-content: space-between;
1455
1576
  gap: 0.65rem;
1456
1577
  }
1578
+ .trace-detail-json-toggle {
1579
+ min-height: 2.4rem;
1580
+ padding: 0.52rem 0.82rem;
1581
+ color: var(--muted-foreground);
1582
+ }
1457
1583
  .trace-detail-scroll {
1458
1584
  min-height: 0;
1459
1585
  flex: 1;
@@ -1671,6 +1797,18 @@ pre {
1671
1797
  color: var(--foreground);
1672
1798
  opacity: 1;
1673
1799
  }
1800
+ .detail-tabs {
1801
+ padding: 0.24rem;
1802
+ border-radius: 16px;
1803
+ background: rgba(243, 247, 251, 0.98);
1804
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.72), 0 1px 2px rgba(32, 50, 76, 0.04);
1805
+ }
1806
+ .detail-tabs .tabs-trigger {
1807
+ padding: 0.62rem 0.94rem;
1808
+ font-size: 0.84rem;
1809
+ font-weight: 700;
1810
+ letter-spacing: -0.01em;
1811
+ }
1674
1812
  .tabs-root[data-value=conversation] .tabs-trigger[data-tab-value=conversation],
1675
1813
  .tabs-root[data-value=request] .tabs-trigger[data-tab-value=request],
1676
1814
  .tabs-root[data-value=response] .tabs-trigger[data-tab-value=response],
@@ -1824,6 +1962,13 @@ pre {
1824
1962
  border-top: 1px solid rgba(88, 105, 130, 0.12);
1825
1963
  }
1826
1964
  .conversation-row {
1965
+ --message-accent: rgba(120, 137, 159, 0.24);
1966
+ --message-border-color: rgba(88, 105, 130, 0.12);
1967
+ --message-surface: rgba(255, 255, 255, 0.92);
1968
+ --message-label-color: color-mix(in srgb, var(--foreground) 52%, var(--muted-foreground));
1969
+ --message-label-border: rgba(88, 105, 130, 0.12);
1970
+ --message-label-surface: rgba(88, 105, 130, 0.06);
1971
+ --message-role-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.62);
1827
1972
  display: flex;
1828
1973
  flex-direction: column;
1829
1974
  gap: 0.45rem;
@@ -1831,6 +1976,12 @@ pre {
1831
1976
  }
1832
1977
  .conversation-row.is-user {
1833
1978
  align-self: flex-end;
1979
+ --message-accent: rgba(46, 181, 129, 0.58);
1980
+ --message-border-color: rgba(46, 181, 129, 0.28);
1981
+ --message-surface: rgba(232, 251, 242, 0.98);
1982
+ --message-label-color: #178b61;
1983
+ --message-label-border: rgba(46, 181, 129, 0.26);
1984
+ --message-label-surface: rgba(46, 181, 129, 0.16);
1834
1985
  }
1835
1986
  .conversation-row.is-assistant,
1836
1987
  .conversation-row.is-system,
@@ -1838,50 +1989,85 @@ pre {
1838
1989
  .conversation-row.is-tool-call {
1839
1990
  align-self: flex-start;
1840
1991
  }
1992
+ .conversation-row.is-assistant {
1993
+ --message-accent: rgba(151, 96, 255, 0.48);
1994
+ --message-border-color: rgba(151, 96, 255, 0.24);
1995
+ --message-surface: rgba(247, 240, 255, 0.98);
1996
+ --message-label-color: #7a41e3;
1997
+ --message-label-border: rgba(151, 96, 255, 0.24);
1998
+ --message-label-surface: rgba(151, 96, 255, 0.16);
1999
+ }
2000
+ .conversation-row.is-system {
2001
+ --message-accent: rgba(46, 104, 255, 0.56);
2002
+ --message-border-color: rgba(46, 104, 255, 0.28);
2003
+ --message-surface: rgba(233, 240, 255, 0.98);
2004
+ --message-label-color: #245fd6;
2005
+ --message-label-border: rgba(46, 104, 255, 0.24);
2006
+ --message-label-surface: rgba(46, 104, 255, 0.16);
2007
+ }
2008
+ .conversation-row.is-tool {
2009
+ --message-accent: rgba(23, 171, 108, 0.52);
2010
+ --message-border-color: rgba(23, 171, 108, 0.25);
2011
+ --message-surface: rgba(231, 251, 240, 0.98);
2012
+ --message-label-color: #0f8a58;
2013
+ --message-label-border: rgba(23, 171, 108, 0.24);
2014
+ --message-label-surface: rgba(23, 171, 108, 0.16);
2015
+ }
2016
+ .conversation-row.is-tool-call {
2017
+ --message-accent: rgba(255, 153, 28, 0.56);
2018
+ --message-border-color: rgba(255, 153, 28, 0.28);
2019
+ --message-surface: rgba(255, 244, 227, 0.98);
2020
+ --message-label-color: #b96b00;
2021
+ --message-label-border: rgba(255, 153, 28, 0.24);
2022
+ --message-label-surface: rgba(255, 153, 28, 0.16);
2023
+ }
1841
2024
  .conversation-role {
1842
- color: var(--muted-foreground);
2025
+ align-self: flex-start;
2026
+ display: inline-flex;
2027
+ align-items: center;
2028
+ gap: 0.35rem;
2029
+ border: 1px solid var(--message-label-border);
2030
+ border-radius: 999px;
2031
+ background: var(--message-label-surface);
2032
+ box-shadow: var(--message-role-shadow);
2033
+ color: var(--message-label-color);
1843
2034
  font-size: 0.74rem;
1844
2035
  font-weight: 700;
1845
2036
  letter-spacing: 0.06em;
2037
+ padding: 0.28rem 0.55rem;
1846
2038
  text-transform: uppercase;
1847
2039
  }
1848
2040
  .conversation-bubble {
1849
2041
  --expandable-fade-color: rgba(255, 255, 255, 0.96);
1850
- border: 1px solid var(--line);
2042
+ border: 1px solid var(--message-border-color);
1851
2043
  border-radius: 14px;
1852
- background: rgba(255, 255, 255, 0.9);
2044
+ background: var(--message-surface);
1853
2045
  padding: 0.9rem 1rem;
1854
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.72);
2046
+ box-shadow: inset 3px 0 0 var(--message-accent), inset 0 1px 0 rgba(255, 255, 255, 0.72);
2047
+ }
2048
+ .conversation-row.is-user .conversation-role {
2049
+ align-self: flex-end;
1855
2050
  }
1856
2051
  .conversation-row.is-user .conversation-bubble {
1857
- --expandable-fade-color: rgba(224, 236, 248, 0.96);
1858
- background: rgba(224, 236, 248, 0.88);
2052
+ --expandable-fade-color: rgba(232, 251, 242, 0.98);
1859
2053
  }
1860
2054
  .conversation-row.is-assistant .conversation-bubble {
1861
2055
  --expandable-fade-color: rgba(255, 255, 255, 0.98);
1862
- background: rgba(255, 255, 255, 0.96);
1863
- }
1864
- .conversation-row.is-system .conversation-role {
1865
- color: var(--primary);
1866
2056
  }
1867
2057
  .conversation-row.is-system .conversation-bubble {
1868
2058
  --expandable-fade-color: rgba(235, 242, 250, 0.98);
1869
- border-color: rgba(40, 93, 168, 0.16);
1870
- background: rgba(235, 242, 250, 0.94);
1871
- box-shadow: inset 3px 0 0 rgba(40, 93, 168, 0.4);
1872
2059
  }
1873
2060
  .tool-result-bubble {
1874
- --expandable-fade-color: rgba(245, 248, 251, 0.98);
2061
+ --expandable-fade-color: rgba(238, 248, 243, 0.98);
1875
2062
  display: flex;
1876
2063
  flex-direction: column;
1877
2064
  gap: 0.8rem;
1878
- background: rgba(245, 248, 251, 0.94);
1879
2065
  }
1880
2066
  .tool-call-bubble {
2067
+ --expandable-fade-color: rgba(252, 245, 232, 0.98);
1881
2068
  display: flex;
1882
2069
  flex-direction: column;
1883
2070
  gap: 0.8rem;
1884
- background: rgba(237, 243, 249, 0.96);
1885
2071
  }
1886
2072
  .tool-result-meta {
1887
2073
  display: flex;
@@ -1922,19 +2108,21 @@ pre {
1922
2108
  }
1923
2109
  .expandable-toggle {
1924
2110
  align-self: flex-start;
1925
- border: 0;
1926
- border-radius: 8px;
1927
- background: transparent;
2111
+ margin-top: 0.22rem;
2112
+ border: 1px solid rgba(40, 93, 168, 0.12);
2113
+ border-radius: 999px;
2114
+ background: rgba(40, 93, 168, 0.06);
1928
2115
  color: var(--primary-strong);
1929
2116
  cursor: pointer;
1930
- font-size: 0.82rem;
2117
+ font-size: 0.78rem;
1931
2118
  font-weight: 650;
1932
2119
  line-height: 1;
1933
- padding: 0;
2120
+ padding: 0.42rem 0.7rem;
1934
2121
  }
1935
2122
  .expandable-toggle:hover {
1936
- text-decoration: underline;
1937
- text-underline-offset: 0.18em;
2123
+ text-decoration: none;
2124
+ border-color: rgba(40, 93, 168, 0.18);
2125
+ background: rgba(40, 93, 168, 0.1);
1938
2126
  }
1939
2127
  .conversation-bubble p {
1940
2128
  margin: 0;
@@ -2204,14 +2392,18 @@ pre {
2204
2392
  gap: 0.8rem;
2205
2393
  }
2206
2394
  .message-card {
2395
+ --message-accent: rgba(120, 137, 159, 0.22);
2396
+ --message-border-color: rgba(88, 105, 130, 0.1);
2397
+ --message-surface: rgba(255, 255, 255, 0.92);
2207
2398
  --expandable-fade-color: rgba(255, 255, 255, 0.98);
2208
2399
  display: flex;
2209
2400
  flex-direction: column;
2210
2401
  gap: 0.75rem;
2211
2402
  padding: 0.9rem;
2212
2403
  border-radius: 12px;
2213
- background: rgba(255, 255, 255, 0.92);
2214
- border: 1px solid rgba(88, 105, 130, 0.08);
2404
+ background: var(--message-surface);
2405
+ border: 1px solid var(--message-border-color);
2406
+ box-shadow: inset 3px 0 0 var(--message-accent), inset 0 1px 0 rgba(255, 255, 255, 0.68);
2215
2407
  }
2216
2408
  .message-card-header {
2217
2409
  display: flex;
@@ -2237,21 +2429,28 @@ pre {
2237
2429
  font-weight: 600;
2238
2430
  }
2239
2431
  .message-card.role-system {
2432
+ --message-accent: rgba(46, 104, 255, 0.56);
2433
+ --message-border-color: rgba(46, 104, 255, 0.24);
2434
+ --message-surface: rgba(233, 240, 255, 0.98);
2240
2435
  --expandable-fade-color: rgba(236, 242, 250, 0.98);
2241
- border-color: rgba(40, 93, 168, 0.14);
2242
- background: rgba(236, 242, 250, 0.94);
2243
2436
  }
2244
2437
  .message-card.role-assistant {
2438
+ --message-accent: rgba(151, 96, 255, 0.48);
2439
+ --message-border-color: rgba(151, 96, 255, 0.2);
2440
+ --message-surface: rgba(247, 240, 255, 0.98);
2245
2441
  --expandable-fade-color: rgba(255, 255, 255, 0.98);
2246
- background: rgba(255, 255, 255, 0.96);
2247
2442
  }
2248
2443
  .message-card.role-user {
2249
- --expandable-fade-color: rgba(227, 237, 248, 0.96);
2250
- background: rgba(227, 237, 248, 0.82);
2444
+ --message-accent: rgba(46, 181, 129, 0.58);
2445
+ --message-border-color: rgba(46, 181, 129, 0.24);
2446
+ --message-surface: rgba(232, 251, 242, 0.97);
2447
+ --expandable-fade-color: rgba(232, 251, 242, 0.98);
2251
2448
  }
2252
2449
  .message-card.role-tool {
2253
- --expandable-fade-color: rgba(243, 247, 251, 0.98);
2254
- background: rgba(243, 247, 251, 0.94);
2450
+ --message-accent: rgba(23, 171, 108, 0.52);
2451
+ --message-border-color: rgba(23, 171, 108, 0.22);
2452
+ --message-surface: rgba(231, 251, 240, 0.97);
2453
+ --expandable-fade-color: rgba(238, 248, 243, 0.98);
2255
2454
  }
2256
2455
  .tool-call-stack {
2257
2456
  display: flex;
@@ -2527,6 +2726,16 @@ pre {
2527
2726
  color: var(--primary-strong);
2528
2727
  box-shadow: inset 0 0 0 1px rgba(134, 184, 255, 0.2), 0 1px 2px rgba(1, 7, 18, 0.24);
2529
2728
  }
2729
+ :root[data-theme=dark] .tag-filter-toggle.is-active {
2730
+ border-color: rgba(134, 184, 255, 0.24);
2731
+ background: rgba(134, 184, 255, 0.14);
2732
+ color: var(--primary-strong);
2733
+ }
2734
+ :root[data-theme=dark] .session-sidebar-toolbar {
2735
+ border-color: rgba(128, 153, 189, 0.14);
2736
+ background: rgba(16, 24, 36, 0.82);
2737
+ box-shadow: 0 10px 24px rgba(2, 10, 24, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.04);
2738
+ }
2530
2739
  :root[data-theme=dark] .trace-group-button,
2531
2740
  :root[data-theme=dark] .nav-item,
2532
2741
  :root[data-theme=dark] .tree-node-card,
@@ -2622,33 +2831,37 @@ pre {
2622
2831
  color: color-mix(in srgb, var(--semantic-badge-color) 74%, white);
2623
2832
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
2624
2833
  }
2625
- :root[data-theme=dark] .hierarchy-timeline-row {
2626
- background: rgba(22, 32, 47, 0.52);
2627
- }
2628
2834
  :root[data-theme=dark] .hierarchy-timeline-hint {
2629
2835
  color: rgba(182, 197, 219, 0.72);
2630
2836
  }
2631
- :root[data-theme=dark] .hierarchy-timeline-row.is-clickable {
2837
+ :root[data-theme=dark] .hierarchy-timeline-row::before {
2838
+ background: rgba(22, 32, 47, 0.52);
2839
+ }
2840
+ :root[data-theme=dark] .hierarchy-timeline-row.is-clickable::before {
2632
2841
  border-color: rgba(134, 184, 255, 0.12);
2633
2842
  background: rgba(24, 35, 52, 0.74);
2634
2843
  box-shadow: 0 8px 20px rgba(2, 10, 24, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.04);
2635
2844
  }
2636
- :root[data-theme=dark] .hierarchy-timeline-row.is-structure {
2637
- border-color: rgba(128, 153, 189, 0.08);
2638
- background: rgba(18, 27, 40, 0.26);
2845
+ :root[data-theme=dark] .hierarchy-timeline-row.is-clickable:hover::before {
2846
+ border-color: rgba(134, 184, 255, 0.2);
2847
+ background: rgba(29, 43, 64, 0.88);
2848
+ }
2849
+ :root[data-theme=dark] .hierarchy-timeline-row.is-structure::before {
2850
+ border-color: color-mix(in srgb, var(--timeline-row-color) 18%, rgba(128, 153, 189, 0.08));
2851
+ background: color-mix(in srgb, var(--timeline-row-color) 8%, rgba(18, 27, 40, 0.4));
2639
2852
  }
2640
- :root[data-theme=dark] .hierarchy-timeline-row.is-in-path {
2853
+ :root[data-theme=dark] .hierarchy-timeline-row.is-in-path::before {
2641
2854
  background: rgba(27, 40, 60, 0.7);
2642
2855
  }
2643
- :root[data-theme=dark] .hierarchy-timeline-row.is-structure.is-in-path {
2856
+ :root[data-theme=dark] .hierarchy-timeline-row.is-structure.is-in-path::before {
2644
2857
  background: rgba(24, 35, 52, 0.38);
2645
2858
  }
2646
- :root[data-theme=dark] .hierarchy-timeline-row.is-detail-trace:not(.is-active) {
2859
+ :root[data-theme=dark] .hierarchy-timeline-row.is-detail-trace:not(.is-active)::before {
2647
2860
  border-color: rgba(134, 184, 255, 0.16);
2648
2861
  background: rgba(26, 38, 57, 0.84);
2649
2862
  box-shadow: inset 2px 0 0 rgba(134, 184, 255, 0.6), 0 8px 18px rgba(2, 10, 24, 0.18);
2650
2863
  }
2651
- :root[data-theme=dark] .hierarchy-timeline-row.is-active {
2864
+ :root[data-theme=dark] .hierarchy-timeline-row.is-active::before {
2652
2865
  border-color: rgba(134, 184, 255, 0.2);
2653
2866
  background: rgba(31, 45, 66, 0.94);
2654
2867
  box-shadow: inset 3px 0 0 rgba(134, 184, 255, 0.82), 0 10px 22px rgba(2, 10, 24, 0.18);
@@ -2660,6 +2873,13 @@ pre {
2660
2873
  :root[data-theme=dark] .hierarchy-timeline-title {
2661
2874
  color: rgba(182, 197, 219, 0.78);
2662
2875
  }
2876
+ :root[data-theme=dark] .hierarchy-timeline-row-gutter::before,
2877
+ :root[data-theme=dark] .hierarchy-timeline-row-gutter::after {
2878
+ background: color-mix(in srgb, var(--timeline-row-color) 24%, rgba(128, 153, 189, 0.14));
2879
+ }
2880
+ :root[data-theme=dark] .hierarchy-timeline-row.is-structure .hierarchy-timeline-row-title-text {
2881
+ color: color-mix(in srgb, var(--timeline-row-color) 48%, white);
2882
+ }
2663
2883
  :root[data-theme=dark] .hierarchy-timeline-row-inspect {
2664
2884
  border-color: rgba(134, 184, 255, 0.18);
2665
2885
  background: rgba(134, 184, 255, 0.12);
@@ -2669,12 +2889,26 @@ pre {
2669
2889
  border-color: rgba(134, 184, 255, 0.24);
2670
2890
  background: rgba(134, 184, 255, 0.18);
2671
2891
  }
2892
+ :root[data-theme=dark] .trace-detail-breadcrumb {
2893
+ color: rgba(182, 197, 219, 0.74);
2894
+ }
2895
+ :root[data-theme=dark] .trace-detail-breadcrumb-separator {
2896
+ color: rgba(182, 197, 219, 0.42);
2897
+ }
2898
+ :root[data-theme=dark] .trace-detail-breadcrumb-segment.is-current {
2899
+ background: rgba(134, 184, 255, 0.14);
2900
+ color: rgba(186, 214, 255, 0.96);
2901
+ }
2902
+ :root[data-theme=dark] .trace-detail-subtitle,
2903
+ :root[data-theme=dark] .trace-detail-json-toggle {
2904
+ color: rgba(182, 197, 219, 0.74);
2905
+ }
2672
2906
  :root[data-theme=dark] .hierarchy-timeline-row-title-text {
2673
2907
  color: var(--foreground);
2674
2908
  }
2675
2909
  :root[data-theme=dark] .hierarchy-timeline-axis-track::before,
2676
2910
  :root[data-theme=dark] .hierarchy-timeline-axis-tick::before,
2677
- :root[data-theme=dark] .hierarchy-timeline-row-labels::before,
2911
+ :root[data-theme=dark] .hierarchy-timeline-row-gutter::before,
2678
2912
  :root[data-theme=dark] .hierarchy-timeline-row-track::before {
2679
2913
  background: rgba(128, 153, 189, 0.14);
2680
2914
  }
@@ -2706,6 +2940,10 @@ pre {
2706
2940
  :root[data-theme=dark] .tabs-list {
2707
2941
  background: rgba(16, 24, 36, 0.92);
2708
2942
  }
2943
+ :root[data-theme=dark] .detail-tabs {
2944
+ background: rgba(16, 24, 36, 0.96);
2945
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 1px 2px rgba(1, 7, 18, 0.22);
2946
+ }
2709
2947
  :root[data-theme=dark] .tabs-trigger:hover {
2710
2948
  background: rgba(134, 184, 255, 0.08);
2711
2949
  color: var(--foreground);
@@ -2728,29 +2966,64 @@ pre {
2728
2966
  background: rgba(12, 18, 28, 0.96);
2729
2967
  box-shadow: -24px 0 70px rgba(1, 7, 18, 0.42);
2730
2968
  }
2969
+ :root[data-theme=dark] .conversation-row,
2970
+ :root[data-theme=dark] .message-card {
2971
+ --message-role-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
2972
+ }
2731
2973
  :root[data-theme=dark] .conversation-row.is-user .conversation-bubble,
2732
2974
  :root[data-theme=dark] .message-card.role-user {
2733
- --expandable-fade-color: rgba(33, 47, 69, 0.98);
2734
- background: rgba(33, 47, 69, 0.96);
2975
+ --message-accent: rgba(76, 218, 157, 0.58);
2976
+ --message-border-color: rgba(76, 218, 157, 0.28);
2977
+ --message-surface: rgba(10, 72, 49, 0.98);
2978
+ --message-label-color: rgba(209, 255, 234, 0.98);
2979
+ --message-label-border: rgba(76, 218, 157, 0.24);
2980
+ --message-label-surface: rgba(76, 218, 157, 0.18);
2981
+ --expandable-fade-color: rgba(10, 72, 49, 0.99);
2735
2982
  }
2736
2983
  :root[data-theme=dark] .conversation-row.is-assistant .conversation-bubble,
2737
2984
  :root[data-theme=dark] .message-card.role-assistant {
2985
+ --message-accent: rgba(177, 108, 255, 0.54);
2986
+ --message-border-color: rgba(177, 108, 255, 0.24);
2987
+ --message-surface: rgba(54, 24, 89, 0.98);
2988
+ --message-label-color: rgba(231, 208, 255, 0.98);
2989
+ --message-label-border: rgba(177, 108, 255, 0.22);
2990
+ --message-label-surface: rgba(177, 108, 255, 0.16);
2738
2991
  --expandable-fade-color: rgba(22, 32, 48, 0.99);
2739
- background: rgba(22, 32, 48, 0.98);
2740
2992
  }
2741
2993
  :root[data-theme=dark] .conversation-row.is-system .conversation-bubble,
2742
2994
  :root[data-theme=dark] .message-card.role-system {
2995
+ --message-accent: rgba(79, 136, 255, 0.62);
2996
+ --message-border-color: rgba(79, 136, 255, 0.28);
2997
+ --message-surface: rgba(17, 42, 96, 0.98);
2998
+ --message-label-color: rgba(203, 221, 255, 0.98);
2999
+ --message-label-border: rgba(79, 136, 255, 0.26);
3000
+ --message-label-surface: rgba(79, 136, 255, 0.18);
2743
3001
  --expandable-fade-color: rgba(26, 39, 57, 0.99);
2744
- border-color: rgba(134, 184, 255, 0.24);
2745
- background: rgba(26, 39, 57, 0.98);
2746
- box-shadow: inset 3px 0 0 rgba(134, 184, 255, 0.42);
3002
+ }
3003
+ :root[data-theme=dark] .conversation-row.is-tool .conversation-bubble,
3004
+ :root[data-theme=dark] .message-card.role-tool {
3005
+ --message-accent: rgba(60, 212, 144, 0.56);
3006
+ --message-border-color: rgba(60, 212, 144, 0.26);
3007
+ --message-surface: rgba(11, 63, 42, 0.98);
3008
+ --message-label-color: rgba(203, 255, 229, 0.98);
3009
+ --message-label-border: rgba(60, 212, 144, 0.22);
3010
+ --message-label-surface: rgba(60, 212, 144, 0.16);
3011
+ --expandable-fade-color: rgba(18, 34, 33, 0.99);
3012
+ }
3013
+ :root[data-theme=dark] .conversation-row.is-tool-call .conversation-bubble {
3014
+ --message-accent: rgba(255, 170, 66, 0.6);
3015
+ --message-border-color: rgba(255, 170, 66, 0.28);
3016
+ --message-surface: rgba(84, 43, 5, 0.98);
3017
+ --message-label-color: rgba(255, 228, 184, 0.98);
3018
+ --message-label-border: rgba(255, 170, 66, 0.24);
3019
+ --message-label-surface: rgba(255, 170, 66, 0.16);
3020
+ --expandable-fade-color: rgba(44, 31, 16, 0.99);
2747
3021
  }
2748
3022
  :root[data-theme=dark] .tool-result-bubble {
2749
- --expandable-fade-color: rgba(17, 26, 39, 0.99);
2750
- background: rgba(17, 26, 39, 0.96);
3023
+ --expandable-fade-color: rgba(18, 34, 33, 0.99);
2751
3024
  }
2752
3025
  :root[data-theme=dark] .tool-call-bubble {
2753
- background: rgba(20, 32, 48, 0.98);
3026
+ --expandable-fade-color: rgba(44, 31, 16, 0.99);
2754
3027
  }
2755
3028
  :root[data-theme=dark] .markdown-body code {
2756
3029
  background: rgba(101, 134, 182, 0.18);
@@ -2806,6 +3079,15 @@ pre {
2806
3079
  background: rgba(29, 42, 60, 0.92);
2807
3080
  border-color: rgba(128, 153, 189, 0.12);
2808
3081
  }
3082
+ :root[data-theme=dark] .expandable-toggle {
3083
+ border-color: rgba(134, 184, 255, 0.18);
3084
+ background: rgba(134, 184, 255, 0.1);
3085
+ color: rgba(186, 214, 255, 0.96);
3086
+ }
3087
+ :root[data-theme=dark] .expandable-toggle:hover {
3088
+ border-color: rgba(134, 184, 255, 0.24);
3089
+ background: rgba(134, 184, 255, 0.16);
3090
+ }
2809
3091
  :root[data-theme=dark] .workspace-grid::-webkit-scrollbar-thumb {
2810
3092
  background: rgba(128, 153, 189, 0.28);
2811
3093
  }
@@ -2877,10 +3159,12 @@ pre {
2877
3159
  padding-right: 0;
2878
3160
  }
2879
3161
  .hierarchy-timeline-axis {
2880
- grid-template-columns: 4.5rem minmax(0, 1fr) minmax(11rem, 1fr);
3162
+ --timeline-time-column: 4.5rem;
3163
+ grid-template-columns: var(--timeline-time-column) minmax(0, 1fr) minmax(11rem, 1fr);
2881
3164
  }
2882
3165
  .hierarchy-timeline-row {
2883
- grid-template-columns: 4.5rem minmax(0, 1fr) minmax(11rem, 1fr);
3166
+ --timeline-time-column: 4.5rem;
3167
+ grid-template-columns: var(--timeline-time-column) minmax(0, 1fr) minmax(11rem, 1fr);
2884
3168
  }
2885
3169
  .sheet-panel {
2886
3170
  width: min(100vw, 48rem);
@@ -2969,6 +3253,17 @@ pre {
2969
3253
  .trace-detail-secondary .hierarchy-timeline-row-time {
2970
3254
  text-align: left;
2971
3255
  }
3256
+ .trace-detail-secondary .hierarchy-timeline-row::before {
3257
+ top: 1.7rem;
3258
+ left: 0;
3259
+ right: 0;
3260
+ }
3261
+ .trace-detail-secondary .hierarchy-timeline-row-branch {
3262
+ grid-template-columns: minmax(0, 1fr);
3263
+ }
3264
+ .trace-detail-secondary .hierarchy-timeline-row-gutter {
3265
+ display: none;
3266
+ }
2972
3267
  .trace-detail-secondary .hierarchy-timeline-row-bars {
2973
3268
  grid-column: auto;
2974
3269
  grid-template-columns: minmax(0, 1fr) auto;
@@ -2989,10 +3284,24 @@ pre {
2989
3284
  }
2990
3285
  .hierarchy-timeline-row {
2991
3286
  grid-template-columns: minmax(0, 1fr);
3287
+ padding-left: 0;
3288
+ padding-right: 0;
2992
3289
  }
2993
3290
  .hierarchy-timeline-row-time {
3291
+ justify-content: flex-start;
2994
3292
  text-align: left;
2995
3293
  }
3294
+ .hierarchy-timeline-row::before {
3295
+ top: 1.7rem;
3296
+ left: 0;
3297
+ right: 0;
3298
+ }
3299
+ .hierarchy-timeline-row-branch {
3300
+ grid-template-columns: minmax(0, 1fr);
3301
+ }
3302
+ .hierarchy-timeline-row-gutter {
3303
+ display: none;
3304
+ }
2996
3305
  .hierarchy-timeline-row-bars {
2997
3306
  grid-column: auto;
2998
3307
  grid-template-columns: minmax(0, 1fr) auto;
@@ -21696,25 +21696,35 @@ var init_check = __esm({
21696
21696
  }
21697
21697
  });
21698
21698
 
21699
+ // node_modules/lucide-react/dist/esm/icons/chevron-right.js
21700
+ var __iconNode6, ChevronRight;
21701
+ var init_chevron_right = __esm({
21702
+ "node_modules/lucide-react/dist/esm/icons/chevron-right.js"() {
21703
+ init_createLucideIcon();
21704
+ __iconNode6 = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
21705
+ ChevronRight = createLucideIcon("chevron-right", __iconNode6);
21706
+ }
21707
+ });
21708
+
21699
21709
  // node_modules/lucide-react/dist/esm/icons/copy.js
21700
- var __iconNode6, Copy;
21710
+ var __iconNode7, Copy;
21701
21711
  var init_copy = __esm({
21702
21712
  "node_modules/lucide-react/dist/esm/icons/copy.js"() {
21703
21713
  init_createLucideIcon();
21704
- __iconNode6 = [
21714
+ __iconNode7 = [
21705
21715
  ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
21706
21716
  ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
21707
21717
  ];
21708
- Copy = createLucideIcon("copy", __iconNode6);
21718
+ Copy = createLucideIcon("copy", __iconNode7);
21709
21719
  }
21710
21720
  });
21711
21721
 
21712
21722
  // node_modules/lucide-react/dist/esm/icons/funnel.js
21713
- var __iconNode7, Funnel;
21723
+ var __iconNode8, Funnel;
21714
21724
  var init_funnel = __esm({
21715
21725
  "node_modules/lucide-react/dist/esm/icons/funnel.js"() {
21716
21726
  init_createLucideIcon();
21717
- __iconNode7 = [
21727
+ __iconNode8 = [
21718
21728
  [
21719
21729
  "path",
21720
21730
  {
@@ -21723,16 +21733,16 @@ var init_funnel = __esm({
21723
21733
  }
21724
21734
  ]
21725
21735
  ];
21726
- Funnel = createLucideIcon("funnel", __iconNode7);
21736
+ Funnel = createLucideIcon("funnel", __iconNode8);
21727
21737
  }
21728
21738
  });
21729
21739
 
21730
21740
  // node_modules/lucide-react/dist/esm/icons/moon.js
21731
- var __iconNode8, Moon;
21741
+ var __iconNode9, Moon;
21732
21742
  var init_moon = __esm({
21733
21743
  "node_modules/lucide-react/dist/esm/icons/moon.js"() {
21734
21744
  init_createLucideIcon();
21735
- __iconNode8 = [
21745
+ __iconNode9 = [
21736
21746
  [
21737
21747
  "path",
21738
21748
  {
@@ -21741,45 +21751,45 @@ var init_moon = __esm({
21741
21751
  }
21742
21752
  ]
21743
21753
  ];
21744
- Moon = createLucideIcon("moon", __iconNode8);
21754
+ Moon = createLucideIcon("moon", __iconNode9);
21745
21755
  }
21746
21756
  });
21747
21757
 
21748
21758
  // node_modules/lucide-react/dist/esm/icons/network.js
21749
- var __iconNode9, Network;
21759
+ var __iconNode10, Network;
21750
21760
  var init_network = __esm({
21751
21761
  "node_modules/lucide-react/dist/esm/icons/network.js"() {
21752
21762
  init_createLucideIcon();
21753
- __iconNode9 = [
21763
+ __iconNode10 = [
21754
21764
  ["rect", { x: "16", y: "16", width: "6", height: "6", rx: "1", key: "4q2zg0" }],
21755
21765
  ["rect", { x: "2", y: "16", width: "6", height: "6", rx: "1", key: "8cvhb9" }],
21756
21766
  ["rect", { x: "9", y: "2", width: "6", height: "6", rx: "1", key: "1egb70" }],
21757
21767
  ["path", { d: "M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3", key: "1jsf9p" }],
21758
21768
  ["path", { d: "M12 12V8", key: "2874zd" }]
21759
21769
  ];
21760
- Network = createLucideIcon("network", __iconNode9);
21770
+ Network = createLucideIcon("network", __iconNode10);
21761
21771
  }
21762
21772
  });
21763
21773
 
21764
21774
  // node_modules/lucide-react/dist/esm/icons/search.js
21765
- var __iconNode10, Search;
21775
+ var __iconNode11, Search;
21766
21776
  var init_search = __esm({
21767
21777
  "node_modules/lucide-react/dist/esm/icons/search.js"() {
21768
21778
  init_createLucideIcon();
21769
- __iconNode10 = [
21779
+ __iconNode11 = [
21770
21780
  ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
21771
21781
  ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
21772
21782
  ];
21773
- Search = createLucideIcon("search", __iconNode10);
21783
+ Search = createLucideIcon("search", __iconNode11);
21774
21784
  }
21775
21785
  });
21776
21786
 
21777
21787
  // node_modules/lucide-react/dist/esm/icons/sun.js
21778
- var __iconNode11, Sun;
21788
+ var __iconNode12, Sun;
21779
21789
  var init_sun = __esm({
21780
21790
  "node_modules/lucide-react/dist/esm/icons/sun.js"() {
21781
21791
  init_createLucideIcon();
21782
- __iconNode11 = [
21792
+ __iconNode12 = [
21783
21793
  ["circle", { cx: "12", cy: "12", r: "4", key: "4exip2" }],
21784
21794
  ["path", { d: "M12 2v2", key: "tus03m" }],
21785
21795
  ["path", { d: "M12 20v2", key: "1lh1kg" }],
@@ -21790,20 +21800,20 @@ var init_sun = __esm({
21790
21800
  ["path", { d: "m6.34 17.66-1.41 1.41", key: "1m8zz5" }],
21791
21801
  ["path", { d: "m19.07 4.93-1.41 1.41", key: "1shlcs" }]
21792
21802
  ];
21793
- Sun = createLucideIcon("sun", __iconNode11);
21803
+ Sun = createLucideIcon("sun", __iconNode12);
21794
21804
  }
21795
21805
  });
21796
21806
 
21797
21807
  // node_modules/lucide-react/dist/esm/icons/x.js
21798
- var __iconNode12, X;
21808
+ var __iconNode13, X;
21799
21809
  var init_x = __esm({
21800
21810
  "node_modules/lucide-react/dist/esm/icons/x.js"() {
21801
21811
  init_createLucideIcon();
21802
- __iconNode12 = [
21812
+ __iconNode13 = [
21803
21813
  ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
21804
21814
  ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
21805
21815
  ];
21806
- X = createLucideIcon("x", __iconNode12);
21816
+ X = createLucideIcon("x", __iconNode13);
21807
21817
  }
21808
21818
  });
21809
21819
 
@@ -21816,6 +21826,7 @@ var init_lucide_react = __esm({
21816
21826
  init_bot();
21817
21827
  init_boxes();
21818
21828
  init_check();
21829
+ init_chevron_right();
21819
21830
  init_copy();
21820
21831
  init_moon();
21821
21832
  init_network();
@@ -37067,6 +37078,7 @@ function App() {
37067
37078
  const hasActiveFilters = Boolean(
37068
37079
  filters.search || filters.status || filters.kind || filters.tags
37069
37080
  );
37081
+ const activeTagFilterCount = countTagFilters(filters.tags);
37070
37082
  const onFilterChange = (key, value) => {
37071
37083
  (0, import_react4.startTransition)(() => {
37072
37084
  setFilters((current) => ({ ...current, [key]: value }));
@@ -37243,11 +37255,7 @@ function App() {
37243
37255
  eventsConnected ? "Connected" : "Reconnecting"
37244
37256
  ]
37245
37257
  }
37246
- ),
37247
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "inspector-meta", children: [
37248
- data.traces.total,
37249
- " stored"
37250
- ] })
37258
+ )
37251
37259
  ] }),
37252
37260
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "inspector-header-actions", children: [
37253
37261
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -37301,10 +37309,14 @@ function App() {
37301
37309
  Button,
37302
37310
  {
37303
37311
  variant: "outline",
37312
+ className: cn(
37313
+ "tag-filter-toggle",
37314
+ (showAdvancedFilters || activeTagFilterCount > 0) && "is-active"
37315
+ ),
37304
37316
  onClick: () => setShowAdvancedFilters((current) => !current),
37305
37317
  children: [
37306
37318
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Funnel, { "data-icon": "inline-start" }),
37307
- showAdvancedFilters || filters.tags ? "Hide filters" : "More filters"
37319
+ showAdvancedFilters || filters.tags ? "Hide tag filters" : activeTagFilterCount > 0 ? `Tag filters \xB7 ${activeTagFilterCount}` : "Tag filters"
37308
37320
  ]
37309
37321
  }
37310
37322
  ),
@@ -37413,10 +37425,12 @@ function ThemeSwitcher({
37413
37425
  type: "button",
37414
37426
  className: cn("theme-switch-button", theme === "light" && "is-active"),
37415
37427
  "aria-pressed": theme === "light",
37428
+ "aria-label": "Use light theme",
37429
+ title: "Light theme",
37416
37430
  onClick: () => onChange("light"),
37417
37431
  children: [
37418
37432
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Sun, { "data-icon": "inline-start" }),
37419
- "Light"
37433
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "sr-only", children: "Light theme" })
37420
37434
  ]
37421
37435
  }
37422
37436
  ),
@@ -37426,10 +37440,12 @@ function ThemeSwitcher({
37426
37440
  type: "button",
37427
37441
  className: cn("theme-switch-button", theme === "dark" && "is-active"),
37428
37442
  "aria-pressed": theme === "dark",
37443
+ "aria-label": "Use dark theme",
37444
+ title: "Dark theme",
37429
37445
  onClick: () => onChange("dark"),
37430
37446
  children: [
37431
37447
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Moon, { "data-icon": "inline-start" }),
37432
- "Dark"
37448
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "sr-only", children: "Dark theme" })
37433
37449
  ]
37434
37450
  }
37435
37451
  )
@@ -37523,20 +37539,29 @@ function HierarchyTimelineOverview({
37523
37539
  };
37524
37540
  const rowContent = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react4.Fragment, { children: [
37525
37541
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hierarchy-timeline-row-time", children: formatTimelineTimestamp(row.startedAt) }),
37526
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hierarchy-timeline-row-labels", children: [
37527
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hierarchy-timeline-row-title", children: [
37528
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "hierarchy-timeline-row-title-text", children: row.label }),
37529
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
37530
- Badge,
37531
- {
37532
- variant: "secondary",
37533
- className: "hierarchy-timeline-pill",
37534
- semantic: row.badge,
37535
- children: row.badge
37536
- }
37537
- )
37538
- ] }),
37539
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hierarchy-timeline-row-meta", children: row.meta })
37542
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hierarchy-timeline-row-branch", children: [
37543
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
37544
+ "div",
37545
+ {
37546
+ className: "hierarchy-timeline-row-gutter",
37547
+ "aria-hidden": "true"
37548
+ }
37549
+ ),
37550
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hierarchy-timeline-row-labels", children: [
37551
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hierarchy-timeline-row-title", children: [
37552
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "hierarchy-timeline-row-title-text", children: row.label }),
37553
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
37554
+ Badge,
37555
+ {
37556
+ variant: "secondary",
37557
+ className: "hierarchy-timeline-pill",
37558
+ semantic: row.badge,
37559
+ children: row.badge
37560
+ }
37561
+ )
37562
+ ] }),
37563
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hierarchy-timeline-row-meta", children: row.meta })
37564
+ ] })
37540
37565
  ] }),
37541
37566
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hierarchy-timeline-row-bars", children: [
37542
37567
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -37612,13 +37637,32 @@ function TraceDetailPanel({
37612
37637
  const detailCopy = detail ? getTraceDisplayCopy(detail) : fallbackTrace ? getTraceDisplayCopy(fallbackTrace) : null;
37613
37638
  const detailStatus = detail?.status ?? fallbackTrace?.status ?? null;
37614
37639
  const detailDuration = detail ? formatTraceDuration(detail) : fallbackTrace ? fallbackTrace.durationMs == null ? "Running" : `${fallbackTrace.durationMs} ms` : null;
37615
- const detailSubtitle = detail ? detailCopy?.subtitle : fallbackTrace ? detailCopy?.subtitle : null;
37640
+ const detailSubtitle = formatTraceProviderSummary(detail ?? fallbackTrace);
37616
37641
  const detailCostUsd = detail ? getUsageCostUsd(detail.usage) : fallbackTrace?.costUsd ?? null;
37617
37642
  const detailCostLabel = formatUsdCost(detailCostUsd);
37618
37643
  const hasSecondaryInspector = Boolean(detail && timelineModel);
37619
37644
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "trace-detail-panel", role: "region", "aria-label": "Trace detail", children: [
37620
37645
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "trace-detail-header", children: [
37621
37646
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "trace-detail-heading", children: [
37647
+ detailCopy?.pathParts?.length ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "trace-detail-breadcrumb", "aria-label": "Trace path", children: detailCopy.pathParts.map((part, index2) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react4.Fragment, { children: [
37648
+ index2 > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
37649
+ ChevronRight,
37650
+ {
37651
+ className: "trace-detail-breadcrumb-separator",
37652
+ "aria-hidden": "true"
37653
+ }
37654
+ ) : null,
37655
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
37656
+ "span",
37657
+ {
37658
+ className: cn(
37659
+ "trace-detail-breadcrumb-segment",
37660
+ index2 === detailCopy.pathParts.length - 1 && "is-current"
37661
+ ),
37662
+ children: part
37663
+ }
37664
+ )
37665
+ ] }, `${part}-${index2}`)) }) : null,
37622
37666
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "trace-detail-title-row", children: [
37623
37667
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: detailCopy?.title || "Loading trace" }),
37624
37668
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "trace-detail-meta", children: [
@@ -37627,8 +37671,7 @@ function TraceDetailPanel({
37627
37671
  detailCostLabel ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TraceMetricPill, { tone: "cost", children: detailCostLabel }) : null
37628
37672
  ] })
37629
37673
  ] }),
37630
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: detailCopy?.path || "Loading the full request and response context." }),
37631
- detailSubtitle ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "trace-detail-subtitle", children: detailSubtitle }) : null
37674
+ detailSubtitle ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "trace-detail-subtitle", children: detailSubtitle }) : detailCopy?.path ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "trace-detail-subtitle", children: detailCopy.path }) : null
37632
37675
  ] }),
37633
37676
  onBack ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "trace-detail-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Button, { variant: "outline", onClick: onBack, children: "Show hierarchy" }) }) : null
37634
37677
  ] }),
@@ -37648,6 +37691,7 @@ function TraceDetailPanel({
37648
37691
  Button,
37649
37692
  {
37650
37693
  variant: "outline",
37694
+ className: "trace-detail-json-toggle",
37651
37695
  onClick: () => onToggleJsonMode(activeTab),
37652
37696
  children: [
37653
37697
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Boxes, { "data-icon": "inline-start" }),
@@ -38307,11 +38351,11 @@ function StructuredMessageCard({
38307
38351
  const isToolResult = message.role === "tool";
38308
38352
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: cn("message-card", `role-${message.role}`), children: [
38309
38353
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "message-card-header", children: [
38310
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Badge, { variant: "secondary", children: message.role }),
38354
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Badge, { semantic: message.role, variant: "secondary", children: message.role }),
38311
38355
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "message-card-header-meta", children: [
38312
38356
  isToolResult && message.name ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Badge, { variant: "outline", children: message.name }) : null,
38313
38357
  isToolResult && message.tool_call_id ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Badge, { variant: "secondary", children: message.tool_call_id }) : null,
38314
- isToolCallTurn ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Badge, { variant: "outline", children: formatCountLabel(toolCalls.length, "tool call") }) : null
38358
+ isToolCallTurn ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Badge, { semantic: "tool-call", variant: "outline", children: formatCountLabel(toolCalls.length, "tool call") }) : null
38315
38359
  ] })
38316
38360
  ] }),
38317
38361
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "message-card-body", children: [
@@ -38615,6 +38659,15 @@ function getHierarchyNodeCopy(node2, traceById) {
38615
38659
  }
38616
38660
  function getTraceDisplayCopy(trace) {
38617
38661
  const actor = trace.hierarchy.childActorId || trace.hierarchy.rootActorId;
38662
+ const pathParts = getTracePathParts(trace);
38663
+ return {
38664
+ path: pathParts.join(" / "),
38665
+ pathParts,
38666
+ subtitle: formatList([actor, trace.provider, trace.model]),
38667
+ title: getTraceTitle(trace)
38668
+ };
38669
+ }
38670
+ function getTracePathParts(trace) {
38618
38671
  const pathParts = [
38619
38672
  `Session ${shortId(trace.hierarchy.sessionId)}`,
38620
38673
  trace.hierarchy.rootActorId
@@ -38633,11 +38686,13 @@ function getTraceDisplayCopy(trace) {
38633
38686
  pathParts.push(`Stage: ${trace.hierarchy.stage}`);
38634
38687
  }
38635
38688
  }
38636
- return {
38637
- path: pathParts.join(" / "),
38638
- subtitle: formatList([actor, trace.provider, trace.model]),
38639
- title: getTraceTitle(trace)
38640
- };
38689
+ return pathParts;
38690
+ }
38691
+ function formatTraceProviderSummary(trace) {
38692
+ if (!trace) {
38693
+ return null;
38694
+ }
38695
+ return formatList([trace.provider, trace.model]);
38641
38696
  }
38642
38697
  function groupTracesForNav(items) {
38643
38698
  const groups = /* @__PURE__ */ new Map();
@@ -39003,6 +39058,12 @@ function mergeTagFilter(current, nextEntry) {
39003
39058
  }
39004
39059
  return [...existing, nextEntry].join(",");
39005
39060
  }
39061
+ function countTagFilters(value) {
39062
+ if (!value.trim()) {
39063
+ return 0;
39064
+ }
39065
+ return value.split(",").map((entry) => entry.trim()).filter(Boolean).length;
39066
+ }
39006
39067
  function getHierarchyNodeCostUsd(node2) {
39007
39068
  return typeof node2?.meta?.costUsd === "number" && Number.isFinite(node2.meta.costUsd) ? node2.meta.costUsd : null;
39008
39069
  }
@@ -39086,7 +39147,7 @@ function createCurrencyMetadataEntry(label, rawValue, secondary) {
39086
39147
  label,
39087
39148
  monospace: false,
39088
39149
  secondary,
39089
- value: formatUsdCost(rawValue) || `$${rawValue.toFixed(4)}`
39150
+ value: formatUsdCost(rawValue) ?? "$0.0000"
39090
39151
  };
39091
39152
  }
39092
39153
  function getUsageSegmentCostUsd(usage, segment) {
@@ -39554,6 +39615,17 @@ function getSemanticBadgeValue(value) {
39554
39615
  return "session";
39555
39616
  case "actor":
39556
39617
  return "actor";
39618
+ case "assistant":
39619
+ return "assistant";
39620
+ case "user":
39621
+ return "user";
39622
+ case "system":
39623
+ return "system";
39624
+ case "tool":
39625
+ return "tool";
39626
+ case "tool call":
39627
+ case "tool-call":
39628
+ return "tool-call";
39557
39629
  case "guardrail":
39558
39630
  return "guardrail";
39559
39631
  case "call":
@@ -39759,13 +39831,13 @@ var init_app = __esm({
39759
39831
  init_theme();
39760
39832
  import_jsx_runtime2 = __toESM(require_jsx_runtime());
39761
39833
  MESSAGE_COLLAPSE_CHAR_LIMIT = 900;
39762
- MESSAGE_COLLAPSE_LINE_LIMIT = 12;
39763
- MESSAGE_COLLAPSE_HEIGHT_PROSE = "6.5rem";
39764
- MESSAGE_COLLAPSE_HEIGHT_STRUCTURED = "10.75rem";
39765
- MESSAGE_COLLAPSE_CHAR_LIMIT_SYSTEM = 320;
39766
- MESSAGE_COLLAPSE_LINE_LIMIT_SYSTEM = 4;
39767
- MESSAGE_COLLAPSE_HEIGHT_PROSE_SYSTEM = "4.6rem";
39768
- MESSAGE_COLLAPSE_HEIGHT_STRUCTURED_SYSTEM = "7rem";
39834
+ MESSAGE_COLLAPSE_LINE_LIMIT = 10;
39835
+ MESSAGE_COLLAPSE_HEIGHT_PROSE = "9rem";
39836
+ MESSAGE_COLLAPSE_HEIGHT_STRUCTURED = "9rem";
39837
+ MESSAGE_COLLAPSE_CHAR_LIMIT_SYSTEM = 500;
39838
+ MESSAGE_COLLAPSE_LINE_LIMIT_SYSTEM = 5;
39839
+ MESSAGE_COLLAPSE_HEIGHT_PROSE_SYSTEM = "9rem";
39840
+ MESSAGE_COLLAPSE_HEIGHT_STRUCTURED_SYSTEM = "9rem";
39769
39841
  TIMELINE_AXIS_STOPS = [0, 0.25, 0.5, 0.75, 1];
39770
39842
  STATUS_OPTIONS = [
39771
39843
  { label: "All statuses", value: "" },
@@ -39872,6 +39944,7 @@ lucide-react/dist/esm/icons/arrow-up-right.js:
39872
39944
  lucide-react/dist/esm/icons/bot.js:
39873
39945
  lucide-react/dist/esm/icons/boxes.js:
39874
39946
  lucide-react/dist/esm/icons/check.js:
39947
+ lucide-react/dist/esm/icons/chevron-right.js:
39875
39948
  lucide-react/dist/esm/icons/copy.js:
39876
39949
  lucide-react/dist/esm/icons/funnel.js:
39877
39950
  lucide-react/dist/esm/icons/moon.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mtharrison/loupe",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Lightweight local tracing dashboard for LLM calls",
5
5
  "author": "Matt Harrison",
6
6
  "license": "MIT",