@copilotkit/web-inspector 1.69.2 → 1.69.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.
package/dist/index.mjs CHANGED
@@ -242,6 +242,21 @@ const LAUNCHER_BASE_LABEL = "Web Inspector";
242
242
  const EDGE_MARGIN = 16;
243
243
  /** HUD card plus the hover bridge. Used to pick left vs right. */
244
244
  const LAUNCHER_HUD_WIDTH = 248;
245
+ /**
246
+ * One page-load preview of the launcher's feature HUD.
247
+ *
248
+ * The card arrives after the host page has had a beat to settle. Its four rows
249
+ * then come online in order, stay readable, and leave together. Nothing is
250
+ * persisted: a new Inspector element means a new preview.
251
+ */
252
+ const LAUNCHER_HUD_INTRO_MS = {
253
+ delay: 500,
254
+ duration: 3400,
255
+ rowStart: 180,
256
+ rowStagger: 170,
257
+ rowDuration: 300,
258
+ blockedRetry: 250
259
+ };
245
260
  const DRAG_THRESHOLD = 6;
246
261
  const MIN_WINDOW_WIDTH = 880;
247
262
  const MIN_WINDOW_WIDTH_DOCKED_LEFT = 640;
@@ -347,6 +362,29 @@ const AGENT_EVENT_TYPES = [
347
362
  "ACTIVITY_SNAPSHOT",
348
363
  "ACTIVITY_DELTA"
349
364
  ];
365
+ const EMPTY_INSPECTOR_MESSAGES = [];
366
+ function textFromUnknownContent(content) {
367
+ if (typeof content === "string") return content;
368
+ if (Array.isArray(content)) {
369
+ const parts = [];
370
+ for (const part of content) {
371
+ if (typeof part === "string") {
372
+ parts.push(part);
373
+ continue;
374
+ }
375
+ if (typeof part === "object" && part !== null && "text" in part) {
376
+ const text = part.text;
377
+ if (typeof text === "string") parts.push(text);
378
+ }
379
+ }
380
+ return parts.join("");
381
+ }
382
+ if (typeof content === "object" && content !== null && "text" in content) {
383
+ const text = content.text;
384
+ if (typeof text === "string") return text;
385
+ }
386
+ return "";
387
+ }
350
388
  /**
351
389
  * Map core.tools (the registry INCLUDING disabled tools) into Capabilities-tab
352
390
  * frontend-tool rows. Pure: no DOM, no `this`. Reads current on/off state from
@@ -605,13 +643,6 @@ function highlightedJson(obj) {
605
643
  const cached = highlightedJsonCache.get(obj);
606
644
  if (cached !== void 0) return cached;
607
645
  }
608
- const colors = {
609
- key: "#5558B2",
610
- str: "#087653",
611
- num: "#8a5900",
612
- bool: "#c0333a",
613
- nil: "#68686e"
614
- };
615
646
  const json = JSON.stringify(obj, null, 2);
616
647
  if (!json) return "";
617
648
  const parts = [];
@@ -621,11 +652,11 @@ function highlightedJson(obj) {
621
652
  while ((match = re.exec(json)) !== null) {
622
653
  parts.push(escapeHtml(json.slice(lastIndex, match.index)));
623
654
  const m = match[0];
624
- let color = colors.num;
625
- if (m.startsWith("\"")) color = m.trimEnd().endsWith(":") ? colors.key : colors.str;
626
- else if (m === "true" || m === "false") color = colors.bool;
627
- else if (m === "null") color = colors.nil;
628
- parts.push(`<span style="color:${color}">${escapeHtml(m)}</span>`);
655
+ let token = "num";
656
+ if (m.startsWith("\"")) token = m.trimEnd().endsWith(":") ? "key" : "str";
657
+ else if (m === "true" || m === "false") token = "bool";
658
+ else if (m === "null") token = "nil";
659
+ parts.push(`<span class="cpk-json-token cpk-json-token--${token}">${escapeHtml(m)}</span>`);
629
660
  lastIndex = match.index + m.length;
630
661
  }
631
662
  parts.push(escapeHtml(json.slice(lastIndex)));
@@ -650,31 +681,23 @@ function renderHighlightedJsonBlock(value, options = {}) {
650
681
  ${unsafeHTML(highlightedJson(parsed))}</pre
651
682
  >`;
652
683
  }
653
- function eventColors(type) {
654
- if (type.startsWith("TEXT_MESSAGE")) return {
655
- bg: "#EEE6FE",
656
- fg: "#57575B"
657
- };
658
- if (type.startsWith("TOOL_CALL")) return {
659
- bg: "rgba(133,236,206,0.15)",
660
- fg: "#087653"
661
- };
662
- if (type.startsWith("STATE")) return {
663
- bg: "rgba(190,194,255,0.102)",
664
- fg: "#5558B2"
665
- };
666
- if (type === "RUN_ERROR" || type === "ERROR") return {
667
- bg: "rgba(250,95,103,0.13)",
668
- fg: "#c0333a"
669
- };
670
- if (type.startsWith("RUN_") || type.startsWith("STEP_")) return {
671
- bg: "rgba(255,172,77,0.2)",
672
- fg: "#8a5900"
673
- };
674
- return {
675
- bg: "#F7F7F9",
676
- fg: "#68686e"
677
- };
684
+ function humanizeEventType(type) {
685
+ const words = type.trim().split(/[_\s]+/).filter(Boolean).map((word) => word.toLowerCase());
686
+ if (words.length === 0) return "Event";
687
+ const [first = "event", ...rest] = words;
688
+ return [`${first.charAt(0).toUpperCase()}${first.slice(1)}`, ...rest].join(" ");
689
+ }
690
+ function messageTitle(role) {
691
+ const normalized = role.trim() || "message";
692
+ return `${`${normalized.charAt(0).toUpperCase()}${normalized.slice(1).toLowerCase()}`} message`;
693
+ }
694
+ function eventCategory(type) {
695
+ if (type === "RUN_ERROR" || type === "ERROR") return "error";
696
+ if (type.startsWith("TEXT_MESSAGE")) return "message";
697
+ if (type.startsWith("TOOL_CALL")) return "tool";
698
+ if (type.startsWith("STATE") || type.startsWith("MESSAGES")) return "state";
699
+ if (type.startsWith("RUN_") || type.startsWith("STEP_")) return "run";
700
+ return "event";
678
701
  }
679
702
  function formatTimestamp(ts) {
680
703
  const date = typeof ts === "number" ? new Date(ts) : new Date(ts);
@@ -1076,6 +1099,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1076
1099
  this.threadInspectionAvailable = false;
1077
1100
  this.agentStateInput = null;
1078
1101
  this.agentEventsInput = [];
1102
+ this.agentMessagesInput = EMPTY_INSPECTOR_MESSAGES;
1079
1103
  this.liveMessageVersion = 0;
1080
1104
  this.viewInAppMode = "hidden";
1081
1105
  this.viewInAppError = null;
@@ -1151,6 +1175,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1151
1175
  threadInspectionAvailable: { attribute: false },
1152
1176
  agentStateInput: { attribute: false },
1153
1177
  agentEventsInput: { attribute: false },
1178
+ agentMessagesInput: { attribute: false },
1154
1179
  liveMessageVersion: { attribute: false },
1155
1180
  viewInAppMode: { attribute: false },
1156
1181
  viewInAppError: { attribute: false },
@@ -1295,6 +1320,11 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1295
1320
  display: flex;
1296
1321
  flex-direction: row;
1297
1322
  overflow: hidden;
1323
+ --cpk-json-key: #3d408f;
1324
+ --cpk-json-str: #0b6b4c;
1325
+ --cpk-json-num: #8a5900;
1326
+ --cpk-json-bool: #c0333a;
1327
+ --cpk-json-nil: #57575b;
1298
1328
  }
1299
1329
 
1300
1330
  .cpk-td {
@@ -1419,11 +1449,25 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1419
1449
  flex-shrink: 0;
1420
1450
  }
1421
1451
 
1422
- .cpk-td__metadata-strip {
1452
+ .cpk-td__chrome-actions {
1453
+ margin-inline-start: auto;
1423
1454
  display: flex;
1455
+ flex-wrap: wrap;
1424
1456
  align-items: center;
1457
+ justify-content: flex-end;
1425
1458
  gap: 6px;
1426
- flex-wrap: wrap;
1459
+ padding-inline: 8px;
1460
+ min-width: 0;
1461
+ }
1462
+
1463
+ .cpk-td__chrome-actions + .cpk-td__panel-toggle {
1464
+ margin-inline-start: 0;
1465
+ }
1466
+
1467
+ .cpk-td__metadata-strip {
1468
+ display: flex;
1469
+ flex-direction: column;
1470
+ gap: 8px;
1427
1471
  padding: 10px 16px;
1428
1472
  border-bottom: 1px solid #e9e9ef;
1429
1473
  background: #fbfbfd;
@@ -1432,19 +1476,22 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1432
1476
 
1433
1477
  .cpk-td__metadata-pills {
1434
1478
  display: flex;
1479
+ align-items: center;
1435
1480
  gap: 6px;
1436
- flex: 1;
1437
- flex-wrap: wrap;
1481
+ width: 100%;
1438
1482
  min-width: 0;
1483
+ flex-wrap: nowrap;
1439
1484
  }
1440
1485
 
1441
1486
  .cpk-td__metadata-pill {
1442
1487
  display: inline-flex;
1443
1488
  align-items: center;
1444
- gap: 5px;
1445
- max-width: 220px;
1446
- padding: 3px 7px;
1447
- border: 1px solid #e9e9ef;
1489
+ gap: 6px;
1490
+ flex: 1 1 0;
1491
+ min-width: 0;
1492
+ height: 24px;
1493
+ padding: 0 8px;
1494
+ border: 1px solid #dbdbe5;
1448
1495
  border-radius: 6px;
1449
1496
  background: #ffffff;
1450
1497
  color: #57575b;
@@ -1460,20 +1507,17 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1460
1507
  }
1461
1508
 
1462
1509
  .cpk-td__metadata-value {
1510
+ min-width: 0;
1463
1511
  overflow: hidden;
1464
1512
  text-overflow: ellipsis;
1513
+ white-space: nowrap;
1465
1514
  }
1466
1515
 
1516
+ .cpk-td__metadata-value--wrap,
1467
1517
  .cpk-td__metadata-pill--wrap {
1468
- max-width: 100%;
1469
- white-space: normal;
1470
- }
1471
-
1472
- .cpk-td__metadata-value--wrap {
1473
- overflow: visible;
1474
- text-overflow: clip;
1475
- white-space: normal;
1476
- overflow-wrap: anywhere;
1518
+ overflow: hidden;
1519
+ text-overflow: ellipsis;
1520
+ white-space: nowrap;
1477
1521
  }
1478
1522
 
1479
1523
  .cpk-td__view-in-app {
@@ -1484,11 +1528,18 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1484
1528
  border-radius: 6px;
1485
1529
  background: #5558b2;
1486
1530
  color: #ffffff;
1487
- font-family: "Plus Jakarta Sans", sans-serif;
1488
- font-size: 11px;
1531
+ font-family: "Spline Sans Mono", monospace;
1532
+ font-size: 10px;
1489
1533
  font-weight: 600;
1490
- padding: 5px 10px;
1534
+ line-height: 1.2;
1535
+ min-height: 24px;
1536
+ padding: 3px 8px;
1491
1537
  cursor: pointer;
1538
+ transition:
1539
+ transform 160ms cubic-bezier(0.23, 1, 0.32, 1),
1540
+ background 120ms ease,
1541
+ color 120ms ease,
1542
+ border-color 120ms ease;
1492
1543
  }
1493
1544
 
1494
1545
  .cpk-td__view-in-app:focus-visible {
@@ -1496,6 +1547,10 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1496
1547
  outline-offset: 2px;
1497
1548
  }
1498
1549
 
1550
+ .cpk-td__view-in-app:active {
1551
+ transform: scale(0.96);
1552
+ }
1553
+
1499
1554
  .cpk-td__view-in-app--stop {
1500
1555
  background: #ffffff;
1501
1556
  color: #5558b2;
@@ -1507,6 +1562,16 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1507
1562
  font-size: 11px;
1508
1563
  }
1509
1564
 
1565
+ @media (prefers-reduced-motion: reduce) {
1566
+ .cpk-td__view-in-app {
1567
+ transition: none;
1568
+ }
1569
+
1570
+ .cpk-td__view-in-app:active {
1571
+ transform: none;
1572
+ }
1573
+ }
1574
+
1510
1575
  /*
1511
1576
  * Each tab's content is wrapped in this panel so the keep-mounted
1512
1577
  * inactive panels can be hidden via display:none without disturbing
@@ -1703,15 +1768,16 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1703
1768
  .cpk-td__tool-pre {
1704
1769
  margin: 0;
1705
1770
  font-family: "Spline Sans Mono", monospace;
1706
- font-size: 10px;
1771
+ font-size: 12px;
1707
1772
  background: #f7f7f9;
1708
- padding: 6px 8px;
1709
- border-radius: 5px;
1773
+ padding: 10px 12px;
1774
+ border-radius: 6px;
1710
1775
  overflow-x: auto;
1711
1776
  white-space: pre-wrap;
1712
- word-break: break-all;
1777
+ overflow-wrap: anywhere;
1778
+ word-break: normal;
1713
1779
  color: #010507;
1714
- line-height: 1.6;
1780
+ line-height: 1.65;
1715
1781
  }
1716
1782
 
1717
1783
  /* ── Tool call group ─────────────────────────────────────────────── */
@@ -1764,12 +1830,31 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1764
1830
 
1765
1831
  /* ── Interaction timeline ───────────────────────────────────────── */
1766
1832
  .cpk-td__timeline-item {
1767
- border: 1px solid #e9e9ef;
1768
- border-radius: 7px;
1769
- background: #ffffff;
1833
+ border: 1px solid transparent;
1834
+ border-radius: 10px;
1835
+ background: transparent;
1770
1836
  overflow: hidden;
1771
1837
  }
1772
1838
 
