@copilotkit/web-inspector 1.69.1 → 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.
Files changed (39) hide show
  1. package/dist/index.cjs +1221 -994
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +30 -46
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.mts +30 -46
  6. package/dist/index.d.mts.map +1 -1
  7. package/dist/index.mjs +1223 -994
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/index.umd.js +1304 -1644
  10. package/dist/index.umd.js.map +1 -1
  11. package/dist/lib/inspector-nav.cjs +0 -1
  12. package/dist/lib/inspector-nav.cjs.map +1 -1
  13. package/dist/lib/inspector-nav.mjs +0 -1
  14. package/dist/lib/inspector-nav.mjs.map +1 -1
  15. package/dist/lib/telemetry.cjs +1 -19
  16. package/dist/lib/telemetry.cjs.map +1 -1
  17. package/dist/lib/telemetry.d.cts.map +1 -1
  18. package/dist/lib/telemetry.d.mts.map +1 -1
  19. package/dist/lib/telemetry.mjs +2 -18
  20. package/dist/lib/telemetry.mjs.map +1 -1
  21. package/dist/package.cjs +1 -1
  22. package/dist/package.mjs +1 -1
  23. package/dist/styles/generated.cjs +1 -1
  24. package/dist/styles/generated.cjs.map +1 -1
  25. package/dist/styles/generated.mjs +1 -1
  26. package/dist/styles/generated.mjs.map +1 -1
  27. package/package.json +3 -3
  28. package/dist/lib/event-snippets.cjs +0 -559
  29. package/dist/lib/event-snippets.cjs.map +0 -1
  30. package/dist/lib/event-snippets.d.cts +0 -61
  31. package/dist/lib/event-snippets.d.cts.map +0 -1
  32. package/dist/lib/event-snippets.d.mts +0 -61
  33. package/dist/lib/event-snippets.d.mts.map +0 -1
  34. package/dist/lib/event-snippets.mjs +0 -537
  35. package/dist/lib/event-snippets.mjs.map +0 -1
  36. package/dist/lib/inspector-nav.d.cts +0 -11
  37. package/dist/lib/inspector-nav.d.cts.map +0 -1
  38. package/dist/lib/inspector-nav.d.mts +0 -11
  39. package/dist/lib/inspector-nav.d.mts.map +0 -1
package/dist/index.cjs CHANGED
@@ -9,7 +9,6 @@ const require_inspector_metadata = require('./lib/inspector-metadata.cjs');
9
9
  const require_home_briefing = require('./lib/home-briefing.cjs');
10
10
  const require_inspector_nav = require('./lib/inspector-nav.cjs');
11
11
  const require_thread_selection = require('./lib/thread-selection.cjs');
12
- const require_event_snippets = require('./lib/event-snippets.cjs');
13
12
  const require_telemetry = require('./lib/telemetry.cjs');
14
13
  let lit = require("lit");
15
14
  let marked = require("marked");
@@ -244,6 +243,21 @@ const LAUNCHER_BASE_LABEL = "Web Inspector";
244
243
  const EDGE_MARGIN = 16;
245
244
  /** HUD card plus the hover bridge. Used to pick left vs right. */
246
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
+ };
247
261
  const DRAG_THRESHOLD = 6;
248
262
  const MIN_WINDOW_WIDTH = 880;
249
263
  const MIN_WINDOW_WIDTH_DOCKED_LEFT = 640;
@@ -349,6 +363,29 @@ const AGENT_EVENT_TYPES = [
349
363
  "ACTIVITY_SNAPSHOT",
350
364
  "ACTIVITY_DELTA"
351
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
+ }
352
389
  /**
353
390
  * Map core.tools (the registry INCLUDING disabled tools) into Capabilities-tab
354
391
  * frontend-tool rows. Pure: no DOM, no `this`. Reads current on/off state from
@@ -607,13 +644,6 @@ function highlightedJson(obj) {
607
644
  const cached = highlightedJsonCache.get(obj);
608
645
  if (cached !== void 0) return cached;
609
646
  }
610
- const colors = {
611
- key: "#5558B2",
612
- str: "#087653",
613
- num: "#8a5900",
614
- bool: "#c0333a",
615
- nil: "#68686e"
616
- };
617
647
  const json = JSON.stringify(obj, null, 2);
618
648
  if (!json) return "";
619
649
  const parts = [];
@@ -623,11 +653,11 @@ function highlightedJson(obj) {
623
653
  while ((match = re.exec(json)) !== null) {
624
654
  parts.push(escapeHtml(json.slice(lastIndex, match.index)));
625
655
  const m = match[0];
626
- let color = colors.num;
627
- if (m.startsWith("\"")) color = m.trimEnd().endsWith(":") ? colors.key : colors.str;
628
- else if (m === "true" || m === "false") color = colors.bool;
629
- else if (m === "null") color = colors.nil;
630
- 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>`);
631
661
  lastIndex = match.index + m.length;
632
662
  }
633
663
  parts.push(escapeHtml(json.slice(lastIndex)));
@@ -652,31 +682,23 @@ function renderHighlightedJsonBlock(value, options = {}) {
652
682
  ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(parsed))}</pre
653
683
  >`;
654
684
  }
655
- function eventColors(type) {
656
- if (type.startsWith("TEXT_MESSAGE")) return {
657
- bg: "#EEE6FE",
658
- fg: "#57575B"
659
- };
660
- if (type.startsWith("TOOL_CALL")) return {
661
- bg: "rgba(133,236,206,0.15)",
662
- fg: "#087653"
663
- };
664
- if (type.startsWith("STATE")) return {
665
- bg: "rgba(190,194,255,0.102)",
666
- fg: "#5558B2"
667
- };
668
- if (type === "RUN_ERROR" || type === "ERROR") return {
669
- bg: "rgba(250,95,103,0.13)",
670
- fg: "#c0333a"
671
- };
672
- if (type.startsWith("RUN_") || type.startsWith("STEP_")) return {
673
- bg: "rgba(255,172,77,0.2)",
674
- fg: "#8a5900"
675
- };
676
- return {
677
- bg: "#F7F7F9",
678
- fg: "#68686e"
679
- };
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";
680
702
  }
681
703
  function formatTimestamp(ts) {
682
704
  const date = typeof ts === "number" ? new Date(ts) : new Date(ts);
@@ -1078,6 +1100,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1078
1100
  this.threadInspectionAvailable = false;
1079
1101
  this.agentStateInput = null;
1080
1102
  this.agentEventsInput = [];
1103
+ this.agentMessagesInput = EMPTY_INSPECTOR_MESSAGES;
1081
1104
  this.liveMessageVersion = 0;
1082
1105
  this.viewInAppMode = "hidden";
1083
1106
  this.viewInAppError = null;
@@ -1153,6 +1176,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1153
1176
  threadInspectionAvailable: { attribute: false },
1154
1177
  agentStateInput: { attribute: false },
1155
1178
  agentEventsInput: { attribute: false },
1179
+ agentMessagesInput: { attribute: false },
1156
1180
  liveMessageVersion: { attribute: false },
1157
1181
  viewInAppMode: { attribute: false },
1158
1182
  viewInAppError: { attribute: false },
@@ -1297,6 +1321,11 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1297
1321
  display: flex;
1298
1322
  flex-direction: row;
1299
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;
1300
1329
  }
1301
1330
 
1302
1331
  .cpk-td {
@@ -1421,11 +1450,25 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1421
1450
  flex-shrink: 0;
1422
1451
  }
1423
1452
 
1424
- .cpk-td__metadata-strip {
1453
+ .cpk-td__chrome-actions {
1454
+ margin-inline-start: auto;
1425
1455
  display: flex;
1456
+ flex-wrap: wrap;
1426
1457
  align-items: center;
1458
+ justify-content: flex-end;
1427
1459
  gap: 6px;
1428
- 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;
1429
1472
  padding: 10px 16px;
1430
1473
  border-bottom: 1px solid #e9e9ef;
1431
1474
  background: #fbfbfd;
@@ -1434,19 +1477,22 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1434
1477
 
1435
1478
  .cpk-td__metadata-pills {
1436
1479
  display: flex;
1480
+ align-items: center;
1437
1481
  gap: 6px;
1438
- flex: 1;
1439
- flex-wrap: wrap;
1482
+ width: 100%;
1440
1483
  min-width: 0;
1484
+ flex-wrap: nowrap;
1441
1485
  }
1442
1486
 
1443
1487
  .cpk-td__metadata-pill {
1444
1488
  display: inline-flex;
1445
1489
  align-items: center;
1446
- gap: 5px;
1447
- max-width: 220px;
1448
- padding: 3px 7px;
1449
- 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;
1450
1496
  border-radius: 6px;
1451
1497
  background: #ffffff;
1452
1498
  color: #57575b;
@@ -1462,20 +1508,17 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1462
1508
  }
1463
1509
 
1464
1510
  .cpk-td__metadata-value {
1511
+ min-width: 0;
1465
1512
  overflow: hidden;
1466
1513
  text-overflow: ellipsis;
1514
+ white-space: nowrap;
1467
1515
  }
1468
1516
 
1517
+ .cpk-td__metadata-value--wrap,
1469
1518
  .cpk-td__metadata-pill--wrap {
1470
- max-width: 100%;
1471
- white-space: normal;
1472
- }
1473
-
1474
- .cpk-td__metadata-value--wrap {
1475
- overflow: visible;
1476
- text-overflow: clip;
1477
- white-space: normal;
1478
- overflow-wrap: anywhere;
1519
+ overflow: hidden;
1520
+ text-overflow: ellipsis;
1521
+ white-space: nowrap;
1479
1522
  }
1480
1523
 
1481
1524
  .cpk-td__view-in-app {
@@ -1486,11 +1529,18 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1486
1529
  border-radius: 6px;
1487
1530
  background: #5558b2;
1488
1531
  color: #ffffff;
1489
- font-family: "Plus Jakarta Sans", sans-serif;
1490
- font-size: 11px;
1532
+ font-family: "Spline Sans Mono", monospace;
1533
+ font-size: 10px;
1491
1534
  font-weight: 600;
1492
- padding: 5px 10px;
1535
+ line-height: 1.2;
1536
+ min-height: 24px;
1537
+ padding: 3px 8px;
1493
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;
1494
1544
  }
1495
1545
 
1496
1546
  .cpk-td__view-in-app:focus-visible {
@@ -1498,6 +1548,10 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1498
1548
  outline-offset: 2px;
1499
1549
  }
1500
1550
 
1551
+ .cpk-td__view-in-app:active {
1552
+ transform: scale(0.96);
1553
+ }
1554
+
1501
1555
  .cpk-td__view-in-app--stop {
1502
1556
  background: #ffffff;
1503
1557
  color: #5558b2;
@@ -1509,6 +1563,16 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1509
1563
  font-size: 11px;
1510
1564
  }
1511
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
+
1512
1576
  /*
1513
1577
  * Each tab's content is wrapped in this panel so the keep-mounted
1514
1578
  * inactive panels can be hidden via display:none without disturbing
@@ -1705,15 +1769,16 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1705
1769
  .cpk-td__tool-pre {
1706
1770
  margin: 0;
1707
1771
  font-family: "Spline Sans Mono", monospace;
1708
- font-size: 10px;
1772
+ font-size: 12px;
1709
1773
  background: #f7f7f9;
1710
- padding: 6px 8px;
1711
- border-radius: 5px;
1774
+ padding: 10px 12px;
1775
+ border-radius: 6px;
1712
1776
  overflow-x: auto;
1713
1777
  white-space: pre-wrap;
1714
- word-break: break-all;
1778
+ overflow-wrap: anywhere;
1779
+ word-break: normal;
1715
1780
  color: #010507;
1716
- line-height: 1.6;
1781
+ line-height: 1.65;
1717
1782
  }
1718
1783
 
1719
1784
  /* ── Tool call group ─────────────────────────────────────────────── */
@@ -1766,12 +1831,31 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1766
1831
 
1767
1832
  /* ── Interaction timeline ───────────────────────────────────────── */
1768
1833
  .cpk-td__timeline-item {
1769
- border: 1px solid #e9e9ef;
1770
- border-radius: 7px;
1771
- background: #ffffff;
1834
+ border: 1px solid transparent;
1835
+ border-radius: 10px;
1836
+ background: transparent;
1772
1837
  overflow: hidden;
1773
1838
  }
1774
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
+
1775
1859
  .cpk-td__timeline-item--warning {
1776
1860
  border-color: rgba(250, 95, 103, 0.35);
1777
1861
  background: rgba(250, 95, 103, 0.04);
@@ -1781,29 +1865,72 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1781
1865
  display: flex;
1782
1866
  align-items: center;
1783
1867
  gap: 8px;
1784
- 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;
1785
1874
  background: #f7f7f9;
1786
1875
  }
1787
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
+
1788
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;
1789
1892
  font-family: "Spline Sans Mono", monospace;
1790
- font-size: 9px;
1893
+ font-size: 10px;
1791
1894
  font-weight: 600;
1895
+ letter-spacing: 0.04em;
1896
+ line-height: 1.2;
1792
1897
  text-transform: uppercase;
