@copilotkit/web-inspector 1.76.0 → 1.77.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,6 +1,9 @@
1
1
  import { acknowledgeNotification, compareNotifications, emptyNotificationState, reconcileNotifications } from "./lib/notifications.mjs";
2
2
  import { loadNotificationFeed } from "./lib/notification-loader.mjs";
3
- import { INSPECTOR_DISMISSAL_MAX_DURATION_MS, clearLegacyAnnouncementReadState, hasNotificationPulsed, isValidAnchor, isValidDockMode, isValidPosition, isValidSize, loadInspectorDismissedUntil, loadInspectorState, loadNotificationState, migrateAnnouncementReadState, saveInspectorDismissedUntil, saveInspectorState, saveNotificationPulsedId, saveNotificationState } from "./lib/persistence.mjs";
3
+ import { resolveHudContent } from "./lib/hud-config.mjs";
4
+ import { loadHudFeed } from "./lib/hud-loader.mjs";
5
+ import { HUD_DEFAULT_CONTENT } from "./lib/hud-defaults.mjs";
6
+ import { INSPECTOR_DISMISSAL_MAX_DURATION_MS, clearLegacyAnnouncementReadState, hasNotificationPulsed, isValidAnchor, isValidDockMode, isValidPosition, isValidSize, loadInspectorDismissedUntil, loadInspectorState, loadNotificationState, migrateAnnouncementReadState, saveInspectorDismissedForever, saveInspectorDismissedUntil, saveInspectorState, saveNotificationPulsedId, saveNotificationState } from "./lib/persistence.mjs";
4
7
  import generated_default from "./styles/generated.mjs";
5
8
  import { notificationArticleStyles } from "./styles/notification-article.mjs";
6
9
  import inspector_logo_default from "./assets/inspector-logo.mjs";
@@ -12,7 +15,7 @@ import { InspectorLearningUnsupportedError, fetchInspectorLearning } from "./lib
12
15
  import { buildPopOutFeatures, ensureBrandFont, openPopOutWindow } from "./lib/pop-out.mjs";
13
16
  import { projectInspectorMetadata } from "./lib/inspector-metadata.mjs";
14
17
  import { buildHomeModel, runtimeConnectionNeedsAttention } from "./lib/home-briefing.mjs";
15
- import { INSPECTOR_GROUPS, INSPECTOR_NAV_SECTIONS, getGroupForMenu, isInspectorMenuKey, shouldUseIconRail } from "./lib/inspector-nav.mjs";
18
+ import { INSPECTOR_GROUPS, INSPECTOR_MENU_KEYS, INSPECTOR_NAV_SECTIONS, getGroupForMenu, isInspectorMenuKey, shouldUseIconRail } from "./lib/inspector-nav.mjs";
16
19
  import { selectVisibleRealThreadId } from "./lib/thread-selection.mjs";
17
20
  import { TELEMETRY_DOCS_URL, ensureTelemetryDistinctId, getRuntimeUrlType, getTelemetryDistinctIdForUrl, learningCountBucket, learningDurationBucket, maybeShowDisclosure, trackErrorSignalViewed, trackHomeCtaClicked, trackHomeFeaturePromptClicked, trackHomePromptCopied, trackHomeStoryBeatSelected, trackHomeViewed, trackHudFeatureClicked, trackHudFeatureToggleClicked, trackHudFeatureToggleViewed, trackHudHideClicked, trackHudHideViewed, trackHudNotificationClicked, trackHudNotificationViewed, trackHudViewed, trackInspectorOpened, trackLearningEvidenceOpened, trackLearningPageChanged, trackLearningPaneViewed, trackLearningSetupPromptClicked, trackLearningSkillToggled, trackLearningSnapshotLoaded, trackLearningWebAppOpened, trackMemoriesTabClicked, trackMetadataActionClicked, trackMetadataModuleViewed, trackTalkToEngineerClicked, trackThreadsEmptyEnabledViewed, trackThreadsEnabledViewed, trackThreadsExampleSelected, trackThreadsExampleTourCompleted, trackThreadsExampleTourDismissed, trackThreadsExampleTourReopened, trackThreadsExampleTourStarted, trackThreadsExampleTourStepViewed, trackThreadsExampleViewed, trackThreadsIntelligenceSignupClicked, trackThreadsLockedViewed, trackThreadsTabClicked, trackThreadsTalkToEngineerClicked, trackThreadsTryFromHereClicked, trackWhatsNewClicked, trackWhatsNewSignalViewed, trackWhatsNewViewed } from "./lib/telemetry.mjs";
18
21
  import { createFeatureOnboardingPrompt, createOnboardingPrompt, createOnboardingRunId } from "./lib/onboarding-prompt.mjs";
