@copilotkit/web-inspector 1.70.0 → 1.70.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
@@ -2,13 +2,13 @@ import generated_default from "./styles/generated.mjs";
2
2
  import inspector_logo_default from "./assets/inspector-logo.mjs";
3
3
  import inspector_logo_kite_default from "./assets/inspector-logo-kite.mjs";
4
4
  import { applyAnchorPosition, centerContext, clampSize, constrainToViewport, keepPositionWithinViewport, updateAnchorFromPosition, updateSizeFromElement } from "./lib/context-helpers.mjs";
5
- import { clearLegacyAnnouncementReadState, isValidAnchor, isValidDockMode, isValidPosition, isValidSize, loadAnnouncementPulsedTimestamp, loadAnnouncementReadTimestamp, loadInspectorState, saveAnnouncementPulsedTimestamp, saveAnnouncementReadTimestamp, saveInspectorState } from "./lib/persistence.mjs";
5
+ import { INSPECTOR_DISMISSAL_MAX_DURATION_MS, clearLegacyAnnouncementReadState, isValidAnchor, isValidDockMode, isValidPosition, isValidSize, loadAnnouncementPulsedTimestamp, loadAnnouncementReadTimestamp, loadInspectorDismissedUntil, loadInspectorState, saveAnnouncementPulsedTimestamp, saveAnnouncementReadTimestamp, saveInspectorDismissedUntil, saveInspectorState } from "./lib/persistence.mjs";
6
6
  import { buildPopOutFeatures, ensureBrandFont, openPopOutWindow } from "./lib/pop-out.mjs";
7
7
  import { projectInspectorMetadata } from "./lib/inspector-metadata.mjs";
8
- import { buildHomeModel, runtimeConnectionNeedsAttention } from "./lib/home-briefing.mjs";
8
+ import { buildHomeModel, homeFeatureImplementationPrompt, runtimeConnectionNeedsAttention } from "./lib/home-briefing.mjs";
9
9
  import { INSPECTOR_GROUPS, INSPECTOR_NAV_SECTIONS, getGroupForMenu, isInspectorMenuKey, shouldUseIconRail } from "./lib/inspector-nav.mjs";
10
10
  import { selectVisibleRealThreadId } from "./lib/thread-selection.mjs";