1793
- 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;
1794
1914
  }
1795
1915
 
1796
1916
  .cpk-td__timeline-title {
1797
1917
  flex: 1;
1798
1918
  min-width: 0;
1919
+ font-family: "Plus Jakarta Sans", sans-serif;
1799
1920
  font-size: 12px;
1800
1921
  font-weight: 500;
1801
- color: #010507;
1922
+ color: #57575b;
1802
1923
  overflow: hidden;
1803
1924
  text-overflow: ellipsis;
1804
1925
  white-space: nowrap;
1805
1926
  }
1806
1927
 
1928
+ .cpk-td__timeline-item--message .cpk-td__timeline-title {
1929
+ font-size: 13px;
1930
+ font-weight: 600;
1931
+ color: #010507;
1932
+ }
1933
+
1807
1934
  .cpk-td__timeline-time {
1808
1935
  font-family: "Spline Sans Mono", monospace;
1809
1936
  font-size: 9px;
@@ -1814,6 +1941,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1814
1941
  .cpk-td__timeline-body {
1815
1942
  margin: 0;
1816
1943
  padding: 0 10px 9px;
1944
+ font-family: "Plus Jakarta Sans", sans-serif;
1817
1945
  font-size: 12px;
1818
1946
  line-height: 1.55;
1819
1947
  color: #57575b;
@@ -1821,21 +1949,26 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1821
1949
  word-break: break-word;
1822
1950
  }
1823
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
+
1824
1958
  .cpk-td__timeline-toolbar {
1825
1959
  display: flex;
1826
1960
  gap: 6px;
1827
- margin-left: auto;
1828
1961
  }
1829
1962
 
1830
1963
  .cpk-td__timeline-bulk-toggle {
1831
1964
  margin: 0;
1832
- padding: 4px 8px;
1833
- border: 1px solid #dcdce8;
1834
- border-radius: 7px;
1965
+ padding: 6px 10px;
1966
+ border: 1px solid #dbdbe5;
1967
+ border-radius: 8px;
1835
1968
  background: #ffffff;
1836
1969
  color: #36363a;
1837
1970
  cursor: pointer;
1838
- font-family: "Inter", sans-serif;
1971
+ font-family: "Spline Sans Mono", monospace;
1839
1972
  font-size: 11px;
1840
1973
  font-weight: 600;
1841
1974
  line-height: 1.2;
@@ -1910,84 +2043,6 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1910
2043
  }
1911
2044
  }
1912
2045
 
1913
- @keyframes cpk-playground-message-enter {
1914
- from {
1915
- opacity: 0;
1916
- filter: blur(2px);
1917
- transform: translateY(4px);
1918
- }
1919
- to {
1920
- opacity: 1;
1921
- filter: blur(0);
1922
- transform: translateY(0);
1923
- }
1924
- }
1925
-
1926
- @keyframes cpk-playground-thinking {
1927
- 0%,
1928
- 60%,
1929
- 100% {
1930
- opacity: 0.28;
1931
- transform: translateY(0);
1932
- }
1933
- 30% {
1934
- opacity: 1;
1935
- transform: translateY(-2px);
1936
- }
1937
- }
1938
-
1939
- .cpk-playground-root {
1940
- container-type: inline-size;
1941
- }
1942
-
1943
- .cpk-playground-message-enter {
1944
- animation: cpk-playground-message-enter 0.24s cubic-bezier(0.16, 1, 0.3, 1)
1945
- both;
1946
- }
1947
-
1948
- .cpk-playground-thinking-dot {
1949
- animation: cpk-playground-thinking 1.2s ease-in-out infinite;
1950
- }
1951
-
1952
- .cpk-playground-thinking-dot:nth-child(2) {
1953
- animation-delay: 0.12s;
1954
- }
1955
-
1956
- .cpk-playground-thinking-dot:nth-child(3) {
1957
- animation-delay: 0.24s;
1958
- }
1959
-
1960
- .cpk-playground-reasoning summary::-webkit-details-marker {
1961
- display: none;
1962
- }
1963
-
1964
- .cpk-playground-reasoning[open] .cpk-playground-reasoning-chevron {
1965
- transform: rotate(90deg);
1966
- }
1967
-
1968
- @container (max-width: 560px) {
1969
- .cpk-playground-header {
1970
- align-items: stretch;
1971
- }
1972
-
1973
- .cpk-playground-actions {
1974
- width: 100%;
1975
- }
1976
-
1977
- .cpk-playground-thread-select {
1978
- min-width: 0;
1979
- max-width: none;
1980
- flex: 1;
1981
- }
1982
- }
1983
-
1984
- @media (prefers-reduced-motion: reduce) {
1985
- .cpk-playground-message-enter,
1986
- .cpk-playground-thinking-dot {
1987
- animation: none;
1988
- }
1989
- }
1990
-
1991
2046
  .cpk-td__genui {
1992
2047
  display: flex;
1993
2048
  flex-direction: column;
@@ -2029,8 +2084,9 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2029
2084
  /* ── AG-UI Events ────────────────────────────────────────────────── */
2030
2085
  .cpk-td__event {
2031
2086
  flex-shrink: 0;
2032
- border: 1px solid #e9e9ef;
2033
- border-radius: 7px;
2087
+ border: 1px solid #dbdbe5;
2088
+ border-radius: 10px;
2089
+ background: #ffffff;
2034
2090
  overflow: hidden;
2035
2091
  /*
2036
2092
  * content-visibility: auto lets the browser skip layout + paint for
@@ -2046,48 +2102,89 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2046
2102
  contain-intrinsic-size: 0 80px;
2047
2103
  }
2048
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
+
2049
2110
  .cpk-td__event-header {
2050
2111
  display: flex;
2051
- justify-content: space-between;
2052
2112
  align-items: center;
2053
- padding: 5px 10px;
2113
+ gap: 8px;
2114
+ padding: 6px 10px;
2115
+ background: transparent;
2054
2116
  }
2055
2117
 
2056
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;
2057
2125
  font-family: "Spline Sans Mono", monospace;
2058
- font-size: 9px;
2059
- font-weight: 500;
2060
- 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;
2061
2143
  }
2062
2144
 
2063
2145
  .cpk-td__event-time {
2146
+ margin-inline-start: auto;
2064
2147
  font-family: "Spline Sans Mono", monospace;
2065
2148
  font-size: 9px;
2066
2149
  color: #68686e;
2150
+ flex-shrink: 0;
2067
2151
  }
2068
2152
 
2069
- .cpk-td__event-payload {
2070
- margin: 0;
2071
- font-family: "Spline Sans Mono", monospace;
2072
- font-size: 10px;
2073
- line-height: 1.6;
2074
- white-space: pre-wrap;
2075
- word-break: break-all;
2076
- color: #57575b;
2077
- padding: 8px 10px;
2078
- border-top: 1px solid #e9e9ef;
2079
- }
2080
-
2081
- /* ── JSON block (agent state) ────────────────────────────────────── */
2153
+ .cpk-td__event-payload,
2082
2154
  .cpk-td__json-block,
2083
2155
  .cpk-json-block {
2084
2156
  margin: 0;
2157
+ padding: 10px 12px;
2158
+ border-top: 1px solid #dbdbe5;
2159
+ background: #f7f7f9;
2085
2160
  font-family: "Spline Sans Mono", monospace;
2086
- font-size: 11px;
2087
- line-height: 1.8;
2161
+ font-size: 12px;
2162
+ line-height: 1.65;
2088
2163
  white-space: pre-wrap;
2089
- word-break: break-all;
2090
- 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);
2091
2188
  }
2092
2189
 
2093
2190
  /* ── Resize divider ──────────────────────────────────────────────── */
@@ -2186,6 +2283,11 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2186
2283
 
2187
2284
  :host([data-color-scheme="dark"]) {
2188
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;
2189
2291
  }
2190
2292
 
2191
2293
  :host([data-color-scheme="dark"]) .cpk-td {
@@ -2226,11 +2328,15 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2226
2328
  }
2227
2329
 
2228
2330
  :host([data-color-scheme="dark"]) .cpk-td__timeline-header,
2229
- :host([data-color-scheme="dark"]) .cpk-td__tool-body,
2230
- :host([data-color-scheme="dark"]) .cpk-td__tool-pre {
2331
+ :host([data-color-scheme="dark"]) .cpk-td__tool-body {
2231
2332
  background: #171a22;
2232
2333
  }
2233
2334
 
2335
+ :host([data-color-scheme="dark"]) .cpk-td__tool-pre {
2336
+ background: #111319;
2337
+ color: #f3f4f8;
2338
+ }
2339
+
2234
2340
  :host([data-color-scheme="dark"]) .cpk-td__panel-toggle:hover,
2235
2341
  :host([data-color-scheme="dark"]) .cpk-td__tool-header:hover,
2236
2342
  :host([data-color-scheme="dark"]) .cpk-td__timeline-bulk-toggle:hover,
@@ -2240,12 +2346,115 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2240
2346
 
2241
2347
  :host([data-color-scheme="dark"]) .cpk-td__panel-toggle--active,
2242
2348
  :host([data-color-scheme="dark"]) .cpk-td__inline-chip,
2243
- :host([data-color-scheme="dark"]) .cpk-td__timeline-kind,
2244
2349
  :host([data-color-scheme="dark"]) .cpk-td__genui-badge {
2245
2350
  background: #302b43;
2246
2351
  color: #d8d9ff;
2247
2352
  }
2248
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
+
2249
2458
  :host([data-color-scheme="dark"]) .cpk-td__tab,
2250
2459
  :host([data-color-scheme="dark"]) .cpk-td__panel-toggle,
2251
2460
  :host([data-color-scheme="dark"]) .cpk-td__metadata-label,
@@ -2272,7 +2481,9 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2272
2481
  :host([data-color-scheme="dark"]) .cpk-td__event-payload,
2273
2482
  :host([data-color-scheme="dark"]) .cpk-td__json-block,
2274
2483
  :host([data-color-scheme="dark"]) .cpk-json-block {
2275
- color: #c7c9d2;
2484
+ background: #111319;
2485
+ border-top-color: #343742;
2486
+ color: #f3f4f8;
2276
2487
  }
2277
2488
 
2278
2489
  :host([data-color-scheme="dark"]) .cpk-tdp__divider {
@@ -2292,7 +2503,8 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2292
2503
  if (this.canFetchEvents()) {
2293
2504
  this._eventsFetched = true;
2294
2505
  this.fetchEvents(this.threadId);
2295
- } else this.fetchMessages(this.threadId);
2506
+ }
2507
+ if (this.canFetchMessages()) this.fetchMessages(this.threadId);
2296
2508
  } else {
2297
2509
  this._fetchedMetadata = null;
2298
2510
  this._conversation = [];
@@ -2303,7 +2515,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2303
2515
  this._messagesAbort = null;
2304
2516
  this.fetchMessages(this.threadId, true);
2305
2517
  }
2306
- 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");
2307
2519
  if (this.focusMessageId && (this.focusRequestId > this._scrolledFocusRequestId || focusedContentChanged)) {
2308
2520
  if (this._tab !== "timeline") {
2309
2521
  this._activatedTabs = new Set([...this._activatedTabs, "timeline"]);
@@ -2460,18 +2672,14 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2460
2672
  if (result.status === "not-available") {
2461
2673
  this._eventsNotAvailable = true;
2462
2674
  this._fetchedEvents = [];
2463
- if (this.canFetchMessages()) this.fetchMessages(threadId);
2464
2675
  return;
2465
2676
  }
2466
- const mappedEvents = this.mapApiEvents(result.events);
2467
- this._fetchedEvents = mappedEvents;
2468
- if (mappedEvents.length === 0 && this.canFetchMessages()) this.fetchMessages(threadId);
2677
+ this._fetchedEvents = this.mapApiEvents(result.events);
2469
2678
  } catch (err) {
2470
2679
  if (err instanceof Error && err.name === "AbortError") return;
2471
2680
  if (this.threadId !== threadId) return;
2472
2681
  this._eventsError = err instanceof Error ? err.message : "Failed to load events";
2473
2682
  this._fetchedEvents = [];
2474
- if (this.canFetchMessages()) this.fetchMessages(threadId);
2475
2683
  } finally {
2476
2684
  if (!controller.signal.aborted && this.threadId === threadId) this._loadingEvents = false;
2477
2685
  }
@@ -2545,13 +2753,15 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2545
2753
  mapMessages(messages) {
2546
2754
  const items = [];
2547
2755
  const toolCallMap = /* @__PURE__ */ new Map();
2548
- for (const msg of messages) if (msg.role === "user" && msg.content) items.push({
2549
- id: msg.id,
2550
- type: "user",
2551
- content: msg.content,
2552
- createdAt: ""
2553
- });
2554
- 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") {
2555
2765
  if (msg.toolCalls?.length) for (const tc of msg.toolCalls) {
2556
2766
  let args = {};
2557
2767
  if (typeof tc.args === "string") try {
@@ -2580,10 +2790,11 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2580
2790
  toolCallMap.set(tc.id, item);
2581
2791
  items.push(item);
2582
2792
  }
2583
- if (msg.content) items.push({
2793
+ const assistantContent = textFromUnknownContent(msg.content);
2794
+ if (assistantContent) items.push({
2584
2795
  id: msg.id,
2585
2796
  type: "assistant",
2586
- content: msg.content,
2797
+ content: assistantContent,
2587
2798
  createdAt: ""
2588
2799
  });
2589
2800
  } else if (msg.role === "activity") items.push({
@@ -2631,14 +2842,86 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2631
2842
  return this.timelineItemsForEvents(this.activeEvents);
2632
2843
  }
2633
2844
  timelineItemsForEvents(events) {
2634
- if (this._timelineItemsCache?.events === events) return this._timelineItemsCache.items;
2635
- 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));
2636
2849
  this._timelineItemsCache = {
2637
2850
  events,
2851
+ conversation,
2852
+ agentMessages,
2638
2853
  items
2639
2854
  };
2640
2855
  return items;
2641
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
+ }
2642
2925
  timelineItemsFromEvents(events) {
2643
2926
  if (events.length === 0) return [];
2644
2927
  const items = [];
@@ -2677,7 +2960,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2677
2960
  id: `message-${key}`,
2678
2961
  messageId: key,
2679
2962
  kind: "message",
2680
- title: `${role || "message"} message`,
2963
+ title: messageTitle(role || "message"),
2681
2964
  body: "",
2682
2965
  timestamp: event.timestamp,
2683
2966
  sourceIndex
@@ -2825,7 +3108,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2825
3108
  items.push({
2826
3109
  id: `${type}-${sourceIndex}`,
2827
3110
  kind: "state",
2828
- title: type === "STATE_SNAPSHOT" ? "State snapshot captured" : "State delta captured",
3111
+ title: type === "STATE_SNAPSHOT" ? "State snapshot" : "State delta",
2829
3112
  timestamp: event.timestamp,
2830
3113
  sourceIndex,
2831
3114
  details: payload
@@ -2835,7 +3118,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2835
3118
  items.push({
2836
3119
  id: `event-${sourceIndex}`,
2837
3120
  kind: "event",
2838
- title: type,
3121
+ title: humanizeEventType(type),
2839
3122
  timestamp: event.timestamp,
2840
3123
  sourceIndex,
2841
3124
  details: payload
@@ -2974,6 +3257,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2974
3257
  });
2975
3258
  }
2976
3259
  render() {
3260
+ const viewInApp = this.renderViewInAppAction();
2977
3261
  return lit.html`
2978
3262
  <div class="cpk-td">
2979
3263
  <!-- ── Left area: tabs + content ─────────────────────────────────── -->
@@ -3001,6 +3285,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3001
3285
  </button>
3002
3286
  `)}
3003
3287
  </div>
3288
+ ${viewInApp !== lit.nothing ? lit.html`<div class="cpk-td__chrome-actions">${viewInApp}</div>` : lit.nothing}
3004
3289
  ${this.renderPanelToggle()}
3005
3290
  </div>
3006
3291
  ${this.renderMetadataStrip()}
@@ -3055,8 +3340,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3055
3340
  value: metadata?.name ?? this.thread?.name ?? "Untitled"
3056
3341
  }, {
3057
3342
  label: "ID",
3058
- value: metadata?.id ?? this.threadId ?? "—",
3059
- wrap: true
3343
+ value: metadata?.id ?? this.threadId ?? "—"
3060
3344
  }];
3061
3345
  for (const fact of [
3062
3346
  {
@@ -3078,7 +3362,6 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3078
3362
  value: fact.label === "Created" || fact.label === "Updated" ? this.fmtTime(fact.value) : fact.value
3079
3363
  });
3080
3364
  }
3081
- const bulkControls = this.renderActiveBulkControls();
3082
3365
  return lit.html`
3083
3366
  <div
3084
3367
  class="cpk-td__metadata-strip"
@@ -3101,8 +3384,6 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3101
3384
  </span>
3102
3385
  `)}
3103
3386
  </div>
3104
- ${this.renderViewInAppAction()}
3105
- ${bulkControls}
3106
3387
  </div>
3107
3388
  `;
3108
3389
  }
@@ -3129,10 +3410,8 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3129
3410
  >` : lit.nothing}