1839
+ .cpk-td__timeline-item--run,
1840
+ .cpk-td__timeline-item--state,
1841
+ .cpk-td__timeline-item--event,
1842
+ .cpk-td__timeline-item--tool,
1843
+ .cpk-td__event--run,
1844
+ .cpk-td__event--event,
1845
+ .cpk-td__event--state,
1846
+ .cpk-td__event--message,
1847
+ .cpk-td__event--tool {
1848
+ border-color: #dbdbe5;
1849
+ background: #ffffff;
1850
+ }
1851
+
1852
+ .cpk-td__timeline-item--message {
1853
+ border-color: #dbdbe5;
1854
+ background: #ffffff;
1855
+ box-shadow: 0 1px 2px #0105070d;
1856
+ }
1857
+
1773
1858
  .cpk-td__timeline-item--warning {
1774
1859
  border-color: rgba(250, 95, 103, 0.35);
1775
1860
  background: rgba(250, 95, 103, 0.04);
@@ -1779,29 +1864,72 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1779
1864
  display: flex;
1780
1865
  align-items: center;
1781
1866
  gap: 8px;
1782
- padding: 7px 10px;
1867
+ padding: 6px 10px;
1868
+ background: transparent;
1869
+ }
1870
+
1871
+ .cpk-td__timeline-item--message .cpk-td__timeline-header {
1872
+ padding: 10px 12px;
1783
1873
  background: #f7f7f9;
1784
1874
  }
1785
1875
 
1876
+ .cpk-td__timeline-item--user .cpk-td__timeline-header {
1877
+ background: #bec2ff1a;
1878
+ }
1879
+
1880
+ .cpk-td__timeline-item--assistant .cpk-td__timeline-header {
1881
+ background: #85ecce1a;
1882
+ }
1883
+
1786
1884
  .cpk-td__timeline-kind {
1885
+ display: inline-flex;
1886
+ align-items: center;
1887
+ padding: 4px 8px;
1888
+ border-radius: 999px;
1889
+ background: #f0f0f4;
1890
+ color: #57575b;
1787
1891
  font-family: "Spline Sans Mono", monospace;
1788
- font-size: 9px;
1892
+ font-size: 10px;
1789
1893
  font-weight: 600;
1894
+ letter-spacing: 0.04em;
1895
+ line-height: 1.2;
1790
1896
  text-transform: uppercase;
1791
- color: #5558b2;
1897
+ flex-shrink: 0;
1898
+ }
1899
+
1900
+ .cpk-td__timeline-item--message .cpk-td__timeline-kind {
1901
+ background: #bec2ff33;
1902
+ color: #010507;
1903
+ }
1904
+
1905
+ .cpk-td__timeline-item--assistant .cpk-td__timeline-kind {
1906
+ background: #85ecce4d;
1907
+ color: #010507;
1908
+ }
1909
+
1910
+ .cpk-td__timeline-item--warning .cpk-td__timeline-kind {
1911
+ background: rgba(250, 95, 103, 0.16);
1912
+ color: #c0333a;
1792
1913
  }
1793
1914
 
1794
1915
  .cpk-td__timeline-title {
1795
1916
  flex: 1;
1796
1917
  min-width: 0;
1918
+ font-family: "Plus Jakarta Sans", sans-serif;
1797
1919
  font-size: 12px;
1798
1920
  font-weight: 500;
1799
- color: #010507;
1921
+ color: #57575b;
1800
1922
  overflow: hidden;
1801
1923
  text-overflow: ellipsis;
1802
1924
  white-space: nowrap;
1803
1925
  }
1804
1926
 
1927
+ .cpk-td__timeline-item--message .cpk-td__timeline-title {
1928
+ font-size: 13px;
1929
+ font-weight: 600;
1930
+ color: #010507;
1931
+ }
1932
+
1805
1933
  .cpk-td__timeline-time {
1806
1934
  font-family: "Spline Sans Mono", monospace;
1807
1935
  font-size: 9px;
@@ -1812,6 +1940,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1812
1940
  .cpk-td__timeline-body {
1813
1941
  margin: 0;
1814
1942
  padding: 0 10px 9px;
1943
+ font-family: "Plus Jakarta Sans", sans-serif;
1815
1944
  font-size: 12px;
1816
1945
  line-height: 1.55;
1817
1946
  color: #57575b;
@@ -1819,21 +1948,26 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1819
1948
  word-break: break-word;
1820
1949
  }
1821
1950
 
1951
+ .cpk-td__timeline-item--message .cpk-td__timeline-body {
1952
+ padding: 0 12px 12px;
1953
+ font-size: 13px;
1954
+ color: #010507;
1955
+ }
1956
+
1822
1957
  .cpk-td__timeline-toolbar {
1823
1958
  display: flex;
1824
1959
  gap: 6px;
1825
- margin-left: auto;
1826
1960
  }
1827
1961
 
1828
1962
  .cpk-td__timeline-bulk-toggle {
1829
1963
  margin: 0;
1830
- padding: 4px 8px;
1831
- border: 1px solid #dcdce8;
1832
- border-radius: 7px;
1964
+ padding: 6px 10px;
1965
+ border: 1px solid #dbdbe5;
1966
+ border-radius: 8px;
1833
1967
  background: #ffffff;
1834
1968
  color: #36363a;
1835
1969
  cursor: pointer;
1836
- font-family: "Inter", sans-serif;
1970
+ font-family: "Spline Sans Mono", monospace;
1837
1971
  font-size: 11px;
1838
1972
  font-weight: 600;
1839
1973
  line-height: 1.2;
@@ -1908,84 +2042,6 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1908
2042
  }
1909
2043
  }
1910
2044
 