11
- import { TELEMETRY_DOCS_URL, ensureTelemetryDistinctId, getRuntimeUrlType, getTelemetryDistinctIdForUrl, maybeShowDisclosure, trackErrorSignalViewed, trackHomeCtaClicked, trackHomePromptCopied, trackHomeStoryBeatSelected, trackHomeViewed, trackInspectorOpened, 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";
11
+ import { TELEMETRY_DOCS_URL, ensureTelemetryDistinctId, getRuntimeUrlType, getTelemetryDistinctIdForUrl, maybeShowDisclosure, trackErrorSignalViewed, trackHomeCtaClicked, trackHomeFeaturePromptClicked, trackHomePromptCopied, trackHomeStoryBeatSelected, trackHomeViewed, trackInspectorOpened, 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";
12
12
  import { createOnboardingPrompt, createOnboardingRunId } from "./lib/onboarding-prompt.mjs";
13
13
  import { LitElement, css, html, nothing, render, unsafeCSS } from "lit";
14
14
  import { marked } from "marked";
@@ -111,20 +111,15 @@ const EVENT_ERROR_GUIDANCE = {
111
111
  * an announcement, and it would double the spoken length.
112
112
  */
113
113
  const PILL_SUBLINE_LABEL = "Open Inspector for details";
114
- const HUD_OPEN_INSPECTOR_LABEL = "Open Inspector";
115
- const HUD_THREADS_OFF_LABEL = "Turn on Threads";
116
- const HUD_THREADS_ON_LABEL = "Threads on";
117
- const HUD_INTELLIGENCE_OFF_LABEL = "Turn on Intelligence";
118
- const HUD_INTELLIGENCE_ON_LABEL = "Intelligence connected";
119
- const HUD_THREADS_OFF_DETAIL = "Inspect conversations from this app.";
120
- const HUD_THREADS_ON_DETAIL = "Threads is on. Opens the Threads view.";
121
- const HUD_INTELLIGENCE_OFF_DETAIL = "Connect Intelligence to use Threads and Learning.";
122
- const HUD_INTELLIGENCE_ON_DETAIL = "Intelligence is connected. Opens Home.";
123
- const HUD_LEARNING_OFF_LABEL = "Turn on Learning";
124
- const HUD_LEARNING_ON_LABEL = "Learning on";
125
- const HUD_LEARNING_OFF_DETAIL = "Connect Intelligence to use Learning.";
126
- const HUD_LEARNING_ON_DETAIL = "Learning is on. Opens the Learning view.";
127
- const HUD_OPEN_INSPECTOR_DETAIL = "Same as clicking the circle. Opens the full Inspector.";
114
+ const HUD_INSPECTOR_LABEL = "CopilotKit Inspector";
115
+ const HUD_ANNOUNCEMENT_TITLE_LIMIT = 80;
116
+ const HUD_THREADS_LABEL = "Rich Threads";
117
+ const HUD_LEARNING_LABEL = "Automatic Learning";
118
+ const HUD_LEARN_MORE_LABEL = "Click to learn more";
119
+ const INSPECTOR_DISMISSAL_MS = {
120
+ day: 1440 * 60 * 1e3,
121
+ week: INSPECTOR_DISMISSAL_MAX_DURATION_MS
122
+ };
128
123
  const LAUNCHER_SIGNALS = {
129
124
  "whats-new": {
130
125
  tone: "news",
@@ -242,22 +237,24 @@ const THREAD_LIST_DEBOUNCE_MS = 300;
242
237
  const LAUNCHER_BASE_LABEL = "Web Inspector";
243
238
  const EDGE_MARGIN = 16;
244
239
  /** HUD card plus the hover bridge. Used to pick left vs right. */
245
- const LAUNCHER_HUD_WIDTH = 248;
240
+ const LAUNCHER_HUD_WIDTH = 258;
246
241
  /**
247
242
  * One page-load preview of the launcher's feature HUD.
248
243
  *
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.
244
+ * The card arrives after the host page has had a beat to settle. Its feature
245
+ * contents then arrive from top to bottom, stay readable, and leave together.
246
+ * Nothing is persisted: a new Inspector element means a new preview.
252
247
  */
253
248
  const LAUNCHER_HUD_INTRO_MS = {
254
249
  delay: 500,
255
250
  duration: 3400,
256
- rowStart: 180,
257
- rowStagger: 170,
258
- rowDuration: 300,
251
+ waterfallStart: 180,
252
+ waterfallStagger: 170,
253
+ waterfallDuration: 300,
259
254
  blockedRetry: 250
260
255
  };
256
+ /** Return the staggered reveal delay for one launcher HUD layer. */
257
+ const launcherHudWaterfallDelay = (introIndex) => `${LAUNCHER_HUD_INTRO_MS.waterfallStart + introIndex * LAUNCHER_HUD_INTRO_MS.waterfallStagger}ms`;
261
258
  const DRAG_THRESHOLD = 6;
262
259
  const MIN_WINDOW_WIDTH = 880;
263
260
  const MIN_WINDOW_WIDTH_DOCKED_LEFT = 640;
@@ -286,17 +283,7 @@ function createPlaygroundThreadId() {
286
283
  return globalThis.crypto?.randomUUID?.() ?? `playground-${Date.now()}`;
287
284
  }
288
285
  const THREADS_DOCS_URL = "https://docs.copilotkit.ai/threads";
289
- const THREADS_RUNTIME_SETUP_DOCS_URL = "https://docs.copilotkit.ai/backend/runtime-endpoints#enable-rich-threads-routes";
290
- const THREADS_RUNTIME_SETUP_PROMPT = [
291
- `Read ${THREADS_RUNTIME_SETUP_DOCS_URL} and finish setting up Rich Threads in this repository.`,
292
- "",
293
- "First inspect the repository's agent instructions, installed CopilotKit versions, Runtime adapter, frontend provider, route or proxy setup, and existing authentication. Preserve the current framework and deployment model. Preserve existing authentication middleware and access checks on every Runtime route.",
294
- "",
295
- "Follow the guide to enable the multi-route Runtime, align the frontend transport, scope identifyUser to the existing server-verified signed-in application user, and expose the full Runtime subtree for GET, POST, PATCH, and DELETE. Never use a fixed demo identity in production. If no trusted user identity exists, stop and ask me which auth source to use.",
296
- "",
297
- "Start the app and verify GET {basePath}/info reports threadEndpoints.list, inspect, mutations, and realtimeMetadata as true. Run focused tests, lint, and typecheck. Report the files changed, commands run, and verification result. If blocked, explain the missing input; do not invent setup."
298
- ].join("\n");
299
- const SELF_HOSTED_INTELLIGENCE_URL = "https://docs.copilotkit.ai/premium/self-hosting";
286
+ const SELF_HOSTED_INTELLIGENCE_URL = "https://docs.copilotkit.ai/intelligence/self-hosting";
300
287
  const INTELLIGENCE_STORY_BEATS = [
301
288
  {
302
289
  id: "threads",
@@ -5023,11 +5010,12 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
5023
5010
  this.pillTimeoutId = null;
5024
5011
  this.launcherHudOpen = false;
5025
5012
  this.launcherHudSide = "left";
5026
- this.launcherHudHelp = null;
5027
5013
  this.launcherHudCloseTimer = null;
5028
5014
  this.launcherHudIntro = false;
5029
5015
  this.launcherHudIntroStartTimer = null;
5030
5016
  this.launcherHudIntroEndTimer = null;
5017
+ this.inspectorDismissedUntil = null;
5018
+ this.inspectorDismissalTimer = null;
5031
5019
  this.hudLandingMenu = null;
5032
5020
  this.pillOutcome = null;
5033
5021
  this.viewedNewsSignalIds = /* @__PURE__ */ new Set();
@@ -5055,9 +5043,9 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
5055
5043
  this.threadsExampleOverviewVideoPlayAttemptGeneration = 0;
5056
5044
  this.threadsExampleOverviewVideoPlayPromise = null;
5057
5045
  this.threadsExampleOverviewVideoPlayOnNextBind = false;
5058
- this.threadsSetupPromptCopyState = "idle";
5059
- this.threadsSetupPromptCopyResetTimeoutId = null;
5060
- this.threadsSetupPromptCopyGeneration = 0;
5046
+ this.homeFeaturePromptCopyState = null;
5047
+ this.homeFeaturePromptCopyResetTimeoutId = null;
5048
+ this.homeFeaturePromptCopyGeneration = 0;
5061
5049
  this.contextState = {
5062
5050
  button: {
5063
5051
  position: {
@@ -5103,7 +5091,8 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
5103
5091
  this.customTabIcons = { threads: `<svg class="h-3.5 w-3.5" width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.04167 15C8.29167 15 7.65972 14.7431 7.14583 14.2292C6.63194 13.7153 6.375 13.0972 6.375 12.375C6.375 11.3194 6.80208 10.3646 7.65625 9.51042C8.51042 8.65625 9.57639 8.125 10.8542 7.91667C10.8125 7.41667 10.6875 7.03819 10.4792 6.78125C10.2708 6.52431 9.98611 6.39583 9.625 6.39583C9.20833 6.39583 8.75694 6.56944 8.27083 6.91667C7.78472 7.26389 7.20833 7.83333 6.54167 8.625C5.45833 9.91667 4.66319 10.7569 4.15625 11.1458C3.64931 11.5347 3.10417 11.7292 2.52083 11.7292C1.8125 11.7292 1.21528 11.4653 0.729167 10.9375C0.243056 10.4097 0 9.77083 0 9.02083C0 8.27083 0.163194 7.50347 0.489583 6.71875C0.815972 5.93403 1.36806 4.99306 2.14583 3.89583C2.40972 3.53472 2.60417 3.22917 2.72917 2.97917C2.85417 2.72917 2.91667 2.52778 2.91667 2.375C2.91667 2.27778 2.89931 2.20486 2.86458 2.15625C2.82986 2.10764 2.77778 2.08333 2.70833 2.08333C2.56944 2.08333 2.39583 2.17014 2.1875 2.34375C1.97917 2.51736 1.73611 2.78472 1.45833 3.14583L0 1.66667C0.444444 1.125 0.895833 0.711806 1.35417 0.427083C1.8125 0.142361 2.26389 0 2.70833 0C3.34722 0 3.88889 0.222222 4.33333 0.666667C4.77778 1.11111 5 1.66667 5 2.33333C5 2.73611 4.89583 3.18056 4.6875 3.66667C4.47917 4.15278 4.13194 4.73611 3.64583 5.41667C3.11806 6.16667 2.72569 6.82639 2.46875 7.39583C2.21181 7.96528 2.08333 8.46528 2.08333 8.89583C2.08333 9.13194 2.12153 9.31597 2.19792 9.44792C2.27431 9.57986 2.38194 9.64583 2.52083 9.64583C2.65972 9.64583 2.78125 9.60764 2.88542 9.53125C2.98958 9.45486 3.18056 9.27083 3.45833 8.97917C3.63889 8.78472 3.85417 8.54514 4.10417 8.26042C4.35417 7.97569 4.65972 7.625 5.02083 7.20833C5.89583 6.16667 6.6875 5.42361 7.39583 4.97917C8.10417 4.53472 8.84722 4.3125 9.625 4.3125C10.5556 4.3125 11.3194 4.625 11.9167 5.25C12.5139 5.875 12.8542 6.72917 12.9375 7.8125H15V9.89583H12.9375C12.8264 11.4514 12.4201 12.691 11.7188 13.6146C11.0174 14.5382 10.125 15 9.04167 15ZM9.08333 12.9167C9.52778 12.9167 9.90278 12.6632 10.2083 12.1562C10.5139 11.6493 10.7222 10.9444 10.8333 10.0417C10.1944 10.1944 9.63889 10.4965 9.16667 10.9479C8.69444 11.3993 8.45833 11.8472 8.45833 12.2917C8.45833 12.4861 8.51389 12.6389 8.625 12.75C8.73611 12.8611 8.88889 12.9167 9.08333 12.9167Z" fill="currentColor"/></svg>` };
5104
5092
  this.handleDocumentVisibilityChange = () => {
5105
5093
  this.accountCtaMotionPaused = document.visibilityState !== "visible";
5106
- if (document.visibilityState === "visible" && !this.isOpen) this.flushPendingSignalPulse();
5094
+ this.refreshInspectorDismissalState();
5095
+ if (document.visibilityState === "visible" && !this.isOpen && !this.isInspectorDismissed) this.flushPendingSignalPulse();
5107
5096
  this.requestUpdate();
5108
5097
  };
5109
5098
  this.handlePillClick = (event) => {
@@ -5143,21 +5132,33 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
5143
5132
  this.handleHudActionClick = (event, row) => {
5144
5133
  event.preventDefault();
5145
5134
  event.stopPropagation();
5146
- this.hudLandingMenu = row === "inspector" ? null : row === "threads" ? "threads" : row === "learning" ? "memories" : "home";
5135
+ this.hudLandingMenu = row === "threads" ? "threads" : row === "learning" ? "memories" : "home";
5147
5136
  this.closeLauncherHud();
5148
5137
  this.openInspector("floating_button");
5149
5138
  };
5150
- this.handleHudHelpClick = (event, row) => {
5151
- event.preventDefault();
5152
- event.stopPropagation();
5153
- this.launcherHudHelp = this.launcherHudHelp === row ? null : row;
5154
- this.requestUpdate();
5155
- };
5156
5139
  this.handleHudRowClick = (event, row) => {
5157
5140
  const target = event.target;
5158
- if (target instanceof Element && target.closest(".cpk-launcher-hud__help, [data-cpk-hud-action]")) return;
5141
+ if (target instanceof Element && target.closest(".cpk-launcher-hud__controls, [data-cpk-hud-action]")) return;
5159
5142
  this.handleHudActionClick(event, row);
5160
5143
  };
5144
+ this.handleHudNewsClick = (event) => {
5145
+ event.preventDefault();
5146
+ event.stopPropagation();
5147
+ this.hudLandingMenu = WHATS_NEW_MENU_KEY;
5148
+ this.closeLauncherHud();
5149
+ this.openInspector("floating_button");
5150
+ };
5151
+ this.handleHudNewsDismissClick = (event) => {
5152
+ event.preventDefault();
5153
+ event.stopPropagation();
5154
+ this.clearNewsSignal();
5155
+ this.activeRoot.querySelector(".console-button")?.focus({ preventScroll: true });
5156
+ };
5157
+ this.handleHudDismissDayClick = (event) => {
5158
+ event.preventDefault();
5159
+ event.stopPropagation();
5160
+ this.dismissInspectorFor("day");
5161
+ };
5161
5162
  this.handleSidebarToggle = () => {
5162
5163
  this.sidebarRailTooltip = null;
5163
5164
  this.sidebarCollapsed = !this.sidebarCollapsed;
@@ -5200,6 +5201,31 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
5200
5201
  this.applyEventErrorLanding(key);
5201
5202
  this.requestUpdate();
5202
5203
  };
5204
+ this.handleHomeFeaturePromptCopy = async (service, event) => {
5205
+ const generation = this.homeFeaturePromptCopyGeneration += 1;
5206
+ if (this.homeFeaturePromptCopyResetTimeoutId !== null) {
5207
+ window.clearTimeout(this.homeFeaturePromptCopyResetTimeoutId);
5208
+ this.homeFeaturePromptCopyResetTimeoutId = null;
5209
+ }
5210
+ this.homeFeaturePromptCopyState = null;
5211
+ this.requestUpdate();
5212
+ const onboardingRunId = createOnboardingRunId();
5213
+ if (!this.core?.telemetryDisabled) trackHomeFeaturePromptClicked({
5214
+ feature_id: service.id,
5215
+ onboarding_run_id: onboardingRunId
5216
+ });
5217
+ const clipboard = this.getClipboard(event);
5218
+ if (!clipboard?.writeText) {
5219
+ this.showHomeFeaturePromptCopyState(service.id, "error", generation);
5220
+ return;
5221
+ }
5222
+ try {
5223
+ await clipboard.writeText(homeFeatureImplementationPrompt(service, { onboardingRunId }));
5224
+ this.showHomeFeaturePromptCopyState(service.id, "copied", generation);
5225
+ } catch {
5226
+ this.showHomeFeaturePromptCopyState(service.id, "error", generation);
5227
+ }
5228
+ };
5203
5229
  this.handleIntelligencePromptCopy = async (event) => {
5204
5230
  this.clearIntelligencePromptReset();
5205
5231
  const runId = this.getOnboardingRunId();
@@ -5679,26 +5705,6 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
5679
5705
  }
5680
5706
  this.playThreadsExampleOverviewVideo(video, lifecycleGeneration);
5681
5707
  };
5682
- this.handleThreadsSetupPromptCopy = async (event) => {
5683
- const generation = this.threadsSetupPromptCopyGeneration += 1;
5684
- if (this.threadsSetupPromptCopyResetTimeoutId !== null) {
5685
- window.clearTimeout(this.threadsSetupPromptCopyResetTimeoutId);
5686
- this.threadsSetupPromptCopyResetTimeoutId = null;
5687
- }
5688
- this.threadsSetupPromptCopyState = "idle";
5689
- this.requestUpdate();
5690
- const clipboard = this.getClipboard(event);
5691
- if (!clipboard?.writeText) {
5692
- this.showThreadsSetupPromptCopyState("error", generation);
5693
- return;
5694
- }
5695
- try {
5696
- await clipboard.writeText(THREADS_RUNTIME_SETUP_PROMPT);
5697
- this.showThreadsSetupPromptCopyState("copied", generation);
5698
- } catch {
5699
- this.showThreadsSetupPromptCopyState("error", generation);
5700
- }
5701
- };
5702
5708
  this.handleClearEvents = () => {
5703
5709
  if (this.selectedContext === "all-agents") {
5704
5710
  this.agentEvents.clear();
@@ -6044,9 +6050,6 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
6044
6050
  getThreadsDocsUrl() {
6045
6051
  return this.appendRefParam(THREADS_DOCS_URL, "cpk-inspector-threads");
6046
6052
  }
6047
- getThreadsRuntimeSetupDocsUrl() {
6048
- return this.appendRefParam(THREADS_RUNTIME_SETUP_DOCS_URL, "cpk-inspector-threads");
6049
- }
6050
6053
  getThreadsIntelligenceSignupUrl() {
6051
6054
  return this.appendRefParam(INTELLIGENCE_SIGNUP_URL, "cpk-inspector-threads");
6052
6055
  }
@@ -8095,56 +8098,66 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8095
8098
 
8096
8099
  .cpk-launcher-hud {
8097
8100
  --hud-fill: var(--cpk-inspector-surface-dark);
8098
- --hud-line: rgb(190 194 255 / 0.5);
8101
+ --hud-line: rgb(190 194 255 / 0.38);
8102
+ --hud-accent: #b8adf5;
8103
+ --hud-accent-soft: rgb(184 173 245 / 0.13);
8104
+ --hud-hover-fill: #252231;
8099
8105
  --hud-blur: blur(12px) saturate(1.2);
8106
+ --hud-card-gap: 8px;
8107
+ --hud-dismiss-day-height: 32px;
8100
8108
  position: absolute;
8101
- top: 0;
8102
8109
  z-index: 4;
8103
- padding-right: 14px;
8110
+ width: 258px;
8104
8111
  pointer-events: none;
8105
8112
  opacity: 0;
8106
8113
  visibility: hidden;
8107
- transform: translateX(8px);
8108
8114
  transition:
8109
8115
  opacity 160ms ease,
8110
8116
  transform 200ms cubic-bezier(0.16, 1, 0.3, 1);
8111
8117
  }
8112
8118
 
8119
+ .cpk-launcher-hud[data-cpk-hud-vertical="top"] {
8120
+ top: 0;
8121
+ bottom: auto;
8122
+ }
8123
+
8124
+ .cpk-launcher-hud[data-cpk-hud-vertical="bottom"] {
8125
+ top: auto;
8126
+ bottom: 0;
8127
+ }
8128
+
8113
8129
  .cpk-launcher-hud[data-cpk-hud-side="left"] {
8114
8130
  right: 100%;
8131
+ left: auto;
8115
8132
  padding-right: 14px;
8116
- padding-left: 0;
8133
+ transform: translateX(8px);
8117
8134
  }
8118
8135
 
8119
8136
  .cpk-launcher-hud[data-cpk-hud-side="right"] {
8120
8137
  left: 100%;
8121
8138
  right: auto;
8122
- padding-right: 0;
8123
8139
  padding-left: 14px;
8124
8140
  transform: translateX(-8px);
8125
8141
  }
8126
8142
 
8127
- .console-button-wrapper[data-cpk-hud="open"]
8128
- .cpk-launcher-hud[data-cpk-hud-side="right"] {
8143
+ .console-button-wrapper[data-cpk-hud="open"] .cpk-launcher-hud {
8129
8144
  transform: none;
8130
8145
  }
8131
8146
 
8132
8147
  .cpk-launcher-hud__card {
8133
8148
  position: relative;
8134
- width: 228px;
8135
- padding: 4px;
8136
- border: 1px dotted var(--hud-line);
8137
- border-radius: var(--cpk-inspector-shell-radius);
8138
- background: var(--hud-fill);
8149
+ display: grid;
8150
+ width: 244px;
8151
+ gap: var(--hud-card-gap);
8139
8152
  color: #fff;
8140
- backdrop-filter: var(--hud-blur);
8141
- -webkit-backdrop-filter: var(--hud-blur);
8142
- box-shadow: 0 8px 20px rgb(1 5 7 / 0.18);
8143
8153
  }
8144
8154
 
8145
8155
  .cpk-launcher-hud[data-color-scheme="light"] {
8146
8156
  --hud-fill: #fff;
8147
- --hud-line: #d8d8e8;
8157
+ --hud-line: #ddd6f4;
8158
+ --hud-accent: #6757b0;
8159
+ --hud-accent-soft: #f1edff;
8160
+ --hud-hover-fill: #f1edff;
8148
8161
  }
8149
8162
 
8150
8163
  .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__card {
@@ -8154,23 +8167,47 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8154
8167
  .cpk-launcher-hud__arrow {
8155
8168
  position: absolute;
8156
8169
  top: calc(var(--cpk-launcher-size) / 2);
8157
- z-index: 1;
8170
+ z-index: 2;
8158
8171
  width: 10px;
8159
8172
  height: 10px;
8160
8173
  border: 0;
8161
- /* The card frosts the page behind it, so it reads lighter than the
8162
- raw fill. Mix a little white so the arrow matches the glass card
8163
- without going lighter than the HUD. */
8164
- background: color-mix(in srgb, var(--hud-fill) 88%, white 12%);
8165
- transform: translateY(-50%) rotate(45deg);
8174
+ background: var(--hud-fill);
8175
+ transform: rotate(45deg);
8176
+ transition: background 120ms ease;
8166
8177
  }
8167
8178
 
8168
8179
  .cpk-launcher-hud[data-cpk-hud-side="left"] .cpk-launcher-hud__arrow {
8169
8180
  right: 9px;
8181
+ border-top: 1px solid var(--hud-line);
8182
+ border-right: 1px solid var(--hud-line);
8170
8183
  }
8171
8184
 
8172
8185
  .cpk-launcher-hud[data-cpk-hud-side="right"] .cpk-launcher-hud__arrow {
8173
8186
  left: 9px;
8187
+ border-bottom: 1px solid var(--hud-line);
8188
+ border-left: 1px solid var(--hud-line);
8189
+ }
8190
+
8191
+ .cpk-launcher-hud[data-cpk-hud-vertical="top"] .cpk-launcher-hud__arrow {
8192
+ top: calc(var(--cpk-launcher-size) / 2 - 5px);
8193
+ }
8194
+
8195
+ .cpk-launcher-hud[data-cpk-hud-vertical="bottom"]
8196
+ .cpk-launcher-hud__arrow {
8197
+ top: auto;
8198
+ bottom: calc(var(--cpk-launcher-size) / 2 - 5px);
8199
+ }
8200
+
8201
+ /* A bottom-anchored HUD can end with the narrower dismissal bubble.
8202
+ Keep the pointer attached to the full-width feature panel instead of
8203
+ letting it float in the empty space beside that final action. */
8204
+ .cpk-launcher-hud[data-cpk-hud-vertical="bottom"]:has(
8205
+ .cpk-launcher-hud__dismiss-day
8206
+ )
8207
+ .cpk-launcher-hud__arrow {
8208
+ bottom: calc(
8209
+ var(--hud-dismiss-day-height) + var(--hud-card-gap) + 2px
8210
+ );
8174
8211
  }
8175
8212
 
8176
8213
  .cpk-launcher-hud__list {
@@ -8179,47 +8216,248 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8179
8216
  list-style: none;
8180
8217
  }
8181
8218
 
8182
- .cpk-launcher-hud__list + .cpk-launcher-hud__list {
8183
- margin-top: 4px;
8184
- padding-top: 4px;
8185
- border-top: 1px dotted var(--hud-line);
8219
+ .cpk-launcher-hud__masthead {
8220
+ position: relative;
8221
+ z-index: 1;
8222
+ margin-top: 6px;
8223
+ padding: 0;
8224
+ border: 1px solid var(--hud-line);
8225
+ border-radius: var(--cpk-inspector-shell-radius);
8226
+ background: var(--hud-fill);
8227
+ backdrop-filter: var(--hud-blur);
8228
+ -webkit-backdrop-filter: var(--hud-blur);
8229
+ box-shadow: 0 10px 28px rgb(46 37 91 / 0.16);
8230
+ transition: background 120ms ease;
8231
+ }
8232
+
8233
+ .cpk-launcher-hud__news-wrap {
8234
+ position: relative;
8235
+ margin: 0;
8236
+ }
8237
+
8238
+ .cpk-launcher-hud__news {
8239
+ position: relative;
8240
+ display: flex;
8241
+ width: 100%;
8242
+ min-width: 0;
8243
+ flex-direction: column;
8244
+ align-items: flex-start;
8245
+ padding: 18px 12px 11px;
8246
+ border: 0;
8247
+ border-radius: calc(var(--cpk-inspector-shell-radius) - 1px);
8248
+ background: transparent;
8249
+ color: #fff;
8250
+ font-family: inherit;
8251
+ line-height: 1;
8252
+ text-align: start;
8253
+ cursor: pointer;
8254
+ }
8255
+
8256
+ .cpk-launcher-hud__news:hover,
8257
+ .cpk-launcher-hud__news:focus-visible {
8258
+ background: transparent;
8259
+ }
8260
+
8261
+ .cpk-launcher-hud__masthead:has(.cpk-launcher-hud__news:hover),
8262
+ .cpk-launcher-hud__masthead:has(.cpk-launcher-hud__news:focus-visible),
8263
+ .cpk-launcher-hud:has(.cpk-launcher-hud__news:hover)
8264
+ .cpk-launcher-hud__arrow,
8265
+ .cpk-launcher-hud:has(.cpk-launcher-hud__news:focus-visible)
8266
+ .cpk-launcher-hud__arrow {
8267
+ background: var(--hud-hover-fill);
8268
+ }
8269
+
8270
+ .cpk-launcher-hud__news:focus-visible {
8271
+ outline: 2px solid #bec2ff;
8272
+ outline-offset: 1px;
8273
+ }
8274
+
8275
+ .cpk-launcher-hud__news-title {
8276
+ display: block;
8277
+ font-size: 12px;
8278
+ font-weight: 650;
8279
+ line-height: 1.32;
8280
+ overflow-wrap: anywhere;
8281
+ white-space: normal;
8282
+ }
8283
+
8284
+ .cpk-launcher-hud__news-label {
8285
+ position: absolute;
8286
+ top: -9px;
8287
+ left: 12px;
8288
+ display: inline-flex;
8289
+ min-height: 20px;
8290
+ align-items: center;
8291
+ padding: 3px 8px;
8292
+ border-radius: 6px;
8293
+ background: #7563c7;
8294
+ color: #fff;
8295
+ box-shadow: 0 3px 8px rgb(46 37 91 / 0.18);
8296
+ font-size: 9px;
8297
+ font-weight: 700;
8298
+ line-height: 1;
8299
+ }
8300
+
8301
+ .cpk-launcher-hud__news-dismiss {
8302
+ position: absolute;
8303
+ top: -1px;
8304
+ right: 2px;
8305
+ z-index: 2;
8306
+ display: inline-flex;
8307
+ width: 20px;
8308
+ height: 20px;
8309
+ align-items: center;
8310
+ justify-content: center;
8311
+ padding: 0;
8312
+ border: 0;
8313
+ border-radius: 4px;
8314
+ background: transparent;
8315
+ color: rgb(255 255 255 / 0.68);
8316
+ cursor: pointer;
8317
+ }
8318
+
8319
+ .cpk-launcher-hud__news-dismiss:hover,
8320
+ .cpk-launcher-hud__news-dismiss:focus-visible {
8321
+ background: var(--hud-accent-soft);
8322
+ color: #fff;
8323
+ }
8324
+
8325
+ .cpk-launcher-hud[data-color-scheme="light"]
8326
+ .cpk-launcher-hud__news-dismiss {
8327
+ color: #6e697c;
8328
+ }
8329
+
8330
+ .cpk-launcher-hud[data-color-scheme="light"]
8331
+ .cpk-launcher-hud__news-dismiss:hover,
8332
+ .cpk-launcher-hud[data-color-scheme="light"]
8333
+ .cpk-launcher-hud__news-dismiss:focus-visible {
8334
+ color: #27233a;
8335
+ }
8336
+
8337
+ .cpk-launcher-hud__news-dismiss:focus-visible {
8338
+ outline: 2px solid #bec2ff;
8339
+ outline-offset: 1px;
8340
+ }
8341
+
8342
+ .cpk-launcher-hud__news-dismiss svg {
8343
+ width: 7px;
8344
+ height: 7px;
8345
+ }
8346
+
8347
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__news {
8348
+ color: #17131f;
8349
+ }
8350
+
8351
+ .cpk-launcher-hud__dismiss-day {
8352
+ position: relative;
8353
+ z-index: 1;
8354
+ display: flex;
8355
+ width: auto;
8356
+ min-height: var(--hud-dismiss-day-height);
8357
+ align-items: center;
8358
+ justify-content: center;
8359
+ justify-self: center;
8360
+ gap: 6px;
8361
+ margin: 0;
8362
+ padding: 7px 13px;
8363
+ border: 1px solid var(--hud-line);
8364
+ border-radius: var(--cpk-inspector-shell-radius);
8365
+ background: var(--hud-fill);
8366
+ color: #c9cad3;
8367
+ box-shadow: 0 8px 20px rgb(17 14 29 / 0.18);
8368
+ font-family: inherit;
8369
+ font-size: 10px;
8370
+ font-weight: 650;
8371
+ line-height: 1.2;
8372
+ cursor: pointer;
8373
+ transition:
8374
+ border-color 120ms ease,
8375
+ background 120ms ease,
8376
+ color 120ms ease;
8377
+ }
8378
+
8379
+ .cpk-launcher-hud__dismiss-day:hover,
8380
+ .cpk-launcher-hud__dismiss-day:focus-visible {
8381
+ border-color: var(--hud-accent);
8382
+ background: var(--hud-hover-fill);
8383
+ color: #f3f4f8;
8384
+ }
8385
+
8386
+ .cpk-launcher-hud__dismiss-day:focus-visible {
8387
+ outline: 2px solid #bec2ff;
8388
+ outline-offset: 1px;
8389
+ }
8390
+
8391
+ .cpk-launcher-hud__dismiss-day svg {
8392
+ width: 12px;
8393
+ height: 12px;
8394
+ }
8395
+
8396
+ .cpk-launcher-hud[data-color-scheme="light"]
8397
+ .cpk-launcher-hud__dismiss-day {
8398
+ box-shadow: 0 8px 20px rgb(46 37 91 / 0.12);
8399
+ color: #5f6068;
8400
+ }
8401
+
8402
+ .cpk-launcher-hud[data-color-scheme="light"]
8403
+ .cpk-launcher-hud__dismiss-day:hover,
8404
+ .cpk-launcher-hud[data-color-scheme="light"]
8405
+ .cpk-launcher-hud__dismiss-day:focus-visible {
8406
+ color: #36373d;
8407
+ }
8408
+
8409
+ .cpk-launcher-hud__feature-list {
8410
+ position: relative;
8411
+ z-index: 1;
8412
+ padding: 5px;
8413
+ border: 1px solid var(--hud-line);
8414
+ border-radius: var(--cpk-inspector-shell-radius);
8415
+ background: var(--hud-fill);
8416
+ backdrop-filter: var(--hud-blur);
8417
+ -webkit-backdrop-filter: var(--hud-blur);
8418
+ box-shadow: 0 10px 28px rgb(46 37 91 / 0.16);
8186
8419
  }
8187
8420
 
8188
8421
  .cpk-launcher-hud__row {
8189
8422
  position: relative;
8190
8423
  display: grid;
8191
- grid-template-columns: 1fr 28px;
8192
- align-items: start;
8193
- border-radius: 7px;
8424
+ grid-template-columns: minmax(0, 1fr) auto;
8425
+ align-items: center;
8426
+ min-height: 54px;
8427
+ border-radius: 9px;
8194
8428
  cursor: pointer;
8195
8429
  }
8196
8430
 
8197
8431
  .cpk-launcher-hud__row + .cpk-launcher-hud__row {
8198
- margin-top: 1px;
8432
+ border-top: 1px solid var(--hud-line);
8433
+ border-radius: 0 0 9px 9px;
8199
8434
  }
8200
8435
 
8201
8436
  .cpk-launcher-hud__row:hover,
8202
- .cpk-launcher-hud__row:focus-within,
8203
- .cpk-launcher-hud__row[data-cpk-hud-help="open"] {
8437
+ .cpk-launcher-hud__row:focus-within {
8204
8438
  background: rgb(255 255 255 / 0.06);
8205
8439
  }
8206
8440
 
8207
8441
  .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__row:hover,
8208
- .cpk-launcher-hud[data-color-scheme="light"]
8209
- .cpk-launcher-hud__row:focus-within,
8210
- .cpk-launcher-hud[data-color-scheme="light"]
8211
- .cpk-launcher-hud__row[data-cpk-hud-help="open"] {
8212
- background: #f0f0f4;
8442
+ .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__row:focus-within {
8443
+ background: #f7f5ff;
8444
+ }
8445
+
8446
+ .cpk-launcher-hud__primary {
8447
+ position: relative;
8448
+ display: flex;
8449
+ min-width: 0;
8213
8450
  }
8214
8451
 
8215
8452
  .cpk-launcher-hud__action {
8216
8453
  display: flex;
8454
+ width: 100%;
8217
8455
  gap: 8px;
8218
- min-height: 32px;
8456
+ min-height: 52px;
8219
8457
  align-items: center;
8220
- padding: 6px 8px;
8458
+ padding: 7px 4px;
8221
8459
  border: 0;
8222
- border-radius: 7px;
8460
+ border-radius: 9px;
8223
8461
  background: transparent;
8224
8462
  color: #fff;
8225
8463
  font-family: inherit;
@@ -8229,114 +8467,243 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8229
8467
  cursor: pointer;
8230
8468
  }
8231
8469
 
8470
+ .cpk-launcher-hud__label {
8471
+ min-width: 0;
8472
+ }
8473
+
8474
+ .cpk-launcher-hud__feature-icon {
8475
+ display: inline-flex;
8476
+ width: 28px;
8477
+ height: 32px;
8478
+ flex: none;
8479
+ align-items: center;
8480
+ justify-content: center;
8481
+ background: transparent;
8482
+ color: var(--hud-accent);
8483
+ }
8484
+
8485
+ .cpk-launcher-hud__feature-icon svg {
8486
+ width: 17px;
8487
+ height: 17px;
8488
+ stroke-width: 1.8;
8489
+ }
8490
+
8232
8491
  .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__action {
8233
8492
  color: #010507;
8234
8493
  }
8235
8494
 
8236
- /* Stretch the row action over the whole tab, including the detail
8237
- copy. The help mark sits above this layer. */
8495
+ /* Stretch the row action over the whole tab. The icon controls sit
8496
+ above this layer and keep their own focused interactions. */
8238
8497
  .cpk-launcher-hud__action::after {
8239
8498
  content: "";
8240
8499
  position: absolute;
8241
8500
  inset: 0;
8242
8501
  }
8243
8502
 
8244
- .cpk-launcher-hud__check {
8245
- flex: none;
8246
- width: 14px;
8247
- height: 14px;
8248
- color: #34d399;
8249
- }
8250
-
8251
- .cpk-launcher-hud__help {
8503
+ .cpk-launcher-hud__controls {
8252
8504
  position: relative;
8253
8505
  z-index: 1;
8506
+ display: flex;
8507
+ gap: 0;
8508
+ align-items: center;
8509
+ padding-right: 5px;
8510
+ }
8511
+
8512
+ .cpk-launcher-hud__learn-more {
8254
8513
  display: inline-flex;
8255
- width: 28px;
8256
- height: 32px;
8514
+ width: 24px;
8515
+ height: 44px;
8257
8516
  align-items: center;
8258
8517
  justify-content: center;
8259
8518
  padding: 0;
8260
8519
  border: 0;
8261
8520
  background: transparent;
8262
- color: rgb(255 255 255 / 0.78);
8263
- font-size: 12px;
8264
- font-weight: 600;
8521
+ color: rgb(190 194 255 / 0.72);
8265
8522
  cursor: pointer;
8266
8523
  }
8267
8524
 
8268
- .cpk-launcher-hud__help span {
8269
- display: inline-flex;
8525
+ .cpk-launcher-hud__learn-more:hover,
8526
+ .cpk-launcher-hud__learn-more:focus-visible {
8527
+ color: #fff;
8528
+ }
8529
+
8530
+ .cpk-launcher-hud[data-color-scheme="light"]
8531
+ .cpk-launcher-hud__learn-more {
8532
+ color: #777080;
8533
+ }
8534
+
8535
+ .cpk-launcher-hud[data-color-scheme="light"]
8536
+ .cpk-launcher-hud__learn-more:hover,
8537
+ .cpk-launcher-hud[data-color-scheme="light"]
8538
+ .cpk-launcher-hud__learn-more:focus-visible {
8539
+ color: #4b416b;
8540
+ }
8541
+
8542
+ .cpk-launcher-hud__learn-more svg {
8270
8543
  width: 16px;
8271
8544
  height: 16px;
8545
+ stroke-width: 1.8;
8546
+ }
8547
+
8548
+ .cpk-launcher-hud__toggle {
8549
+ display: inline-flex;
8550
+ width: 38px;
8551
+ height: 44px;
8272
8552
  align-items: center;
8273
8553
  justify-content: center;
8274
- border: 1px dotted rgb(190 194 255 / 0.55);
8554
+ padding: 0;
8555
+ border: 0;
8556
+ background: transparent;
8557
+ color: rgb(255 255 255 / 0.78);
8558
+ font-size: 12px;
8559
+ font-weight: 600;
8560
+ cursor: pointer;
8561
+ }
8562
+
8563
+ .cpk-launcher-hud__toggle:disabled {
8564
+ cursor: not-allowed;
8565
+ opacity: 1;
8566
+ }
8567
+
8568
+ .cpk-launcher-hud__toggle-track {
8569
+ position: relative;
8570
+ display: block;
8571
+ width: 34px;
8572
+ height: 20px;
8573
+ border: 1px solid rgb(190 194 255 / 0.38);
8574
+ border-radius: 999px;
8575
+ background: rgb(255 255 255 / 0.08);
8576
+ transition:
8577
+ border-color 120ms ease,
8578
+ background 120ms ease;
8579
+ }
8580
+
8581
+ .cpk-launcher-hud__toggle-track::after {
8582
+ content: "";
8583
+ position: absolute;
8584
+ top: 2px;
8585
+ left: 2px;
8586
+ width: 14px;
8587
+ height: 14px;
8275
8588
  border-radius: 50%;
8276
- line-height: 1;
8589
+ background: #8c8e99;
8590
+ transition:
8591
+ background 120ms ease,
8592
+ transform 120ms ease;
8277
8593
  }
8278
8594
 
8279
- .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__help {
8280
- color: #68686e;
8595
+ .cpk-launcher-hud__toggle[data-enabled="true"]
8596
+ .cpk-launcher-hud__toggle-track {
8597
+ border-color: var(--hud-accent);
8598
+ background: color-mix(in srgb, var(--hud-accent) 76%, transparent);
8599
+ }
8600
+
8601
+ .cpk-launcher-hud__toggle[data-enabled="true"]
8602
+ .cpk-launcher-hud__toggle-track::after {
8603
+ background: #fff;
8604
+ transform: translateX(14px);
8605
+ }
8606
+
8607
+ .cpk-launcher-hud[data-color-scheme="light"]
8608
+ .cpk-launcher-hud__toggle-track {
8609
+ border-color: #c9c9d2;
8610
+ background: #e7e7ec;
8611
+ }
8612
+
8613
+ .cpk-launcher-hud[data-color-scheme="light"]
8614
+ .cpk-launcher-hud__toggle-track::after {
8615
+ background: #777780;
8616
+ }
8617
+
8618
+ .cpk-launcher-hud[data-color-scheme="light"]
8619
+ .cpk-launcher-hud__toggle[data-enabled="true"]
8620
+ .cpk-launcher-hud__toggle-track {
8621
+ border-color: #6757b0;
8622
+ background: #7563c7;
8623
+ }
8624
+
8625
+ .cpk-launcher-hud[data-color-scheme="light"]
8626
+ .cpk-launcher-hud__toggle[data-enabled="true"]
8627
+ .cpk-launcher-hud__toggle-track::after {
8628
+ background: #fff;
8281
8629
  }
8282
8630
 
8283
- .cpk-launcher-hud__help:focus-visible,
8631
+ .cpk-launcher-hud__toggle:focus-visible,
8632
+ .cpk-launcher-hud__learn-more:focus-visible,
8284
8633
  .cpk-launcher-hud__action:focus-visible {
8285
8634
  outline: 2px solid #bec2ff;
8286
8635
  outline-offset: 1px;
8287
8636
  }
8288
8637
 
8289
- .cpk-launcher-hud__detail {
8290
- grid-column: 1 / -1;
8291
- max-height: 0;
8292
- margin: 0;
8293
- padding: 0 8px;
8294
- overflow: hidden;
8295
- color: rgb(255 255 255 / 0.78);
8296
- font-size: 11px;
8297
- font-weight: 400;
8298
- line-height: 1.4;
8638
+ .cpk-launcher-hud__tooltip {
8639
+ position: absolute;
8640
+ top: 50%;
8641
+ z-index: 30;
8642
+ width: max-content;
8643
+ max-width: min(220px, 52vw);
8644
+ padding: 7px 9px;
8645
+ border: 1px solid #3a3d49;
8646
+ border-radius: 4px;
8647
+ background: #15171e;
8648
+ color: #f3f4f8;
8649
+ box-shadow: 0 8px 20px rgb(1 5 7 / 0.18);
8650
+ font-size: 10px;
8651
+ font-weight: 500;
8652
+ line-height: 1.45;
8299
8653
  opacity: 0;
8300
8654
  pointer-events: none;
8301
- transform: translateY(-6px);
8655
+ transform: translate(3px, -50%);
8656
+ white-space: normal;
8302
8657
  transition:
8303
- max-height 200ms cubic-bezier(0.16, 1, 0.3, 1),
8304
- opacity 150ms ease-out,
8305
- transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
8306
- padding-bottom 200ms cubic-bezier(0.16, 1, 0.3, 1);
8658
+ opacity 120ms ease,
8659
+ transform 120ms ease;
8307
8660
  }
8308
8661
 
8309
- .cpk-launcher-hud[data-color-scheme="light"] .cpk-launcher-hud__detail {
8310
- color: #68686e;
8662
+ .cpk-launcher-hud__row:has(.cpk-launcher-hud__learn-more:hover)
8663
+ .cpk-launcher-hud__tooltip,
8664
+ .cpk-launcher-hud__row:has(.cpk-launcher-hud__learn-more:focus-visible)
8665
+ .cpk-launcher-hud__tooltip {
8666
+ opacity: 1;
8667
+ transform: translate(0, -50%);
8311
8668
  }
8312
8669
 
8313
- .cpk-launcher-hud__row:hover .cpk-launcher-hud__detail,
8314
- .cpk-launcher-hud__row:focus-within .cpk-launcher-hud__detail,
8315
- .cpk-launcher-hud__row[data-cpk-hud-help="open"]
8316
- .cpk-launcher-hud__detail {
8317
- max-height: 72px;
8318
- padding: 0 8px 7px;
8319
- opacity: 1;
8320
- transform: none;
8670
+ .cpk-launcher-hud[data-cpk-hud-side="left"] .cpk-launcher-hud__tooltip {
8671
+ right: calc(100% + 8px);
8672
+ left: auto;
8673
+ }
8674
+
8675
+ .cpk-launcher-hud[data-cpk-hud-side="right"] .cpk-launcher-hud__tooltip {
8676
+ right: auto;
8677
+ left: calc(100% + 8px);
8678
+ transform: translate(-3px, -50%);
8679
+ }
8680
+
8681
+ .cpk-launcher-hud[data-cpk-hud-side="right"]
8682
+ .cpk-launcher-hud__row:has(.cpk-launcher-hud__learn-more:hover)
8683
+ .cpk-launcher-hud__tooltip,
8684
+ .cpk-launcher-hud[data-cpk-hud-side="right"]
8685
+ .cpk-launcher-hud__row:has(.cpk-launcher-hud__learn-more:focus-visible)
8686
+ .cpk-launcher-hud__tooltip {
8687
+ transform: translate(0, -50%);
8321
8688
  }
8322
8689
 
8323
8690
  @media (prefers-reduced-motion: reduce) {
8324
8691
  .cpk-launcher-hud,
8325
- .cpk-launcher-hud__detail {
8692
+ .cpk-launcher-hud__tooltip {
8326
8693
  transition: none;
8327
8694
  }
8328
8695
  }
8329
8696
 
8330
8697
  /*
8331
8698
  * On mount, borrow the hover HUD for one short introduction. The card
8332
- * establishes the destination first; its rows then resolve in order so
8333
- * the eye can count the available features instead of receiving one
8334
- * undifferentiated block. Only opacity and transform move.
8699
+ * establishes the destination first; notification, features, and hide
8700
+ * action then fall into place from top to bottom. Only opacity and
8701
+ * transform move.
8335
8702
  */
8336
8703
  @keyframes cpk-launcher-hud-intro {
8337
8704
  0% {
8338
8705
  opacity: 0;
8339
- transform: translateX(8px);
8706
+ transform: translateY(-4px);
8340
8707
  }
8341
8708
  8%,
8342
8709
  88% {
@@ -8345,30 +8712,14 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8345
8712
  }
8346
8713
  100% {
8347
8714
  opacity: 0;
8348
- transform: translateX(4px);
8715
+ transform: translateY(3px);
8349
8716
  }
8350
8717
  }
8351
8718
 
8352
- @keyframes cpk-launcher-hud-intro-right {
8353
- 0% {
8354
- opacity: 0;
8355
- transform: translateX(-8px);
8356
- }
8357
- 8%,
8358
- 88% {
8359
- opacity: 1;
8360
- transform: none;
8361
- }
8362
- 100% {
8363
- opacity: 0;
8364
- transform: translateX(-4px);
8365
- }
8366
- }
8367
-
8368
- @keyframes cpk-launcher-hud-row-online {
8719
+ @keyframes cpk-launcher-hud-waterfall {
8369
8720
  from {
8370
8721
  opacity: 0;
8371
- transform: translateY(4px);
8722
+ transform: translateY(-8px);
8372
8723
  }
8373
8724
  to {
8374
8725
  opacity: 1;
@@ -8376,43 +8727,33 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8376
8727
  }
8377
8728
  }
8378
8729
 
8379
- @keyframes cpk-launcher-hud-check-online {
8380
- from {
8381
- opacity: 0;
8382
- transform: scale(0.65);
8383
- }
8384
- to {
8385
- opacity: 1;
8386
- transform: scale(1);
8387
- }
8388
- }
8389
-
8390
8730
  .cpk-launcher-hud[data-cpk-hud-intro="true"] {
8391
8731
  animation: cpk-launcher-hud-intro var(--cpk-launcher-hud-intro-duration)
8392
8732
  cubic-bezier(0.16, 1, 0.3, 1) both;
8393
8733
  }
8394
8734
 
8395
- .cpk-launcher-hud[data-cpk-hud-intro="true"][data-cpk-hud-side="right"] {
8396
- animation-name: cpk-launcher-hud-intro-right;
8397
- }
8398
-
8399
- .cpk-launcher-hud[data-cpk-hud-intro="true"] .cpk-launcher-hud__row {
8400
- animation: cpk-launcher-hud-row-online
8401
- var(--cpk-launcher-hud-row-duration) cubic-bezier(0.16, 1, 0.3, 1)
8402
- both;
8403
- animation-delay: var(--cpk-hud-row-delay);
8404
- }
8405
-
8406
- .cpk-launcher-hud[data-cpk-hud-intro="true"] .cpk-launcher-hud__check {
8407
- animation: cpk-launcher-hud-check-online 220ms
8735
+ .cpk-launcher-hud[data-cpk-hud-intro="true"]
8736
+ :is(
8737
+ .cpk-launcher-hud__masthead,
8738
+ .cpk-launcher-hud__feature-list,
8739
+ .cpk-launcher-hud__row,
8740
+ .cpk-launcher-hud__dismiss-day
8741
+ ) {
8742
+ animation: cpk-launcher-hud-waterfall
8743
+ var(--cpk-launcher-hud-waterfall-duration)
8408
8744
  cubic-bezier(0.16, 1, 0.3, 1) both;
8409
- animation-delay: calc(var(--cpk-hud-row-delay) + 90ms);
8745
+ animation-delay: var(--cpk-hud-waterfall-delay);
8410
8746
  }
8411
8747
 
8412
8748
  @media (prefers-reduced-motion: reduce) {
8413
8749
  .cpk-launcher-hud[data-cpk-hud-intro="true"],
8414
- .cpk-launcher-hud[data-cpk-hud-intro="true"] .cpk-launcher-hud__row,
8415
- .cpk-launcher-hud[data-cpk-hud-intro="true"] .cpk-launcher-hud__check {
8750
+ .cpk-launcher-hud[data-cpk-hud-intro="true"]
8751
+ :is(
8752
+ .cpk-launcher-hud__masthead,
8753
+ .cpk-launcher-hud__feature-list,
8754
+ .cpk-launcher-hud__row,
8755
+ .cpk-launcher-hud__dismiss-day
8756
+ ) {
8416
8757
  animation: none !important;
8417
8758
  opacity: 1;
8418
8759
  transform: none;
@@ -8456,15 +8797,15 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8456
8797
  }
8457
8798
 
8458
8799
  .inspector-account-strip {
8459
- background: linear-gradient(
8460
- 90deg,
8461
- #ffffff 0%,
8462
- #f3f1ff 58%,
8463
- #eefbf7 100%
8464
- ) !important;
8800
+ background: #f7f6fd !important;
8465
8801
  color: #010507 !important;
8466
8802
  }
8467
8803
 
8804
+ .inspector-window[data-color-scheme="dark"] .drag-handle,
8805
+ .inspector-window[data-color-scheme="dark"] .inspector-account-strip {
8806
+ background: #15171e !important;
8807
+ }
8808
+
8468
8809
  /* ── Tab buttons ─────────────────────────────────────────────── */
8469
8810
  /*
8470
8811
  * Named classes owned by this component — no Tailwind conflict.
@@ -8827,11 +9168,12 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8827
9168
  const viteHot = import.meta.hot;
8828
9169
  if (viteHot) viteHot.on("vite:beforeUpdate", this.handleAppBeforeUnload);
8829
9170
  this.hydrateStateFromStorageEarly();
9171
+ this.refreshInspectorDismissalState();
8830
9172
  this.subscribeToSystemColorScheme();
8831
9173
  this.exampleTourDismissed = this.readThreadsExampleTourDismissed();
8832
9174
  clearLegacyAnnouncementReadState();
8833
9175
  this.tryAutoAttachCore();
8834
- this.ensureAnnouncementLoading();
9176
+ if (!this.isInspectorDismissed) this.ensureAnnouncementLoading();
8835
9177
  this.subscribeToInspectorThreadBridge();
8836
9178
  }
8837
9179
  this.requestUpdate();
@@ -8859,15 +9201,16 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8859
9201
  this.unsubscribeFromInspectorThreadBridge();
8860
9202
  this.stopIntelligenceStory();
8861
9203
  this.clearIntelligencePromptReset();
8862
- this.threadsSetupPromptCopyGeneration += 1;
8863
- if (this.threadsSetupPromptCopyResetTimeoutId !== null) {
8864
- window.clearTimeout(this.threadsSetupPromptCopyResetTimeoutId);
8865
- this.threadsSetupPromptCopyResetTimeoutId = null;
9204
+ this.homeFeaturePromptCopyGeneration += 1;
9205
+ if (this.homeFeaturePromptCopyResetTimeoutId !== null) {
9206
+ window.clearTimeout(this.homeFeaturePromptCopyResetTimeoutId);
9207
+ this.homeFeaturePromptCopyResetTimeoutId = null;
8866
9208
  }
8867
- this.threadsSetupPromptCopyState = "idle";
9209
+ this.homeFeaturePromptCopyState = null;
8868
9210
  this.stopSignalPulse();
8869
9211
  this.cancelGestureTail();
8870
9212
  this.cancelLauncherHudIntro();
9213
+ this.clearInspectorDismissalTimer();
8871
9214
  this.cancelThreadRefreshDebounce();
8872
9215
  this.clearInspectorUsageRefresh();
8873
9216
  this.cleanupThreadsExampleOverviewVideo();
@@ -8902,11 +9245,13 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8902
9245
  this.applyAnchorPosition("button");
8903
9246
  if (this.dockMode === "floating") if (this.hasCustomPosition.window) this.applyAnchorPosition("window");
8904
9247
  else this.centerContext("window");
8905
- this.ensureAnnouncementLoading();
9248
+ if (this.isInspectorDismissed) this.persistState();
9249
+ else this.ensureAnnouncementLoading();
8906
9250
  this.updateHostTransform(this.isOpen ? "window" : "button");
8907
- this.scheduleLauncherHudIntro();
9251
+ if (!this.isInspectorDismissed) this.scheduleLauncherHudIntro();
8908
9252
  }
8909
9253
  render() {
9254
+ if (this.isInspectorDismissed) return nothing;
8910
9255
  return this.isOpen ? html`
8911
9256
  <div data-inspector-portal-anchor></div>
8912
9257
  ` : this.renderButton();
@@ -8999,7 +9344,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
8999
9344
  aria-expanded=${this.launcherHudOpen ? "true" : "false"}
9000
9345
  aria-controls=${this.launcherHudOpen ? "cpk-launcher-hud" : nothing}
9001
9346
  aria-label=${signal && signal.tone === "error" ? `${LAUNCHER_BASE_LABEL}, ${signal.accessibleLabel}` : LAUNCHER_BASE_LABEL}
9002
- title=${activeSignal === NEWS_SIGNAL_ID ? `${WHATS_NEW_VIEW_LABEL} — unread` : nothing}
9347
+ title=${HUD_INSPECTOR_LABEL}
9003
9348
  data-drag-context="button"
9004
9349
  data-cpk-signal=${signal ? signal.tone : nothing}
9005
9350
  data-cpk-signal-pulsing=${activeSignal !== null && this.pulsingSignal === activeSignal ? "true" : nothing}
@@ -9084,14 +9429,78 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9084
9429
  </span>
9085
9430
  `;
9086
9431
  }
9432
+ /** Whether a persisted temporary dismissal is still active. */
9433
+ get isInspectorDismissed() {
9434
+ return this.inspectorDismissedUntil !== null && this.inspectorDismissedUntil > Date.now();
9435
+ }
9436
+ /** Cancel the timer that restores Inspector after a temporary dismissal. */
9437
+ clearInspectorDismissalTimer() {
9438
+ if (this.inspectorDismissalTimer === null) return;
9439
+ clearTimeout(this.inspectorDismissalTimer);
9440
+ this.inspectorDismissalTimer = null;
9441
+ }
9442
+ /** Schedule Inspector to return just after its persisted deadline. */
9443
+ scheduleInspectorDismissalExpiry() {
9444
+ this.clearInspectorDismissalTimer();
9445
+ if (this.inspectorDismissedUntil === null) return;
9446
+ const delay = Math.max(0, this.inspectorDismissedUntil - Date.now() + 25);
9447
+ this.inspectorDismissalTimer = setTimeout(() => {
9448
+ this.inspectorDismissalTimer = null;
9449
+ this.refreshInspectorDismissalState();
9450
+ }, delay);
9451
+ }
9452
+ /** Reconcile this tab with host-scoped dismissal state from other ports. */
9453
+ refreshInspectorDismissalState() {
9454
+ const hadDismissal = this.inspectorDismissedUntil !== null;
9455
+ this.inspectorDismissedUntil = loadInspectorDismissedUntil();
9456
+ this.clearInspectorDismissalTimer();
9457
+ if (this.inspectorDismissedUntil !== null) {
9458
+ this.closePopOut();
9459
+ this.closeInspector();
9460
+ this.scheduleInspectorDismissalExpiry();
9461
+ if (!hadDismissal) this.requestUpdate();
9462
+ return;
9463
+ }
9464
+ if (!hadDismissal || !this.isConnected) return;
9465
+ this.ensureAnnouncementLoading();
9466
+ this.requestUpdate();
9467
+ this.updateComplete.then(() => {
9468
+ if (!this.isConnected || this.isInspectorDismissed) return;
9469
+ this.measureContext("button");
9470
+ this.applyAnchorPosition("button");
9471
+ this.scheduleLauncherHudIntro();
9472
+ this.flushPendingSignalPulse();
9473
+ });
9474
+ }
9475
+ /** Hide Inspector for a supported duration and persist it for this host. */
9476
+ dismissInspectorFor(duration) {
9477
+ const now = Date.now();
9478
+ const until = now + INSPECTOR_DISMISSAL_MS[duration];
9479
+ saveInspectorDismissedUntil(until, now);
9480
+ this.inspectorDismissedUntil = until;
9481
+ this.scheduleInspectorDismissalExpiry();
9482
+ this.settingsOpen = false;
9483
+ this.closeLauncherHud();
9484
+ this.stopSignalPulse();
9485
+ this.cancelGestureTail();
9486
+ this.cancelLauncherHudIntro();
9487
+ this.closePopOut();
9488
+ if (this.isOpen) {
9489
+ this.closeInspector();
9490
+ return;
9491
+ }
9492
+ this.persistState();
9493
+ this.requestUpdate();
9494
+ }
9087
9495
  isLauncherHudBlocked() {
9088
- return this.gestureSignal !== null;
9496
+ return this.gestureSignal !== null || this.isInspectorDismissed;
9089
9497
  }
9090
9498
  scheduleLauncherHudIntro(delay = LAUNCHER_HUD_INTRO_MS.delay) {
9499
+ if (this.isInspectorDismissed) return;
9091
9500
  if (this.launcherHudIntroStartTimer !== null) clearTimeout(this.launcherHudIntroStartTimer);
9092
9501
  this.launcherHudIntroStartTimer = setTimeout(() => {
9093
9502
  this.launcherHudIntroStartTimer = null;
9094
- if (!this.isConnected || this.isOpen) return;
9503
+ if (!this.isConnected || this.isOpen || this.isInspectorDismissed) return;
9095
9504
  if (this.isLauncherHudBlocked()) {
9096
9505
  this.scheduleLauncherHudIntro(LAUNCHER_HUD_INTRO_MS.blockedRetry);
9097
9506
  return;
@@ -9104,7 +9513,6 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9104
9513
  this.launcherHudIntroEndTimer = null;
9105
9514
  this.launcherHudIntro = false;
9106
9515
  this.launcherHudOpen = false;
9107
- this.launcherHudHelp = null;
9108
9516
  this.requestUpdate();
9109
9517
  }, LAUNCHER_HUD_INTRO_MS.duration);
9110
9518
  }, delay);
@@ -9155,67 +9563,78 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9155
9563
  clearTimeout(this.launcherHudCloseTimer);
9156
9564
  this.launcherHudCloseTimer = null;
9157
9565
  }
9158
- if (!this.launcherHudOpen && this.launcherHudHelp === null) return;
9566
+ if (!this.launcherHudOpen) return;
9159
9567
  this.launcherHudOpen = false;
9160
- this.launcherHudHelp = null;
9161
9568
  this.requestUpdate();
9162
9569
  }
9163
- renderHudCheck() {
9164
- return html`
9165
- <svg
9166
- class="cpk-launcher-hud__check"
9167
- viewBox="0 0 16 16"
9168
- aria-hidden="true"
9169
- focusable="false"
9170
- data-cpk-hud-check
9171
- >
9172
- <path
9173
- fill="none"
9174
- stroke="currentColor"
9175
- stroke-width="2"
9176
- stroke-linecap="round"
9177
- stroke-linejoin="round"
9178
- d="M3 8.5 6.5 12 13 4.5"
9179
- />
9180
- </svg>
9181
- `;
9570
+ getUnreadAnnouncementTitle() {
9571
+ if (!this.newsSignalArmed || !this.announcementLoaded) return null;
9572
+ const title = this.announcementPreviewText?.trim() || "New in CopilotKit";
9573
+ const titleCharacters = Array.from(title);
9574
+ return titleCharacters.length > HUD_ANNOUNCEMENT_TITLE_LIMIT ? `${titleCharacters.slice(0, HUD_ANNOUNCEMENT_TITLE_LIMIT).join("").trimEnd()}...` : title;
9182
9575
  }
9183
9576
  renderHudRow(args) {
9184
- const helpOpen = this.launcherHudHelp === args.id;
9185
9577
  const detailId = `cpk-hud-detail-${args.id}`;
9186
9578
  return html`
9187
9579
  <li
9188
9580
  class="cpk-launcher-hud__row"
9189
9581
  data-cpk-hud-row=${args.id}
9190
- data-cpk-hud-help=${helpOpen ? "open" : nothing}
9191
- style=${styleMap({
9192
- "--cpk-hud-row-index": `${args.introIndex}`,
9193
- "--cpk-hud-row-delay": `${LAUNCHER_HUD_INTRO_MS.rowStart + args.introIndex * LAUNCHER_HUD_INTRO_MS.rowStagger}ms`
9194
- })}
9582
+ data-cpk-hud-action-kind="navigate"
9583
+ style=${styleMap({ "--cpk-hud-waterfall-delay": launcherHudWaterfallDelay(args.introIndex) })}
9195
9584
  @click=${(event) => this.handleHudRowClick(event, args.id)}
9196
9585
  >
9197
- <button
9198
- type="button"
9199
- class="cpk-launcher-hud__action"
9200
- data-cpk-hud-action
9201
- aria-describedby=${detailId}
9202
- @click=${(event) => this.handleHudActionClick(event, args.id)}
9203
- @pointerdown=${(event) => event.stopPropagation()}
9204
- >
9205
- ${args.connected ? this.renderHudCheck() : nothing}${args.label}
9206
- </button>
9207
- <button
9208
- type="button"
9209
- class="cpk-launcher-hud__help"
9210
- aria-expanded=${helpOpen ? "true" : "false"}
9211
- aria-controls=${detailId}
9212
- aria-label=${`About ${args.label}`}
9213
- @click=${(event) => this.handleHudHelpClick(event, args.id)}
9214
- @pointerdown=${(event) => event.stopPropagation()}
9215
- >
9216
- <span aria-hidden="true">?</span>
9217
- </button>
9218
- <p class="cpk-launcher-hud__detail" id=${detailId}>${args.detail}</p>
9586
+ <span class="cpk-launcher-hud__primary">
9587
+ <button
9588
+ type="button"
9589
+ class="cpk-launcher-hud__action"
9590
+ data-cpk-hud-action
9591
+ aria-label=${`Open ${args.label} in Inspector`}
9592
+ @click=${(event) => this.handleHudActionClick(event, args.id)}
9593
+ @pointerdown=${(event) => event.stopPropagation()}
9594
+ >
9595
+ <span
9596
+ class="cpk-launcher-hud__feature-icon"
9597
+ data-cpk-hud-icon=${args.id}
9598
+ aria-hidden="true"
9599
+ >${this.renderIcon(args.icon)}</span
9600
+ >
9601
+ <span class="cpk-launcher-hud__label">${args.label}</span>
9602
+ </button>
9603
+ <span
9604
+ class="cpk-launcher-hud__tooltip"
9605
+ id=${detailId}
9606
+ role="tooltip"
9607
+ >${HUD_LEARN_MORE_LABEL}</span
9608
+ >
9609
+ </span>
9610
+ <span class="cpk-launcher-hud__controls">
9611
+ <button
9612
+ type="button"
9613
+ class="cpk-launcher-hud__learn-more"
9614
+ data-cpk-hud-learn-more=${args.id}
9615
+ aria-label=${`Learn more about ${args.label}`}
9616
+ aria-describedby=${detailId}
9617
+ @click=${(event) => this.handleHudActionClick(event, args.id)}
9618
+ @pointerdown=${(event) => event.stopPropagation()}
9619
+ >
9620
+ ${this.renderIcon("CircleHelp")}
9621
+ </button>
9622
+ <button
9623
+ type="button"
9624
+ class="cpk-launcher-hud__toggle"
9625
+ data-cpk-hud-toggle=${args.id}
9626
+ data-enabled=${args.connected ? "true" : "false"}
9627
+ aria-label=${args.connected ? `${args.label} is enabled` : `Open ${args.label} in Inspector`}
9628
+ ?disabled=${args.connected}
9629
+ @click=${(event) => this.handleHudActionClick(event, args.id)}
9630
+ @pointerdown=${(event) => event.stopPropagation()}
9631
+ >
9632
+ <span
9633
+ class="cpk-launcher-hud__toggle-track"
9634
+ aria-hidden="true"
9635
+ ></span>
9636
+ </button>
9637
+ </span>
9219
9638
  </li>
9220
9639
  `;
9221
9640
  }
@@ -9224,53 +9643,92 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9224
9643
  const homeModel = this.getHomeModel();
9225
9644
  const threadsOn = homeModel.services.some((service) => service.id === "threads" && service.enabled);
9226
9645
  const learningOn = homeModel.services.some((service) => service.id === "memory" && service.enabled);
9227
- const intelligenceOn = homeModel.hero.connection === "connected";
9646
+ const announcementTitle = this.getUnreadAnnouncementTitle();
9647
+ const featureBlockIntroIndex = announcementTitle ? 1 : 0;
9228
9648
  return html`
9229
9649
  <div
9230
9650
  class="cpk-launcher-hud"
9231
9651
  id="cpk-launcher-hud"
9232
9652
  data-cpk-launcher-hud
9233
9653
  data-cpk-hud-side=${this.launcherHudSide}
9654
+ data-cpk-hud-vertical=${this.contextState.button.anchor.vertical}
9234
9655
  data-cpk-hud-intro=${this.launcherHudIntro ? "true" : nothing}
9235
9656
  data-color-scheme=${this.colorScheme}
9236
9657
  style=${styleMap({
9237
9658
  "--cpk-launcher-hud-intro-duration": `${LAUNCHER_HUD_INTRO_MS.duration}ms`,
9238
- "--cpk-launcher-hud-row-duration": `${LAUNCHER_HUD_INTRO_MS.rowDuration}ms`
9659
+ "--cpk-launcher-hud-waterfall-duration": `${LAUNCHER_HUD_INTRO_MS.waterfallDuration}ms`
9239
9660
  })}
9240
9661
  >
9241
9662
  <span class="cpk-launcher-hud__arrow" aria-hidden="true"></span>
9242
9663
  <div class="cpk-launcher-hud__card">
9243
- <ul class="cpk-launcher-hud__list" role="list">
9244
- ${this.renderHudRow({
9245
- id: "inspector",
9246
- label: HUD_OPEN_INSPECTOR_LABEL,
9247
- detail: HUD_OPEN_INSPECTOR_DETAIL,
9248
- introIndex: 0
9249
- })}
9250
- </ul>
9251
- <ul class="cpk-launcher-hud__list" role="list">
9664
+ ${announcementTitle ? html`
9665
+ <div
9666
+ class="cpk-launcher-hud__masthead"
9667
+ style=${styleMap({ "--cpk-hud-waterfall-delay": launcherHudWaterfallDelay(0) })}
9668
+ >
9669
+ <div class="cpk-launcher-hud__news-wrap">
9670
+ <button
9671
+ type="button"
9672
+ class="cpk-launcher-hud__news"
9673
+ data-cpk-hud-news
9674
+ aria-label=${`Open new notification: ${announcementTitle}`}
9675
+ @click=${this.handleHudNewsClick}
9676
+ @pointerdown=${(event) => event.stopPropagation()}
9677
+ >
9678
+ <span
9679
+ class="cpk-launcher-hud__news-label"
9680
+ data-cpk-hud-news-label
9681
+ aria-hidden="true"
9682
+ >New</span
9683
+ >
9684
+ <span class="cpk-launcher-hud__news-title"
9685
+ >${announcementTitle}</span
9686
+ >
9687
+ </button>
9688
+ <button
9689
+ type="button"
9690
+ class="cpk-launcher-hud__news-dismiss"
9691
+ data-cpk-hud-news-dismiss
9692
+ aria-label="Dismiss notification"
9693
+ @click=${this.handleHudNewsDismissClick}
9694
+ @pointerdown=${(event) => event.stopPropagation()}
9695
+ >
9696
+ ${this.renderIcon("X")}
9697
+ </button>
9698
+ </div>
9699
+ </div>
9700
+ ` : nothing}
9701
+ <ul
9702
+ class="cpk-launcher-hud__list cpk-launcher-hud__feature-list"
9703
+ role="list"
9704
+ style=${styleMap({ "--cpk-hud-waterfall-delay": launcherHudWaterfallDelay(featureBlockIntroIndex) })}
9705
+ >
9252
9706
  ${this.renderHudRow({
9253
9707
  id: "threads",
9254
- label: threadsOn ? HUD_THREADS_ON_LABEL : HUD_THREADS_OFF_LABEL,
9255
- detail: threadsOn ? HUD_THREADS_ON_DETAIL : HUD_THREADS_OFF_DETAIL,
9708
+ label: HUD_THREADS_LABEL,
9709
+ icon: "MessageSquare",
9256
9710
  connected: threadsOn,
9257
- introIndex: 1
9258
- })}
9259
- ${this.renderHudRow({
9260
- id: "intelligence",
9261
- label: intelligenceOn ? HUD_INTELLIGENCE_ON_LABEL : HUD_INTELLIGENCE_OFF_LABEL,
9262
- detail: intelligenceOn ? HUD_INTELLIGENCE_ON_DETAIL : HUD_INTELLIGENCE_OFF_DETAIL,
9263
- connected: intelligenceOn,
9264
- introIndex: 2
9711
+ introIndex: featureBlockIntroIndex + 1
9265
9712
  })}
9266
9713
  ${this.renderHudRow({
9267
9714
  id: "learning",
9268
- label: learningOn ? HUD_LEARNING_ON_LABEL : HUD_LEARNING_OFF_LABEL,
9269
- detail: learningOn ? HUD_LEARNING_ON_DETAIL : HUD_LEARNING_OFF_DETAIL,
9715
+ label: HUD_LEARNING_LABEL,
9716
+ icon: "Brain",
9270
9717
  connected: learningOn,
9271
- introIndex: 3
9718
+ introIndex: featureBlockIntroIndex + 2
9272
9719
  })}
9273
9720
  </ul>
9721
+ <button
9722
+ type="button"
9723
+ class="cpk-launcher-hud__dismiss-day"
9724
+ data-cpk-dismiss-inspector="day"
9725
+ style=${styleMap({ "--cpk-hud-waterfall-delay": launcherHudWaterfallDelay(featureBlockIntroIndex + 3) })}
9726
+ @click=${this.handleHudDismissDayClick}
9727
+ @pointerdown=${(event) => event.stopPropagation()}
9728
+ >
9729
+ <span aria-hidden="true">${this.renderIcon("Clock")}</span>
9730
+ Hide Inspector for a day
9731
+ </button>
9274
9732
  </div>
9275
9733
  </div>
9276
9734
  `;
@@ -9491,7 +9949,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9491
9949
  type: lastRuntimeEvent.type,
9492
9950
  timestamp: lastRuntimeEvent.timestamp
9493
9951
  } : void 0,
9494
- memoriesOn: this._memoriesAvailable,
9952
+ memoriesOn: this._memorySubscribed && !this._memoriesLoading && this._memoriesAvailable,
9495
9953
  a2uiOn: this._core?.a2uiEnabled === true,
9496
9954
  openGenUiOn: this._core?.openGenerativeUIEnabled === true,
9497
9955
  suggestionsOn: this._core?.suggestions === true,
@@ -9899,23 +10357,67 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9899
10357
  renderHomeFeatures(model) {
9900
10358
  const enabledServices = model.services.filter((service) => service.enabled);
9901
10359
  const disabledServices = model.services.filter((service) => !service.enabled);
9902
- const renderService = (service) => html`
9903
- <a
10360
+ const renderService = (service) => {
10361
+ const copyState = this.homeFeaturePromptCopyState?.serviceId === service.id ? this.homeFeaturePromptCopyState.state : "idle";
10362
+ const stateDescription = `${service.label} is ${service.enabled ? "enabled in your runtime" : "not enabled in your runtime"}`;
10363
+ const copyLabel = copyState === "copied" ? "Copied" : copyState === "error" ? "Copy failed" : "Copy prompt";
10364
+ const copyTitle = copyLabel;
10365
+ return html`
10366
+ <div
9904
10367
  class="inspector-home-feature"
9905
10368
  data-inspector-service=${service.id}
9906
10369
  data-state=${service.enabled ? "on" : "off"}
9907
- href=${this.appendRefParam(service.docsUrl, "cpk-inspector-home")}
9908
- target="_blank"
9909
- rel="noopener noreferrer"
9910
- aria-label="Learn more about ${service.label}, currently ${service.enabled ? "on" : "off"}"
10370
+ role="listitem"
9911
10371
  >
9912
- <span>${service.label}</span>
9913
- <small>${service.enabled ? "On" : "Off"}</small>
9914
- <span class="inspector-home-feature-arrow" aria-hidden="true">
9915
- ${this.renderIcon("ArrowUpRight")}
10372
+ <span
10373
+ class="inspector-home-feature-status"
10374
+ role="img"
10375
+ aria-label=${stateDescription}
10376
+ title=${stateDescription}
10377
+ >
10378
+ <span aria-hidden="true"></span>
9916
10379
  </span>
9917
- </a>
10380
+ <a
10381
+ class="inspector-home-feature-label"
10382
+ data-inspector-home-feature-docs=${service.id}
10383
+ href=${this.appendRefParam(service.docsUrl, "cpk-inspector-home")}
10384
+ target="_blank"
10385
+ rel="noopener noreferrer"
10386
+ aria-label="Open ${service.label} documentation in a new tab"
10387
+ >
10388
+ <span>${service.label}</span>
10389
+ <span class="inspector-home-feature-label-icon" aria-hidden="true"
10390
+ >${this.renderIcon("ArrowUpRight")}</span
10391
+ >
10392
+ </a>
10393
+ <span class="inspector-home-feature-actions">
10394
+ ${service.enabled ? nothing : html`
10395
+ <button
10396
+ type="button"
10397
+ class="inspector-home-feature-action inspector-system-health-url"
10398
+ data-inspector-home-feature-prompt=${service.id}
10399
+ data-copy-state=${copyState}
10400
+ data-full-value=${copyTitle}
10401
+ aria-label="${copyLabel} for ${service.label}"
10402
+ @click=${(event) => this.handleHomeFeaturePromptCopy(service, event)}
10403
+ >
10404
+ <span class="inspector-home-feature-action-icon" aria-hidden="true"
10405
+ >${this.renderIcon(copyState === "copied" ? "Check" : "Bot")}</span
10406
+ >
10407
+ <span class="inspector-home-feature-action-label"
10408
+ >${copyTitle}</span
10409
+ >
10410
+ </button>
10411
+ `}
10412
+ ${service.enabled ? nothing : html`
10413
+ <span class="sr-only" aria-live="polite">
10414
+ ${copyState === "copied" ? `${service.label} implementation prompt copied.` : copyState === "error" ? `Could not copy the ${service.label} implementation prompt.` : ""}
10415
+ </span>
10416
+ `}
10417
+ </span>
10418
+ </div>
9918
10419
  `;
10420
+ };
9919
10421
  return html`
9920
10422
  <section
9921
10423
  class="inspector-home-section inspector-home-features"
@@ -9924,7 +10426,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9924
10426
  <header class="inspector-home-section-header">
9925
10427
  <h2 class="inspector-home-section-title">Features</h2>
9926
10428
  <span>
9927
- ${enabledServices.length} active, ${disabledServices.length} off
10429
+ ${enabledServices.length} enabled, ${disabledServices.length} available
9928
10430
  </span>
9929
10431
  </header>
9930
10432
  ${model.services.length === 0 ? html`
@@ -9936,13 +10438,13 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9936
10438
  <section
9937
10439
  class="inspector-home-feature-group"
9938
10440
  data-feature-state-group="active"
9939
- aria-label="Active features"
10441
+ aria-label="Enabled features"
9940
10442
  >
9941
10443
  <header class="inspector-home-feature-group-header">
9942
- <strong>Active</strong>
10444
+ <strong>Enabled</strong>
9943
10445
  <span>${enabledServices.length}</span>
9944
10446
  </header>
9945
- <div class="inspector-home-feature-list">
10447
+ <div class="inspector-home-feature-list" role="list">
9946
10448
  ${enabledServices.length > 0 ? enabledServices.map(renderService) : html`
9947
10449
  <p class="inspector-home-feature-group-empty">None enabled</p>
9948
10450
  `}
@@ -9951,13 +10453,13 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9951
10453
  <section
9952
10454
  class="inspector-home-feature-group"
9953
10455
  data-feature-state-group="available"
9954
- aria-label="Available features"
10456
+ aria-label="Features available to add"
9955
10457
  >
9956
10458
  <header class="inspector-home-feature-group-header">
9957
- <strong>Available</strong>
10459
+ <strong>Available to add</strong>
9958
10460
  <span>${disabledServices.length}</span>
9959
10461
  </header>
9960
- <div class="inspector-home-feature-list">
10462
+ <div class="inspector-home-feature-list" role="list">
9961
10463
  ${disabledServices.length > 0 ? disabledServices.map(renderService) : html`
9962
10464
  <p class="inspector-home-feature-group-empty">Everything is active</p>
9963
10465
  `}
@@ -9966,6 +10468,47 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
9966
10468
  </div>
9967
10469
  `}
9968
10470
  </section>
10471
+ `;
10472
+ }
10473
+ showHomeFeaturePromptCopyState(serviceId, state, generation) {
10474
+ if (!this.isConnected || generation !== this.homeFeaturePromptCopyGeneration) return;
10475
+ if (this.homeFeaturePromptCopyResetTimeoutId !== null) window.clearTimeout(this.homeFeaturePromptCopyResetTimeoutId);
10476
+ this.homeFeaturePromptCopyState = {
10477
+ serviceId,
10478
+ state
10479
+ };
10480
+ this.requestUpdate();
10481
+ this.homeFeaturePromptCopyResetTimeoutId = window.setTimeout(() => {
10482
+ if (!this.isConnected || generation !== this.homeFeaturePromptCopyGeneration) return;
10483
+ this.homeFeaturePromptCopyState = null;
10484
+ this.homeFeaturePromptCopyResetTimeoutId = null;
10485
+ this.requestUpdate();
10486
+ }, 2e3);
10487
+ }
10488
+ getHomeFeaturePromptTarget(serviceId) {
10489
+ return this.getHomeModel().services.find((service) => service.id === serviceId);
10490
+ }
10491
+ renderFeatureSetupPrompt(serviceId, className) {
10492
+ const service = this.getHomeFeaturePromptTarget(serviceId);
10493
+ if (!service) return nothing;
10494
+ const copyState = this.homeFeaturePromptCopyState?.serviceId === service.id ? this.homeFeaturePromptCopyState.state : "idle";
10495
+ const label = copyState === "copied" ? "Copied" : copyState === "error" ? "Copy blocked" : "Copy setup prompt";
10496
+ return html`
10497
+ <button
10498
+ type="button"
10499
+ class=${className}
10500
+ data-inspector-feature-setup-prompt=${service.id}
10501
+ data-inspector-threads-setup-prompt=${service.id === "threads" ? "" : nothing}
10502
+ data-copy-state=${copyState}
10503
+ aria-label=${copyState === "copied" ? `${service.label} setup prompt copied` : copyState === "error" ? `Could not copy the ${service.label} setup prompt. Try again` : `Copy setup prompt for ${service.label}`}
10504
+ @click=${(event) => this.handleHomeFeaturePromptCopy(service, event)}
10505
+ >
10506
+ ${this.renderIcon(copyState === "copied" ? "Check" : "Copy")}
10507
+ ${label}
10508
+ </button>
10509
+ <span class="sr-only" aria-live="polite">
10510
+ ${copyState === "copied" ? `${service.label} setup prompt copied.` : copyState === "error" ? `Could not copy the ${service.label} setup prompt.` : ""}
10511
+ </span>
9969
10512
  `;
9970
10513
  }
9971
10514
  handleHomeHeroCta(action) {
@@ -10961,6 +11504,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
10961
11504
  this.draggedDuringInteraction = false;
10962
11505
  }
10963
11506
  openInspector(source, options = {}) {
11507
+ if (this.isInspectorDismissed) return;
10964
11508
  if (options.threadId) this.focusThread(options);
10965
11509
  if (this.isPoppedOut) return;
10966
11510
  if (this.isOpen) return;
@@ -10972,10 +11516,8 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
10972
11516
  this.closeLauncherHud();
10973
11517
  const hudMenu = this.hudLandingMenu;
10974
11518
  this.hudLandingMenu = null;
10975
- if (hudMenu) {
10976
- this.selectedMenu = hudMenu;
10977
- this.lastSelectedMenuByGroup[getGroupForMenu(hudMenu)] = hudMenu;
10978
- } else if (activeSignalAtOpen !== null && source === "floating_button") {
11519
+ if (hudMenu) this.handleMenuSelect(hudMenu);
11520
+ else if (activeSignalAtOpen !== null && source === "floating_button") {
10979
11521
  const landing = LAUNCHER_SIGNALS[activeSignalAtOpen].landingTarget;
10980
11522
  this.selectedMenu = landing;
10981
11523
  this.lastSelectedMenuByGroup[getGroupForMenu(landing)] = landing;
@@ -11849,6 +12391,40 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
11849
12391
  </a>
11850
12392
  </div>
11851
12393
  </section>
12394
+
12395
+ <section
12396
+ class="inspector-settings-section"
12397
+ aria-labelledby="inspector-settings-visibility-title"
12398
+ >
12399
+ <div class="inspector-settings-section-heading">
12400
+ <span class="inspector-settings-section-icon" aria-hidden="true">
12401
+ ${this.renderIcon("EyeOff")}
12402
+ </span>
12403
+ <div>
12404
+ <h2 id="inspector-settings-visibility-title">Visibility</h2>
12405
+ <p>Temporarily hide the Inspector on this domain.</p>
12406
+ </div>
12407
+ </div>
12408
+
12409
+ <div class="inspector-settings-visibility">
12410
+ <div>
12411
+ <h3>Take a break from the Inspector</h3>
12412
+ <p>
12413
+ Hide the Inspector for seven days. It will return automatically
12414
+ when the week is over.
12415
+ </p>
12416
+ </div>
12417
+ <button
12418
+ type="button"
12419
+ class="inspector-settings-dismiss"
12420
+ data-cpk-dismiss-inspector="week"
12421
+ @click=${() => this.dismissInspectorFor("week")}
12422
+ >
12423
+ <span aria-hidden="true">${this.renderIcon("Clock")}</span>
12424
+ Hide Inspector for one week
12425
+ </button>
12426
+ </div>
12427
+ </section>
11852
12428
  </div>
11853
12429
  `;
11854
12430
  }
@@ -12390,19 +12966,6 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
12390
12966
  ` : nothing}
12391
12967
  `;
12392
12968
  }
12393
- /** Show a copy result briefly and announce it to assistive technology. */
12394
- showThreadsSetupPromptCopyState(state, generation) {
12395
- if (!this.isConnected || generation !== this.threadsSetupPromptCopyGeneration) return;
12396
- if (this.threadsSetupPromptCopyResetTimeoutId !== null) window.clearTimeout(this.threadsSetupPromptCopyResetTimeoutId);
12397
- this.threadsSetupPromptCopyState = state;
12398
- this.requestUpdate();
12399
- this.threadsSetupPromptCopyResetTimeoutId = window.setTimeout(() => {
12400
- if (!this.isConnected || generation !== this.threadsSetupPromptCopyGeneration) return;
12401
- this.threadsSetupPromptCopyState = "idle";
12402
- this.threadsSetupPromptCopyResetTimeoutId = null;
12403
- this.requestUpdate();
12404
- }, 2e3);
12405
- }
12406
12969
  renderThreadsExampleOverview(locked) {
12407
12970
  const lockedCopy = locked ? this.getThreadsLockedCopy() : void 0;
12408
12971
  const { lockedAction } = this.inspectorMetadataProjection;
@@ -12420,32 +12983,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
12420
12983
  ${locked ? this.renderRuntimeEntitlementDiagnostic(this.getRuntimeEntitlementDiagnostic()) : nothing}
12421
12984
  <div class="cpk-threads-overview-actions">
12422
12985
  ${locked ? html`
12423
- ${this.inspectorMetadataProjection.licenseState === "valid" ? html`
12424
- <button
12425
- data-inspector-threads-setup-prompt
12426
- type="button"
12427
- aria-label=${this.threadsSetupPromptCopyState === "copied" ? "Setup prompt copied" : this.threadsSetupPromptCopyState === "error" ? "Copy setup prompt failed. Try again" : "Copy setup prompt for your coding agent"}
12428
- @click=${this.handleThreadsSetupPromptCopy}
12429
- >
12430
- ${this.renderIcon(this.threadsSetupPromptCopyState === "copied" ? "Check" : "Copy")}
12431
- ${this.threadsSetupPromptCopyState === "copied" ? "Copied" : this.threadsSetupPromptCopyState === "error" ? "Copy blocked" : "Copy prompt for your agent"}
12432
- </button>
12433
- <a
12434
- data-inspector-threads-setup-link
12435
- href=${this.getThreadsRuntimeSetupDocsUrl()}
12436
- target="_blank"
12437
- rel="noopener"
12438
- aria-label="Open setup guide (opens in a new tab)"
12439
- >
12440
- Open setup guide
12441
- </a>
12442
- <span
12443
- class="sr-only"
12444
- data-inspector-threads-setup-copy-status
12445
- aria-live="polite"
12446
- >${this.threadsSetupPromptCopyState === "copied" ? "Setup prompt copied." : this.threadsSetupPromptCopyState === "error" ? "Setup prompt copy failed. Open the setup guide and copy it manually." : ""}</span
12447
- >
12448
- ` : nothing}
12986
+ ${this.renderFeatureSetupPrompt("threads", "cpk-threads-overview-action cpk-threads-overview-action-primary")}
12449
12987
  ${lockedAction ? this.renderInspectorAction(lockedAction, "locked") : nothing}
12450
12988
  ` : html`
12451
12989
  <a
@@ -12698,7 +13236,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
12698
13236
  `;
12699
13237
  }
12700
13238
  renderMemoriesView() {
12701
- if (!this.core?.intelligence || !this._memoriesAvailable) return html`
13239
+ if (!this.getHomeModel().services.some((service) => service.id === "memory" && service.enabled)) return html`
12702
13240
  <div class="cpk-memory-locked">
12703
13241
  ${this.renderThreadsLockedBackgroundMockup()}
12704
13242
  <div aria-hidden="true" class="cpk-memory-locked-scrim"></div>
@@ -12713,6 +13251,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
12713
13251
  ${this._memoryStoreUnsupported ? "Learning is unavailable in this version of the @copilotkit SDK. Upgrade @copilotkit/core (and @copilotkit/react) to a version that supports long-term memory." : "Learning turns durable information from agent interactions into reusable context. It isn't enabled on this deployment."}
12714
13252
  </p>
12715
13253
  <div class="cpk-memory-locked-actions">
13254
+ ${this.renderFeatureSetupPrompt("memory", "cpk-memory-locked-action")}
12716
13255
  <a
12717
13256
  href=${this.getTalkToEngineerUrl()}
12718
13257
  target="_blank"
@@ -14509,12 +15048,12 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
14509
15048
  /**
14510
15049
  * Requests one beat for a signal, running it now or deferring it.
14511
15050
  *
14512
- * There is a single pending slot and four reasons a beat cannot land. All
14513
- * four are the same situation — "cannot land now, run later" — and treating
15051
+ * There is a single pending slot and five reasons a beat cannot land. All
15052
+ * five are the same situation — "cannot land now, run later" — and treating
14514
15053
  * them alike is the point: three separate behaviours for one situation would
14515
15054
  * not survive a third signal.
14516
15055
  *
14517
- * Reason 3 is not cosmetic. Starting a beat while one runs does not restart
15056
+ * Reason 4 is not cosmetic. Starting a beat while one runs does not restart
14518
15057
  * the animation, because the attribute it binds to does not change value and
14519
15058
  * the pseudo-element selectors match on attribute *presence*; the running
14520
15059
  * beat would merely change colour mid-flight. A failure that arms during an
@@ -14523,11 +15062,11 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
14523
15062
  *
14524
15063
  * A failure's beat is followed by a pill, and the whole 3.4-second gesture
14525
15064
  * holds this one slot for its full duration. That is not a second scheduling
14526
- * concept: reason 3 already says "another beat is running", and a gesture is
15065
+ * concept: reason 4 already says "another beat is running", and a gesture is
14527
15066
  * simply a longer beat.
14528
15067
  */
14529
15068
  startSignalPulse(key) {
14530
- if (this.isOpen || typeof document !== "undefined" && document.visibilityState !== "visible" || this.gestureSlotSignal !== null && this.gestureSlotSignal !== key || this.getActiveLauncherSignal() !== key) {
15069
+ if (this.isOpen || this.isInspectorDismissed || typeof document !== "undefined" && document.visibilityState !== "visible" || this.gestureSlotSignal !== null && this.gestureSlotSignal !== key || this.getActiveLauncherSignal() !== key) {
14531
15070
  const pending = this.pendingPulseSignal;
14532
15071
  if (pending === null || LAUNCHER_SIGNALS[key].priority >= LAUNCHER_SIGNALS[pending].priority) this.pendingPulseSignal = key;
14533
15072
  this.requestUpdate();
@@ -14592,7 +15131,7 @@ var WebInspectorElement = class WebInspectorElement extends LitElement {
14592
15131
  }
14593
15132
  /**
14594
15133
  * The signal holding the single gesture slot: a beat in flight, or the pill
14595
- * and spoken sentence that follow it. One slot, not two — see reason 3 in
15134
+ * and spoken sentence that follow it. One slot, not two — see reason 4 in
14596
15135
  * `startSignalPulse`.
14597
15136
  */
14598
15137
  get gestureSlotSignal() {