3130
3411
  `;
3131
3412
  }
3132
- renderActiveBulkControls() {
3413
+ renderTimelineBulkControls() {
3133
3414
  if (this._eventsNotAvailable) return lit.nothing;
3134
- if (this._tab === "raw-events") return this.renderRawEventBulkControls();
3135
- if (this._tab !== "timeline") return lit.nothing;
3136
3415
  const detailIds = this.timelineItemsForEvents(this.activeEvents).filter((item) => item.details).map((item) => item.id);
3137
3416
  if (detailIds.length <= 1) return lit.nothing;
3138
3417
  return lit.html`<div class="cpk-td__timeline-toolbar">
@@ -3205,7 +3484,12 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3205
3484
  `;
3206
3485
  }
3207
3486
  const events = this.activeEvents;
3208
- 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
+ ]);
3209
3493
  if (cachedTimeline) return cachedTimeline;
3210
3494
  const timelineItems = this.timelineItemsForEvents(events);
3211
3495
  if (timelineItems.length === 0) {
@@ -3221,14 +3505,28 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3221
3505
  </div>
3222
3506
  `;
3223
3507
  }
3224
- 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(" ");
3225
3524
  }
3226
3525
  renderTimelineItem(item) {
3227
- const isWarning = item.kind === "warning";
3228
3526
  const detailsExpanded = this._expandedTimelineDetails.has(item.id);
3229
3527
  return lit.html`
3230
3528
  <div
3231
- class="cpk-td__timeline-item ${isWarning ? "cpk-td__timeline-item--warning" : ""}"
3529
+ class=${this.timelineItemClass(item)}
3232
3530
  data-message-id=${item.messageId ?? lit.nothing}
3233
3531
  >
3234
3532
  <div class="cpk-td__timeline-header">
@@ -3236,13 +3534,15 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3236
3534
  >${item.severity === "error" ? "error" : item.kind}</span
3237
3535
  >
3238
3536
  <span class="cpk-td__timeline-title">${item.title}</span>
3239
- <button
3240
- type="button"
3241
- class="cpk-td__source-link"
3242
- @click=${() => this.revealSourceEvent(item.sourceIndex)}
3243
- >
3244
- Source event #${item.sourceIndex}
3245
- </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}
3246
3546
  <span class="cpk-td__timeline-time"
3247
3547
  >${formatTimestamp(item.timestamp)}</span
3248
3548
  >
@@ -3279,9 +3579,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3279
3579
  <span>${detailsExpanded ? "Hide details" : "Show details"}</span>
3280
3580
  </button>` : lit.nothing}
3281
3581
  ${item.body ? lit.html`<div class="cpk-td__timeline-body">${item.body}</div>` : lit.nothing}
3282
- ${item.details && detailsExpanded ? lit.html`<pre class="cpk-td__timeline-body">
3283
- ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(item.details))}</pre
3284
- >` : lit.nothing}
3582
+ ${item.details && detailsExpanded ? renderHighlightedJsonBlock(item.details) : lit.nothing}
3285
3583
  </div>
3286
3584
  `;
3287
3585
  }
@@ -3411,9 +3709,7 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(item.details))}<
3411
3709
  ${expanded ? lit.html`
3412
3710
  <div class="cpk-td__tool-body">
3413
3711
  <div class="cpk-td__tool-section-label">Arguments</div>
3414
- <pre class="cpk-td__tool-pre">
3415
- ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(item.arguments))}</pre
3416
- >
3712
+ ${renderHighlightedJsonBlock(item.arguments)}
3417
3713
  ${item.result ? lit.html`
3418
3714
  <div
3419
3715
  class="cpk-td__tool-section-label"
@@ -3421,9 +3717,7 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(item.arguments))
3421
3717
  >
3422
3718
  Result
3423
3719
  </div>
3424
- <pre class="cpk-td__tool-pre">
3425
- ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(item.result))}</pre
3426
- >
3720
+ ${renderHighlightedJsonBlock(item.result)}
3427
3721
  ` : lit.nothing}
3428
3722
  </div>
3429
3723
  ` : lit.nothing}
@@ -3538,15 +3832,17 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(item.result))}</
3538
3832
  </div>
3539
3833
  `;