1911
- @keyframes cpk-playground-message-enter {
1912
- from {
1913
- opacity: 0;
1914
- filter: blur(2px);
1915
- transform: translateY(4px);
1916
- }
1917
- to {
1918
- opacity: 1;
1919
- filter: blur(0);
1920
- transform: translateY(0);
1921
- }
1922
- }
1923
-
1924
- @keyframes cpk-playground-thinking {
1925
- 0%,
1926
- 60%,
1927
- 100% {
1928
- opacity: 0.28;
1929
- transform: translateY(0);
1930
- }
1931
- 30% {
1932
- opacity: 1;
1933
- transform: translateY(-2px);
1934
- }
1935
- }
1936
-
1937
- .cpk-playground-root {
1938
- container-type: inline-size;
1939
- }
1940
-
1941
- .cpk-playground-message-enter {
1942
- animation: cpk-playground-message-enter 0.24s cubic-bezier(0.16, 1, 0.3, 1)
1943
- both;
1944
- }
1945
-
1946
- .cpk-playground-thinking-dot {
1947
- animation: cpk-playground-thinking 1.2s ease-in-out infinite;
1948
- }
1949
-
1950
- .cpk-playground-thinking-dot:nth-child(2) {
1951
- animation-delay: 0.12s;
1952
- }
1953
-
1954
- .cpk-playground-thinking-dot:nth-child(3) {
1955
- animation-delay: 0.24s;
1956
- }
1957
-
1958
- .cpk-playground-reasoning summary::-webkit-details-marker {
1959
- display: none;
1960
- }
1961
-
1962
- .cpk-playground-reasoning[open] .cpk-playground-reasoning-chevron {
1963
- transform: rotate(90deg);
1964
- }
1965
-
1966
- @container (max-width: 560px) {
1967
- .cpk-playground-header {
1968
- align-items: stretch;
1969
- }
1970
-
1971
- .cpk-playground-actions {
1972
- width: 100%;
1973
- }
1974
-
1975
- .cpk-playground-thread-select {
1976
- min-width: 0;
1977
- max-width: none;
1978
- flex: 1;
1979
- }
1980
- }
1981
-
1982
- @media (prefers-reduced-motion: reduce) {
1983
- .cpk-playground-message-enter,
1984
- .cpk-playground-thinking-dot {
1985
- animation: none;
1986
- }
1987
- }
1988
-
1989
2045
  .cpk-td__genui {
1990
2046
  display: flex;
1991
2047
  flex-direction: column;
@@ -2027,8 +2083,9 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2027
2083
  /* ── AG-UI Events ────────────────────────────────────────────────── */
2028
2084
  .cpk-td__event {
2029
2085
  flex-shrink: 0;
2030
- border: 1px solid #e9e9ef;
2031
- border-radius: 7px;
2086
+ border: 1px solid #dbdbe5;
2087
+ border-radius: 10px;
2088
+ background: #ffffff;
2032
2089
  overflow: hidden;
2033
2090
  /*
2034
2091
  * content-visibility: auto lets the browser skip layout + paint for
@@ -2044,48 +2101,89 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2044
2101
  contain-intrinsic-size: 0 80px;
2045
2102
  }
2046
2103
 
2104
+ .cpk-td__event--error {
2105
+ border-color: rgba(250, 95, 103, 0.35);
2106
+ background: rgba(250, 95, 103, 0.04);
2107
+ }
2108
+
2047
2109
  .cpk-td__event-header {
2048
2110
  display: flex;
2049
- justify-content: space-between;
2050
2111
  align-items: center;
2051
- padding: 5px 10px;
2112
+ gap: 8px;
2113
+ padding: 6px 10px;
2114
+ background: transparent;
2052
2115
  }
2053
2116
 
2054
2117
  .cpk-td__event-type {
2118
+ display: inline-flex;
2119
+ align-items: center;
2120
+ padding: 4px 8px;
2121
+ border-radius: 999px;
2122
+ background: #f0f0f4;
2123
+ color: #010507;
2055
2124
  font-family: "Spline Sans Mono", monospace;
2056
- font-size: 9px;
2057
- font-weight: 500;
2058
- text-transform: uppercase;
2125
+ font-size: 10px;
2126
+ font-weight: 600;
2127
+ letter-spacing: 0.02em;
2128
+ line-height: 1.2;
2129
+ }
2130
+
2131
+ .cpk-td__event--message .cpk-td__event-type {
2132
+ background: #bec2ff33;
2133
+ }
2134
+
2135
+ .cpk-td__event--tool .cpk-td__event-type {
2136
+ background: #85ecce4d;
2137
+ }
2138
+
2139
+ .cpk-td__event--error .cpk-td__event-type {
2140
+ background: rgba(250, 95, 103, 0.16);
2141
+ color: #c0333a;
2059
2142
  }
2060
2143
 
2061
2144
  .cpk-td__event-time {
2145
+ margin-inline-start: auto;
2062
2146
  font-family: "Spline Sans Mono", monospace;
2063
2147
  font-size: 9px;
2064
2148
  color: #68686e;
2149
+ flex-shrink: 0;
2065
2150
  }
2066
2151
 
2067
- .cpk-td__event-payload {
2068
- margin: 0;
2069
- font-family: "Spline Sans Mono", monospace;
2070
- font-size: 10px;
2071
- line-height: 1.6;
2072
- white-space: pre-wrap;
2073
- word-break: break-all;
2074
- color: #57575b;
2075
- padding: 8px 10px;
2076
- border-top: 1px solid #e9e9ef;
2077
- }
2078
-
2079
- /* ── JSON block (agent state) ────────────────────────────────────── */
2152
+ .cpk-td__event-payload,
2080
2153
  .cpk-td__json-block,
2081
2154
  .cpk-json-block {
2082
2155
  margin: 0;
2156
+ padding: 10px 12px;
2157
+ border-top: 1px solid #dbdbe5;
2158
+ background: #f7f7f9;
2083
2159
  font-family: "Spline Sans Mono", monospace;
2084
- font-size: 11px;
2085
- line-height: 1.8;
2160
+ font-size: 12px;
2161
+ line-height: 1.65;
2086
2162
  white-space: pre-wrap;
2087
- word-break: break-all;
2088
- color: #57575b;
2163
+ overflow-wrap: anywhere;
2164
+ word-break: normal;
2165
+ color: #010507;
2166
+ overflow: auto;
2167
+ }
2168
+
2169
+ .cpk-json-token--key {
2170
+ color: var(--cpk-json-key);
2171
+ }
2172
+
2173
+ .cpk-json-token--str {
2174
+ color: var(--cpk-json-str);
2175
+ }
2176
+
2177
+ .cpk-json-token--num {
2178
+ color: var(--cpk-json-num);
2179
+ }
2180
+
2181
+ .cpk-json-token--bool {
2182
+ color: var(--cpk-json-bool);
2183
+ }
2184
+
2185
+ .cpk-json-token--nil {
2186
+ color: var(--cpk-json-nil);
2089
2187
  }
2090
2188
 
2091
2189
  /* ── Resize divider ──────────────────────────────────────────────── */
@@ -2184,6 +2282,11 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2184
2282
 
2185
2283
  :host([data-color-scheme="dark"]) {
2186
2284
  color-scheme: dark;
2285
+ --cpk-json-key: #bec2ff;
2286
+ --cpk-json-str: #85ecce;
2287
+ --cpk-json-num: #ffac4d;
2288
+ --cpk-json-bool: #fa5f67;
2289
+ --cpk-json-nil: #afafb7;
2187
2290
  }
2188
2291
 
2189
2292
  :host([data-color-scheme="dark"]) .cpk-td {
@@ -2224,11 +2327,15 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2224
2327
  }
2225
2328
 
2226
2329
  :host([data-color-scheme="dark"]) .cpk-td__timeline-header,
2227
- :host([data-color-scheme="dark"]) .cpk-td__tool-body,
2228
- :host([data-color-scheme="dark"]) .cpk-td__tool-pre {
2330
+ :host([data-color-scheme="dark"]) .cpk-td__tool-body {
2229
2331
  background: #171a22;
2230
2332
  }
2231
2333
 
2334
+ :host([data-color-scheme="dark"]) .cpk-td__tool-pre {
2335
+ background: #111319;
2336
+ color: #f3f4f8;
2337
+ }
2338
+
2232
2339
  :host([data-color-scheme="dark"]) .cpk-td__panel-toggle:hover,
2233
2340
  :host([data-color-scheme="dark"]) .cpk-td__tool-header:hover,
2234
2341
  :host([data-color-scheme="dark"]) .cpk-td__timeline-bulk-toggle:hover,
@@ -2238,12 +2345,115 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2238
2345
 
2239
2346
  :host([data-color-scheme="dark"]) .cpk-td__panel-toggle--active,
2240
2347
  :host([data-color-scheme="dark"]) .cpk-td__inline-chip,
2241
- :host([data-color-scheme="dark"]) .cpk-td__timeline-kind,
2242
2348
  :host([data-color-scheme="dark"]) .cpk-td__genui-badge {
2243
2349
  background: #302b43;
2244
2350
  color: #d8d9ff;
2245
2351
  }
2246
2352
 
2353
+ :host([data-color-scheme="dark"]) .cpk-td__timeline-item--message {
2354
+ background: #191c24;
2355
+ border-color: #343742;
2356
+ box-shadow: none;
2357
+ }
2358
+
2359
+ :host([data-color-scheme="dark"])
2360
+ .cpk-td__timeline-item--user
2361
+ .cpk-td__timeline-header {
2362
+ background: #bec2ff1a;
2363
+ }
2364
+
2365
+ :host([data-color-scheme="dark"])
2366
+ .cpk-td__timeline-item--assistant
2367
+ .cpk-td__timeline-header {
2368
+ background: #85ecce1a;
2369
+ }
2370
+
2371
+ :host([data-color-scheme="dark"])
2372
+ .cpk-td__timeline-item--message
2373
+ .cpk-td__timeline-kind {
2374
+ background: #302b43;
2375
+ color: #d8d9ff;
2376
+ }
2377
+
2378
+ :host([data-color-scheme="dark"])
2379
+ .cpk-td__timeline-item--assistant
2380
+ .cpk-td__timeline-kind {
2381
+ background: #1a3a32;
2382
+ color: #85ecce;
2383
+ }
2384
+
2385
+ :host([data-color-scheme="dark"]) .cpk-td__timeline-item--run,
2386
+ :host([data-color-scheme="dark"]) .cpk-td__timeline-item--event,
2387
+ :host([data-color-scheme="dark"]) .cpk-td__timeline-item--state,
2388
+ :host([data-color-scheme="dark"]) .cpk-td__timeline-item--tool,
2389
+ :host([data-color-scheme="dark"]) .cpk-td__event--run,
2390
+ :host([data-color-scheme="dark"]) .cpk-td__event--event,
2391
+ :host([data-color-scheme="dark"]) .cpk-td__event--state,
2392
+ :host([data-color-scheme="dark"]) .cpk-td__event--message,
2393
+ :host([data-color-scheme="dark"]) .cpk-td__event--tool {
2394
+ background: #191c24;
2395
+ border-color: #343742;
2396
+ }
2397
+
2398
+ :host([data-color-scheme="dark"])
2399
+ .cpk-td__timeline-item--run
2400
+ .cpk-td__timeline-header,
2401
+ :host([data-color-scheme="dark"])
2402
+ .cpk-td__timeline-item--event
2403
+ .cpk-td__timeline-header,
2404
+ :host([data-color-scheme="dark"])
2405
+ .cpk-td__timeline-item--state
2406
+ .cpk-td__timeline-header {
2407
+ background: transparent;
2408
+ }
2409
+
2410
+ :host([data-color-scheme="dark"]) .cpk-td__timeline-kind {
2411
+ background: #20232d;
2412
+ color: #aeb1bd;
2413
+ }
2414
+
2415
+ :host([data-color-scheme="dark"])
2416
+ .cpk-td__timeline-item--run
2417
+ .cpk-td__timeline-title,
2418
+ :host([data-color-scheme="dark"])
2419
+ .cpk-td__timeline-item--event
2420
+ .cpk-td__timeline-title,
2421
+ :host([data-color-scheme="dark"])
2422
+ .cpk-td__timeline-item--state
2423
+ .cpk-td__timeline-title {
2424
+ color: #aeb1bd;
2425
+ }
2426
+
2427
+ :host([data-color-scheme="dark"]) .cpk-td__event-header {
2428
+ background: transparent;
2429
+ }
2430
+
2431
+ :host([data-color-scheme="dark"]) .cpk-td__event-type {
2432
+ background: #20232d;
2433
+ color: #f3f4f8;
2434
+ }
2435
+
2436
+ :host([data-color-scheme="dark"]) .cpk-td__event--message .cpk-td__event-type {
2437
+ background: #302b43;
2438
+ color: #d8d9ff;
2439
+ }
2440
+
2441
+ :host([data-color-scheme="dark"]) .cpk-td__event--tool .cpk-td__event-type {
2442
+ background: #1a3a32;
2443
+ color: #85ecce;
2444
+ }
2445
+
2446
+ :host([data-color-scheme="dark"]) .cpk-td__event--error .cpk-td__event-type {
2447
+ background: rgba(250, 95, 103, 0.2);
2448
+ color: #fa5f67;
2449
+ }
2450
+
2451
+ :host([data-color-scheme="dark"])
2452
+ .cpk-td__timeline-item--message
2453
+ .cpk-td__timeline-body {
2454
+ color: #f3f4f8;
2455
+ }
2456
+
2247
2457
  :host([data-color-scheme="dark"]) .cpk-td__tab,
2248
2458
  :host([data-color-scheme="dark"]) .cpk-td__panel-toggle,
2249
2459
  :host([data-color-scheme="dark"]) .cpk-td__metadata-label,
@@ -2270,7 +2480,9 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2270
2480
  :host([data-color-scheme="dark"]) .cpk-td__event-payload,
2271
2481
  :host([data-color-scheme="dark"]) .cpk-td__json-block,
2272
2482
  :host([data-color-scheme="dark"]) .cpk-json-block {
2273
- color: #c7c9d2;
2483
+ background: #111319;
2484
+ border-top-color: #343742;
2485
+ color: #f3f4f8;
2274
2486
  }
2275
2487
 
2276
2488
  :host([data-color-scheme="dark"]) .cpk-tdp__divider {
@@ -2290,7 +2502,8 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2290
2502
  if (this.canFetchEvents()) {
2291
2503
  this._eventsFetched = true;
2292
2504
  this.fetchEvents(this.threadId);
2293
- } else this.fetchMessages(this.threadId);
2505
+ }
2506
+ if (this.canFetchMessages()) this.fetchMessages(this.threadId);
2294
2507
  } else {
2295
2508
  this._fetchedMetadata = null;
2296
2509
  this._conversation = [];
@@ -2301,7 +2514,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2301
2514
  this._messagesAbort = null;
2302
2515
  this.fetchMessages(this.threadId, true);
2303
2516
  }
2304
- const focusedContentChanged = _changed.has("_fetchedEvents") || _changed.has("agentEventsInput") || _changed.has("_conversation");
2517
+ const focusedContentChanged = _changed.has("_fetchedEvents") || _changed.has("agentEventsInput") || _changed.has("agentMessagesInput") || _changed.has("_conversation");
2305
2518
  if (this.focusMessageId && (this.focusRequestId > this._scrolledFocusRequestId || focusedContentChanged)) {
2306
2519
  if (this._tab !== "timeline") {
2307
2520
  this._activatedTabs = new Set([...this._activatedTabs, "timeline"]);
@@ -2458,18 +2671,14 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2458
2671
  if (result.status === "not-available") {
2459
2672
  this._eventsNotAvailable = true;
2460
2673
  this._fetchedEvents = [];
2461
- if (this.canFetchMessages()) this.fetchMessages(threadId);
2462
2674
  return;
2463
2675
  }
2464
- const mappedEvents = this.mapApiEvents(result.events);
2465
- this._fetchedEvents = mappedEvents;
2466
- if (mappedEvents.length === 0 && this.canFetchMessages()) this.fetchMessages(threadId);
2676
+ this._fetchedEvents = this.mapApiEvents(result.events);
2467
2677
  } catch (err) {
2468
2678
  if (err instanceof Error && err.name === "AbortError") return;
2469
2679
  if (this.threadId !== threadId) return;
2470
2680
  this._eventsError = err instanceof Error ? err.message : "Failed to load events";
2471
2681
  this._fetchedEvents = [];
2472
- if (this.canFetchMessages()) this.fetchMessages(threadId);
2473
2682
  } finally {
2474
2683
  if (!controller.signal.aborted && this.threadId === threadId) this._loadingEvents = false;
2475
2684
  }
@@ -2543,13 +2752,15 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2543
2752
  mapMessages(messages) {
2544
2753
  const items = [];
2545
2754
  const toolCallMap = /* @__PURE__ */ new Map();
2546
- for (const msg of messages) if (msg.role === "user" && msg.content) items.push({
2547
- id: msg.id,
2548
- type: "user",
2549
- content: msg.content,
2550
- createdAt: ""
2551
- });
2552
- else if (msg.role === "assistant") {
2755
+ for (const msg of messages) if (msg.role === "user") {
2756
+ const content = textFromUnknownContent(msg.content);
2757
+ if (content) items.push({
2758
+ id: msg.id,
2759
+ type: "user",
2760
+ content,
2761
+ createdAt: ""
2762
+ });
2763
+ } else if (msg.role === "assistant") {
2553
2764
  if (msg.toolCalls?.length) for (const tc of msg.toolCalls) {
2554
2765
  let args = {};
2555
2766
  if (typeof tc.args === "string") try {
@@ -2578,10 +2789,11 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2578
2789
  toolCallMap.set(tc.id, item);
2579
2790
  items.push(item);
2580
2791
  }
2581
- if (msg.content) items.push({
2792
+ const assistantContent = textFromUnknownContent(msg.content);
2793
+ if (assistantContent) items.push({
2582
2794
  id: msg.id,
2583
2795
  type: "assistant",
2584
- content: msg.content,
2796
+ content: assistantContent,
2585
2797
  createdAt: ""
2586
2798
  });
2587
2799
  } else if (msg.role === "activity") items.push({
@@ -2629,14 +2841,86 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2629
2841
  return this.timelineItemsForEvents(this.activeEvents);
2630
2842
  }
2631
2843
  timelineItemsForEvents(events) {
2632
- if (this._timelineItemsCache?.events === events) return this._timelineItemsCache.items;
2633
- const items = this.timelineItemsFromEvents(events);
2844
+ const conversation = this._conversation;
2845
+ const agentMessages = this.agentMessagesInput;
2846
+ if (this._timelineItemsCache?.events === events && this._timelineItemsCache.conversation === conversation && this._timelineItemsCache.agentMessages === agentMessages) return this._timelineItemsCache.items;
2847
+ const items = this.mergeUserMessagesIntoTimeline(this.timelineItemsFromEvents(events));
2634
2848
  this._timelineItemsCache = {
2635
2849
  events,
2850
+ conversation,
2851
+ agentMessages,
2636
2852
  items
2637
2853
  };
2638
2854
  return items;
2639
2855
  }
2856
+ conversationUsers() {
2857
+ const users = [];
2858
+ const seenIds = /* @__PURE__ */ new Set();
2859
+ const seenBodies = /* @__PURE__ */ new Set();
2860
+ const push = (user) => {
2861
+ const body = user.content.trim();
2862
+ if (!body) return;
2863
+ if (seenIds.has(user.id) || seenBodies.has(body)) return;
2864
+ seenIds.add(user.id);
2865
+ seenBodies.add(body);
2866
+ users.push(user);
2867
+ };
2868
+ for (const item of this._conversation) if (item.type === "user") push(item);
2869
+ this.agentMessagesInput.forEach((message, index) => {
2870
+ if (message.role !== "user") return;
2871
+ push({
2872
+ id: message.id ?? `live-user-${index}`,
2873
+ type: "user",
2874
+ content: message.contentText,
2875
+ createdAt: ""
2876
+ });
2877
+ });
2878
+ return users;
2879
+ }
2880
+ mergeUserMessagesIntoTimeline(items) {
2881
+ if (items.length === 0) return items;
2882
+ const users = this.conversationUsers();
2883
+ if (users.length === 0) return items;
2884
+ const shownIds = /* @__PURE__ */ new Set();
2885
+ const shownBodies = /* @__PURE__ */ new Set();
2886
+ for (const item of items) {
2887
+ if (item.kind !== "message") continue;
2888
+ if (!item.title.toLowerCase().startsWith("user")) continue;
2889
+ if (item.messageId) shownIds.add(item.messageId);
2890
+ const body = item.body?.trim();
2891
+ if (body) shownBodies.add(body);
2892
+ }
2893
+ const missing = users.filter((user) => {
2894
+ if (shownIds.has(user.id)) return false;
2895
+ if (shownBodies.has(user.content.trim())) return false;
2896
+ return true;
2897
+ });
2898
+ if (missing.length === 0) return items;
2899
+ const insertAt = [];
2900
+ for (let index = 0; index < items.length; index++) {
2901
+ const item = items[index];
2902
+ if (item.kind === "run" && item.title === "Run started") insertAt.push(index);
2903
+ }
2904
+ if (insertAt.length === 0) for (let index = 0; index < items.length; index++) {
2905
+ const item = items[index];
2906
+ if (item.kind === "message" && item.title.toLowerCase().includes("assistant")) insertAt.push(index);
2907
+ }
2908
+ const merged = [...items];
2909
+ for (let index = missing.length - 1; index >= 0; index--) {
2910
+ const user = missing[index];
2911
+ const row = {
2912
+ id: `conversation-user-${user.id}`,
2913
+ messageId: user.id,
2914
+ kind: "message",
2915
+ title: "User message",
2916
+ body: user.content,
2917
+ timestamp: user.createdAt || 0,
2918
+ sourceIndex: 0
2919
+ };
2920
+ merged.splice(insertAt[index] ?? 0, 0, row);
2921
+ }
2922
+ return merged;
2923
+ }
2640
2924
  timelineItemsFromEvents(events) {
2641
2925
  if (events.length === 0) return [];
2642
2926
  const items = [];
@@ -2675,7 +2959,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2675
2959
  id: `message-${key}`,
2676
2960
  messageId: key,
2677
2961
  kind: "message",
2678
- title: `${role || "message"} message`,
2962
+ title: messageTitle(role || "message"),
2679
2963
  body: "",
2680
2964
  timestamp: event.timestamp,
2681
2965
  sourceIndex
@@ -2823,7 +3107,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2823
3107
  items.push({
2824
3108
  id: `${type}-${sourceIndex}`,
2825
3109
  kind: "state",
2826
- title: type === "STATE_SNAPSHOT" ? "State snapshot captured" : "State delta captured",
3110
+ title: type === "STATE_SNAPSHOT" ? "State snapshot" : "State delta",
2827
3111
  timestamp: event.timestamp,
2828
3112
  sourceIndex,
2829
3113
  details: payload
@@ -2833,7 +3117,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2833
3117
  items.push({
2834
3118
  id: `event-${sourceIndex}`,
2835
3119
  kind: "event",
2836
- title: type,
3120
+ title: humanizeEventType(type),
2837
3121
  timestamp: event.timestamp,
2838
3122
  sourceIndex,
2839
3123
  details: payload
@@ -2972,6 +3256,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2972
3256
  });
2973
3257
  }
2974
3258
  render() {
3259
+ const viewInApp = this.renderViewInAppAction();
2975
3260
  return html`
2976
3261
  <div class="cpk-td">
2977
3262
  <!-- ── Left area: tabs + content ─────────────────────────────────── -->
@@ -2999,6 +3284,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2999
3284
  </button>
3000
3285
  `)}
3001
3286
  </div>
3287
+ ${viewInApp !== nothing ? html`<div class="cpk-td__chrome-actions">${viewInApp}</div>` : nothing}
3002
3288
  ${this.renderPanelToggle()}
3003
3289
  </div>
3004
3290
  ${this.renderMetadataStrip()}
@@ -3053,8 +3339,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3053
3339
  value: metadata?.name ?? this.thread?.name ?? "Untitled"
3054
3340
  }, {
3055
3341
  label: "ID",
3056
- value: metadata?.id ?? this.threadId ?? "—",
3057
- wrap: true
3342
+ value: metadata?.id ?? this.threadId ?? "—"
3058
3343
  }];
3059
3344
  for (const fact of [
3060
3345
  {
@@ -3076,7 +3361,6 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3076
3361
  value: fact.label === "Created" || fact.label === "Updated" ? this.fmtTime(fact.value) : fact.value
3077
3362
  });
3078
3363
  }
3079
- const bulkControls = this.renderActiveBulkControls();
3080
3364
  return html`
3081
3365
  <div
3082
3366
  class="cpk-td__metadata-strip"
@@ -3099,8 +3383,6 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3099
3383
  </span>
3100
3384
  `)}
3101
3385
  </div>
3102
- ${this.renderViewInAppAction()}
3103
- ${bulkControls}
3104
3386
  </div>
3105
3387
  `;
3106
3388
  }
@@ -3127,10 +3409,8 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3127
3409
  >` : nothing}
3128
3410
  `;
3129
3411
  }
3130
- renderActiveBulkControls() {
3412
+ renderTimelineBulkControls() {
3131
3413
  if (this._eventsNotAvailable) return nothing;
3132
- if (this._tab === "raw-events") return this.renderRawEventBulkControls();
3133
- if (this._tab !== "timeline") return nothing;
3134
3414
  const detailIds = this.timelineItemsForEvents(this.activeEvents).filter((item) => item.details).map((item) => item.id);
3135
3415
  if (detailIds.length <= 1) return nothing;
3136
3416
  return html`<div class="cpk-td__timeline-toolbar">
@@ -3203,7 +3483,12 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3203
3483
  `;
3204
3484
  }
3205
3485
  const events = this.activeEvents;
3206
- const cachedTimeline = this.getCachedPanelTpl("timeline", [events, this._expandedTimelineDetails]);
3486
+ const cachedTimeline = this.getCachedPanelTpl("timeline", [
3487
+ events,
3488
+ this._conversation,
3489
+ this.agentMessagesInput,
3490
+ this._expandedTimelineDetails
3491
+ ]);
3207
3492
  if (cachedTimeline) return cachedTimeline;
3208
3493
  const timelineItems = this.timelineItemsForEvents(events);
3209
3494
  if (timelineItems.length === 0) {
@@ -3219,14 +3504,28 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3219
3504
  </div>
3220
3505
  `;
3221
3506
  }
3222
- return this.cachedPanelTpl("timeline", [events, this._expandedTimelineDetails], () => html`${timelineItems.map((item) => this.renderTimelineItem(item))}`);
3507
+ return this.cachedPanelTpl("timeline", [
3508
+ events,
3509
+ this._conversation,
3510
+ this.agentMessagesInput,
3511
+ this._expandedTimelineDetails
3512
+ ], () => html`${this.renderTimelineBulkControls()}${timelineItems.map((item) => this.renderTimelineItem(item))}`);
3513
+ }
3514
+ timelineItemClass(item) {
3515
+ const classes = ["cpk-td__timeline-item", `cpk-td__timeline-item--${item.kind}`];
3516
+ if (item.kind === "warning" || item.severity === "error") classes.push("cpk-td__timeline-item--warning");
3517
+ if (item.kind === "message") {
3518
+ const title = item.title.toLowerCase();
3519
+ if (title.startsWith("user")) classes.push("cpk-td__timeline-item--user");
3520
+ else if (title.includes("assistant")) classes.push("cpk-td__timeline-item--assistant");
3521
+ }
3522
+ return classes.join(" ");
3223
3523
  }
3224
3524
  renderTimelineItem(item) {
3225
- const isWarning = item.kind === "warning";
3226
3525
  const detailsExpanded = this._expandedTimelineDetails.has(item.id);
3227
3526
  return html`
3228
3527
  <div
3229
- class="cpk-td__timeline-item ${isWarning ? "cpk-td__timeline-item--warning" : ""}"
3528
+ class=${this.timelineItemClass(item)}
3230
3529
  data-message-id=${item.messageId ?? nothing}
3231
3530
  >
3232
3531
  <div class="cpk-td__timeline-header">
@@ -3234,13 +3533,15 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3234
3533
  >${item.severity === "error" ? "error" : item.kind}</span
3235
3534
  >
3236
3535
  <span class="cpk-td__timeline-title">${item.title}</span>
3237
- <button
3238
- type="button"
3239
- class="cpk-td__source-link"
3240
- @click=${() => this.revealSourceEvent(item.sourceIndex)}
3241
- >
3242
- Source event #${item.sourceIndex}
3243
- </button>
3536
+ ${item.sourceIndex ? html`
3537
+ <button
3538
+ type="button"
3539
+ class="cpk-td__source-link"
3540
+ @click=${() => this.revealSourceEvent(item.sourceIndex)}
3541
+ >
3542
+ Source event #${item.sourceIndex}
3543
+ </button>
3544
+ ` : nothing}
3244
3545
  <span class="cpk-td__timeline-time"
3245
3546
  >${formatTimestamp(item.timestamp)}</span
3246
3547
  >
@@ -3277,9 +3578,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3277
3578
  <span>${detailsExpanded ? "Hide details" : "Show details"}</span>
3278
3579
  </button>` : nothing}
3279
3580
  ${item.body ? html`<div class="cpk-td__timeline-body">${item.body}</div>` : nothing}
3280
- ${item.details && detailsExpanded ? html`<pre class="cpk-td__timeline-body">
3281
- ${unsafeHTML(highlightedJson(item.details))}</pre
3282
- >` : nothing}
3581
+ ${item.details && detailsExpanded ? renderHighlightedJsonBlock(item.details) : nothing}
3283
3582
  </div>
3284
3583
  `;
3285
3584
  }
@@ -3409,9 +3708,7 @@ ${unsafeHTML(highlightedJson(item.details))}</pre
3409
3708
  ${expanded ? html`
3410
3709
  <div class="cpk-td__tool-body">
3411
3710
  <div class="cpk-td__tool-section-label">Arguments</div>
3412
- <pre class="cpk-td__tool-pre">
3413
- ${unsafeHTML(highlightedJson(item.arguments))}</pre
3414
- >
3711
+ ${renderHighlightedJsonBlock(item.arguments)}
3415
3712
  ${item.result ? html`
3416
3713
  <div
3417
3714
  class="cpk-td__tool-section-label"
@@ -3419,9 +3716,7 @@ ${unsafeHTML(highlightedJson(item.arguments))}</pre
3419
3716
  >
3420
3717
  Result
3421
3718
  </div>
3422
- <pre class="cpk-td__tool-pre">
3423
- ${unsafeHTML(highlightedJson(item.result))}</pre
3424
- >
3719
+ ${renderHighlightedJsonBlock(item.result)}
3425
3720
  ` : nothing}
3426
3721
  </div>
3427
3722
  ` : nothing}
@@ -3536,15 +3831,17 @@ ${unsafeHTML(highlightedJson(item.result))}</pre
3536
3831
  </div>
3537
3832
  `;
3538
3833
  return this.cachedPanelTpl("raw-events", [events, this._expandedRawEvents], () => {
3539
- return html`${events.map((event) => {
3540
- const { bg, fg } = eventColors(event.type);
3834
+ return html`${this.renderRawEventBulkControls()}${events.map((event) => {
3541
3835
  const eventId = this.rawEventId(event);
3542
3836
  const detailsExpanded = this._expandedRawEvents.has(eventId);
3543
3837
  return html`
3544
- <div class="cpk-td__event" data-source-index=${event.sourceIndex}>
3545
- <div class="cpk-td__event-header" style="background:${bg}">
3546
- <span class="cpk-td__event-type" style="color:${fg}"
3547
- >${event.type}</span
3838
+ <div
3839
+ class="cpk-td__event cpk-td__event--${eventCategory(event.type)}"
3840
+ data-source-index=${event.sourceIndex}
3841
+ >
3842
+ <div class="cpk-td__event-header">
3843
+ <span class="cpk-td__event-type" title=${event.type}
3844
+ >${humanizeEventType(event.type)}</span
3548
3845
  >
3549
3846
  <span class="cpk-td__event-time"
3550
3847
  >${formatTimestamp(event.timestamp)}</span
@@ -3583,9 +3880,7 @@ ${unsafeHTML(highlightedJson(item.result))}</pre
3583
3880
  >${detailsExpanded ? "Hide details" : "Show details"}</span
3584
3881
  >
3585
3882
  </button>
3586
- ${detailsExpanded ? html`<pre class="cpk-td__event-payload">
3587
- ${unsafeHTML(highlightedJson(event.rawEvent ?? event))}</pre
3588
- >` : nothing}
3883
+ ${detailsExpanded ? renderHighlightedJsonBlock(event.rawEvent ?? event) : nothing}
3589
3884
  </div>
3590
3885
  `;
3591
3886
  })}`;
@@ -4444,6 +4739,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
4444
4739
  this.threadCapabilityEnabled = null;
4445
4740
  this.threadCapabilityGeneration = 0;
4446
4741
  this.contextMenuOpen = false;
4742
+ this.iconRailContextCloseTimer = null;
4447
4743
  this.layoutMenuOpen = false;
4448
4744
  this.dockMode = "floating";
4449
4745
  this.popOut = null;
@@ -4505,6 +4801,9 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
4505
4801
  this.launcherHudSide = "left";
4506
4802
  this.launcherHudHelp = null;
4507
4803
  this.launcherHudCloseTimer = null;
4804
+ this.launcherHudIntro = false;
4805
+ this.launcherHudIntroStartTimer = null;
4806
+ this.launcherHudIntroEndTimer = null;
4508
4807
  this.hudLandingMenu = null;
4509
4808
  this.pillOutcome = null;
4510
4809
  this.viewedNewsSignalIds = /* @__PURE__ */ new Set();
@@ -4589,6 +4888,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
4589
4888
  this.openInspector("floating_button");
4590
4889
  };
4591
4890
  this.handleLauncherHudEnter = () => {
4891
+ this.cancelLauncherHudIntro();
4592
4892
  this.openLauncherHud();
4593
4893
  };
4594
4894
  this.handleLauncherHudLeave = () => {
@@ -4599,6 +4899,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
4599
4899
  }, 160);
4600
4900
  };
4601
4901
  this.handleLauncherHudFocusIn = () => {
4902
+ this.cancelLauncherHudIntro();
4602
4903
  this.openLauncherHud();
4603
4904
  };
4604
4905
  this.handleLauncherHudFocusOut = (event) => {
@@ -5145,15 +5446,21 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
5145
5446
  this.requestUpdate();
5146
5447
  };
5147
5448
  this.handleIconRailContextPointerEnter = (event) => {
5148
- if (event.pointerType === "touch" || this.contextMenuOpen) return;
5449
+ if (event.pointerType === "touch") return;
5450
+ this.clearIconRailContextCloseTimer();
5451
+ if (this.contextMenuOpen) return;
5149
5452
  this.layoutMenuOpen = false;
5150
5453
  this.contextMenuOpen = true;
5151
5454
  this.requestUpdate();
5152
5455
  };
5153
5456
  this.handleIconRailContextPointerLeave = () => {
5154
5457
  if (!this.contextMenuOpen) return;
5155
- this.contextMenuOpen = false;
5156
- this.requestUpdate();
5458
+ this.clearIconRailContextCloseTimer();
5459
+ this.iconRailContextCloseTimer = setTimeout(() => {
5460
+ this.iconRailContextCloseTimer = null;
5461
+ this.contextMenuOpen = false;
5462
+ this.requestUpdate();
5463
+ }, 180);
5157
5464
  };
5158
5465
  this.handleIconRailContextPointerDown = (event) => {
5159
5466
  if (event.pointerType === "touch") {
@@ -5164,6 +5471,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
5164
5471
  event.stopPropagation();
5165
5472
  };
5166
5473
  this.handleIconRailContextFocusIn = () => {
5474
+ this.clearIconRailContextCloseTimer();
5167
5475
  if (this.contextMenuOpen) return;
5168
5476
  this.layoutMenuOpen = false;
5169
5477
  this.contextMenuOpen = true;
@@ -6134,7 +6442,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
6134
6442
  const messages = this.normalizeAgentMessages(agent.messages);
6135
6443
  if (messages) this.agentMessages.set(agent.agentId, messages);
6136
6444
  else this.agentMessages.delete(agent.agentId);
6137
- const runThreadId = agent.threadId;
6445
+ const runThreadId = this.readAgentThreadId(agent);
6138
6446
  if (runThreadId) this.liveMessageVersion.set(runThreadId, (this.liveMessageVersion.get(runThreadId) ?? 0) + 1);
6139
6447
  this.requestUpdate();
6140
6448
  } catch (error) {
@@ -6238,6 +6546,20 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
6238
6546
  getLatestMessagesForAgent(agentId) {
6239
6547
  return this.agentMessages.get(agentId) ?? null;
6240
6548
  }
6549
+ readAgentThreadId(agent) {
6550
+ if (!("threadId" in agent)) return void 0;
6551
+ const threadId = agent.threadId;
6552
+ return typeof threadId === "string" ? threadId : void 0;
6553
+ }
6554
+ getLiveAgentMessagesForThread(thread) {
6555
+ const messages = this.agentMessages.get(thread.agentId) ?? EMPTY_INSPECTOR_MESSAGES;
6556
+ const core = this._core;
6557
+ if (!core || typeof core.getAgent !== "function") return messages;
6558
+ const agent = core.getAgent(thread.agentId);
6559
+ if (!agent) return EMPTY_INSPECTOR_MESSAGES;
6560
+ if (this.readAgentThreadId(agent) !== thread.id) return EMPTY_INSPECTOR_MESSAGES;
6561
+ return messages;
6562
+ }
6241
6563
  getAgentStatus(agentId) {
6242
6564
  const events = this.agentEvents.get(agentId) ?? [];
6243
6565
  if (events.length === 0) return "idle";
@@ -6284,11 +6606,9 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
6284
6606
  ${isFailedCall && toolError?.message ? html`<p class="mt-2 break-words leading-relaxed text-gray-800">
6285
6607
  ${toolError.message}
6286
6608
  </p>` : nothing}
6287
- ${argsString ? html`<pre
6288
- class="mt-2 overflow-auto rounded bg-white p-2 text-[11px] leading-relaxed text-gray-800"
6289
- >
6290
- ${argsString}</pre
6291
- >` : nothing}
6609
+ ${argsString ? html`<div class="mt-2">
6610
+ ${renderHighlightedJsonBlock(coerceJsonValue(call.function?.arguments))}
6611
+ </div>` : nothing}
6292
6612
  </div>
6293
6613
  `;
6294
6614
  })}
@@ -6340,15 +6660,14 @@ ${argsString}</pre
6340
6660
  return String(state);
6341
6661
  }
6342
6662
  getEventBadgeClasses(type) {
6343
- const base = "font-mono text-[10px] font-medium inline-flex items-center rounded-sm px-1.5 py-0.5 border";
6344
- if (type === "RUN_ERROR") return `${base} bg-rose-50 text-rose-700 border-rose-200`;
6345
- if (type.startsWith("RUN_")) return `${base} bg-blue-50 text-blue-700 border-blue-200`;
6346
- if (type.startsWith("TEXT_MESSAGE")) return `${base} bg-emerald-50 text-emerald-700 border-emerald-200`;
6347
- if (type.startsWith("TOOL_CALL")) return `${base} bg-amber-50 text-amber-700 border-amber-200`;
6348
- if (type.startsWith("REASONING")) return `${base} bg-fuchsia-50 text-fuchsia-700 border-fuchsia-200`;
6349
- if (type.startsWith("STATE")) return `${base} bg-violet-50 text-violet-700 border-violet-200`;
6350
- if (type.startsWith("MESSAGES")) return `${base} bg-sky-50 text-sky-700 border-sky-200`;
6351
- return `${base} bg-gray-100 text-gray-600 border-gray-200`;
6663
+ const base = "font-mono text-[10px] font-semibold inline-flex items-center rounded-sm px-1.5 py-0.5 border";
6664
+ if (type === "RUN_ERROR") return `${base} bg-rose-50 text-rose-800 border-rose-200`;
6665
+ if (type.startsWith("TEXT_MESSAGE")) return `${base} bg-violet-50 text-gray-900 border-violet-200`;
6666
+ if (type.startsWith("TOOL_CALL")) return `${base} bg-emerald-50 text-gray-900 border-emerald-200`;
6667
+ if (type.startsWith("RUN_") || type.startsWith("STEP_")) return `${base} bg-gray-100 text-gray-900 border-gray-200`;
6668
+ if (type.startsWith("REASONING")) return `${base} bg-violet-50 text-gray-900 border-violet-200`;
6669
+ if (type.startsWith("STATE") || type.startsWith("MESSAGES")) return `${base} bg-violet-50 text-gray-900 border-violet-200`;
6670
+ return `${base} bg-gray-100 text-gray-900 border-gray-200`;
6352
6671
  }
6353
6672
  stringifyPayload(payload, pretty) {
6354
6673
  try {
@@ -6395,6 +6714,13 @@ ${argsString}</pre
6395
6714
  static {
6396
6715
  this.styles = [unsafeCSS(generated_default), css`
6397
6716
  :host {
6717
+ --cpk-inspector-shell-radius: 5px;
6718
+ --cpk-inspector-surface-dark: #111319;
6719
+ --cpk-json-key: #3d408f;
6720
+ --cpk-json-str: #0b6b4c;
6721
+ --cpk-json-num: #8a5900;
6722
+ --cpk-json-bool: #c0333a;
6723
+ --cpk-json-nil: #57575b;
6398
6724
  position: fixed;
6399
6725
  top: 0;
6400
6726
  left: 0;
@@ -6404,6 +6730,191 @@ ${argsString}</pre
6404
6730
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
6405
6731
  }
6406
6732
 
6733
+ :host([data-color-scheme="dark"]),
6734
+ .inspector-window[data-color-scheme="dark"] {
6735
+ --cpk-json-key: #bec2ff;
6736
+ --cpk-json-str: #85ecce;
6737
+ --cpk-json-num: #ffac4d;
6738
+ --cpk-json-bool: #fa5f67;
6739
+ --cpk-json-nil: #afafb7;
6740
+ }
6741
+
6742
+ .cpk-json-token--key {
6743
+ color: var(--cpk-json-key);
6744
+ }
6745
+
6746
+ .cpk-json-token--str {
6747
+ color: var(--cpk-json-str);
6748
+ }
6749
+
6750
+ .cpk-json-token--num {
6751
+ color: var(--cpk-json-num);
6752
+ }
6753
+
6754
+ .cpk-json-token--bool {
6755
+ color: var(--cpk-json-bool);
6756
+ }
6757
+
6758
+ .cpk-json-token--nil {
6759
+ color: var(--cpk-json-nil);
6760
+ }
6761
+
6762
+ .cpk-json-block {
6763
+ margin: 0;
6764
+ padding: 10px 12px;
6765
+ border: 1px solid #dbdbe5;
6766
+ border-radius: 8px;
6767
+ background: #f7f7f9;
6768
+ font-family: "Spline Sans Mono", monospace;
6769
+ font-size: 12px;
6770
+ line-height: 1.65;
6771
+ white-space: pre-wrap;
6772
+ overflow-wrap: anywhere;
6773
+ word-break: normal;
6774
+ color: #010507;
6775
+ overflow: auto;
6776
+ }
6777
+
6778
+ :host([data-color-scheme="dark"]) .cpk-json-block,
6779
+ .inspector-window[data-color-scheme="dark"] .cpk-json-block {
6780
+ background: #111319;
6781
+ border-color: #343742;
6782
+ color: #f3f4f8;
6783
+ }
6784
+
6785
+ @keyframes cpk-playground-message-enter {
6786
+ from {
6787
+ opacity: 0;
6788
+ filter: blur(2px);
6789
+ transform: translateY(4px);
6790
+ }
6791
+ to {
6792
+ opacity: 1;
6793
+ filter: blur(0);
6794
+ transform: translateY(0);
6795
+ }
6796
+ }
6797
+
6798
+ @keyframes cpk-playground-thinking {
6799
+ 0%,
6800
+ 60%,
6801
+ 100% {
6802
+ opacity: 0.28;
6803
+ transform: translateY(0);
6804
+ }
6805
+ 30% {
6806
+ opacity: 1;
6807
+ transform: translateY(-2px);
6808
+ }
6809
+ }
6810
+
6811
+ .cpk-playground-root {
6812
+ container-type: inline-size;
6813
+ background: #fbfbfd !important;
6814
+ }
6815
+
6816
+ .cpk-playground-header {
6817
+ min-height: 58px;
6818
+ background: #f7f6fd !important;
6819
+ }
6820
+
6821
+ .cpk-playground-welcome {
6822
+ max-width: 560px;
6823
+ padding: 24px;
6824
+ }
6825
+
6826
+ .cpk-playground-welcome-title {
6827
+ color: #24242b;
6828
+ font-size: 15px;
6829
+ font-weight: 600;
6830
+ letter-spacing: -0.015em;
6831
+ }
6832
+
6833
+ .cpk-playground-composer {
6834
+ border: 1px solid #dcdce8;
6835
+ box-shadow: 0 8px 22px rgba(31, 23, 57, 0.08),
6836
+ 0 1px 2px rgba(31, 23, 57, 0.1);
6837
+ }
6838
+
6839
+ .cpk-playground-composer:focus-within {
6840
+ border-color: #aaa4d4;
6841
+ box-shadow: 0 10px 26px rgba(86, 53, 155, 0.13),
6842
+ 0 0 0 3px rgba(190, 194, 255, 0.3);
6843
+ }
6844
+
6845
+ .inspector-window[data-color-scheme="dark"] .cpk-playground-root,
6846
+ .inspector-window[data-color-scheme="dark"] .cpk-playground-header {
6847
+ background: #15171e !important;
6848
+ }
6849
+
6850
+ .inspector-window[data-color-scheme="dark"]
6851
+ .cpk-playground-welcome-title {
6852
+ color: #f3f4f8 !important;
6853
+ }
6854
+
6855
+ .inspector-window[data-color-scheme="dark"] .cpk-playground-composer {
6856
+ border-color: #464957;
6857
+ background: #15171e !important;
6858
+ box-shadow: 0 8px 22px rgba(0, 0, 0, 0.26),
6859
+ 0 1px 2px rgba(0, 0, 0, 0.36);
6860
+ }
6861
+
6862
+ .inspector-window[data-color-scheme="dark"]
6863
+ .cpk-playground-composer:focus-within {
6864
+ border-color: #777aae;
6865
+ box-shadow: 0 10px 26px rgba(0, 0, 0, 0.34),
6866
+ 0 0 0 3px rgba(102, 106, 158, 0.3);
6867
+ }
6868
+
6869
+ .cpk-playground-message-enter {
6870
+ animation: cpk-playground-message-enter 0.24s cubic-bezier(0.16, 1, 0.3, 1)
6871
+ both;
6872
+ }
6873
+
6874
+ .cpk-playground-thinking-dot {
6875
+ animation: cpk-playground-thinking 1.2s ease-in-out infinite;
6876
+ }
6877
+
6878
+ .cpk-playground-thinking-dot:nth-child(2) {
6879
+ animation-delay: 0.12s;
6880
+ }
6881
+
6882
+ .cpk-playground-thinking-dot:nth-child(3) {
6883
+ animation-delay: 0.24s;
6884
+ }
6885
+
6886
+ .cpk-playground-reasoning summary::-webkit-details-marker {
6887
+ display: none;
6888
+ }
6889
+
6890
+ .cpk-playground-reasoning[open]
6891
+ .cpk-playground-reasoning-chevron {
6892
+ transform: rotate(90deg);
6893
+ }
6894
+
6895
+ @container (max-width: 560px) {
6896
+ .cpk-playground-header {
6897
+ align-items: stretch;
6898
+ }
6899
+
6900
+ .cpk-playground-actions {
6901
+ width: 100%;
6902
+ }
6903
+
6904
+ .cpk-playground-thread-select {
6905
+ min-width: 0;
6906
+ max-width: none;
6907
+ flex: 1;
6908
+ }
6909
+ }
6910
+
6911
+ @media (prefers-reduced-motion: reduce) {
6912
+ .cpk-playground-message-enter,
6913
+ .cpk-playground-thinking-dot {
6914
+ animation: none;
6915
+ }
6916
+ }
6917
+
6407
6918
  .rounded-sm {
6408
6919
  border-radius: 3px;
6409
6920
  }
@@ -6463,6 +6974,10 @@ ${argsString}</pre
6463
6974
  box-sizing: border-box;
6464
6975
  transition:
6465
6976
  transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1),
6977
+ scale 300ms cubic-bezier(0.34, 1.56, 0.64, 1),
6978
+ background-color 200ms ease,
6979
+ border-color 200ms ease,
6980
+ box-shadow 200ms ease,
6466
6981
  opacity 160ms ease;
6467
6982
  }
6468
6983
 
@@ -6490,6 +7005,7 @@ ${argsString}</pre
6490
7005
  touch-action: none;
6491
7006
  user-select: none;
6492
7007
  z-index: 60;
7008
+ background: transparent;
6493
7009
  }
6494
7010
 
6495
7011
  .edge-resize-handle {
@@ -6624,18 +7140,77 @@ ${argsString}</pre
6624
7140
  flex-shrink: 0;
6625
7141
  transition:
6626
7142
  background-color 0.15s,
6627
- border-color 0.15s;
7143
+ border-color 0.15s,
7144
+ color 0.15s;
6628
7145
  }
6629
7146
  .cpk-copy-btn:hover {
6630
7147
  background-color: #f0f0f4;
6631
7148
  border-color: #afafb7;
6632
7149
  }
6633
7150
 
7151
+ .inspector-window[data-color-scheme="dark"] .cpk-copy-btn {
7152
+ background: #191c24;
7153
+ border-color: #3a3d49;
7154
+ color: #f3f4f8;
7155
+ }
7156
+
7157
+ .inspector-window[data-color-scheme="dark"] .cpk-copy-btn:hover {
7158
+ background: #20232d;
7159
+ border-color: #57575b;
7160
+ }
7161
+
7162
+ .inspector-sidebar[data-icon-rail="true"]
7163
+ .inspector-sidebar-agent-scope
7164
+ [data-context-dropdown-root="true"]
7165
+ > div {
7166
+ left: 100%;
7167
+ margin-inline-start: 8px;
7168
+ }
7169
+
7170
+ .inspector-icon-rail-menu {
7171
+ transform-origin: left center;
7172
+ opacity: 0;
7173
+ visibility: hidden;
7174
+ pointer-events: none;
7175
+ transform: translateX(-8px) scale(0.96);
7176
+ transition:
7177
+ opacity 180ms ease,
7178
+ transform 180ms ease,
7179
+ visibility 180ms ease;
7180
+ }
7181
+
7182
+ .inspector-icon-rail-menu[data-open="true"] {
7183
+ opacity: 1;
7184
+ visibility: visible;
7185
+ pointer-events: auto;
7186
+ transform: translateX(0) scale(1);
7187
+ }
7188
+
7189
+ @media (prefers-reduced-motion: reduce) {
7190
+ .inspector-icon-rail-menu {
7191
+ transition: none;
7192
+ }
7193
+ }
7194
+
7195
+ .inspector-sidebar[data-icon-rail="true"]
7196
+ .inspector-sidebar-agent-scope
7197
+ [data-context-dropdown-root="true"]
7198
+ > div::before {
7199
+ content: "";
7200
+ position: absolute;
7201
+ inset-block: 0;
7202
+ inset-inline-end: 100%;
7203
+ width: 12px;
7204
+ }
7205
+
6634
7206
  .cpk-section-header {
6635
7207
  background: #e8edf5;
6636
7208
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
6637
7209
  padding: 10px 16px;
6638
7210
  }
7211
+ .inspector-window[data-color-scheme="dark"] .cpk-section-header {
7212
+ border-bottom-color: #3a3d49;
7213
+ }
6639
7214
  .cpk-section-header h4 {
6640
7215
  font-size: 11px;
6641
7216
  font-weight: 600;
@@ -6882,6 +7457,7 @@ ${argsString}</pre
6882
7457
  .console-button:hover {
6883
7458
  background-color: var(--cpk-launcher-face-solid) !important;
6884
7459
  border-color: rgba(190, 194, 255, 0.45) !important;
7460
+ transform: scale(1.05);
6885
7461
  }
6886
7462
  .console-button:focus-visible {
6887
7463
  outline-color: #bec2ff !important;
@@ -7230,6 +7806,12 @@ ${argsString}</pre
7230
7806
  .cpk-launcher-signal-wash {
7231
7807
  animation: none !important;
7232
7808
  }
7809
+ .console-button {
7810
+ transition: opacity 160ms ease;
7811
+ }
7812
+ .console-button:hover {
7813
+ transform: none;
7814
+ }
7233
7815
  }
7234
7816
 
7235
7817
  /* ── Launcher HUD: hover menu, quieter than the error island ── */
@@ -7241,6 +7823,9 @@ ${argsString}</pre
7241
7823
  }
7242
7824
 
7243
7825
  .cpk-launcher-hud {
7826
+ --hud-fill: var(--cpk-inspector-surface-dark);
7827
+ --hud-line: rgb(190 194 255 / 0.5);
7828
+ --hud-blur: blur(12px) saturate(1.2);
7244
7829
  position: absolute;
7245
7830
  top: 0;
7246
7831
  z-index: 4;
@@ -7274,38 +7859,47 @@ ${argsString}</pre
7274
7859
  }
7275
7860
 
7276
7861
  .cpk-launcher-hud__card {
7277
- --hud-fill: rgb(28 31 36 / 0.88);
7278
- --hud-line: rgb(190 194 255 / 0.5);
7279
7862
  position: relative;
7280
7863
  width: 228px;
7281
7864
  padding: 4px;
7282
7865
  border: 1px dotted var(--hud-line);
7283
- border-radius: 10px;
7866
+ border-radius: var(--cpk-inspector-shell-radius);
7284
7867
  background: var(--hud-fill);
7285
7868
  color: #fff;
7286
- backdrop-filter: blur(12px) saturate(1.2);
7869
+ backdrop-filter: var(--hud-blur);
7870
+ -webkit-backdrop-filter: var(--hud-blur);
7287
7871
  box-shadow: 0 8px 20px rgb(1 5 7 / 0.18);
7288
7872
  }
7289
7873
 
7874
+ .cpk-launcher-hud[data-color-scheme="light"] {
7875
+ --hud-fill: #fff;
7876
+ --hud-line: #d8d8e8;
7877
+ }
7878
+
7879
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__card {
7880
+ color: #010507;
7881
+ }
7882
+
7290
7883
  .cpk-launcher-hud__arrow {
7291
7884
  position: absolute;
7292
7885
  top: calc(var(--cpk-launcher-size) / 2);
7886
+ z-index: 1;
7293
7887
  width: 10px;
7294
7888
  height: 10px;
7295
- background: var(--hud-fill);
7889
+ border: 0;
7890
+ /* The card frosts the page behind it, so it reads lighter than the
7891
+ raw fill. Mix a little white so the arrow matches the glass card
7892
+ without going lighter than the HUD. */
7893
+ background: color-mix(in srgb, var(--hud-fill) 88%, white 12%);
7296
7894
  transform: translateY(-50%) rotate(45deg);
7297
7895
  }
7298
7896
 
7299
7897
  .cpk-launcher-hud[data-cpk-hud-side="left"] .cpk-launcher-hud__arrow {
7300
- right: -5px;
7301
- border-top: 1px solid var(--hud-line);
7302
- border-right: 1px solid var(--hud-line);
7898
+ right: 9px;
7303
7899
  }
7304
7900
 
7305
7901
  .cpk-launcher-hud[data-cpk-hud-side="right"] .cpk-launcher-hud__arrow {
7306
- left: -5px;
7307
- border-bottom: 1px solid var(--hud-line);
7308
- border-left: 1px solid var(--hud-line);
7902
+ left: 9px;
7309
7903
  }
7310
7904
 
7311
7905
  .cpk-launcher-hud__list {
@@ -7339,6 +7933,12 @@ ${argsString}</pre
7339
7933
  background: rgb(255 255 255 / 0.06);
7340
7934
  }
7341
7935
 
7936
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__row:hover,
7937
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__row:focus-within,
7938
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__row[data-cpk-hud-help="open"] {
7939
+ background: #f0f0f4;
7940
+ }
7941
+
7342
7942
  .cpk-launcher-hud__action {
7343
7943
  display: flex;
7344
7944
  gap: 8px;
@@ -7356,6 +7956,10 @@ ${argsString}</pre
7356
7956
  cursor: pointer;
7357
7957
  }
7358
7958
 
7959
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__action {
7960
+ color: #010507;
7961
+ }
7962
+
7359
7963
  /* Stretch the row action over the whole tab, including the detail
7360
7964
  copy. The help mark sits above this layer. */
7361
7965
  .cpk-launcher-hud__action::after {
@@ -7399,6 +8003,10 @@ ${argsString}</pre
7399
8003
  line-height: 1;
7400
8004
  }
7401
8005
 
8006
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__help {
8007
+ color: #68686e;
8008
+ }
8009
+
7402
8010
  .cpk-launcher-hud__help:focus-visible,
7403
8011
  .cpk-launcher-hud__action:focus-visible {
7404
8012
  outline: 2px solid #bec2ff;
@@ -7425,6 +8033,10 @@ ${argsString}</pre
7425
8033
  padding-bottom 200ms cubic-bezier(0.16, 1, 0.3, 1);
7426
8034
  }
7427
8035
 
8036
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__detail {
8037
+ color: #68686e;
8038
+ }
8039
+
7428
8040
  .cpk-launcher-hud__row:hover .cpk-launcher-hud__detail,
7429
8041
  .cpk-launcher-hud__row:focus-within .cpk-launcher-hud__detail,
7430
8042
  .cpk-launcher-hud__row[data-cpk-hud-help="open"] .cpk-launcher-hud__detail {
@@ -7441,6 +8053,103 @@ ${argsString}</pre
7441
8053
  }
7442
8054
  }
7443
8055
 
8056
+ /*
8057
+ * On mount, borrow the hover HUD for one short introduction. The card
8058
+ * establishes the destination first; its rows then resolve in order so
8059
+ * the eye can count the available features instead of receiving one
8060
+ * undifferentiated block. Only opacity and transform move.
8061
+ */
8062
+ @keyframes cpk-launcher-hud-intro {
8063
+ 0% {
8064
+ opacity: 0;
8065
+ transform: translateX(8px);
8066
+ }
8067
+ 8%,
8068
+ 88% {
8069
+ opacity: 1;
8070
+ transform: none;
8071
+ }
8072
+ 100% {
8073
+ opacity: 0;
8074
+ transform: translateX(4px);
8075
+ }
8076
+ }
8077
+
8078
+ @keyframes cpk-launcher-hud-intro-right {
8079
+ 0% {
8080
+ opacity: 0;
8081
+ transform: translateX(-8px);
8082
+ }
8083
+ 8%,
8084
+ 88% {
8085
+ opacity: 1;
8086
+ transform: none;
8087
+ }
8088
+ 100% {
8089
+ opacity: 0;
8090
+ transform: translateX(-4px);
8091
+ }
8092
+ }
8093
+
8094
+ @keyframes cpk-launcher-hud-row-online {
8095
+ from {
8096
+ opacity: 0;
8097
+ transform: translateY(4px);
8098
+ }
8099
+ to {
8100
+ opacity: 1;
8101
+ transform: none;
8102
+ }
8103
+ }
8104
+
8105
+ @keyframes cpk-launcher-hud-check-online {
8106
+ from {
8107
+ opacity: 0;
8108
+ transform: scale(0.65);
8109
+ }
8110
+ to {
8111
+ opacity: 1;
8112
+ transform: scale(1);
8113
+ }
8114
+ }
8115
+
8116
+ .cpk-launcher-hud[data-cpk-hud-intro="true"] {
8117
+ animation: cpk-launcher-hud-intro
8118
+ var(--cpk-launcher-hud-intro-duration)
8119
+ cubic-bezier(0.16, 1, 0.3, 1) both;
8120
+ }
8121
+
8122
+ .cpk-launcher-hud[data-cpk-hud-intro="true"][data-cpk-hud-side="right"] {
8123
+ animation-name: cpk-launcher-hud-intro-right;
8124
+ }
8125
+
8126
+ .cpk-launcher-hud[data-cpk-hud-intro="true"]
8127
+ .cpk-launcher-hud__row {
8128
+ animation: cpk-launcher-hud-row-online
8129
+ var(--cpk-launcher-hud-row-duration)
8130
+ cubic-bezier(0.16, 1, 0.3, 1) both;
8131
+ animation-delay: var(--cpk-hud-row-delay);
8132
+ }
8133
+
8134
+ .cpk-launcher-hud[data-cpk-hud-intro="true"]
8135
+ .cpk-launcher-hud__check {
8136
+ animation: cpk-launcher-hud-check-online 220ms
8137
+ cubic-bezier(0.16, 1, 0.3, 1) both;
8138
+ animation-delay: calc(var(--cpk-hud-row-delay) + 90ms);
8139
+ }
8140
+
8141
+ @media (prefers-reduced-motion: reduce) {
8142
+ .cpk-launcher-hud[data-cpk-hud-intro="true"],
8143
+ .cpk-launcher-hud[data-cpk-hud-intro="true"]
8144
+ .cpk-launcher-hud__row,
8145
+ .cpk-launcher-hud[data-cpk-hud-intro="true"]
8146
+ .cpk-launcher-hud__check {
8147
+ animation: none !important;
8148
+ opacity: 1;
8149
+ transform: none;
8150
+ }
8151
+ }
8152
+
7444
8153
  /*
7445
8154
  * Marker on the navigation entry, which is what keeps a signal alive
7446
8155
  * once the panel is open and the launcher is hidden. Static by design:
@@ -7467,7 +8176,7 @@ ${argsString}</pre
7467
8176
  /* ── Inspector window ────────────────────────────────────────── */
7468
8177
  .inspector-window {
7469
8178
  border: 1px solid #d8d8e8 !important;
7470
- border-radius: 5px !important;
8179
+ border-radius: var(--cpk-inspector-shell-radius) !important;
7471
8180
  box-shadow: none !important;
7472
8181
  }
7473
8182
 
@@ -7583,10 +8292,69 @@ ${argsString}</pre
7583
8292
  .inspector-sidebar[data-icon-rail="true"] .inspector-nav-control,
7584
8293
  .inspector-sidebar[data-icon-rail="true"] .inspector-sidebar-control,
7585
8294
  .inspector-sidebar[data-icon-rail="true"] .inspector-sidebar-toggle {
8295
+ box-sizing: border-box !important;
8296
+ width: 36px !important;
8297
+ height: 36px !important;
8298
+ min-width: 36px !important;
8299
+ min-height: 36px !important;
8300
+ justify-content: center !important;
8301
+ align-items: center !important;
8302
+ gap: 0 !important;
8303
+ padding: 0 !important;
8304
+ overflow: visible !important;
8305
+ }
8306
+ .inspector-sidebar[data-icon-rail="true"] .inspector-nav-icon,
8307
+ .inspector-sidebar[data-icon-rail="true"] .inspector-nav-icon svg,
8308
+ .inspector-sidebar[data-icon-rail="true"]
8309
+ .inspector-context-dropdown-icon,
8310
+ .inspector-sidebar[data-icon-rail="true"]
8311
+ .inspector-context-dropdown-icon
8312
+ svg,
8313
+ .inspector-sidebar[data-icon-rail="true"] .inspector-agent-placeholder svg {
8314
+ width: 18px !important;
8315
+ height: 18px !important;
8316
+ overflow: visible !important;
8317
+ }
8318
+ .inspector-sidebar[data-icon-rail="true"]
8319
+ .inspector-agent-selector
8320
+ > [data-context-dropdown-root="true"] {
8321
+ display: flex !important;
8322
+ flex: none !important;
8323
+ width: 36px !important;
8324
+ min-width: 36px !important;
8325
+ max-width: 36px !important;
7586
8326
  justify-content: center !important;
7587
8327
  align-items: center !important;
8328
+ }
8329
+ .inspector-sidebar[data-icon-rail="true"]
8330
+ .inspector-agent-selector
8331
+ > [data-context-dropdown-root="true"]
8332
+ > button,
8333
+ .inspector-sidebar[data-icon-rail="true"] .inspector-agent-placeholder {
8334
+ display: flex !important;
8335
+ width: 36px !important;
8336
+ height: 36px !important;
8337
+ min-width: 36px !important;
8338
+ min-height: 36px !important;
8339
+ max-width: 36px !important;
8340
+ align-items: center !important;
8341
+ justify-content: center !important;
7588
8342
  gap: 0 !important;
7589
- padding-inline: 0 !important;
8343
+ padding: 0 !important;
8344
+ transition:
8345
+ background-color 180ms ease,
8346
+ border-color 180ms ease,
8347
+ color 180ms ease !important;
8348
+ }
8349
+ .inspector-sidebar[data-icon-rail="true"]
8350
+ .inspector-context-dropdown-label,
8351
+ .inspector-sidebar[data-icon-rail="true"]
8352
+ .inspector-context-dropdown-chevron {
8353
+ display: none !important;
8354
+ width: 0 !important;
8355
+ min-width: 0 !important;
8356
+ flex: none !important;
8357
+ overflow: hidden !important;
7590
8358
  }
7591
8359
  .inspector-sidebar[data-icon-rail="true"] .inspector-nav-label,
7592
8360
  .inspector-sidebar[data-icon-rail="true"] .inspector-sidebar-label {
@@ -7816,6 +8584,7 @@ ${argsString}</pre
7816
8584
  clearTimeout(this.transitionTimeoutId);
7817
8585
  this.transitionTimeoutId = null;
7818
8586
  }
8587
+ this.clearIconRailContextCloseTimer();
7819
8588
  this.unsubscribeFromInspectorThreadBridge();
7820
8589
  this.threadsSetupPromptCopyGeneration += 1;
7821
8590
  if (this.threadsSetupPromptCopyResetTimeoutId !== null) {
@@ -7825,6 +8594,7 @@ ${argsString}</pre
7825
8594
  this.threadsSetupPromptCopyState = "idle";
7826
8595
  this.stopSignalPulse();
7827
8596
  this.cancelGestureTail();
8597
+ this.cancelLauncherHudIntro();
7828
8598
  this.cancelThreadRefreshDebounce();
7829
8599
  this.clearInspectorUsageRefresh();
7830
8600
  this.cleanupThreadsExampleOverviewVideo();
@@ -7861,6 +8631,7 @@ ${argsString}</pre
7861
8631
  else this.centerContext("window");
7862
8632
  this.ensureAnnouncementLoading();
7863
8633
  this.updateHostTransform(this.isOpen ? "window" : "button");
8634
+ this.scheduleLauncherHudIntro();
7864
8635
  }
7865
8636
  render() {
7866
8637
  return this.isOpen ? html`
@@ -7923,8 +8694,6 @@ ${argsString}</pre
7923
8694
  "text-xs",
7924
8695
  "font-medium",
7925
8696
  "text-white",
7926
- "transition",
7927
- "hover:scale-105",
7928
8697
  "focus-visible:outline",
7929
8698
  "focus-visible:outline-2",
7930
8699
  "focus-visible:outline-offset-2",
@@ -8044,6 +8813,41 @@ ${argsString}</pre
8044
8813
  isLauncherHudBlocked() {
8045
8814
  return this.gestureSignal !== null;
8046
8815
  }
8816
+ scheduleLauncherHudIntro(delay = LAUNCHER_HUD_INTRO_MS.delay) {
8817
+ if (this.launcherHudIntroStartTimer !== null) clearTimeout(this.launcherHudIntroStartTimer);
8818
+ this.launcherHudIntroStartTimer = setTimeout(() => {
8819
+ this.launcherHudIntroStartTimer = null;
8820
+ if (!this.isConnected || this.isOpen) return;
8821
+ if (this.isLauncherHudBlocked()) {
8822
+ this.scheduleLauncherHudIntro(LAUNCHER_HUD_INTRO_MS.blockedRetry);
8823
+ return;
8824
+ }
8825
+ this.resolveLauncherHudSide();
8826
+ this.launcherHudIntro = true;
8827
+ this.launcherHudOpen = true;
8828
+ this.requestUpdate();
8829
+ this.launcherHudIntroEndTimer = setTimeout(() => {
8830
+ this.launcherHudIntroEndTimer = null;
8831
+ this.launcherHudIntro = false;
8832
+ this.launcherHudOpen = false;
8833
+ this.launcherHudHelp = null;
8834
+ this.requestUpdate();
8835
+ }, LAUNCHER_HUD_INTRO_MS.duration);
8836
+ }, delay);
8837
+ }
8838
+ cancelLauncherHudIntro() {
8839
+ if (this.launcherHudIntroStartTimer !== null) {
8840
+ clearTimeout(this.launcherHudIntroStartTimer);
8841
+ this.launcherHudIntroStartTimer = null;
8842
+ }
8843
+ if (this.launcherHudIntroEndTimer !== null) {
8844
+ clearTimeout(this.launcherHudIntroEndTimer);
8845
+ this.launcherHudIntroEndTimer = null;
8846
+ }
8847
+ if (!this.launcherHudIntro) return;
8848
+ this.launcherHudIntro = false;
8849
+ if (this.isConnected) this.requestUpdate();
8850
+ }
8047
8851
  resolveLauncherHudSide() {
8048
8852
  if (typeof window === "undefined") {
8049
8853
  this.launcherHudSide = "left";
@@ -8072,6 +8876,7 @@ ${argsString}</pre
8072
8876
  this.requestUpdate();
8073
8877
  }
8074
8878
  closeLauncherHud() {
8879
+ this.cancelLauncherHudIntro();
8075
8880
  if (this.launcherHudCloseTimer !== null) {
8076
8881
  clearTimeout(this.launcherHudCloseTimer);
8077
8882
  this.launcherHudCloseTimer = null;
@@ -8109,6 +8914,10 @@ ${argsString}</pre
8109
8914
  class="cpk-launcher-hud__row"
8110
8915
  data-cpk-hud-row=${args.id}
8111
8916
  data-cpk-hud-help=${helpOpen ? "open" : nothing}
8917
+ style=${styleMap({
8918
+ "--cpk-hud-row-index": `${args.introIndex}`,
8919
+ "--cpk-hud-row-delay": `${LAUNCHER_HUD_INTRO_MS.rowStart + args.introIndex * LAUNCHER_HUD_INTRO_MS.rowStagger}ms`
8920
+ })}
8112
8921
  @click=${(event) => this.handleHudRowClick(event, args.id)}
8113
8922
  >
8114
8923
  <button
@@ -8138,23 +8947,31 @@ ${argsString}</pre
8138
8947
  }
8139
8948
  renderLauncherHud() {
8140
8949
  if (!this.launcherHudOpen) return nothing;
8141
- const threadsOn = this.areThreadEndpointsAvailable();
8142
- const intelligenceOn = Boolean(this._core?.intelligence);
8143
- const learningOn = intelligenceOn && this._memoriesAvailable;
8950
+ const homeModel = this.getHomeModel();
8951
+ const threadsOn = homeModel.services.some((service) => service.id === "threads" && service.enabled);
8952
+ const learningOn = homeModel.services.some((service) => service.id === "memory" && service.enabled);
8953
+ const intelligenceOn = homeModel.hero.connection === "connected";
8144
8954
  return html`
8145
8955
  <div
8146
8956
  class="cpk-launcher-hud"
8147
8957
  id="cpk-launcher-hud"
8148
8958
  data-cpk-launcher-hud
8149
8959
  data-cpk-hud-side=${this.launcherHudSide}
8960
+ data-cpk-hud-intro=${this.launcherHudIntro ? "true" : nothing}
8961
+ data-color-scheme=${this.colorScheme}
8962
+ style=${styleMap({
8963
+ "--cpk-launcher-hud-intro-duration": `${LAUNCHER_HUD_INTRO_MS.duration}ms`,
8964
+ "--cpk-launcher-hud-row-duration": `${LAUNCHER_HUD_INTRO_MS.rowDuration}ms`
8965
+ })}
8150
8966
  >
8967
+ <span class="cpk-launcher-hud__arrow" aria-hidden="true"></span>
8151
8968
  <div class="cpk-launcher-hud__card">
8152
- <span class="cpk-launcher-hud__arrow" aria-hidden="true"></span>
8153
8969
  <ul class="cpk-launcher-hud__list" role="list">
8154
8970
  ${this.renderHudRow({
8155
8971
  id: "inspector",
8156
8972
  label: HUD_OPEN_INSPECTOR_LABEL,
8157
- detail: HUD_OPEN_INSPECTOR_DETAIL
8973
+ detail: HUD_OPEN_INSPECTOR_DETAIL,
8974
+ introIndex: 0
8158
8975
  })}
8159
8976
  </ul>
8160
8977
  <ul class="cpk-launcher-hud__list" role="list">
@@ -8162,19 +8979,22 @@ ${argsString}</pre
8162
8979
  id: "threads",
8163
8980
  label: threadsOn ? HUD_THREADS_ON_LABEL : HUD_THREADS_OFF_LABEL,
8164
8981
  detail: threadsOn ? HUD_THREADS_ON_DETAIL : HUD_THREADS_OFF_DETAIL,
8165
- connected: threadsOn
8982
+ connected: threadsOn,
8983
+ introIndex: 1
8166
8984
  })}
8167
8985
  ${this.renderHudRow({
8168
8986
  id: "intelligence",
8169
8987
  label: intelligenceOn ? HUD_INTELLIGENCE_ON_LABEL : HUD_INTELLIGENCE_OFF_LABEL,
8170
8988
  detail: intelligenceOn ? HUD_INTELLIGENCE_ON_DETAIL : HUD_INTELLIGENCE_OFF_DETAIL,
8171
- connected: intelligenceOn
8989
+ connected: intelligenceOn,
8990
+ introIndex: 2
8172
8991
  })}
8173
8992
  ${this.renderHudRow({
8174
8993
  id: "learning",
8175
8994
  label: learningOn ? HUD_LEARNING_ON_LABEL : HUD_LEARNING_OFF_LABEL,
8176
8995
  detail: learningOn ? HUD_LEARNING_ON_DETAIL : HUD_LEARNING_OFF_DETAIL,
8177
- connected: learningOn
8996
+ connected: learningOn,
8997
+ introIndex: 3
8178
8998
  })}
8179
8999
  </ul>
8180
9000
  </div>
@@ -8277,34 +9097,34 @@ ${argsString}</pre
8277
9097
  })}
8278
9098
  </nav>
8279
9099
  ${automaticallyCollapsed ? nothing : html`
8280
- <button
8281
- type="button"
8282
- class="inspector-sidebar-toggle"
8283
- data-inspector-sidebar-toggle
8284
- aria-label=${iconRail ? "Expand sidebar" : "Collapse sidebar"}
8285
- aria-expanded=${iconRail ? "false" : "true"}
8286
- data-inspector-tooltip=${iconRail ? "Expand sidebar" : nothing}
8287
- title=${iconRail ? nothing : "Collapse sidebar"}
8288
- style=${INTERACTIVE_FOCUS_BASE_STYLE}
8289
- @pointerenter=${iconRail ? this.handleSidebarRailTooltipShow : nothing}
8290
- @pointerleave=${iconRail ? this.handleSidebarRailTooltipHide : nothing}
8291
- @focus=${iconRail ? this.handleSidebarRailTooltipShow : nothing}
8292
- @blur=${iconRail ? this.handleSidebarRailTooltipHide : nothing}
8293
- @click=${this.handleSidebarToggle}
8294
- >
8295
- <span class="inspector-nav-icon" aria-hidden="true">
8296
- ${this.renderIcon(iconRail ? "ChevronRight" : "ChevronLeft")}
8297
- </span>
8298
- <span class="inspector-nav-label"
8299
- >${iconRail ? "Expand" : "Collapse"}</span
8300
- >
8301
- </button>
8302
- `}
8303
- ${iconRail ? nothing : html`
8304
9100
  <div class="inspector-sidebar-footer">
8305
- <div class="inspector-sidebar-status-list">
8306
- ${this.renderSidebarIntelligenceStatus(homeModel)}
8307
- </div>
9101
+ ${iconRail ? nothing : html`
9102
+ <div class="inspector-sidebar-status-list">
9103
+ ${this.renderSidebarIntelligenceStatus(homeModel)}
9104
+ </div>
9105
+ `}
9106
+ <button
9107
+ type="button"
9108
+ class="inspector-sidebar-toggle"
9109
+ data-inspector-sidebar-toggle
9110
+ aria-label=${iconRail ? "Expand sidebar" : "Collapse sidebar"}
9111
+ aria-expanded=${iconRail ? "false" : "true"}
9112
+ data-inspector-tooltip=${iconRail ? "Expand sidebar" : nothing}
9113
+ title=${iconRail ? nothing : "Collapse sidebar"}
9114
+ style=${INTERACTIVE_FOCUS_BASE_STYLE}
9115
+ @pointerenter=${iconRail ? this.handleSidebarRailTooltipShow : nothing}
9116
+ @pointerleave=${iconRail ? this.handleSidebarRailTooltipHide : nothing}
9117
+ @focus=${iconRail ? this.handleSidebarRailTooltipShow : nothing}
9118
+ @blur=${iconRail ? this.handleSidebarRailTooltipHide : nothing}
9119
+ @click=${this.handleSidebarToggle}
9120
+ >
9121
+ <span class="inspector-nav-icon" aria-hidden="true">
9122
+ ${this.renderIcon(iconRail ? "ChevronRight" : "ChevronLeft")}
9123
+ </span>
9124
+ <span class="inspector-nav-label"
9125
+ >${iconRail ? "Expand" : "Collapse"}</span
9126
+ >
9127
+ </button>
8308
9128
  </div>
8309
9129
  `}
8310
9130
  </aside>
@@ -9067,16 +9887,6 @@ ${argsString}</pre
9067
9887
  @pointerup=${this.handleResizePointerUp}
9068
9888
  @pointercancel=${this.handleResizePointerCancel}
9069
9889
  ></div>
9070
- <div
9071
- class="resize-handle pointer-events-auto absolute bottom-0 left-0 flex h-7 w-7 cursor-nesw-resize items-center justify-center text-gray-600 transition hover:text-gray-900"
9072
- data-resize-edge="sw"
9073
- role="presentation"
9074
- aria-hidden="true"
9075
- @pointerdown=${this.handleResizePointerDown}
9076
- @pointermove=${this.handleResizePointerMove}
9077
- @pointerup=${this.handleResizePointerUp}
9078
- @pointercancel=${this.handleResizePointerCancel}
9079
- ></div>
9080
9890
  `}
9081
9891
  <div
9082
9892
  class="resize-handle pointer-events-auto absolute bottom-0 right-0 flex h-7 w-7 cursor-nwse-resize items-center justify-center text-gray-600 transition hover:text-gray-900"
@@ -9668,11 +10478,8 @@ ${argsString}</pre
9668
10478
  return this.sanitizeForLogging(payload);
9669
10479
  }
9670
10480
  normalizeMessageContent(content) {
9671
- if (typeof content === "string") return content;
9672
- if (content && typeof content === "object" && "text" in content) {
9673
- const maybeText = content.text;
9674
- if (typeof maybeText === "string") return maybeText;
9675
- }
10481
+ const extracted = textFromUnknownContent(content);
10482
+ if (extracted) return extracted;
9676
10483
  if (content === null || content === void 0) return "";
9677
10484
  if (typeof content === "object") try {
9678
10485
  return JSON.stringify(this.sanitizeForLogging(content));
@@ -9892,7 +10699,7 @@ ${argsString}</pre
9892
10699
  const sendDisabled = !agentId || this.playgroundIsLoadingThread || !this.playgroundIsRunning && !this.playgroundInput.trim();
9893
10700
  return html`
9894
10701
  <form
9895
- class=${centered ? "mt-5 w-full" : "bg-white px-3 pb-3 pt-1.5"}
10702
+ class=${centered ? "cpk-playground-form mt-5 w-full" : "cpk-playground-form bg-white px-3 pb-3 pt-1.5"}
9896
10703
  @submit=${this.handlePlaygroundSubmit}
9897
10704
  >
9898
10705
  ${this.playgroundError ? html`<div
@@ -9921,10 +10728,10 @@ ${argsString}</pre
9921
10728
  ` : nothing}
9922
10729
  </div>` : nothing}
9923
10730
  <div
9924
- class="mx-auto flex max-w-3xl items-end gap-1.5 rounded-[28px] bg-white px-2.5 py-1.5 shadow-[0_4px_4px_0_#0000000a,0_0_1px_0_#0000009e] transition-shadow duration-200 focus-within:shadow-[0_6px_18px_0_#00000014,0_0_1px_0_#0000009e]"
10731
+ class="cpk-playground-composer mx-auto flex max-w-3xl items-end gap-1.5 rounded-[28px] bg-white px-2.5 py-1.5 shadow-[0_4px_4px_0_#0000000a,0_0_1px_0_#0000009e] transition-shadow duration-200 focus-within:shadow-[0_6px_18px_0_#00000014,0_0_1px_0_#0000009e]"
9925
10732
  >
9926
10733
  <textarea
9927
- class="min-h-[40px] max-h-32 flex-1 resize-none bg-transparent px-2.5 py-2.5 text-[13px] leading-5 text-gray-900 outline-none placeholder:text-gray-500 disabled:cursor-not-allowed disabled:opacity-60"
10734
+ class="cpk-playground-input min-h-[40px] max-h-32 flex-1 resize-none bg-transparent px-2.5 py-2.5 text-[13px] leading-5 text-gray-900 outline-none placeholder:text-gray-500 disabled:cursor-not-allowed disabled:opacity-60"
9928
10735
  rows="1"
9929
10736
  placeholder=${placeholder}
9930
10737
  aria-label="Playground message"
@@ -9935,7 +10742,7 @@ ${argsString}</pre
9935
10742
  ></textarea>
9936
10743
  <button
9937
10744
  type=${this.playgroundIsRunning ? "button" : "submit"}
9938
- class=${`mb-0.5 flex h-9 w-9 shrink-0 items-center justify-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-400 focus-visible:ring-offset-2 [&>svg]:h-[18px] [&>svg]:w-[18px] ${sendDisabled ? "cursor-not-allowed bg-[#00000014] text-[rgb(13,13,13)] opacity-50" : "cursor-pointer bg-black text-white hover:opacity-70 active:opacity-60"}`}
10745
+ class=${`cpk-playground-send mb-0.5 flex h-9 w-9 shrink-0 items-center justify-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-400 focus-visible:ring-offset-2 [&>svg]:h-[18px] [&>svg]:w-[18px] ${sendDisabled ? "cursor-not-allowed bg-[#00000014] text-[rgb(13,13,13)] opacity-50" : "cursor-pointer bg-black text-white hover:opacity-70 active:opacity-60"}`}
9939
10746
  aria-label=${this.playgroundIsRunning ? "Stop agent" : "Send playground message"}
9940
10747
  ?disabled=${sendDisabled}
9941
10748
  @click=${this.playgroundIsRunning ? this.handlePlaygroundStop : nothing}
@@ -10095,9 +10902,9 @@ ${argsString}</pre
10095
10902
  </div>
10096
10903
  ` : visibleMessages.length === 0 ? html`
10097
10904
  <div
10098
- class="mx-auto flex h-full w-full max-w-3xl flex-col items-center justify-center text-center"
10905
+ class="cpk-playground-welcome mx-auto flex h-full w-full flex-col items-center justify-center text-center"
10099
10906
  >
10100
- <p class="text-base font-medium tracking-tight text-gray-900">
10907
+ <p class="cpk-playground-welcome-title">
10101
10908
  How can I help you today?
10102
10909
  </p>
10103
10910
  ${this.renderPlaygroundComposer(agentId, busy, hasRetry, true)}
@@ -11472,6 +12279,7 @@ ${argsString}</pre
11472
12279
  .focusRequestId=${this.threadFocusRequestId}
11473
12280
  .agentStateInput=${this.getLatestStateForAgent(selectedThread.agentId)}
11474
12281
  .agentEventsInput=${this.agentEvents.get(selectedThread.agentId) ?? []}
12282
+ .agentMessagesInput=${selectedThreadIsLocalExample ? EMPTY_INSPECTOR_MESSAGES : this.getLiveAgentMessagesForThread(selectedThread)}
11475
12283
  ></cpk-thread-details>
11476
12284
  ${selectedThreadIsLocalExample ? this.renderThreadsExampleTour() : nothing}` : showingExamples ? this.renderThreadsExampleOverview(locked) : html`
11477
12285
  <div
@@ -11712,11 +12520,7 @@ ${argsString}</pre
11712
12520
  >
11713
12521
  ${isExpanded ? html`
11714
12522
  <div class="group relative">
11715
- <pre
11716
- class="m-0 whitespace-pre-wrap break-words text-[10px] font-mono text-gray-600"
11717
- >
11718
- ${prettyEvent}</pre
11719
- >
12523
+ ${renderHighlightedJsonBlock(extractedEvent)}
11720
12524
  <button
11721
12525
  class="absolute right-0 top-0 cursor-pointer rounded px-2 py-1 text-[10px] opacity-0 transition group-hover:opacity-100 ${this.copiedEvents.has(event.id) ? "bg-green-100 text-green-700" : "bg-gray-100 text-gray-600 hover:bg-gray-200 hover:text-gray-900"}"
11722
12526
  @click=${(e) => {
@@ -11938,7 +12742,7 @@ ${prettyEvent}</pre
11938
12742
  <div class="overflow-auto">
11939
12743
  ${messages && messages.length > 0 ? html`
11940
12744
  <div class="w-full text-xs">
11941
- <div class="flex bg-gray-50">
12745
+ <div class="cpk-agent-messages-head flex bg-gray-50">
11942
12746
  <div
11943
12747
  class="w-40 shrink-0 px-4 py-2 font-medium text-gray-700"
11944
12748
  >
@@ -11948,7 +12752,7 @@ ${prettyEvent}</pre
11948
12752
  Content
11949
12753
  </div>
11950
12754
  </div>
11951
- <div class="divide-y divide-gray-200">
12755
+ <div class="cpk-agent-messages-rows">
11952
12756
  ${messages.map((msg) => {
11953
12757
  const role = msg.role || "unknown";
11954
12758
  const roleColors = {
@@ -11966,7 +12770,7 @@ ${prettyEvent}</pre
11966
12770
  const isFailedResult = role === "tool" && toolError?.toolCallId !== void 0 && toolError.toolCallId === msg.toolCallId;
11967
12771
  return html`
11968
12772
  <div
11969
- class=${isFailedResult ? "flex items-start bg-rose-50" : "flex items-start"}
12773
+ class=${isFailedResult ? "cpk-agent-message-row flex items-start bg-rose-50" : "cpk-agent-message-row flex items-start"}
11970
12774
  data-cpk-failed-tool-result=${isFailedResult ? msg.toolCallId : nothing}
11971
12775
  >
11972
12776
  <div class="w-40 shrink-0 px-4 py-2">
@@ -12048,10 +12852,12 @@ ${prettyEvent}</pre
12048
12852
  >${this.renderIcon("ChevronDown")}</span
12049
12853
  >
12050
12854
  </button>
12051
- ${this.contextMenuOpen ? html`
12855
+ ${iconRail || this.contextMenuOpen ? html`
12052
12856
  <div
12053
- class="absolute left-0 z-50 mt-1.5 w-40 rounded-md border border-gray-200 bg-white py-1 shadow-md ring-1 ring-black/5"
12857
+ class="absolute left-0 z-50 mt-1.5 w-40 rounded-md border border-gray-200 bg-white py-1 shadow-md ring-1 ring-black/5${iconRail ? " inspector-icon-rail-menu" : ""}"
12054
12858
  data-context-dropdown-root="true"
12859
+ data-open=${this.contextMenuOpen ? "true" : "false"}
12860
+ aria-hidden=${this.contextMenuOpen ? "false" : "true"}
12055
12861
  >
12056
12862
  ${filteredOptions.map((option) => html`
12057
12863
  <button
@@ -12188,8 +12994,14 @@ ${prettyEvent}</pre
12188
12994
  this.contextMenuOpen = !this.contextMenuOpen;
12189
12995
  this.requestUpdate();
12190
12996
  }
12997
+ clearIconRailContextCloseTimer() {
12998
+ if (this.iconRailContextCloseTimer === null) return;
12999
+ clearTimeout(this.iconRailContextCloseTimer);
13000
+ this.iconRailContextCloseTimer = null;
13001
+ }
12191
13002
  handleContextOptionSelect(key) {
12192
13003
  if (!this.contextOptions.some((option) => option.key === key)) return;
13004
+ this.clearIconRailContextCloseTimer();
12193
13005
  if (this.selectedContext !== key) {
12194
13006
  this.selectedContext = key;
12195
13007
  this.expandedRows.clear();
@@ -12684,23 +13496,25 @@ ${prettyEvent}</pre
12684
13496
  </button>
12685
13497
 
12686
13498
  ${isExpanded ? html`
12687
- <div class="border-t border-gray-200 bg-gray-50/50 px-4 py-3">
13499
+ <div class="border-t border-gray-200 px-4 py-3">
12688
13500
  <div class="mb-3">
12689
- <h5 class="mb-1 text-xs font-semibold text-gray-700">ID</h5>
12690
- <code
12691
- class="font-mono text-xs font-medium text-gray-800 flex-1 truncate min-w-0"
12692
- >${id}</code
12693
- >
12694
- <button
12695
- type="button"
12696
- class="cpk-copy-btn"
12697
- @click=${(e) => {
13501
+ <div class="mb-1 flex items-center justify-between gap-2">
13502
+ <h5 class="text-xs font-semibold text-gray-700">ID</h5>
13503
+ <button
13504
+ type="button"
13505
+ class="cpk-copy-btn"
13506
+ @click=${(e) => {
12698
13507
  e.stopPropagation();
12699
13508
  this.copyContextValue(id, `${id}:id`, e);
12700
13509
  }}
13510
+ >
13511
+ ${this.copiedContextItems.has(`${id}:id`) ? "Copied" : "Copy"}
13512
+ </button>
13513
+ </div>
13514
+ <code
13515
+ class="block min-w-0 truncate font-mono text-xs font-medium text-gray-800"
13516
+ >${id}</code
12701
13517
  >
12702
- ${this.copiedContextItems.has(`${id}:id`) ? "✓" : "Copy"}
12703
- </button>
12704
13518
  </div>
12705
13519
  ${hasValue ? html`
12706
13520
  <div class="mb-2 flex items-center justify-between gap-2">
@@ -13427,8 +14241,18 @@ function defineWebInspector(registry = globalThis.customElements) {
13427
14241
  defineElementOnce(registry, "cpk-memory-list", CpkMemoryList);
13428
14242
  defineElementOnce(registry, WEB_INSPECTOR_TAG, WebInspectorElement);
13429
14243
  }
14244
+ /**
14245
+ * Bind a host-owned core before an Inspector is connected to the DOM. Disabling
14246
+ * auto-attachment first prevents `connectedCallback` from briefly selecting a
14247
+ * different global core.
14248
+ */
14249
+ function configureWebInspectorElement(inspector, core) {
14250
+ inspector.autoAttachCore = false;
14251
+ inspector.core = core;
14252
+ return inspector;
14253
+ }
13430
14254
  defineWebInspector();
13431
14255
 
13432
14256
  //#endregion
13433
- export { CpkThreadInspector, THREAD_INSPECTOR_TAG, WEB_INSPECTOR_TAG, WebInspectorElement, defineWebInspector, ɵCpkThreadDetails, buildCapabilityRows as ɵbuildCapabilityRows, maxRecallScore as ɵmaxRecallScore, normalizeRelevance as ɵnormalizeRelevance, relevanceBarWidth as ɵrelevanceBarWidth };
14257
+ export { CpkThreadInspector, THREAD_INSPECTOR_TAG, WEB_INSPECTOR_TAG, WebInspectorElement, configureWebInspectorElement, defineWebInspector, ɵCpkThreadDetails, buildCapabilityRows as ɵbuildCapabilityRows, maxRecallScore as ɵmaxRecallScore, normalizeRelevance as ɵnormalizeRelevance, relevanceBarWidth as ɵrelevanceBarWidth };
13434
14258
  //# sourceMappingURL=index.mjs.map