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