3540
3834
  return this.cachedPanelTpl("raw-events", [events, this._expandedRawEvents], () => {
3541
- return lit.html`${events.map((event) => {
3542
- const { bg, fg } = eventColors(event.type);
3835
+ return lit.html`${this.renderRawEventBulkControls()}${events.map((event) => {
3543
3836
  const eventId = this.rawEventId(event);
3544
3837
  const detailsExpanded = this._expandedRawEvents.has(eventId);
3545
3838
  return lit.html`
3546
- <div class="cpk-td__event" data-source-index=${event.sourceIndex}>
3547
- <div class="cpk-td__event-header" style="background:${bg}">
3548
- <span class="cpk-td__event-type" style="color:${fg}"
3549
- >${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
3550
3846
  >
3551
3847
  <span class="cpk-td__event-time"
3552
3848
  >${formatTimestamp(event.timestamp)}</span
@@ -3585,9 +3881,7 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(item.result))}</
3585
3881
  >${detailsExpanded ? "Hide details" : "Show details"}</span
3586
3882
  >
3587
3883
  </button>
3588
- ${detailsExpanded ? lit.html`<pre class="cpk-td__event-payload">
3589
- ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.rawEvent ?? event))}</pre
3590
- >` : lit.nothing}
3884
+ ${detailsExpanded ? renderHighlightedJsonBlock(event.rawEvent ?? event) : lit.nothing}
3591
3885
  </div>
3592
3886
  `;
3593
3887
  })}`;
@@ -4406,26 +4700,6 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
4406
4700
  inspect: "ag-ui-events"
4407
4701
  };
4408
4702
  this.lastScrolledAgentNavigationLayout = null;
4409
- this.eventSnippets = [];
4410
- this.selectedSnippetId = null;
4411
- this.snippetRecipe = "tool-call";
4412
- this.snippetName = "";
4413
- this.snippetJson = "[]";
4414
- this.snippetToolName = "";
4415
- this.snippetToolArgs = "{}";
4416
- this.snippetReasoningText = "";
4417
- this.snippetTextContent = "";
4418
- this.snippetActivityType = "a2ui-surface";
4419
- this.snippetActivityContent = "{}";
4420
- this.snippetError = null;
4421
- this.snippetBanner = null;
4422
- this.snippetConfirmOpen = false;
4423
- this.lastInject = null;
4424
- this.snippetListWidth = 200;
4425
- this.snippetDividerResizing = false;
4426
- this.snippetDividerPointerId = -1;
4427
- this.snippetDividerStartX = 0;
4428
- this.snippetDividerStartWidth = 0;
4429
4703
  this.selectedThreadId = null;
4430
4704
  this.inAppThreadId = null;
4431
4705
  this.inAppAgentId = null;
@@ -4466,6 +4740,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
4466
4740
  this.threadCapabilityEnabled = null;
4467
4741
  this.threadCapabilityGeneration = 0;
4468
4742
  this.contextMenuOpen = false;
4743
+ this.iconRailContextCloseTimer = null;
4469
4744
  this.layoutMenuOpen = false;
4470
4745
  this.dockMode = "floating";
4471
4746
  this.popOut = null;
@@ -4527,6 +4802,9 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
4527
4802
  this.launcherHudSide = "left";
4528
4803
  this.launcherHudHelp = null;
4529
4804
  this.launcherHudCloseTimer = null;
4805
+ this.launcherHudIntro = false;
4806
+ this.launcherHudIntroStartTimer = null;
4807
+ this.launcherHudIntroEndTimer = null;
4530
4808
  this.hudLandingMenu = null;
4531
4809
  this.pillOutcome = null;
4532
4810
  this.viewedNewsSignalIds = /* @__PURE__ */ new Set();
@@ -4611,6 +4889,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
4611
4889
  this.openInspector("floating_button");
4612
4890
  };
4613
4891
  this.handleLauncherHudEnter = () => {
4892
+ this.cancelLauncherHudIntro();
4614
4893
  this.openLauncherHud();
4615
4894
  };
4616
4895
  this.handleLauncherHudLeave = () => {
@@ -4621,6 +4900,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
4621
4900
  }, 160);
4622
4901
  };
4623
4902
  this.handleLauncherHudFocusIn = () => {
4903
+ this.cancelLauncherHudIntro();
4624
4904
  this.openLauncherHud();
4625
4905
  };
4626
4906
  this.handleLauncherHudFocusOut = (event) => {
@@ -5026,19 +5306,6 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5026
5306
  this.handlePlaygroundStop = () => {
5027
5307
  this.playgroundAgent?.abortRun();
5028
5308
  };
5029
- this.handleSnippetImportChange = async (event) => {
5030
- const input = event.target;
5031
- const file = input.files?.[0];
5032
- input.value = "";
5033
- if (!file) return;
5034
- try {
5035
- this.eventSnippets = require_event_snippets.importEventSnippets(await file.text());
5036
- this.snippetError = null;
5037
- } catch (error) {
5038
- this.snippetError = error instanceof Error ? error.message : "Import failed.";
5039
- }
5040
- this.requestUpdate();
5041
- };
5042
5309
  this.handleInspectorMetadataActionClick = (action, placement) => {
5043
5310
  if (!this.isOpen || this.runtimeStatus !== _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connected || this.core?.telemetryDisabled) return;
5044
5311
  if (action.kind === "enable_intelligence") {
@@ -5066,26 +5333,6 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5066
5333
  if (this.core?.telemetryDisabled) return;
5067
5334
  require_telemetry.trackThreadsTalkToEngineerClicked(this.getThreadsCtaTelemetryProps("talk_to_engineer", "threads_locked"));
5068
5335
  };
5069
- this.handleSnippetListDividerPointerDown = (event) => {
5070
- this.snippetDividerResizing = true;
5071
- this.snippetDividerPointerId = event.pointerId;
5072
- this.snippetDividerStartX = event.clientX;
5073
- this.snippetDividerStartWidth = this.snippetListWidth;
5074
- event.currentTarget.setPointerCapture(event.pointerId);
5075
- event.preventDefault();
5076
- };
5077
- this.handleSnippetListDividerPointerMove = (event) => {
5078
- if (!this.snippetDividerResizing || this.snippetDividerPointerId !== event.pointerId) return;
5079
- const delta = event.clientX - this.snippetDividerStartX;
5080
- this.snippetListWidth = Math.max(160, Math.min(360, this.snippetDividerStartWidth + delta));
5081
- this.requestUpdate();
5082
- };
5083
- this.handleSnippetListDividerPointerUp = (event) => {
5084
- if (this.snippetDividerPointerId !== event.pointerId) return;
5085
- const target = event.currentTarget;
5086
- if (target.hasPointerCapture(this.snippetDividerPointerId)) target.releasePointerCapture(this.snippetDividerPointerId);
5087
- this.snippetDividerResizing = false;
5088
- };
5089
5336
  this.handleThreadDividerPointerDown = (event) => {
5090
5337
  this.threadDividerResizing = true;
5091
5338
  this.threadDividerPointerId = event.pointerId;
@@ -5200,15 +5447,21 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5200
5447
  this.requestUpdate();
5201
5448
  };
5202
5449
  this.handleIconRailContextPointerEnter = (event) => {
5203
- if (event.pointerType === "touch" || this.contextMenuOpen) return;
5450
+ if (event.pointerType === "touch") return;
5451
+ this.clearIconRailContextCloseTimer();
5452
+ if (this.contextMenuOpen) return;
5204
5453
  this.layoutMenuOpen = false;
5205
5454
  this.contextMenuOpen = true;
5206
5455
  this.requestUpdate();
5207
5456
  };
5208
5457
  this.handleIconRailContextPointerLeave = () => {
5209
5458
  if (!this.contextMenuOpen) return;
5210
- this.contextMenuOpen = false;
5211
- this.requestUpdate();
5459
+ this.clearIconRailContextCloseTimer();
5460
+ this.iconRailContextCloseTimer = setTimeout(() => {
5461
+ this.iconRailContextCloseTimer = null;
5462
+ this.contextMenuOpen = false;
5463
+ this.requestUpdate();
5464
+ }, 180);
5212
5465
  };
5213
5466
  this.handleIconRailContextPointerDown = (event) => {
5214
5467
  if (event.pointerType === "touch") {
@@ -5219,6 +5472,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5219
5472
  event.stopPropagation();
5220
5473
  };
5221
5474
  this.handleIconRailContextFocusIn = () => {
5475
+ this.clearIconRailContextCloseTimer();
5222
5476
  if (this.contextMenuOpen) return;
5223
5477
  this.layoutMenuOpen = false;
5224
5478
  this.contextMenuOpen = true;
@@ -5342,11 +5596,6 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5342
5596
  label: "AG-UI Events",
5343
5597
  icon: "Zap"
5344
5598
  },
5345
- {
5346
- key: "event-snippets",
5347
- label: "Event Snippets",
5348
- icon: "Code"
5349
- },
5350
5599
  {
5351
5600
  key: "agents",
5352
5601
  label: "Agent",
@@ -6194,7 +6443,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6194
6443
  const messages = this.normalizeAgentMessages(agent.messages);
6195
6444
  if (messages) this.agentMessages.set(agent.agentId, messages);
6196
6445
  else this.agentMessages.delete(agent.agentId);
6197
- const runThreadId = agent.threadId;
6446
+ const runThreadId = this.readAgentThreadId(agent);
6198
6447
  if (runThreadId) this.liveMessageVersion.set(runThreadId, (this.liveMessageVersion.get(runThreadId) ?? 0) + 1);
6199
6448
  this.requestUpdate();
6200
6449
  } catch (error) {
@@ -6277,19 +6526,6 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6277
6526
  this.persistState();
6278
6527
  this.requestUpdate();
6279
6528
  }
6280
- focusEventSnippets(options) {
6281
- this.pendingPersistedMenu = null;
6282
- this.selectedMenu = "event-snippets";
6283
- this.settingsOpen = false;
6284
- this.lastSelectedMenuByGroup.inspect = "event-snippets";
6285
- this.contextMenuOpen = false;
6286
- this.layoutMenuOpen = false;
6287
- this.reloadEventSnippets();
6288
- if (options.snippetId) this.selectEventSnippet(options.snippetId);
6289
- if (options.agentId && this.contextOptions.some((option) => option.key === options.agentId)) this.selectedContext = options.agentId;
6290
- this.persistState();
6291
- this.requestUpdate();
6292
- }
6293
6529
  filterEvents(events) {
6294
6530
  const query = this.eventFilterText.trim().toLowerCase();
6295
6531
  return events.filter((event) => {
@@ -6311,6 +6547,20 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6311
6547
  getLatestMessagesForAgent(agentId) {
6312
6548
  return this.agentMessages.get(agentId) ?? null;
6313
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
+ }
6314
6564
  getAgentStatus(agentId) {
6315
6565
  const events = this.agentEvents.get(agentId) ?? [];
6316
6566
  if (events.length === 0) return "idle";
@@ -6357,11 +6607,9 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6357
6607
  ${isFailedCall && toolError?.message ? lit.html`<p class="mt-2 break-words leading-relaxed text-gray-800">
6358
6608
  ${toolError.message}
6359
6609
  </p>` : lit.nothing}
6360
- ${argsString ? lit.html`<pre
6361
- class="mt-2 overflow-auto rounded bg-white p-2 text-[11px] leading-relaxed text-gray-800"
6362
- >
6363
- ${argsString}</pre
6364
- >` : lit.nothing}
6610
+ ${argsString ? lit.html`<div class="mt-2">
6611
+ ${renderHighlightedJsonBlock(coerceJsonValue(call.function?.arguments))}
6612
+ </div>` : lit.nothing}
6365
6613
  </div>
6366
6614
  `;
6367
6615
  })}
@@ -6413,15 +6661,14 @@ ${argsString}</pre
6413
6661
  return String(state);
6414
6662
  }
6415
6663
  getEventBadgeClasses(type) {
6416
- const base = "font-mono text-[10px] font-medium inline-flex items-center rounded-sm px-1.5 py-0.5 border";
6417
- if (type === "RUN_ERROR") return `${base} bg-rose-50 text-rose-700 border-rose-200`;
6418
- if (type.startsWith("RUN_")) return `${base} bg-blue-50 text-blue-700 border-blue-200`;
6419
- if (type.startsWith("TEXT_MESSAGE")) return `${base} bg-emerald-50 text-emerald-700 border-emerald-200`;
6420
- if (type.startsWith("TOOL_CALL")) return `${base} bg-amber-50 text-amber-700 border-amber-200`;
6421
- if (type.startsWith("REASONING")) return `${base} bg-fuchsia-50 text-fuchsia-700 border-fuchsia-200`;
6422
- if (type.startsWith("STATE")) return `${base} bg-violet-50 text-violet-700 border-violet-200`;
6423
- if (type.startsWith("MESSAGES")) return `${base} bg-sky-50 text-sky-700 border-sky-200`;
6424
- 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`;
6425
6672
  }
6426
6673
  stringifyPayload(payload, pretty) {
6427
6674
  try {
@@ -6468,6 +6715,13 @@ ${argsString}</pre
6468
6715
  static {
6469
6716
  this.styles = [(0, lit.unsafeCSS)(require_generated.default), lit.css`
6470
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;
6471
6725
  position: fixed;
6472
6726
  top: 0;
6473
6727
  left: 0;
@@ -6477,6 +6731,191 @@ ${argsString}</pre
6477
6731
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
6478
6732
  }
6479
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
+
6480
6919
  .rounded-sm {
6481
6920
  border-radius: 3px;
6482
6921
  }
@@ -6512,8 +6951,8 @@ ${argsString}</pre
6512
6951
  the two cannot drift apart. A dark grey rather than near-black: the
6513
6952
  launcher sits on a customer's page, and 1,5,7 against white is a
6514
6953
  harder edge than this surface needs. */
6515
- --cpk-launcher-face: rgba(28, 31, 36, 0.95);
6516
- --cpk-launcher-face-solid: rgb(28, 31, 36);
6954
+ --cpk-launcher-face: rgba(24, 28, 31, 0.95);
6955
+ --cpk-launcher-face-solid: rgb(24, 28, 31);
6517
6956
  --cpk-launcher-edge: rgba(190, 194, 255, 0.25);
6518
6957
  /* The launcher's own size, exposed so the signal dot can be placed
6519
6958
  against the OUTER rim with a length rather than a percentage.
@@ -6536,6 +6975,10 @@ ${argsString}</pre
6536
6975
  box-sizing: border-box;
6537
6976
  transition:
6538
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,
6539
6982
  opacity 160ms ease;
6540
6983
  }
6541
6984
 
@@ -6563,6 +7006,7 @@ ${argsString}</pre
6563
7006
  touch-action: none;
6564
7007
  user-select: none;
6565
7008
  z-index: 60;
7009
+ background: transparent;
6566
7010
  }
6567
7011
 
6568
7012
  .edge-resize-handle {
@@ -6697,18 +7141,77 @@ ${argsString}</pre
6697
7141
  flex-shrink: 0;
6698
7142
  transition:
6699
7143
  background-color 0.15s,
6700
- border-color 0.15s;
7144
+ border-color 0.15s,
7145
+ color 0.15s;
6701
7146
  }
6702
7147
  .cpk-copy-btn:hover {
6703
7148
  background-color: #f0f0f4;
6704
7149
  border-color: #afafb7;
6705
7150
  }
6706
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
+
6707
7207
  .cpk-section-header {
6708
7208
  background: #e8edf5;
6709
7209
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
6710
7210
  padding: 10px 16px;
6711
7211
  }
7212
+ .inspector-window[data-color-scheme="dark"] .cpk-section-header {
7213
+ border-bottom-color: #3a3d49;
7214
+ }
6712
7215
  .cpk-section-header h4 {
6713
7216
  font-size: 11px;
6714
7217
  font-weight: 600;
@@ -6933,13 +7436,29 @@ ${argsString}</pre
6933
7436
  .console-button {
6934
7437
  background-color: var(--cpk-launcher-face) !important;
6935
7438
  border-color: var(--cpk-launcher-edge) !important;
7439
+ /* One hairline, not two. The border above is it; a second ring used to
7440
+ sit 1px outside as a box-shadow and hardcoded the lilac instead of
7441
+ reading the --cpk-launcher-edge token, so it could not follow it.
7442
+ What replaces it is a one-pixel light edge along the top, which is
7443
+ what keeps the face from reading flat without drawing a frame.
7444
+
7445
+ The border is not decoration: the face is #181C1F, which against a
7446
+ dark host page (GitHub dark 1.10:1, Tailwind slate-900 1.04:1) is
7447
+ indistinguishable from the page. It is the only thing that gives the
7448
+ launcher an outline there, so it stays. */
6936
7449
  box-shadow:
6937
- 0 0 0 1px rgba(190, 194, 255, 0.15),
7450
+ inset 0 1px 0 rgba(255, 255, 255, 0.07),
6938
7451
  0 4px 14px rgba(1, 5, 7, 0.28) !important;
7452
+ /* Promotes the launcher to its own compositing layer, which the
7453
+ backdrop-filter this replaces used to do as a side effect. Without
7454
+ a layer the hover scale re-rasterises the mark every frame and it
7455
+ visibly jitters; with one, the compositor scales it as a texture. */
7456
+ will-change: transform;
6939
7457
  }
6940
7458
  .console-button:hover {
6941
7459
  background-color: var(--cpk-launcher-face-solid) !important;
6942
7460
  border-color: rgba(190, 194, 255, 0.45) !important;
7461
+ transform: scale(1.05);
6943
7462
  }