@@ -120,13 +123,12 @@ const EVENT_ERROR_GUIDANCE = {
120
123
  const PILL_SUBLINE_LABEL = "Open Inspector for details";
121
124
  const HUD_INSPECTOR_LABEL = "CopilotKit Inspector";
122
125
  const HUD_ANNOUNCEMENT_TITLE_LIMIT = 80;
123
- const HUD_THREADS_LABEL = "Rich Threads";
124
- const HUD_LEARNING_LABEL = "Automatic Learning";
125
- const HUD_LEARN_MORE_LABEL = "Click to learn more";
126
126
  const INSPECTOR_DISMISSAL_MS = {
127
127
  day: 1440 * 60 * 1e3,
128
- week: INSPECTOR_DISMISSAL_MAX_DURATION_MS
128
+ week: 10080 * 60 * 1e3,
129
+ forever: INSPECTOR_DISMISSAL_MAX_DURATION_MS
129
130
  };
131
+ const MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
130
132
  const LAUNCHER_SIGNALS = {
131
133
  "whats-new": {
132
134
  tone: "news",
@@ -1865,6 +1867,13 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1865
1867
  flex-direction: column;
1866
1868
  gap: 12px;
1867
1869
  }
1870
+ .cpk-td__panel--conversation {
1871
+ width: 100%;
1872
+ max-width: 800px;
1873
+ min-width: 0;
1874
+ margin-inline: auto;
1875
+ }
1876
+
1868
1877
  .cpk-td__panel > * {
1869
1878
  flex-shrink: 0;
1870
1879
  }
@@ -1983,123 +1992,148 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
1983
1992
  border: 0;
1984
1993
  }
1985
1994
 
1986
- /* ── Tool call blocks ────────────────────────────────────────────── */
1995
+ /* Tool activity stays compact in the conversation; raw data is opt-in. */
1987
1996
  .cpk-td__tool-block {
1988
- border: 1px solid #e9e9ef;
1989
- border-radius: 12px;
1997
+ min-width: 0;
1998
+ }
1999
+ .cpk-td__tool-block:has(> .cpk-td__tool-header[aria-expanded="true"]) {
2000
+ border-radius: 10px;
1990
2001
  overflow: hidden;
2002
+ background: #ffffff;
2003
+ box-shadow: 0 0 0 1px oklch(0 0 0 / 0.08);
1991
2004
  }
1992
-
1993
2005
  .cpk-td__tool-header {
1994
2006
  display: flex;
1995
2007
  align-items: center;
1996
- gap: 6px;
1997
- padding: 12px;
1998
- background: #ffffff;
1999
- color: #71717a;
2008
+ gap: 10px;
2009
+ padding: 10px 12px;
2010
+ background: transparent;
2011
+ color: #68686e;
2000
2012
  cursor: pointer;
2001
2013
  width: 100%;
2002
2014
  border: 0;
2003
2015
  font-family: inherit;
2004
2016
  text-align: left;
2005
- font-size: 11px;
2006
- user-select: none;
2017
+ font-size: 12px;
2018
+ }
2019
+ .cpk-td__tool-header > svg {
2020
+ flex-shrink: 0;
2007
2021
  }
2008
-
2009
2022
  .cpk-td__tool-header:focus-visible {
2010
2023
  outline: 2px solid var(--cpk-primary-color, #7076b3);
2011
2024
  outline-offset: -2px;
2012
2025
  }
2013
-
2014
2026
  .cpk-td__tool-header:hover {
2015
- background: #fafafa;
2027
+ background: #f7f7f9;
2028
+ border-radius: 8px;
2029
+ }
2030
+ .cpk-td__tool-block:has(> .cpk-td__tool-header[aria-expanded="true"])
2031
+ .cpk-td__tool-header:hover {
2032
+ border-radius: 0;
2033
+ }
2034
+ .cpk-td__tool-copy {
2035
+ flex: 1;
2036
+ min-width: 0;
2037
+ }
2038
+ .cpk-td__tool-title {
2039
+ display: flex;
2040
+ flex-wrap: wrap;
2041
+ align-items: baseline;
2042
+ min-width: 0;
2016
2043
  }
2017
-
2018
2044
  .cpk-td__tool-name {
2019
2045
  font-size: 13px;
2020
2046
  font-weight: 500;
2021
- color: #18181b;
2047
+ line-height: 1.6;
2048
+ color: #57575b;
2022
2049
  overflow-wrap: anywhere;
2023
- min-width: 0;
2024
- flex: 1;
2025
2050
  }
2026
-
2027
2051
  .cpk-td__tool-status {
2028
- font-size: 10px;
2029
- font-weight: 500;
2030
- padding: 3px 7px;
2031
- border-radius: 999px;
2032
- background: #d1fae5;
2033
- color: #065f46;
2052
+ display: block;
2053
+ font-size: 11px;
2054
+ line-height: 1.6;
2055
+ color: #68686e;
2034
2056
  }
2035
-
2036
2057
  .cpk-td__tool-status--pending {
2037
- background: #fef3c7;
2038
2058
  color: #8a5900;
2039
2059
  }
2040
-
2041
2060
  .cpk-td__tool-chevron {
2042
- color: #68686e;
2043
- font-size: 10px;
2061
+ flex-shrink: 0;
2062
+ transition: transform 150ms;
2063
+ }
2064
+ .cpk-td__tool-header[aria-expanded="true"] .cpk-td__tool-chevron {
2065
+ transform: rotate(90deg);
2066
+ }
2067
+ .cpk-td__tool-name--streaming {
2068
+ width: fit-content;
2069
+ background: linear-gradient(100deg, #68686e 35%, #c9c9d5 50%, #68686e 65%);
2070
+ background-size: 250% 100%;
2071
+ background-clip: text;
2072
+ -webkit-background-clip: text;
2073
+ color: transparent;
2074
+ animation: cpk-tool-shimmer 2s linear infinite;
2075
+ }
2076
+ @keyframes cpk-tool-shimmer {
2077
+ from {
2078
+ background-position: 150% 0;
2079
+ }
2080
+ to {
2081
+ background-position: -100% 0;
2082
+ }
2083
+ }
2084
+ @media (prefers-reduced-motion: reduce) {
2085
+ .cpk-td__tool-name--streaming {
2086
+ animation: none;
2087
+ background: none;
2088
+ color: inherit;
2089
+ }
2090
+ .cpk-td__tool-chevron {
2091
+ transition: none;
2092
+ }
2044
2093
  }
2045
-
2046
2094
  .cpk-td__tool-body {
2047
- padding: 8px 10px;
2095
+ min-width: 0;
2096
+ padding-top: 4px;
2048
2097
  border-top: 1px solid #e9e9ef;
2049
- background: #ffffff;
2050
2098
  }
2051
-
2052
- .cpk-td__tool-section-label {
2053
- font-family: "Spline Sans Mono", monospace;
2054
- font-size: 9px;
2055
- font-weight: 500;
2099
+ .cpk-td__tool-identifier {
2100
+ margin-left: 0.35em;
2056
2101
  color: #68686e;
2057
- text-transform: uppercase;
2058
- margin-bottom: 4px;
2059
- letter-spacing: 0.3px;
2102
+ font:
2103
+ 11px/1.6 "Spline Sans Mono",
2104
+ monospace;
2105
+ overflow-wrap: anywhere;
2060
2106
  }
2061
-
2062
- .cpk-td__tool-pre {
2107
+ .cpk-td__tool-data {
2108
+ display: grid;
2109
+ gap: 0;
2110
+ }
2111
+ .cpk-td__tool-section-label {
2112
+ font-family: "Plus Jakarta Sans", sans-serif;
2113
+ font-size: 12px;
2114
+ font-weight: 600;
2115
+ line-height: 1.65;
2116
+ color: #68686e;
2063
2117
  margin: 0;
2064
- font-family: "Spline Sans Mono", monospace;
2118
+ padding: 8px 12px;
2119
+ }
2120
+ .cpk-td__tool-body .cpk-json-block {
2065
2121
  font-size: 12px;
2066
- background: #f7f7f9;
2067
- padding: 10px 12px;
2068
- border-radius: 6px;
2069
- overflow-x: auto;
2070
- white-space: pre-wrap;
2071
- overflow-wrap: anywhere;
2072
- word-break: normal;
2073
- color: #010507;
2074
2122
  line-height: 1.65;
2075
2123
  }
2076
-
2077
- /* ── Tool call group ─────────────────────────────────────────────── */
2124
+ .cpk-td__tool-result {
2125
+ border-top: 1px solid #e9e9ef;
2126
+ }
2078
2127
  .cpk-td__tool-group {
2079
- border: 1px solid #e9e9ef;
2080
- border-radius: 7px;
2081
- overflow: hidden;
2128
+ min-width: 0;
2082
2129
  }
2083
-
2084
2130
  .cpk-td__tool-group-header {
2085
- padding: 5px 10px;
2086
- background: rgba(133, 236, 206, 0.15);
2087
- font-family: "Spline Sans Mono", monospace;
2088
- font-size: 10px;
2089
- color: #087653;
2090
- text-transform: uppercase;
2091
- font-weight: 500;
2092
- border-bottom: 1px solid #e9e9ef;
2131
+ padding: 4px 12px;
2132
+ font-size: 11px;
2133
+ color: #68686e;
2093
2134
  }
2094
-
2095
2135
  .cpk-td__tool-group .cpk-td__tool-block {
2096
- border: none;
2097
- border-bottom: 1px solid #e9e9ef;
2098
- border-radius: 0;
2099
- }
2100
-
2101
- .cpk-td__tool-group .cpk-td__tool-block:last-child {
2102
- border-bottom: none;
2136
+ margin-left: 12px;
2103
2137
  }
2104
2138
 
2105
2139
  /* ── Inline chips (reasoning / state update) ─────────────────────── */
@@ -2385,17 +2419,24 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2385
2419
  }
2386
2420
 
2387
2421
  :host([data-color-scheme="dark"]) .cpk-td__tool-header {
2422
+ background: transparent;
2423
+ }
2424
+ :host([data-color-scheme="dark"])
2425
+ .cpk-td__tool-block:has(> .cpk-td__tool-header[aria-expanded="true"]) {
2388
2426
  background: #191c24;
2427
+ box-shadow: 0 0 0 1px oklch(1 0 0 / 0.12);
2428
+ }
2429
+ :host([data-color-scheme="dark"]) .cpk-td__tool-body,
2430
+ :host([data-color-scheme="dark"]) .cpk-td__tool-result {
2431
+ border-top-color: #343742;
2389
2432
  }
2390
2433
  :host([data-color-scheme="dark"]) .cpk-td__tool-name {
2391
2434
  color: #f4f4f5;
2392
2435
  }
2393
2436
  :host([data-color-scheme="dark"]) .cpk-td__tool-status {
2394
- background: #17392e;
2395
- color: #6ee7b7;
2437
+ color: #a1a1aa;
2396
2438
  }
2397
2439
  :host([data-color-scheme="dark"]) .cpk-td__tool-status--pending {
2398
- background: #3d3019;
2399
2440
  color: #fbbf24;
2400
2441
  }
2401
2442
 
@@ -2618,9 +2659,6 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2618
2659
  :host([data-color-scheme="dark"]) .cpk-td__metadata-strip,
2619
2660
  :host([data-color-scheme="dark"]) .cpk-td__metadata-pill,
2620
2661
  :host([data-color-scheme="dark"]) .cpk-td__try-from-here,
2621
- :host([data-color-scheme="dark"]) .cpk-td__tool-block,
2622
- :host([data-color-scheme="dark"]) .cpk-td__tool-header,
2623
- :host([data-color-scheme="dark"]) .cpk-td__tool-body,
2624
2662
  :host([data-color-scheme="dark"]) .cpk-td__event,
2625
2663
  :host([data-color-scheme="dark"]) .cpk-td__event-payload,
2626
2664
  :host([data-color-scheme="dark"]) .cpk-td__timeline-item,
@@ -2636,7 +2674,6 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2636
2674
 
2637
2675
  :host([data-color-scheme="dark"]) .cpk-td__metadata-pill,
2638
2676
  :host([data-color-scheme="dark"]) .cpk-td__try-from-here,
2639
- :host([data-color-scheme="dark"]) .cpk-td__tool-block,
2640
2677
  :host([data-color-scheme="dark"]) .cpk-td__event,
2641
2678
  :host([data-color-scheme="dark"]) .cpk-td__genui-card,
2642
2679
  :host([data-color-scheme="dark"]) .cpk-td__timeline-item,
@@ -2646,16 +2683,10 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2646
2683
  background: #191c24;
2647
2684
  }
2648
2685
 
2649
- :host([data-color-scheme="dark"]) .cpk-td__timeline-header,
2650
- :host([data-color-scheme="dark"]) .cpk-td__tool-body {
2686
+ :host([data-color-scheme="dark"]) .cpk-td__timeline-header {
2651
2687
  background: #171a22;
2652
2688
  }
2653
2689
 
2654
- :host([data-color-scheme="dark"]) .cpk-td__tool-pre {
2655
- background: #111319;
2656
- color: #f3f4f8;
2657
- }
2658
-
2659
2690
  :host([data-color-scheme="dark"]) .cpk-td__panel-toggle:hover,
2660
2691
  :host([data-color-scheme="dark"]) .cpk-td__tool-header:hover,
2661
2692
  :host([data-color-scheme="dark"]) .cpk-td__timeline-bulk-toggle:hover,
@@ -2789,7 +2820,6 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2789
2820
  :host([data-color-scheme="dark"]) .cpk-td__tab--active,
2790
2821
  :host([data-color-scheme="dark"]) .cpk-td__metadata-value,
2791
2822
  :host([data-color-scheme="dark"]) .cpk-td__tool-name,
2792
- :host([data-color-scheme="dark"]) .cpk-td__tool-pre,
2793
2823
  :host([data-color-scheme="dark"]) .cpk-td__timeline-title,
2794
2824
  :host([data-color-scheme="dark"]) .cpk-td__timeline-bulk-toggle,
2795
2825
  :host([data-color-scheme="dark"]) .cpk-td__timeline-details-toggle,
@@ -2798,6 +2828,28 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
2798
2828
  color: #f3f4f8;
2799
2829
  }
2800
2830
 
2831
+ :host([data-color-scheme="dark"]) .cpk-td__tool-status,
2832
+ :host([data-color-scheme="dark"]) .cpk-td__tool-section-label,
2833
+ :host([data-color-scheme="dark"]) .cpk-td__tool-identifier,
2834
+ :host([data-color-scheme="dark"]) .cpk-td__tool-group-header {
2835
+ color: #aeb1bd;
2836
+ }
2837
+ :host([data-color-scheme="dark"]) .cpk-td__tool-name--streaming {
2838
+ color: transparent;
2839
+ background-image: linear-gradient(
2840
+ 100deg,
2841
+ #aeb1bd 35%,
2842
+ #ffffff 50%,
2843
+ #aeb1bd 65%
2844
+ );
2845
+ }
2846
+ @media (prefers-reduced-motion: reduce) {
2847
+ :host([data-color-scheme="dark"]) .cpk-td__tool-name--streaming {
2848
+ background: none;
2849
+ color: #f3f4f8;
2850
+ }
2851
+ }
2852
+
2801
2853
  :host([data-color-scheme="dark"]) .cpk-td__event-payload,
2802
2854
  :host([data-color-scheme="dark"]) .cpk-td__json-block,
2803
2855
  :host([data-color-scheme="dark"]) .cpk-json-block {
@@ -3631,7 +3683,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3631
3683
  ` : nothing}
3632
3684
  ${CpkThreadInspector.TAB_LIST.map((tab) => this._activatedTabs.has(tab.id) ? html`<div
3633
3685
  id=${this.panelDomId(tab.id)}
3634
- class="cpk-td__panel"
3686
+ class="cpk-td__panel ${tab.id === "timeline" && !this._showEventTimeline && this._conversation.length > 0 ? "cpk-td__panel--conversation" : ""}"
3635
3687
  role="tabpanel"
3636
3688
  aria-labelledby=${this.tabDomId(tab.id)}
3637
3689
  ?hidden=${this._tab !== tab.id || this._panelInitializing}
@@ -3905,11 +3957,13 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3905
3957
  `;
3906
3958
  const items = this.renderItems;
3907
3959
  const errors = this.conversationRunErrors(items);
3960
+ const streamingTools = this.streamingToolCallIds();
3908
3961
  return this.cachedPanelTpl("timeline-fallback", [
3909
3962
  this._conversation,
3910
3963
  this._expandedTools,
3911
3964
  this._expandedMessages,
3912
3965
  JSON.stringify(errors),
3966
+ JSON.stringify([...streamingTools]),
3913
3967
  this._expandedTimelineDetails
3914
3968
  ], () => {
3915
3969
  const errorsAfter = /* @__PURE__ */ new Map();
@@ -3921,10 +3975,29 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3921
3975
  const renderErrors = (after) => errorsAfter.get(after)?.map((item) => this.renderTimelineItem(item));
3922
3976
  return html`
3923
3977
  ${renderErrors(-1)}
3924
- ${items.map((item, index) => html`${this.renderRenderItem(item)}${renderErrors(index)}`)}
3978
+ ${items.map((item, index) => html`${this.renderRenderItem(item, streamingTools)}${renderErrors(index)}`)}
3925
3979
  `;
3926
3980
  });
3927
3981
  }
3982
+ streamingToolCallIds() {
3983
+ const streaming = /* @__PURE__ */ new Set();
3984
+ let currentThread = false;
3985
+ for (let i = this.agentEventsInput.length - 1; i >= 0; i--) {
3986
+ const event = this.agentEventsInput[i];
3987
+ const payload = event.payload.event && typeof event.payload.event === "object" ? event.payload.event : event.payload;
3988
+ if (event.type === "RUN_STARTED") {
3989
+ streaming.clear();
3990
+ currentThread = payload.threadId === this.threadId;
3991
+ } else if (event.type === "RUN_FINISHED" || event.type === "RUN_ERROR") {
3992
+ streaming.clear();
3993
+ currentThread = false;
3994
+ } else if (currentThread && typeof payload.toolCallId === "string") {
3995
+ if (event.type === "TOOL_CALL_START") streaming.add(payload.toolCallId);
3996
+ if (event.type === "TOOL_CALL_END" || event.type === "TOOL_CALL_RESULT") streaming.delete(payload.toolCallId);
3997
+ }
3998
+ }
3999
+ return streaming;
4000
+ }
3928
4001
  conversationRunErrors(items) {
3929
4002
  const positions = /* @__PURE__ */ new Map();
3930
4003
  items.forEach((item, index) => {
@@ -3982,12 +4055,12 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
3982
4055
  if (cached && cached.key.length === key.length && cached.key.every((v, i) => v === key[i])) return cached.tpl;
3983
4056
  return null;
3984
4057
  }
3985
- renderRenderItem(item) {
4058
+ renderRenderItem(item, streamingTools) {
3986
4059
  switch (item.type) {
3987
4060
  case "user":
3988
4061
  case "assistant": return this.renderBubble(item);
3989
- case "tool_call": return this.renderToolBlock(item);
3990
- case "tool_call_group": return this.renderToolGroup(item);
4062
+ case "tool_call": return this.renderToolBlock(item, streamingTools.has(item.toolCallId));
4063
+ case "tool_call_group": return this.renderToolGroup(item, streamingTools);
3991
4064
  case "reasoning": return html`<div class="cpk-td__inline-chip">
3992
4065
  <span>Reasoned for ${item.duration}</span>
3993
4066
  </div>`;
@@ -4026,7 +4099,10 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
4026
4099
  </div>
4027
4100
  `;
4028
4101
  }
4029
- renderToolBlock(item) {
4102
+ renderToolBlock(item, streaming = false) {
4103
+ streaming = streaming && !item.hasResult;
4104
+ const label = item.toolName.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ");
4105
+ const readableName = label.charAt(0).toUpperCase() + label.slice(1);
4030
4106
  const expanded = this._expandedTools.has(item.id);
4031
4107
  return html`
4032
4108
  <div class="cpk-td__tool-block">
@@ -4045,45 +4121,41 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
4045
4121
  stroke-linejoin="round"
4046
4122
  />
4047
4123
  </svg>
4048
- <span class="cpk-td__tool-name">${item.toolName}</span>
4049
- ${item.resultUnreadable ? html`
4050
- <span class="cpk-td__tool-status cpk-td__tool-status--pending"
4051
- >Result unreadable</span
4052
- >
4053
- ` : item.hasResult ? html`
4054
- <span class="cpk-td__tool-status">Result received</span>
4055
- ` : html`
4056
- <span class="cpk-td__tool-status cpk-td__tool-status--pending"
4057
- >No result recorded</span
4058
- >
4059
- `}
4060
- <span class="cpk-td__tool-chevron">${expanded ? "▾" : "▸"}</span>
4124
+ <span class="cpk-td__tool-copy">
4125
+ <span class="cpk-td__tool-title">
4126
+ <span class="cpk-td__tool-name ${streaming ? "cpk-td__tool-name--streaming" : ""}">${readableName}</span><code class="cpk-td__tool-identifier">(${item.toolName})</code>
4127
+ </span>
4128
+ <span class="cpk-td__tool-status ${item.resultUnreadable || !item.hasResult && !streaming ? "cpk-td__tool-status--pending" : ""}">${streaming ? "Receiving arguments" : item.resultUnreadable ? "Result unreadable" : item.hasResult ? "Result received" : "No result recorded"}</span>
4129
+ </span>
4130
+ <svg class="cpk-td__tool-chevron" width="14" height="14" viewBox="0 0 24 24" fill="none" aria-hidden="true">
4131
+ <path d="m9 6 6 6-6 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
4132
+ </svg>
4061
4133
  </button>
4062
4134
  ${expanded ? html`
4063
4135
  <div class="cpk-td__tool-body">
4064
- <div class="cpk-td__tool-section-label">Arguments</div>
4065
- ${renderHighlightedJsonBlock(item.arguments)}
4066
- ${item.hasResult ? html`
4067
- <div
4068
- class="cpk-td__tool-section-label"
4069
- style="margin-top:8px"
4070
- >
4071
- Result
4072
- </div>
4136
+ <div class="cpk-td__tool-data">
4137
+ <section>
4138
+ <div class="cpk-td__tool-section-label">Arguments</div>
4139
+ ${renderHighlightedJsonBlock(item.arguments)}
4140
+ </section>
4141
+ ${item.hasResult ? html`
4142
+ <section class="cpk-td__tool-result">
4143
+ <div class="cpk-td__tool-section-label">Result</div>
4073
4144
  ${renderHighlightedJsonBlock(item.result)}
4074
- ` : nothing}
4145
+ </section>` : nothing}
4146
+ </div>
4075
4147
  </div>
4076
4148
  ` : nothing}
4077
4149
  </div>
4078
4150
  `;
4079
4151
  }
4080
- renderToolGroup(group) {
4152
+ renderToolGroup(group, streamingTools) {
4081
4153
  return html`
4082
4154
  <div class="cpk-td__tool-group">
4083
4155
  <div class="cpk-td__tool-group-header">
4084
4156
  ${group.items.length} tool call${group.items.length !== 1 ? "s" : ""}
4085
4157
  </div>
4086
- ${group.items.map((tc) => this.renderToolBlock(tc))}
4158
+ ${group.items.map((tc) => this.renderToolBlock(tc, streamingTools.has(tc.toolCallId)))}
4087
4159
  </div>
4088
4160
  `;
4089
4161
  }
@@ -5152,6 +5224,9 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
5152
5224
  this.announcementId = null;
5153
5225
  this.announcementLoaded = false;
5154
5226
  this.announcementPromise = null;
5227
+ this.hudFeed = null;
5228
+ this.hudFeedPromise = null;
5229
+ this.hudContent = HUD_DEFAULT_CONTENT;
5155
5230
  this.newsSignalArmed = false;
5156
5231
  this.pulsingSignal = null;
5157
5232
  this.pendingPulseSignal = null;
@@ -5378,9 +5453,13 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
5378
5453
  const service = this.getHomeFeaturePromptTarget("memory");
5379
5454
  if (!service || !this.core?.runtimeUrl) return;
5380
5455
  const request = ++this.learningSetupCopyRequest;
5381
- const copied = await this.copyFeaturePromptToClipboard(service, event, this.getOnboardingRunId());
5456
+ const runId = this.getOnboardingRunId();
5457
+ const copied = await this.copyFeaturePromptToClipboard(service, event, runId);
5382
5458
  if (request !== this.learningSetupCopyRequest) return;
5383
- if (!this.core.telemetryDisabled) trackLearningSetupPromptClicked({ outcome: copied ? "success" : "failure" });
5459
+ if (!this.core.telemetryDisabled) trackLearningSetupPromptClicked({
5460
+ outcome: copied ? "success" : "failure",
5461
+ onboarding_run_id: runId
5462
+ });
5384
5463
  if (!copied) {
5385
5464
  if (recopy) {
5386
5465
  this.cancelLearningPromptRecopyReset();
@@ -5490,7 +5569,8 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
5490
5569
  control,
5491
5570
  trigger
5492
5571
  }));
5493
- this.hudLandingMenu = row === "threads" ? "threads" : row === "learning" ? "memories" : "home";
5572
+ const destination = this.hudContent[row].destination;
5573
+ this.hudLandingMenu = isInspectorMenuKey(destination) && this.menuItems.some((item) => item.key === destination) ? destination : row === "threads" ? "threads" : "memories";
5494
5574
  this.closeLauncherHud();
5495
5575
  this.openInspector("floating_button");
5496
5576
  };
@@ -8813,6 +8893,8 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8813
8893
 
8814
8894
  .cpk-launcher-hud__label {
8815
8895
  min-width: 0;
8896
+ /* Remote copy can be one long word; wrap it inside the row. */
8897
+ overflow-wrap: anywhere;
8816
8898
  }
8817
8899
 
8818
8900
  .cpk-launcher-hud__feature-icon {
@@ -9615,7 +9697,8 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9615
9697
  <div data-inspector-portal-anchor></div>
9616
9698
  ` : this.renderButton();
9617
9699
  }
9618
- willUpdate() {
9700
+ willUpdate(changed) {
9701
+ if (changed.has("notificationContext")) this.refreshHudContent();
9619
9702
  this.evaluateErrorSignals();
9620
9703
  this.reconcileSelectedMenuVisibility();
9621
9704
  if (this.isOpen && this.dockMode === "docked-left") this.setAttribute("data-docked", "true");
@@ -9812,7 +9895,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9812
9895
  scheduleInspectorDismissalExpiry() {
9813
9896
  this.clearInspectorDismissalTimer();
9814
9897
  if (this.inspectorDismissedUntil === null) return;
9815
- const delay = Math.max(0, this.inspectorDismissedUntil - Date.now() + 25);
9898
+ const delay = Math.min(MAX_TIMER_DELAY_MS, Math.max(0, this.inspectorDismissedUntil - Date.now() + 25));
9816
9899
  this.inspectorDismissalTimer = setTimeout(() => {
9817
9900
  this.inspectorDismissalTimer = null;
9818
9901
  this.refreshInspectorDismissalState();
@@ -9845,7 +9928,8 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9845
9928
  dismissInspectorFor(duration) {
9846
9929
  const now = Date.now();
9847
9930
  const until = now + INSPECTOR_DISMISSAL_MS[duration];
9848
- saveInspectorDismissedUntil(until, now);
9931
+ if (duration === "forever") saveInspectorDismissedForever(now);
9932
+ else saveInspectorDismissedUntil(until, now);
9849
9933
  this.inspectorDismissedUntil = until;
9850
9934
  this.scheduleInspectorDismissalExpiry();
9851
9935
  this.settingsOpen = false;
@@ -9999,6 +10083,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9999
10083
  renderHudRow(args) {
10000
10084
  if (args.connected) return nothing;
10001
10085
  const detailId = `cpk-hud-detail-${args.id}`;
10086
+ const { label, description } = this.hudContent[args.id];
10002
10087
  return html`
10003
10088
  <li
10004
10089
  class="cpk-launcher-hud__row"
@@ -10012,7 +10097,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
10012
10097
  type="button"
10013
10098
  class="cpk-launcher-hud__action"
10014
10099
  data-cpk-hud-action
10015
- aria-label=${`Open ${args.label} in Inspector`}
10100
+ aria-label=${`Open ${label} in Inspector`}
10016
10101
  @click=${(event) => this.handleHudActionClick(event, args.id, "action")}
10017
10102
  @pointerdown=${(event) => event.stopPropagation()}
10018
10103
  >
@@ -10022,13 +10107,13 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
10022
10107
  aria-hidden="true"
10023
10108
  >${this.renderIcon(args.icon)}</span
10024
10109
  >
10025
- <span class="cpk-launcher-hud__label">${args.label}</span>
10110
+ <span class="cpk-launcher-hud__label">${label}</span>
10026
10111
  </button>
10027
10112
  <span
10028
10113
  class="cpk-launcher-hud__tooltip"
10029
10114
  id=${detailId}
10030
10115
  role="tooltip"
10031
- >${HUD_LEARN_MORE_LABEL}</span
10116
+ >${description}</span
10032
10117
  >
10033
10118
  </span>
10034
10119
  <span class="cpk-launcher-hud__controls">
@@ -10036,7 +10121,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
10036
10121
  type="button"
10037
10122
  class="cpk-launcher-hud__learn-more"
10038
10123
  data-cpk-hud-learn-more=${args.id}
10039
- aria-label=${`Learn more about ${args.label}`}
10124
+ aria-label=${`Learn more about ${label}`}
10040
10125
  aria-describedby=${detailId}
10041
10126
  @click=${(event) => this.handleHudActionClick(event, args.id, "learn_more")}
10042
10127
  @pointerdown=${(event) => event.stopPropagation()}
@@ -10048,7 +10133,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
10048
10133
  class="cpk-launcher-hud__toggle"
10049
10134
  data-cpk-hud-toggle=${args.id}
10050
10135
  data-enabled=${args.connected ? "true" : "false"}
10051
- aria-label=${args.connected ? `${args.label} is enabled` : `Open ${args.label} in Inspector`}
10136
+ aria-label=${args.connected ? `${label} is enabled` : `Open ${label} in Inspector`}
10052
10137
  ?disabled=${args.connected}
10053
10138
  @click=${(event) => this.handleHudActionClick(event, args.id, "toggle")}
10054
10139
  @pointerdown=${(event) => event.stopPropagation()}
@@ -10134,14 +10219,12 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
10134
10219
  >
10135
10220
  ${this.renderHudRow({
10136
10221
  id: "threads",
10137
- label: HUD_THREADS_LABEL,
10138
10222
  icon: "MessageSquare",
10139
10223
  connected: threadsOn,
10140
10224
  introIndex: featureBlockIntroIndex + 1
10141
10225
  })}
10142
10226
  ${this.renderHudRow({
10143
10227
  id: "learning",
10144
- label: HUD_LEARNING_LABEL,
10145
10228
  icon: "Brain",
10146
10229
  connected: learningOn,
10147
10230
  introIndex: featureBlockIntroIndex + (threadsOn ? 1 : 2)
@@ -12892,7 +12975,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
12892
12975
  </span>
12893
12976
  <div>
12894
12977
  <h2 id="inspector-settings-visibility-title">Visibility</h2>
12895
- <p>Temporarily hide the Inspector on this domain.</p>
12978
+ <p>Hide the Inspector on this domain.</p>
12896
12979
  </div>
12897
12980
  </div>
12898
12981
 
@@ -12914,6 +12997,27 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
12914
12997
  Hide Inspector for one week
12915
12998
  </button>
12916
12999
  </div>
13000
+
13001
+ <div class="inspector-settings-visibility">
13002
+ <div>
13003
+ <h3>Hide the Inspector indefinitely</h3>
13004
+ <p>
13005
+ Keep the Inspector hidden on this domain until you bring it
13006
+ back. To restore it, delete the
13007
+ <code>cpk_inspector_dismissed_until</code> cookie and the
13008
+ <code>cpk:inspector:dismissed_until</code> localStorage entry.
13009
+ </p>
13010
+ </div>
13011
+ <button
13012
+ type="button"
13013
+ class="inspector-settings-dismiss"
13014
+ data-cpk-dismiss-inspector="forever"
13015
+ @click=${() => this.dismissInspectorFor("forever")}
13016
+ >
13017
+ <span aria-hidden="true">${this.renderIcon("EyeOff")}</span>
13018
+ Always hide Inspector
13019
+ </button>
13020
+ </div>
12917
13021
  </section>
12918
13022
  </div>
12919
13023
  `;
@@ -15957,9 +16061,23 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
15957
16061
  trackWhatsNewSignalViewed(props);
15958
16062
  }
15959
16063
  }
16064
+ /** Start the development-only remote feeds; neither blocks rendering. */
15960
16065
  ensureAnnouncementLoading() {
15961
- if (this.isInspectorDismissed || !this.notificationContext.development || !this.isConnected || this.announcementPromise || typeof window === "undefined" || typeof fetch === "undefined") return;
15962
- this.announcementPromise = this.fetchAnnouncement();
16066
+ if (this.isInspectorDismissed || !this.notificationContext.development || !this.isConnected || typeof window === "undefined" || typeof fetch === "undefined") return;
16067
+ this.announcementPromise ??= this.fetchAnnouncement();
16068
+ this.hudFeedPromise ??= this.fetchHudFeed();
16069
+ }
16070
+ async fetchHudFeed() {
16071
+ this.hudFeed = await loadHudFeed();
16072
+ this.refreshHudContent();
16073
+ this.requestUpdate();
16074
+ }
16075
+ /** Overlay the matching feed rule on the built-in HUD content. */
16076
+ refreshHudContent() {
16077
+ this.hudContent = resolveHudContent(this.hudFeed, this.notificationContext, {
16078
+ defaults: HUD_DEFAULT_CONTENT,
16079
+ supportedDestinations: INSPECTOR_MENU_KEYS
16080
+ });
15963
16081
  }
15964
16082
  async fetchAnnouncement() {
15965
16083
  try {