6944
7463
  .console-button:focus-visible {
6945
7464
  outline-color: #bec2ff !important;
@@ -7061,8 +7580,23 @@ ${argsString}</pre
7061
7580
  width: 19%;
7062
7581
  height: 19%;
7063
7582
  border-radius: 50%;
7064
- background: var(--cpk-launcher-signal);
7065
- box-shadow: 0 0 0 1.5px var(--cpk-launcher-face);
7583
+ /* Lit from the upper left and shaded at the lower right, so the dot
7584
+ reads as a lens rather than a flat disc. Both stops are derived from
7585
+ the signal colour, so a new tone needs no new values. */
7586
+ background: radial-gradient(
7587
+ circle at 32% 28%,
7588
+ color-mix(in srgb, var(--cpk-launcher-signal), white 40%) 0%,
7589
+ var(--cpk-launcher-signal) 60%,
7590
+ color-mix(in srgb, var(--cpk-launcher-signal), black 20%) 100%
7591
+ );
7592
+ /* Replaces an opaque 1.5px collar in the launcher's own face. That
7593
+ collar was 21% of the dot's footprint, and because the dot's centre
7594
+ sits *on* the rim, its outer half painted a hard dark crescent onto
7595
+ the host page rather than onto the launcher. A hairline plus a soft
7596
+ drop does the same separating job without the hard edge. */
7597
+ box-shadow:
7598
+ 0 0 0 0.5px rgba(1, 5, 7, 0.4),
7599
+ 0 1px 2.5px rgba(1, 5, 7, 0.5);
7066
7600
  }
7067
7601
 
7068
7602
  /* ── Launcher pill: the launcher opens sideways and says what ─── */
@@ -7273,6 +7807,12 @@ ${argsString}</pre
7273
7807
  .cpk-launcher-signal-wash {
7274
7808
  animation: none !important;
7275
7809
  }
7810
+ .console-button {
7811
+ transition: opacity 160ms ease;
7812
+ }
7813
+ .console-button:hover {
7814
+ transform: none;
7815
+ }
7276
7816
  }
7277
7817
 
7278
7818
  /* ── Launcher HUD: hover menu, quieter than the error island ── */
@@ -7284,6 +7824,9 @@ ${argsString}</pre
7284
7824
  }
7285
7825
 
7286
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);
7287
7830
  position: absolute;
7288
7831
  top: 0;
7289
7832
  z-index: 4;
@@ -7317,38 +7860,47 @@ ${argsString}</pre
7317
7860
  }
7318
7861
 
7319
7862
  .cpk-launcher-hud__card {
7320
- --hud-fill: rgb(28 31 36 / 0.88);
7321
- --hud-line: rgb(190 194 255 / 0.5);
7322
7863
  position: relative;
7323
7864
  width: 228px;
7324
7865
  padding: 4px;
7325
7866
  border: 1px dotted var(--hud-line);
7326
- border-radius: 10px;
7867
+ border-radius: var(--cpk-inspector-shell-radius);
7327
7868
  background: var(--hud-fill);
7328
7869
  color: #fff;
7329
- backdrop-filter: blur(12px) saturate(1.2);
7870
+ backdrop-filter: var(--hud-blur);
7871
+ -webkit-backdrop-filter: var(--hud-blur);
7330
7872
  box-shadow: 0 8px 20px rgb(1 5 7 / 0.18);
7331
7873
  }
7332
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
+
7333
7884
  .cpk-launcher-hud__arrow {
7334
7885
  position: absolute;
7335
7886
  top: calc(var(--cpk-launcher-size) / 2);
7887
+ z-index: 1;
7336
7888
  width: 10px;
7337
7889
  height: 10px;
7338
- 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%);
7339
7895
  transform: translateY(-50%) rotate(45deg);
7340
7896
  }
7341
7897
 
7342
7898
  .cpk-launcher-hud[data-cpk-hud-side="left"] .cpk-launcher-hud__arrow {
7343
- right: -5px;
7344
- border-top: 1px solid var(--hud-line);
7345
- border-right: 1px solid var(--hud-line);
7899
+ right: 9px;
7346
7900
  }
7347
7901
 
7348
7902
  .cpk-launcher-hud[data-cpk-hud-side="right"] .cpk-launcher-hud__arrow {
7349
- left: -5px;
7350
- border-bottom: 1px solid var(--hud-line);
7351
- border-left: 1px solid var(--hud-line);
7903
+ left: 9px;
7352
7904
  }
7353
7905
 
7354
7906
  .cpk-launcher-hud__list {
@@ -7382,6 +7934,12 @@ ${argsString}</pre
7382
7934
  background: rgb(255 255 255 / 0.06);
7383
7935
  }
7384
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
+
7385
7943
  .cpk-launcher-hud__action {
7386
7944
  display: flex;
7387
7945
  gap: 8px;
@@ -7399,6 +7957,10 @@ ${argsString}</pre
7399
7957
  cursor: pointer;
7400
7958
  }
7401
7959
 
7960
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__action {
7961
+ color: #010507;
7962
+ }
7963
+
7402
7964
  /* Stretch the row action over the whole tab, including the detail
7403
7965
  copy. The help mark sits above this layer. */
7404
7966
  .cpk-launcher-hud__action::after {
@@ -7442,6 +8004,10 @@ ${argsString}</pre
7442
8004
  line-height: 1;
7443
8005
  }
7444
8006
 
8007
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__help {
8008
+ color: #68686e;
8009
+ }
8010
+
7445
8011
  .cpk-launcher-hud__help:focus-visible,
7446
8012
  .cpk-launcher-hud__action:focus-visible {
7447
8013
  outline: 2px solid #bec2ff;
@@ -7468,19 +8034,120 @@ ${argsString}</pre
7468
8034
  padding-bottom 200ms cubic-bezier(0.16, 1, 0.3, 1);
7469
8035
  }
7470
8036
 
7471
- .cpk-launcher-hud__row:hover .cpk-launcher-hud__detail,
7472
- .cpk-launcher-hud__row:focus-within .cpk-launcher-hud__detail,
7473
- .cpk-launcher-hud__row[data-cpk-hud-help="open"] .cpk-launcher-hud__detail {
7474
- max-height: 72px;
7475
- padding: 0 8px 7px;
7476
- opacity: 1;
7477
- transform: none;
8037
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__detail {
8038
+ color: #68686e;
8039
+ }
8040
+
8041
+ .cpk-launcher-hud__row:hover .cpk-launcher-hud__detail,
8042
+ .cpk-launcher-hud__row:focus-within .cpk-launcher-hud__detail,
8043
+ .cpk-launcher-hud__row[data-cpk-hud-help="open"] .cpk-launcher-hud__detail {
8044
+ max-height: 72px;
8045
+ padding: 0 8px 7px;
8046
+ opacity: 1;
8047
+ transform: none;
8048
+ }
8049
+
8050
+ @media (prefers-reduced-motion: reduce) {
8051
+ .cpk-launcher-hud,
8052
+ .cpk-launcher-hud__detail {
8053
+ transition: none;
8054
+ }
8055
+ }
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);
7478
8140
  }
7479
8141
 
7480
8142
  @media (prefers-reduced-motion: reduce) {
7481
- .cpk-launcher-hud,
7482
- .cpk-launcher-hud__detail {
7483
- transition: none;
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;
7484
8151
  }
7485
8152
  }
7486
8153
 
@@ -7510,7 +8177,7 @@ ${argsString}</pre
7510
8177
  /* ── Inspector window ────────────────────────────────────────── */
7511
8178
  .inspector-window {
7512
8179
  border: 1px solid #d8d8e8 !important;
7513
- border-radius: 5px !important;
8180
+ border-radius: var(--cpk-inspector-shell-radius) !important;
7514
8181
  box-shadow: none !important;
7515
8182
  }
7516
8183
 
@@ -7626,10 +8293,69 @@ ${argsString}</pre
7626
8293
  .inspector-sidebar[data-icon-rail="true"] .inspector-nav-control,
7627
8294
  .inspector-sidebar[data-icon-rail="true"] .inspector-sidebar-control,
7628
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;
7629
8327
  justify-content: center !important;
7630
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;
7631
8343
  gap: 0 !important;
7632
- 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;
7633
8359
  }
7634
8360
  .inspector-sidebar[data-icon-rail="true"] .inspector-nav-label,
7635
8361
  .inspector-sidebar[data-icon-rail="true"] .inspector-sidebar-label {
@@ -7859,6 +8585,7 @@ ${argsString}</pre
7859
8585
  clearTimeout(this.transitionTimeoutId);
7860
8586
  this.transitionTimeoutId = null;
7861
8587
  }
8588
+ this.clearIconRailContextCloseTimer();
7862
8589
  this.unsubscribeFromInspectorThreadBridge();
7863
8590
  this.threadsSetupPromptCopyGeneration += 1;
7864
8591
  if (this.threadsSetupPromptCopyResetTimeoutId !== null) {
@@ -7868,6 +8595,7 @@ ${argsString}</pre
7868
8595
  this.threadsSetupPromptCopyState = "idle";
7869
8596
  this.stopSignalPulse();
7870
8597
  this.cancelGestureTail();
8598
+ this.cancelLauncherHudIntro();
7871
8599
  this.cancelThreadRefreshDebounce();
7872
8600
  this.clearInspectorUsageRefresh();
7873
8601
  this.cleanupThreadsExampleOverviewVideo();
@@ -7904,6 +8632,7 @@ ${argsString}</pre
7904
8632
  else this.centerContext("window");
7905
8633
  this.ensureAnnouncementLoading();
7906
8634
  this.updateHostTransform(this.isOpen ? "window" : "button");
8635
+ this.scheduleLauncherHudIntro();
7907
8636
  }
7908
8637
  render() {
7909
8638
  return this.isOpen ? lit.html`
@@ -7963,18 +8692,9 @@ ${argsString}</pre
7963
8692
  "justify-center",
7964
8693
  "rounded-full",
7965
8694
  "border",
7966
- "border-white/20",
7967
- "bg-slate-950/95",
7968
8695
  "text-xs",
7969
8696
  "font-medium",
7970
8697
  "text-white",
7971
- "ring-1",
7972
- "ring-white/10",
7973
- "backdrop-blur-md",
7974
- "transition",
7975
- "hover:border-white/30",
7976
- "hover:bg-slate-900/95",
7977
- "hover:scale-105",
7978
8698
  "focus-visible:outline",
7979
8699
  "focus-visible:outline-2",
7980
8700
  "focus-visible:outline-offset-2",
@@ -8094,6 +8814,41 @@ ${argsString}</pre
8094
8814
  isLauncherHudBlocked() {
8095
8815
  return this.gestureSignal !== null;
8096
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
+ }
8097
8852
  resolveLauncherHudSide() {
8098
8853
  if (typeof window === "undefined") {
8099
8854
  this.launcherHudSide = "left";
@@ -8122,6 +8877,7 @@ ${argsString}</pre
8122
8877
  this.requestUpdate();
8123
8878
  }
8124
8879
  closeLauncherHud() {
8880
+ this.cancelLauncherHudIntro();
8125
8881
  if (this.launcherHudCloseTimer !== null) {
8126
8882
  clearTimeout(this.launcherHudCloseTimer);
8127
8883
  this.launcherHudCloseTimer = null;
@@ -8159,6 +8915,10 @@ ${argsString}</pre
8159
8915
  class="cpk-launcher-hud__row"
8160
8916
  data-cpk-hud-row=${args.id}
8161
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
+ })}
8162
8922
  @click=${(event) => this.handleHudRowClick(event, args.id)}
8163
8923
  >
8164
8924
  <button
@@ -8188,23 +8948,31 @@ ${argsString}</pre
8188
8948
  }
8189
8949
  renderLauncherHud() {
8190
8950
  if (!this.launcherHudOpen) return lit.nothing;
8191
- const threadsOn = this.areThreadEndpointsAvailable();
8192
- const intelligenceOn = Boolean(this._core?.intelligence);
8193
- 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";
8194
8955
  return lit.html`
8195
8956
  <div
8196
8957
  class="cpk-launcher-hud"
8197
8958
  id="cpk-launcher-hud"
8198
8959
  data-cpk-launcher-hud
8199
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
+ })}
8200
8967
  >
8968
+ <span class="cpk-launcher-hud__arrow" aria-hidden="true"></span>
8201
8969
  <div class="cpk-launcher-hud__card">
8202
- <span class="cpk-launcher-hud__arrow" aria-hidden="true"></span>
8203
8970
  <ul class="cpk-launcher-hud__list" role="list">
8204
8971
  ${this.renderHudRow({
8205
8972
  id: "inspector",
8206
8973
  label: HUD_OPEN_INSPECTOR_LABEL,
8207
- detail: HUD_OPEN_INSPECTOR_DETAIL
8974
+ detail: HUD_OPEN_INSPECTOR_DETAIL,
8975
+ introIndex: 0
8208
8976
  })}
8209
8977
  </ul>
8210
8978
  <ul class="cpk-launcher-hud__list" role="list">
@@ -8212,19 +8980,22 @@ ${argsString}</pre
8212
8980
  id: "threads",
8213
8981
  label: threadsOn ? HUD_THREADS_ON_LABEL : HUD_THREADS_OFF_LABEL,
8214
8982
  detail: threadsOn ? HUD_THREADS_ON_DETAIL : HUD_THREADS_OFF_DETAIL,
8215
- connected: threadsOn
8983
+ connected: threadsOn,
8984
+ introIndex: 1
8216
8985
  })}
8217
8986
  ${this.renderHudRow({
8218
8987
  id: "intelligence",
8219
8988
  label: intelligenceOn ? HUD_INTELLIGENCE_ON_LABEL : HUD_INTELLIGENCE_OFF_LABEL,
8220
8989
  detail: intelligenceOn ? HUD_INTELLIGENCE_ON_DETAIL : HUD_INTELLIGENCE_OFF_DETAIL,
8221
- connected: intelligenceOn
8990
+ connected: intelligenceOn,
8991
+ introIndex: 2
8222
8992
  })}
8223
8993
  ${this.renderHudRow({
8224
8994
  id: "learning",
8225
8995
  label: learningOn ? HUD_LEARNING_ON_LABEL : HUD_LEARNING_OFF_LABEL,
8226
8996
  detail: learningOn ? HUD_LEARNING_ON_DETAIL : HUD_LEARNING_OFF_DETAIL,
8227
- connected: learningOn
8997
+ connected: learningOn,
8998
+ introIndex: 3
8228
8999
  })}
8229
9000
  </ul>
8230
9001
  </div>
@@ -8327,34 +9098,34 @@ ${argsString}</pre
8327
9098
  })}
8328
9099
  </nav>
8329
9100
  ${automaticallyCollapsed ? lit.nothing : lit.html`
8330
- <button
8331
- type="button"
8332
- class="inspector-sidebar-toggle"
8333
- data-inspector-sidebar-toggle
8334
- aria-label=${iconRail ? "Expand sidebar" : "Collapse sidebar"}
8335
- aria-expanded=${iconRail ? "false" : "true"}
8336
- data-inspector-tooltip=${iconRail ? "Expand sidebar" : lit.nothing}
8337
- title=${iconRail ? lit.nothing : "Collapse sidebar"}
8338
- style=${INTERACTIVE_FOCUS_BASE_STYLE}
8339
- @pointerenter=${iconRail ? this.handleSidebarRailTooltipShow : lit.nothing}
8340
- @pointerleave=${iconRail ? this.handleSidebarRailTooltipHide : lit.nothing}
8341
- @focus=${iconRail ? this.handleSidebarRailTooltipShow : lit.nothing}
8342
- @blur=${iconRail ? this.handleSidebarRailTooltipHide : lit.nothing}
8343
- @click=${this.handleSidebarToggle}
8344
- >
8345
- <span class="inspector-nav-icon" aria-hidden="true">
8346
- ${this.renderIcon(iconRail ? "ChevronRight" : "ChevronLeft")}
8347
- </span>
8348
- <span class="inspector-nav-label"
8349
- >${iconRail ? "Expand" : "Collapse"}</span
8350
- >
8351
- </button>
8352
- `}
8353
- ${iconRail ? lit.nothing : lit.html`
8354
9101
  <div class="inspector-sidebar-footer">
8355
- <div class="inspector-sidebar-status-list">
8356
- ${this.renderSidebarIntelligenceStatus(homeModel)}
8357
- </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>
8358
9129
  </div>
8359
9130
  `}
8360
9131
  </aside>
@@ -9117,16 +9888,6 @@ ${argsString}</pre
9117
9888
  @pointerup=${this.handleResizePointerUp}
9118
9889
  @pointercancel=${this.handleResizePointerCancel}
9119
9890
  ></div>
9120
- <div
9121
- 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"
9122
- data-resize-edge="sw"
9123
- role="presentation"
9124
- aria-hidden="true"
9125
- @pointerdown=${this.handleResizePointerDown}
9126
- @pointermove=${this.handleResizePointerMove}
9127
- @pointerup=${this.handleResizePointerUp}
9128
- @pointercancel=${this.handleResizePointerCancel}
9129
- ></div>
9130
9891
  `}
9131
9892
  <div
9132
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"
@@ -9534,8 +10295,7 @@ ${argsString}</pre
9534
10295
  this.draggedDuringInteraction = false;
9535
10296
  }
9536
10297
  openInspector(source, options = {}) {
9537
- if (options.snippetId || options.menu === "event-snippets") this.focusEventSnippets(options);
9538
- else if (options.threadId) this.focusThread(options);
10298
+ if (options.threadId) this.focusThread(options);
9539
10299
  if (this.isPoppedOut) return;
9540
10300
  if (this.isOpen) return;
9541
10301
  const hadUnseenAnnouncement = this.newsSignalArmed;
@@ -9719,11 +10479,8 @@ ${argsString}</pre
9719
10479
  return this.sanitizeForLogging(payload);
9720
10480
  }
9721
10481
  normalizeMessageContent(content) {
9722
- if (typeof content === "string") return content;
9723
- if (content && typeof content === "object" && "text" in content) {
9724
- const maybeText = content.text;
9725
- if (typeof maybeText === "string") return maybeText;
9726
- }
10482
+ const extracted = textFromUnknownContent(content);
10483
+ if (extracted) return extracted;
9727
10484
  if (content === null || content === void 0) return "";
9728
10485
  if (typeof content === "object") try {
9729
10486
  return JSON.stringify(this.sanitizeForLogging(content));
@@ -9943,7 +10700,7 @@ ${argsString}</pre
9943
10700
  const sendDisabled = !agentId || this.playgroundIsLoadingThread || !this.playgroundIsRunning && !this.playgroundInput.trim();
9944
10701
  return lit.html`
9945
10702
  <form
9946
- 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"}
9947
10704
  @submit=${this.handlePlaygroundSubmit}
9948
10705
  >
9949
10706
  ${this.playgroundError ? lit.html`<div
@@ -9972,10 +10729,10 @@ ${argsString}</pre
9972
10729
  ` : lit.nothing}
9973
10730
  </div>` : lit.nothing}
9974
10731
  <div
9975
- 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]"
9976
10733
  >
9977
10734
  <textarea
9978
- 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"
9979
10736
  rows="1"
9980
10737
  placeholder=${placeholder}
9981
10738
  aria-label="Playground message"
@@ -9986,7 +10743,7 @@ ${argsString}</pre
9986
10743
  ></textarea>
9987
10744
  <button
9988
10745
  type=${this.playgroundIsRunning ? "button" : "submit"}
9989
- 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"}`}
9990
10747
  aria-label=${this.playgroundIsRunning ? "Stop agent" : "Send playground message"}
9991
10748
  ?disabled=${sendDisabled}
9992
10749
  @click=${this.playgroundIsRunning ? this.handlePlaygroundStop : lit.nothing}
@@ -10000,549 +10757,6 @@ ${argsString}</pre
10000
10757
  AI can make mistakes. Please verify important information.
10001
10758
  </p>
10002
10759
  </form>
10003
- `;
10004
- }
10005
- reloadEventSnippets() {
10006
- this.eventSnippets = require_event_snippets.loadEventSnippets();
10007
- }
10008
- renderSnippetImportControl() {
10009
- return lit.html`
10010
- <label
10011
- class="inline-flex shrink-0 cursor-pointer items-center rounded-md border border-gray-300 bg-white px-3 py-1.5 text-[11px] text-gray-700"
10012
- data-testid="cpk-snippet-import"
10013
- >
10014
- Import
10015
- <input
10016
- type="file"
10017
- accept="application/json"
10018
- class="hidden"
10019
- @change=${this.handleSnippetImportChange}
10020
- />
10021
- </label>
10022
- `;
10023
- }
10024
- selectEventSnippet(id) {
10025
- const snippet = this.eventSnippets.find((item) => item.id === id);
10026
- this.selectedSnippetId = id;
10027
- if (!snippet) {
10028
- this.requestUpdate();
10029
- return;
10030
- }
10031
- const editor = require_event_snippets.editorStateFromSnippet(snippet);
10032
- this.snippetRecipe = editor.recipe;
10033
- this.snippetName = editor.name;
10034
- this.snippetJson = editor.json;
10035
- this.snippetToolName = editor.draft.toolName;
10036
- this.snippetToolArgs = editor.draft.toolArgs;
10037
- this.snippetReasoningText = editor.draft.reasoningText;
10038
- this.snippetTextContent = editor.draft.textContent;
10039
- this.snippetActivityType = editor.draft.activityType;
10040
- this.snippetActivityContent = editor.draft.activityContent;
10041
- this.snippetError = null;
10042
- this.requestUpdate();
10043
- }
10044
- compileSnippetDraft() {
10045
- switch (this.snippetRecipe) {
10046
- case "tool-call": return require_event_snippets.compileToolCallRecipe({
10047
- toolName: this.snippetToolName,
10048
- argsJson: this.snippetToolArgs,
10049
- threadId: this.getSnippetThreadId(),
10050
- runId: this.getSnippetRunId()
10051
- });
10052
- case "reasoning": return require_event_snippets.compileReasoningRecipe({
10053
- text: this.snippetReasoningText,
10054
- threadId: this.getSnippetThreadId(),
10055
- runId: this.getSnippetRunId()
10056
- });
10057
- case "text": return require_event_snippets.compileTextRecipe({
10058
- text: this.snippetTextContent,
10059
- threadId: this.getSnippetThreadId(),
10060
- runId: this.getSnippetRunId()
10061
- });
10062
- case "activity": return require_event_snippets.compileActivityRecipe({
10063
- activityType: this.snippetActivityType,
10064
- contentJson: this.snippetActivityContent,
10065
- threadId: this.getSnippetThreadId(),
10066
- runId: this.getSnippetRunId()
10067
- });
10068
- case "raw": return require_event_snippets.parseSnippetEvents(this.snippetJson);
10069
- }
10070
- }
10071
- getSnippetThreadId() {
10072
- return this.selectedThreadId ?? "inspector-snippet";
10073
- }
10074
- getSnippetRunId() {
10075
- return `inspector-snippet-${Date.now()}`;
10076
- }
10077
- getSnippetTargetAgent() {
10078
- const core = this._core;
10079
- if (!core) return null;
10080
- const selected = this.selectedContext !== "all-agents" ? this.selectedContext : null;
10081
- if (selected) return core.getAgent(selected) ?? null;
10082
- const first = this.contextOptions.find((option) => option.key !== "all-agents");
10083
- return first ? core.getAgent(first.key) ?? null : null;
10084
- }
10085
- applyRecipeToEditor() {
10086
- try {
10087
- const events = this.compileSnippetDraft();
10088
- this.snippetJson = JSON.stringify(events, null, 2);
10089
- this.snippetError = null;
10090
- } catch (error) {
10091
- this.snippetError = error instanceof Error ? error.message : "Could not compile recipe.";
10092
- }
10093
- this.requestUpdate();
10094
- }
10095
- handleSnippetRecipeChange(event) {
10096
- const value = event.target.value;
10097
- if (value === "tool-call" || value === "reasoning" || value === "text" || value === "activity" || value === "raw") {
10098
- this.snippetRecipe = value;
10099
- if (value !== "raw") this.applyRecipeToEditor();
10100
- else this.requestUpdate();
10101
- }
10102
- }
10103
- saveCurrentSnippet(source) {
10104
- try {
10105
- const events = require_event_snippets.parseSnippetEvents(this.snippetJson);
10106
- const now = (/* @__PURE__ */ new Date()).toISOString();
10107
- const snippet = {
10108
- id: this.selectedSnippetId ?? require_event_snippets.createSnippetId(),
10109
- name: this.snippetName.trim() || require_event_snippets.recipeLabel(this.snippetRecipe),
10110
- recipe: this.snippetRecipe,
10111
- events,
10112
- createdAt: this.eventSnippets.find((item) => item.id === this.selectedSnippetId)?.createdAt ?? now,
10113
- updatedAt: now
10114
- };
10115
- this.eventSnippets = require_event_snippets.upsertEventSnippet(snippet);
10116
- this.selectedSnippetId = snippet.id;
10117
- this.snippetBanner = "Snippet saved.";
10118
- this.snippetError = null;
10119
- if (!this.core?.telemetryDisabled) require_telemetry.trackEventSnippetsSaved({
10120
- recipe: this.snippetRecipe,
10121
- source,
10122
- success: true
10123
- });
10124
- } catch (error) {
10125
- this.snippetError = error instanceof Error ? error.message : "Could not save snippet.";
10126
- if (!this.core?.telemetryDisabled) require_telemetry.trackEventSnippetsSaved({
10127
- recipe: this.snippetRecipe,
10128
- source,
10129
- success: false
10130
- });
10131
- }
10132
- this.requestUpdate();
10133
- }
10134
- async runCurrentSnippet() {
10135
- this.snippetError = null;
10136
- this.snippetBanner = null;
10137
- let events;
10138
- try {
10139
- events = require_event_snippets.expandSnippetEventsForRun(require_event_snippets.parseSnippetEvents(this.snippetJson));
10140
- } catch (error) {
10141
- this.snippetError = error instanceof Error ? error.message : "Snippet JSON is invalid.";
10142
- this.requestUpdate();
10143
- return;
10144
- }
10145
- if (require_event_snippets.snippetContainsToolCall(events) && !this.snippetConfirmOpen) {
10146
- this.snippetConfirmOpen = true;
10147
- this.requestUpdate();
10148
- return;
10149
- }
10150
- this.snippetConfirmOpen = false;
10151
- const core = this._core;
10152
- const agent = this.getSnippetTargetAgent();
10153
- if (!core || !agent) {
10154
- this.snippetError = "No agent is available to inject into.";
10155
- this.requestUpdate();
10156
- return;
10157
- }
10158
- if (agent.isRunning) {
10159
- this.snippetError = "The agent is running. Wait for the current run to end.";
10160
- this.requestUpdate();
10161
- return;
10162
- }
10163
- try {
10164
- const result = await (0, _copilotkit_core.ɵinjectInspectorEvents)({
10165
- core,
10166
- agent,
10167
- events
10168
- });
10169
- this.lastInject = {
10170
- snippetId: this.selectedSnippetId ?? "unsaved",
10171
- agentId: agent.agentId ?? "default",
10172
- runId: this.getSnippetRunId(),
10173
- messageIds: result.messageIds
10174
- };
10175
- this.snippetBanner = "Inspector injected these events into the live thread.";
10176
- if (!this.core?.telemetryDisabled) require_telemetry.trackEventSnippetsRun({
10177
- recipe: this.snippetRecipe,
10178
- source: "pane",
10179
- success: true
10180
- });
10181
- } catch (error) {
10182
- this.snippetError = error instanceof Error ? error.message : "Could not run snippet.";
10183
- if (!this.core?.telemetryDisabled) require_telemetry.trackEventSnippetsRun({
10184
- recipe: this.snippetRecipe,
10185
- source: "pane",
10186
- success: false
10187
- });
10188
- }
10189
- this.requestUpdate();
10190
- }
10191
- resetLastSnippetRun() {
10192
- const last = this.lastInject;
10193
- const core = this._core;
10194
- if (!last || !core) return;
10195
- const agent = core.getAgent(last.agentId);
10196
- if (!agent) {
10197
- this.snippetError = "The injected agent is no longer available.";
10198
- this.requestUpdate();
10199
- return;
10200
- }
10201
- (0, _copilotkit_core.ɵresetInspectorInject)({
10202
- agent,
10203
- messageIds: last.messageIds
10204
- });
10205
- this.lastInject = null;
10206
- this.snippetBanner = "Last inject was removed from the thread. App state from a tool handler was not undone.";
10207
- this.requestUpdate();
10208
- }
10209
- renderEventSnippetsView() {
10210
- if (this.eventSnippets.length === 0 && this.selectedSnippetId === null) this.reloadEventSnippets();
10211
- const agent = this.getSnippetTargetAgent();
10212
- const runBlocked = agent?.isRunning === true;
10213
- const canRunJson = require_event_snippets.snippetJsonIsRunnable(this.snippetJson);
10214
- const canRun = canRunJson && !!agent && !runBlocked;
10215
- const canSave = canRunJson;
10216
- const canDelete = this.selectedSnippetId !== null;
10217
- const canExport = this.eventSnippets.length > 0;
10218
- const canReset = this.lastInject !== null;
10219
- const snippetGroups = require_event_snippets.groupEventSnippets(this.eventSnippets);
10220
- const tools = this._core?.tools ?? [];
10221
- return lit.html`
10222
- <div class="flex h-full min-h-0 flex-col bg-white">
10223
- <div
10224
- class="flex items-center justify-between gap-4 border-b border-gray-200 px-4 py-3"
10225
- >
10226
- <div class="min-w-0">
10227
- <h2 class="text-sm font-semibold text-gray-900">Event Snippets</h2>
10228
- <p class="mt-1 text-[11px] text-gray-500">
10229
- Compile AG-UI events, run them on the live agent, and save them
10230
- for later. Tool-call runs use the real frontend-tool handler.
10231
- </p>
10232
- </div>
10233
- ${this.renderSnippetImportControl()}
10234
- </div>
10235
- ${this.snippetBanner ? lit.html`<div
10236
- class="border-b border-emerald-200 bg-emerald-50 px-4 py-2 text-[11px] text-emerald-800"
10237
- role="status"
10238
- >
10239
- ${this.snippetBanner}
10240
- </div>` : lit.nothing}
10241
- ${this.snippetError ? lit.html`<div
10242
- class="border-b border-rose-200 bg-rose-50 px-4 py-2 text-[11px] text-rose-800"
10243
- role="alert"
10244
- >
10245
- ${this.snippetError}
10246
- </div>` : lit.nothing}
10247
- ${this.snippetConfirmOpen ? lit.html`<div
10248
- class="border-b border-amber-200 bg-amber-50 px-4 py-2 text-[11px] text-amber-900"
10249
- role="alertdialog"
10250
- aria-label="Confirm tool-call run"
10251
- >
10252
- <p>
10253
- This snippet contains a tool call. Run will execute the real
10254
- handler on the live thread.
10255
- </p>
10256
- <div class="mt-2 flex gap-2">
10257
- <button
10258
- type="button"
10259
- class="rounded-md bg-gray-900 px-2 py-1 text-[11px] text-white"
10260
- data-testid="cpk-snippet-run-handler"
10261
- @click=${() => {
10262
- this.snippetConfirmOpen = true;
10263
- this.runCurrentSnippet();
10264
- }}
10265
- >
10266
- Run handler
10267
- </button>
10268
- <button
10269
- type="button"
10270
- class="rounded-md border border-gray-300 bg-white px-2 py-1 text-[11px]"
10271
- @click=${() => {
10272
- this.snippetConfirmOpen = false;
10273
- this.requestUpdate();
10274
- }}
10275
- >
10276
- Cancel
10277
- </button>
10278
- </div>
10279
- </div>` : lit.nothing}
10280
- <div class="flex min-h-0 flex-1">
10281
- <div
10282
- class="inspector-snippet-sidebar shrink-0"
10283
- style="width:${this.snippetListWidth}px"
10284
- data-testid="cpk-snippet-list"
10285
- >
10286
- ${snippetGroups.length === 0 ? lit.html`
10287
- <p class="px-2 py-2 text-[11px] text-gray-500">No saved snippets yet.</p>
10288
- ` : lit.html`
10289
- <nav class="inspector-sidebar-nav" aria-label="Saved snippets">
10290
- ${snippetGroups.map((group) => lit.html`
10291
- <div class="inspector-sidebar-section">
10292
- <div
10293
- class="inspector-sidebar-label"
10294
- data-testid="cpk-snippet-category"
10295
- data-recipe=${group.recipe}
10296
- >
10297
- ${group.label}
10298
- </div>
10299
- ${group.snippets.map((snippet) => {
10300
- const isSelected = snippet.id === this.selectedSnippetId;
10301
- return lit.html`
10302
- <button
10303
- type="button"
10304
- class="inspector-nav-control inspector-sidebar-control ${isSelected ? "inspector-nav-control-active" : ""}"
10305
- data-testid="cpk-snippet-item"
10306
- data-recipe=${snippet.recipe}
10307
- aria-current=${isSelected ? "page" : lit.nothing}
10308
- aria-label="${require_event_snippets.recipeLabel(snippet.recipe)}: ${snippet.name}"
10309
- style=${INTERACTIVE_FOCUS_BASE_STYLE}
10310
- @click=${() => this.selectEventSnippet(snippet.id)}
10311
- >
10312
- <span
10313
- class="inspector-nav-icon"
10314
- aria-hidden="true"
10315
- >
10316
- <span
10317
- class="flex h-6 w-6 items-center justify-center rounded-md ${require_event_snippets.recipeIconWrapClass(snippet.recipe)}"
10318
- >
10319
- ${this.renderIcon(require_event_snippets.recipeIconName(snippet.recipe))}
10320
- </span>
10321
- </span>
10322
- <span class="inspector-nav-label"
10323
- >${snippet.name}</span
10324
- >
10325
- </button>
10326
- `;
10327
- })}
10328
- </div>
10329
- `)}
10330
- </nav>
10331
- `}
10332
- </div>
10333
- <div
10334
- class="w-1.5 shrink-0 cursor-col-resize bg-gray-200 hover:bg-gray-400"
10335
- role="separator"
10336
- aria-orientation="vertical"
10337
- aria-label="Resize snippet list"
10338
- title="Drag to resize"
10339
- data-testid="cpk-snippet-list-resize"
10340
- style="touch-action:none"
10341
- @pointerdown=${this.handleSnippetListDividerPointerDown}
10342
- @pointermove=${this.handleSnippetListDividerPointerMove}
10343
- @pointerup=${this.handleSnippetListDividerPointerUp}
10344
- @pointercancel=${this.handleSnippetListDividerPointerUp}
10345
- ></div>
10346
- <div class="flex min-h-0 min-w-0 flex-1 flex-col gap-2 overflow-auto p-4">
10347
- <label class="text-[11px] text-gray-600">
10348
- Name
10349
- <input
10350
- class="mt-1 w-full rounded-md border border-gray-200 px-2 py-1 text-[11px]"
10351
- data-testid="cpk-snippet-name"
10352
- .value=${this.snippetName}
10353
- @input=${(event) => {
10354
- this.snippetName = event.target.value;
10355
- }}
10356
- />
10357
- </label>
10358
- <label class="text-[11px] text-gray-600">
10359
- Recipe
10360
- <select
10361
- class="mt-1 w-full rounded-md border border-gray-200 px-2 py-1 text-[11px]"
10362
- data-testid="cpk-snippet-recipe"
10363
- .value=${this.snippetRecipe}
10364
- @change=${this.handleSnippetRecipeChange}
10365
- >
10366
- ${[
10367
- "tool-call",
10368
- "reasoning",
10369
- "text",
10370
- "activity",
10371
- "raw"
10372
- ].map((recipe) => lit.html`<option
10373
- value=${recipe}
10374
- ?selected=${recipe === this.snippetRecipe}
10375
- >
10376
- ${require_event_snippets.recipeLabel(recipe)}
10377
- </option>`)}
10378
- </select>
10379
- </label>
10380
- ${this.snippetRecipe === "tool-call" ? lit.html`
10381
- <label class="text-[11px] text-gray-600">
10382
- Tool
10383
- <input
10384
- list="cpk-snippet-tools"
10385
- class="mt-1 w-full rounded-md border border-gray-200 px-2 py-1 text-[11px]"
10386
- data-testid="cpk-snippet-tool-name"
10387
- .value=${this.snippetToolName}
10388
- @input=${(event) => {
10389
- this.snippetToolName = event.target.value;
10390
- this.applyRecipeToEditor();
10391
- }}
10392
- />
10393
- <datalist id="cpk-snippet-tools">
10394
- ${tools.map((tool) => lit.html`<option value=${tool.name}></option>`)}
10395
- </datalist>
10396
- </label>
10397
- <label class="text-[11px] text-gray-600">
10398
- Args JSON
10399
- <textarea
10400
- class="mt-1 h-20 w-full rounded-md border border-gray-200 px-2 py-1 font-mono text-[11px]"
10401
- data-testid="cpk-snippet-tool-args"
10402
- .value=${this.snippetToolArgs}
10403
- @input=${(event) => {
10404
- this.snippetToolArgs = event.target.value;
10405
- this.applyRecipeToEditor();
10406
- }}
10407
- ></textarea>
10408
- </label>
10409
- ` : lit.nothing}
10410
- ${this.snippetRecipe === "reasoning" ? lit.html`<label class="text-[11px] text-gray-600">
10411
- Reasoning
10412
- <textarea
10413
- class="mt-1 h-20 w-full rounded-md border border-gray-200 px-2 py-1 text-[11px]"
10414
- data-testid="cpk-snippet-reasoning"
10415
- .value=${this.snippetReasoningText}
10416
- @input=${(event) => {
10417
- this.snippetReasoningText = event.target.value;
10418
- this.applyRecipeToEditor();
10419
- }}
10420
- ></textarea>
10421
- </label>` : lit.nothing}
10422
- ${this.snippetRecipe === "text" ? lit.html`<label class="text-[11px] text-gray-600">
10423
- Assistant text
10424
- <textarea
10425
- class="mt-1 h-20 w-full rounded-md border border-gray-200 px-2 py-1 text-[11px]"
10426
- data-testid="cpk-snippet-text"
10427
- .value=${this.snippetTextContent}
10428
- @input=${(event) => {
10429
- this.snippetTextContent = event.target.value;
10430
- this.applyRecipeToEditor();
10431
- }}
10432
- ></textarea>
10433
- </label>` : lit.nothing}
10434
- ${this.snippetRecipe === "activity" ? lit.html`
10435
- <label class="text-[11px] text-gray-600">
10436
- Activity type
10437
- <input
10438
- list="cpk-snippet-activity"
10439
- class="mt-1 w-full rounded-md border border-gray-200 px-2 py-1 text-[11px]"
10440
- data-testid="cpk-snippet-activity-type"
10441
- .value=${this.snippetActivityType}
10442
- @input=${(event) => {
10443
- this.snippetActivityType = event.target.value;
10444
- this.applyRecipeToEditor();
10445
- }}
10446
- />
10447
- <datalist id="cpk-snippet-activity">
10448
- ${require_event_snippets.ACTIVITY_STARTERS.map((type) => lit.html`<option value=${type}></option>`)}
10449
- </datalist>
10450
- </label>
10451
- <label class="text-[11px] text-gray-600">
10452
- Content JSON
10453
- <textarea
10454
- class="mt-1 h-24 w-full rounded-md border border-gray-200 px-2 py-1 font-mono text-[11px]"
10455
- data-testid="cpk-snippet-activity-content"
10456
- .value=${this.snippetActivityContent}
10457
- @input=${(event) => {
10458
- this.snippetActivityContent = event.target.value;
10459
- this.applyRecipeToEditor();
10460
- }}
10461
- ></textarea>
10462
- </label>
10463
- ` : lit.nothing}
10464
- <label class="text-[11px] text-gray-600">
10465
- Events JSON
10466
- <textarea
10467
- class="mt-1 h-40 w-full rounded-md border border-gray-200 px-2 py-1 font-mono text-[11px]"
10468
- data-testid="cpk-snippet-json"
10469
- .value=${this.snippetJson}
10470
- @input=${(event) => {
10471
- this.snippetJson = event.target.value;
10472
- this.requestUpdate();
10473
- }}
10474
- ></textarea>
10475
- </label>
10476
- <div class="flex flex-wrap gap-2">
10477
- <button
10478
- type="button"
10479
- class="rounded-md bg-gray-900 px-3 py-1.5 text-[11px] text-white disabled:opacity-50"
10480
- data-testid="cpk-snippet-run"
10481
- ?disabled=${!canRun}
10482
- title=${runBlocked ? "The agent is running. Wait for the current run to end." : !agent ? "No agent is available to inject into." : !canRunJson ? "Events JSON must be a non-empty event array." : "Run snippet"}
10483
- @click=${() => void this.runCurrentSnippet()}
10484
- >
10485
- ${runBlocked ? "Agent running" : "Run"}
10486
- </button>
10487
- <button
10488
- type="button"
10489
- class="rounded-md border border-gray-300 bg-white px-3 py-1.5 text-[11px] disabled:opacity-50"
10490
- data-testid="cpk-snippet-save"
10491
- ?disabled=${!canSave}
10492
- title=${canSave ? "Save snippet" : "Events JSON must be a non-empty event array."}
10493
- @click=${() => this.saveCurrentSnippet("pane")}
10494
- >
10495
- Save
10496
- </button>
10497
- <button
10498
- type="button"
10499
- class="rounded-md border border-gray-300 bg-white px-3 py-1.5 text-[11px] disabled:opacity-50"
10500
- data-testid="cpk-snippet-reset"
10501
- ?disabled=${!canReset}
10502
- title=${canReset ? "Remove the last inject from the thread" : "No Inspector inject to reset."}
10503
- @click=${() => this.resetLastSnippetRun()}
10504
- >
10505
- Reset last run
10506
- </button>
10507
- <button
10508
- type="button"
10509
- class="rounded-md border border-gray-300 bg-white px-3 py-1.5 text-[11px] disabled:opacity-50"
10510
- data-testid="cpk-snippet-delete"
10511
- ?disabled=${!canDelete}
10512
- title=${canDelete ? "Delete this snippet" : "Select a snippet to delete."}
10513
- @click=${() => {
10514
- if (!this.selectedSnippetId) return;
10515
- if (!window.confirm("Delete this snippet?")) return;
10516
- this.eventSnippets = require_event_snippets.deleteEventSnippet(this.selectedSnippetId);
10517
- this.selectedSnippetId = null;
10518
- this.requestUpdate();
10519
- }}
10520
- >
10521
- Delete
10522
- </button>
10523
- <button
10524
- type="button"
10525
- class="rounded-md border border-gray-300 bg-white px-3 py-1.5 text-[11px] disabled:opacity-50"
10526
- data-testid="cpk-snippet-export"
10527
- ?disabled=${!canExport}
10528
- title=${canExport ? "Export snippets" : "Save a snippet before you export."}
10529
- @click=${() => {
10530
- if (!canExport) return;
10531
- const blob = new Blob([require_event_snippets.exportEventSnippetsJson(this.eventSnippets)], { type: "application/json" });
10532
- const url = URL.createObjectURL(blob);
10533
- const link = document.createElement("a");
10534
- link.href = url;
10535
- link.download = "event-snippets.json";
10536
- link.click();
10537
- URL.revokeObjectURL(url);
10538
- }}
10539
- >
10540
- Export
10541
- </button>
10542
- </div>
10543
- </div>
10544
- </div>
10545
- </div>
10546
10760
  `;
10547
10761
  }
10548
10762
  renderMainContent() {
@@ -10558,7 +10772,6 @@ ${argsString}</pre
10558
10772
  </div>
10559
10773
  `;
10560
10774
  if (this.selectedMenu === "playground") return this.renderPlaygroundView();
10561
- if (this.selectedMenu === "event-snippets") return this.renderEventSnippetsView();
10562
10775
  if (this.selectedMenu === "agents") return this.renderAgentsView();
10563
10776
  if (this.selectedMenu === "frontend-tools") return this.renderToolsView();
10564
10777
  if (this.selectedMenu === "capabilities") return this.renderCapabilitiesView();
@@ -10690,9 +10903,9 @@ ${argsString}</pre
10690
10903
  </div>
10691
10904
  ` : visibleMessages.length === 0 ? lit.html`
10692
10905
  <div
10693
- 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"
10694
10907
  >
10695
- <p class="text-base font-medium tracking-tight text-gray-900">
10908
+ <p class="cpk-playground-welcome-title">
10696
10909
  How can I help you today?
10697
10910
  </p>
10698
10911
  ${this.renderPlaygroundComposer(agentId, busy, hasRetry, true)}
@@ -12067,6 +12280,7 @@ ${argsString}</pre
12067
12280
  .focusRequestId=${this.threadFocusRequestId}
12068
12281
  .agentStateInput=${this.getLatestStateForAgent(selectedThread.agentId)}
12069
12282
  .agentEventsInput=${this.agentEvents.get(selectedThread.agentId) ?? []}
12283
+ .agentMessagesInput=${selectedThreadIsLocalExample ? EMPTY_INSPECTOR_MESSAGES : this.getLiveAgentMessagesForThread(selectedThread)}
12070
12284
  ></cpk-thread-details>
12071
12285
  ${selectedThreadIsLocalExample ? this.renderThreadsExampleTour() : lit.nothing}` : showingExamples ? this.renderThreadsExampleOverview(locked) : lit.html`
12072
12286
  <div
@@ -12307,11 +12521,7 @@ ${argsString}</pre
12307
12521
  >
12308
12522
  ${isExpanded ? lit.html`
12309
12523
  <div class="group relative">
12310
- <pre
12311
- class="m-0 whitespace-pre-wrap break-words text-[10px] font-mono text-gray-600"
12312
- >
12313
- ${prettyEvent}</pre
12314
- >
12524
+ ${renderHighlightedJsonBlock(extractedEvent)}
12315
12525
  <button
12316
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"}"
12317
12527
  @click=${(e) => {
@@ -12533,7 +12743,7 @@ ${prettyEvent}</pre
12533
12743
  <div class="overflow-auto">
12534
12744
  ${messages && messages.length > 0 ? lit.html`
12535
12745
  <div class="w-full text-xs">
12536
- <div class="flex bg-gray-50">
12746
+ <div class="cpk-agent-messages-head flex bg-gray-50">
12537
12747
  <div
12538
12748
  class="w-40 shrink-0 px-4 py-2 font-medium text-gray-700"
12539
12749
  >
@@ -12543,7 +12753,7 @@ ${prettyEvent}</pre
12543
12753
  Content
12544
12754
  </div>
12545
12755
  </div>
12546
- <div class="divide-y divide-gray-200">
12756
+ <div class="cpk-agent-messages-rows">
12547
12757
  ${messages.map((msg) => {
12548
12758
  const role = msg.role || "unknown";
12549
12759
  const roleColors = {
@@ -12561,7 +12771,7 @@ ${prettyEvent}</pre
12561
12771
  const isFailedResult = role === "tool" && toolError?.toolCallId !== void 0 && toolError.toolCallId === msg.toolCallId;
12562
12772
  return lit.html`
12563
12773
  <div
12564
- 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"}
12565
12775
  data-cpk-failed-tool-result=${isFailedResult ? msg.toolCallId : lit.nothing}
12566
12776
  >
12567
12777
  <div class="w-40 shrink-0 px-4 py-2">
@@ -12643,10 +12853,12 @@ ${prettyEvent}</pre
12643
12853
  >${this.renderIcon("ChevronDown")}</span
12644
12854
  >
12645
12855
  </button>
12646
- ${this.contextMenuOpen ? lit.html`
12856
+ ${iconRail || this.contextMenuOpen ? lit.html`
12647
12857
  <div
12648
- 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" : ""}"
12649
12859
  data-context-dropdown-root="true"
12860
+ data-open=${this.contextMenuOpen ? "true" : "false"}
12861
+ aria-hidden=${this.contextMenuOpen ? "false" : "true"}
12650
12862
  >
12651
12863
  ${filteredOptions.map((option) => lit.html`
12652
12864
  <button
@@ -12765,7 +12977,6 @@ ${prettyEvent}</pre
12765
12977
  if (previousMenu !== "memories" && !this.core?.telemetryDisabled) require_telemetry.trackMemoriesTabClicked(this.getMemoriesTelemetryProps());
12766
12978
  }
12767
12979
  if (key === "home" && previousMenu !== "home") this.homeViewedThisOpen = false;
12768
- if (key === "event-snippets") this.reloadEventSnippets();
12769
12980
  if (key === "ag-ui-events" || key === "agents") {
12770
12981
  if (!(this.pendingScrollToEventId !== null || this.pendingScrollToToolCallId !== null)) requestAnimationFrame(() => {
12771
12982
  const scroller = this.activeRoot.querySelector("#cpk-main-scroll");
@@ -12784,8 +12995,14 @@ ${prettyEvent}</pre
12784
12995
  this.contextMenuOpen = !this.contextMenuOpen;
12785
12996
  this.requestUpdate();
12786
12997
  }
12998
+ clearIconRailContextCloseTimer() {
12999
+ if (this.iconRailContextCloseTimer === null) return;
13000
+ clearTimeout(this.iconRailContextCloseTimer);
13001
+ this.iconRailContextCloseTimer = null;
13002
+ }
12787
13003
  handleContextOptionSelect(key) {
12788
13004
  if (!this.contextOptions.some((option) => option.key === key)) return;
13005
+ this.clearIconRailContextCloseTimer();
12789
13006
  if (this.selectedContext !== key) {
12790
13007
  this.selectedContext = key;
12791
13008
  this.expandedRows.clear();
@@ -13280,23 +13497,25 @@ ${prettyEvent}</pre
13280
13497
  </button>
13281
13498
 
13282
13499
  ${isExpanded ? lit.html`
13283
- <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">
13284
13501
  <div class="mb-3">
13285
- <h5 class="mb-1 text-xs font-semibold text-gray-700">ID</h5>
13286
- <code
13287
- class="font-mono text-xs font-medium text-gray-800 flex-1 truncate min-w-0"
13288
- >${id}</code
13289
- >
13290
- <button
13291
- type="button"
13292
- class="cpk-copy-btn"
13293
- @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) => {
13294
13508
  e.stopPropagation();
13295
13509
  this.copyContextValue(id, `${id}:id`, e);
13296
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
13297
13518
  >
13298
- ${this.copiedContextItems.has(`${id}:id`) ? "✓" : "Copy"}
13299
- </button>
13300
13519
  </div>
13301
13520
  ${hasValue ? lit.html`
13302
13521
  <div class="mb-2 flex items-center justify-between gap-2">
@@ -14023,6 +14242,16 @@ function defineWebInspector(registry = globalThis.customElements) {
14023
14242
  defineElementOnce(registry, "cpk-memory-list", CpkMemoryList);
14024
14243
  defineElementOnce(registry, WEB_INSPECTOR_TAG, WebInspectorElement);
14025
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
+ }
14026
14255
  defineWebInspector();
14027
14256
 
14028
14257
  //#endregion
@@ -14030,10 +14259,8 @@ exports.CpkThreadInspector = CpkThreadInspector;
14030
14259
  exports.THREAD_INSPECTOR_TAG = THREAD_INSPECTOR_TAG;
14031
14260
  exports.WEB_INSPECTOR_TAG = WEB_INSPECTOR_TAG;
14032
14261
  exports.WebInspectorElement = WebInspectorElement;
14033
- exports.compileChatSnippet = require_event_snippets.compileChatSnippet;
14034
- exports.compileFromActivityMessage = require_event_snippets.compileFromActivityMessage;
14262
+ exports.configureWebInspectorElement = configureWebInspectorElement;
14035
14263
  exports.defineWebInspector = defineWebInspector;
14036
- exports.upsertEventSnippet = require_event_snippets.upsertEventSnippet;
14037
14264
  exports.ɵCpkThreadDetails = ɵCpkThreadDetails;
14038
14265
  exports.ɵbuildCapabilityRows = buildCapabilityRows;
14039
14266
  exports.ɵmaxRecallScore = maxRecallScore;