@copilotkit/web-inspector 1.70.3 → 1.71.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.
@@ -1 +1 @@
1
- {"version":3,"file":"learning-view.mjs","names":[],"sources":["../../src/components/learning-view.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport type {\n InspectorLearningInsight,\n InspectorLearningSnapshotV1,\n} from \"@copilotkit/shared\";\n\nexport type LearningViewState =\n | \"loading\"\n | \"error\"\n | \"selection_required\"\n | \"invalid\"\n | \"results\"\n | \"first_run\"\n | \"ready\"\n | \"empty\"\n | \"setup\"\n | \"landing\";\n\nexport function deriveLearningViewState(input: {\n readonly supported: boolean;\n readonly loading: boolean;\n readonly error: string | null;\n readonly snapshot: InspectorLearningSnapshotV1 | null;\n readonly setupActive: boolean;\n}): LearningViewState {\n // A Runtime that has not opted into Learning is still a valid product\n // onboarding state. The parent Inspector renders the Learning preview for\n // `landing`; after the setup prompt is copied, keep the user in the setup\n // flow while the Runtime is updated and reconnects.\n if (!input.supported) return input.setupActive ? \"setup\" : \"landing\";\n if (!input.snapshot && input.loading) return \"loading\";\n if (!input.snapshot && input.error) return \"error\";\n const snapshot = input.snapshot;\n if (!snapshot) return \"loading\";\n if (snapshot.configuration.state === \"selection_required\")\n return \"selection_required\";\n if (snapshot.configuration.state === \"invalid\") return \"invalid\";\n const hasResults =\n snapshot.skillsPage.total > 0 || snapshot.insightsPage.total > 0;\n if (hasResults || snapshot.pendingCandidateCount > 0) return \"results\";\n if (snapshot.run.hasActiveRun) return \"first_run\";\n if (snapshot.run.hasEverSucceeded && snapshot.pendingThreadCount === 0)\n return \"empty\";\n if (\n snapshot.configuration.state === \"configured\" &&\n snapshot.pendingThreadCount > 0\n )\n return \"ready\";\n if (input.setupActive || snapshot.configuration.state === \"configured\")\n return \"setup\";\n return \"landing\";\n}\n\nexport class CpkLearningView extends LitElement {\n static properties = {\n supported: { type: Boolean },\n loading: { type: Boolean },\n refreshing: { type: Boolean },\n error: { attribute: false },\n snapshot: { attribute: false },\n setupActive: { type: Boolean },\n copyState: { attribute: false },\n setupPrompt: { attribute: false },\n };\n\n supported = false;\n loading = false;\n refreshing = false;\n error: string | null = null;\n snapshot: InspectorLearningSnapshotV1 | null = null;\n setupActive = false;\n copyState: \"idle\" | \"copied\" | \"error\" = \"idle\";\n setupPrompt = \"\";\n private promptOpen = false;\n private promptTrigger: HTMLElement | null = null;\n private expandedSkillId: string | null = null;\n private selectedInsightId: string | null = null;\n private skillPageKey = \"\";\n\n static styles = css`\n :host {\n --learning-ink: #202127;\n --learning-muted: #64656f;\n --learning-muted-strong: #858690;\n --learning-line: #dcdce4;\n --learning-line-secondary: #cfcfd7;\n --learning-line-accent: #dcd9ff;\n --learning-soft: #f7f7fa;\n --learning-canvas: #fff;\n --learning-surface: #fff;\n --learning-surface-subtle: #fbfbfd;\n --learning-surface-muted: #f8f8fb;\n --learning-surface-hover: #fafaff;\n --learning-purple: #7567ff;\n --learning-purple-dark: #5549e8;\n --learning-soft-purple: #f0edff;\n --learning-purple-border: #cfc8ff;\n --learning-green: #168b69;\n --learning-soft-green: #f7fbf9;\n --learning-green-border: #b9dfd1;\n --learning-soft-danger: #fff4f4;\n --learning-soft-danger-alt: #fff8f8;\n --learning-danger: #7e2929;\n --learning-danger-muted: #8c4a4a;\n --learning-danger-border: #efc7c7;\n --learning-danger-step-border: #d96a6a;\n --learning-track: #e9edf5;\n --learning-step-number: #edf0f5;\n --learning-step-number-ink: #555661;\n --learning-primary: #202127;\n --learning-primary-ink: #fff;\n --learning-secondary: #fff;\n --learning-secondary-ink: #31323a;\n --learning-disabled: #e5e5ea;\n --learning-disabled-ink: #9a9ba3;\n --learning-on-accent: #fff;\n --learning-outcome: #888993;\n --learning-outcome-dash: #cfd0d8;\n --learning-outcome-arrow: #b0b1b9;\n --learning-code: #34353d;\n --learning-dialog-line: #d9d9e1;\n --learning-skeleton-edge: #eeeef2;\n --learning-skeleton-center: #f8f8fa;\n display: block;\n height: 100%;\n overflow: auto;\n color: var(--learning-ink);\n background: var(--learning-canvas);\n font-family: Inter, ui-sans-serif, system-ui, sans-serif;\n }\n :host([data-color-scheme=\"dark\"]) {\n color-scheme: dark;\n --learning-ink: #f3f4f8;\n --learning-muted: #b0b3be;\n --learning-muted-strong: #b8bbc5;\n --learning-line: #3a3e4b;\n --learning-line-secondary: #4c5161;\n --learning-line-accent: #625f95;\n --learning-soft: #20232d;\n --learning-canvas: #15171e;\n --learning-surface: #1a1d25;\n --learning-surface-subtle: #1d2029;\n --learning-surface-muted: #20232d;\n --learning-surface-hover: #252837;\n --learning-purple: #a296ff;\n --learning-purple-dark: #c4baff;\n --learning-soft-purple: #2a2940;\n --learning-purple-border: #625f95;\n --learning-green: #4dc69d;\n --learning-soft-green: #172923;\n --learning-green-border: #28604d;\n --learning-soft-danger: #321f25;\n --learning-soft-danger-alt: #2d2026;\n --learning-danger: #ffabab;\n --learning-danger-muted: #f2b5ba;\n --learning-danger-border: #7a424e;\n --learning-danger-step-border: #a95464;\n --learning-track: #303440;\n --learning-step-number: #303440;\n --learning-step-number-ink: #d8dae4;\n --learning-primary: #f3f4f8;\n --learning-primary-ink: #16181f;\n --learning-secondary: #20232d;\n --learning-secondary-ink: #edf0f6;\n --learning-disabled: #363a46;\n --learning-disabled-ink: #a4a8b5;\n --learning-on-accent: #171920;\n --learning-outcome: #b0b3be;\n --learning-outcome-dash: #545969;\n --learning-outcome-arrow: #858a99;\n --learning-code: #e2e4ec;\n --learning-dialog-line: #484c5a;\n --learning-skeleton-edge: #2a2d38;\n --learning-skeleton-center: #333744;\n }\n * {\n box-sizing: border-box;\n }\n button,\n a,\n summary {\n font: inherit;\n }\n button:focus-visible,\n a:focus-visible,\n summary:focus-visible {\n outline: 2px solid var(--learning-purple);\n outline-offset: 2px;\n }\n .pane-inner {\n max-width: 880px;\n min-height: 100%;\n margin: 0 auto;\n padding: 32px 36px 70px;\n }\n .pane-heading {\n display: flex;\n align-items: start;\n justify-content: space-between;\n gap: 24px;\n margin-bottom: 24px;\n }\n .pane-heading h1 {\n margin: 0 0 7px;\n font-size: 25px;\n line-height: 1.2;\n letter-spacing: -0.035em;\n }\n .pane-heading p {\n max-width: 630px;\n margin: 0;\n color: var(--learning-muted);\n font-size: 14px;\n line-height: 1.5;\n }\n .refreshing {\n color: var(--learning-muted-strong);\n font-size: 11px;\n }\n .setup-card,\n .analysis-card,\n .content-card {\n border: 1px solid var(--learning-line);\n border-radius: 10px;\n background: var(--learning-surface);\n }\n .setup-card {\n padding: 24px;\n background: var(--learning-surface-subtle);\n }\n .setup-top {\n display: flex;\n align-items: start;\n justify-content: space-between;\n gap: 20px;\n }\n .setup-top h2,\n .analysis-card h2 {\n margin: 0;\n font-size: 19px;\n line-height: 1.25;\n letter-spacing: -0.02em;\n }\n .progress-count {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 13px;\n font-weight: 750;\n white-space: nowrap;\n }\n .progress-track {\n height: 8px;\n margin: 20px 0 18px;\n overflow: hidden;\n background: var(--learning-track);\n border-radius: 999px;\n }\n .progress-fill {\n height: 100%;\n background: var(--learning-purple);\n border-radius: inherit;\n }\n .steps {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 10px;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n .step {\n min-height: 142px;\n padding: 15px;\n background: var(--learning-surface);\n border: 1px solid var(--learning-line);\n border-radius: 8px;\n }\n .step.current {\n background: var(--learning-soft-purple);\n border-color: var(--learning-purple);\n }\n .step.error {\n background: var(--learning-soft-danger);\n border-color: var(--learning-danger-step-border);\n }\n .step.complete {\n background: var(--learning-soft-green);\n border-color: var(--learning-green-border);\n }\n .step-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 18px;\n }\n .step-number {\n display: grid;\n place-items: center;\n width: 26px;\n height: 26px;\n color: var(--learning-step-number-ink);\n background: var(--learning-step-number);\n border-radius: 50%;\n font-size: 12px;\n font-weight: 800;\n }\n .step.current .step-number {\n color: var(--learning-on-accent);\n background: var(--learning-purple);\n }\n .step.complete .step-number {\n color: var(--learning-on-accent);\n background: var(--learning-green);\n }\n .step-state {\n color: var(--learning-danger);\n font-size: 9px;\n font-weight: 850;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n }\n .step h3 {\n margin: 0 0 7px;\n font-size: 14px;\n }\n .step p {\n margin: 0;\n color: var(--learning-muted);\n font-size: 12px;\n line-height: 1.45;\n }\n .setup-support {\n margin-top: 14px;\n }\n .collection-panel {\n padding: 15px;\n background: var(--learning-surface);\n border: 1px solid var(--learning-line);\n border-radius: 8px;\n }\n .support-heading {\n margin-bottom: 12px;\n }\n .support-heading h3 {\n margin: 0;\n font-size: 13px;\n }\n .error-alert {\n margin-bottom: 10px;\n padding: 11px 12px;\n color: var(--learning-danger);\n background: var(--learning-soft-danger);\n border: 1px solid var(--learning-danger-border);\n border-radius: 6px;\n }\n .error-alert p {\n margin: 0;\n color: var(--learning-danger-muted);\n font-size: 11px;\n line-height: 1.45;\n }\n .prompt-link {\n display: inline-block;\n margin-top: 7px;\n padding: 0;\n color: var(--learning-danger);\n background: none;\n border: 0;\n font-size: 11px;\n font-weight: 750;\n text-decoration: underline;\n cursor: pointer;\n }\n .collection-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 10px;\n background: var(--learning-soft);\n border-radius: 6px;\n }\n .collection-stat {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 9px;\n }\n .captured-count {\n color: var(--learning-ink);\n font-size: 28px;\n line-height: 1;\n }\n .collection-stat span {\n font-size: 12px;\n font-weight: 700;\n }\n .technical-details {\n margin-top: 10px;\n color: var(--learning-muted);\n font-size: 10px;\n }\n .technical-details summary {\n cursor: pointer;\n font-weight: 700;\n }\n .technical-details dl {\n display: grid;\n grid-template-columns: auto 1fr;\n gap: 5px 12px;\n margin: 9px 0 0;\n padding: 10px;\n background: var(--learning-soft);\n border-radius: 5px;\n }\n .technical-details dt {\n color: var(--learning-muted-strong);\n }\n .technical-details dd {\n margin: 0;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n overflow-wrap: anywhere;\n }\n .primary,\n .secondary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-height: 36px;\n padding: 0 14px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 750;\n text-decoration: none;\n cursor: pointer;\n }\n .primary {\n color: var(--learning-primary-ink);\n background: var(--learning-primary);\n border: 1px solid var(--learning-primary);\n }\n .secondary {\n color: var(--learning-secondary-ink);\n background: var(--learning-secondary);\n border: 1px solid var(--learning-line-secondary);\n }\n .primary:disabled,\n .primary[aria-disabled=\"true\"] {\n color: var(--learning-disabled-ink);\n background: var(--learning-disabled);\n border-color: var(--learning-disabled);\n cursor: not-allowed;\n pointer-events: none;\n }\n .setup-cta:not(:disabled),\n .results-cta {\n min-width: 170px;\n min-height: 40px;\n padding: 0 18px;\n box-shadow: 0 6px 14px rgba(23, 23, 27, 0.2);\n }\n .outcome-preview {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n margin-top: 16px;\n color: var(--learning-outcome);\n font-size: 11px;\n }\n .outcome-preview span {\n padding: 6px 9px;\n background: var(--learning-surface);\n border: 1px dashed var(--learning-outcome-dash);\n border-radius: 5px;\n }\n .outcome-preview b {\n color: var(--learning-outcome-arrow);\n }\n .analysis-card {\n padding: 18px 20px;\n background: var(--learning-surface-muted);\n }\n .analysis-card.ready {\n background: var(--learning-soft-purple);\n border-color: var(--learning-purple-border);\n }\n .analysis-card.error {\n background: var(--learning-soft-danger-alt);\n border-color: var(--learning-danger-border);\n }\n .analysis-row {\n display: flex;\n align-items: center;\n gap: 20px;\n }\n .analysis-copy {\n flex: 1;\n }\n .analysis-card h2 {\n margin-bottom: 7px;\n }\n .analysis-card p {\n margin: 0;\n color: var(--learning-muted);\n font-size: 13px;\n line-height: 1.5;\n }\n .eyebrow {\n margin: 0 0 6px !important;\n color: var(--learning-purple-dark) !important;\n font-size: 10px !important;\n font-weight: 850;\n letter-spacing: 0.09em;\n text-transform: uppercase;\n }\n .retry-strip {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 12px;\n padding: 11px 12px;\n color: var(--learning-danger);\n background: var(--learning-soft-danger);\n border: 1px solid var(--learning-danger-border);\n border-radius: 6px;\n font-size: 11px;\n }\n .result-section {\n margin-top: 14px;\n }\n .result-section-heading {\n display: flex;\n align-items: baseline;\n gap: 6px;\n margin-bottom: 10px;\n }\n .result-section-heading h2 {\n margin: 0;\n font-size: 14px;\n }\n .result-count {\n color: var(--learning-muted-strong);\n font-size: 10px;\n font-weight: 700;\n }\n .review-link {\n margin-left: auto;\n color: var(--learning-purple-dark);\n font-size: 11px;\n font-weight: 750;\n text-decoration: none;\n }\n .quiet-link {\n display: inline-flex;\n margin-top: 12px;\n color: var(--learning-purple-dark);\n font-size: 11px;\n font-weight: 750;\n text-decoration: none;\n }\n .quiet-link:hover,\n .review-link:hover {\n text-decoration: underline;\n }\n .content-card {\n overflow: hidden;\n }\n .empty-card {\n padding: 24px;\n color: var(--learning-muted);\n background: var(--learning-surface-subtle);\n border: 1px solid var(--learning-line);\n border-radius: 8px;\n }\n .empty-card.compact {\n padding: 15px 16px;\n }\n .empty-card h3 {\n margin: 0 0 6px;\n color: var(--learning-ink);\n font-size: 14px;\n }\n .empty-card p {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n }\n .active-skill {\n padding: 16px;\n }\n .active-skill + .active-skill {\n border-top: 1px solid var(--learning-line);\n }\n .active-skill h3 {\n margin: 0 0 6px;\n font-size: 14px;\n }\n .active-skill > p {\n margin: 0;\n color: var(--learning-muted);\n font-size: 12px;\n line-height: 1.45;\n }\n .skill-lineage {\n margin-top: 10px;\n padding: 10px 12px;\n background: var(--learning-surface-muted);\n border: 1px solid var(--learning-line);\n border-radius: 6px;\n }\n .skill-lineage > span {\n display: block;\n margin-bottom: 5px;\n color: var(--learning-muted-strong);\n font-size: 9px;\n font-weight: 800;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n }\n .skill-lineage button {\n display: flex;\n width: 100%;\n align-items: start;\n justify-content: space-between;\n gap: 14px;\n padding: 0;\n color: var(--learning-ink);\n background: none;\n border: 0;\n text-align: left;\n font-size: 11px;\n font-weight: 700;\n line-height: 1.4;\n cursor: pointer;\n }\n .skill-lineage button small {\n flex: 0 0 auto;\n color: var(--learning-purple-dark);\n font-size: 10px;\n font-weight: 750;\n }\n .supporting-unavailable {\n color: var(--learning-muted-strong);\n font-size: 11px;\n font-style: italic;\n }\n .skill-source {\n margin-top: 10px;\n }\n .skill-source summary {\n width: fit-content;\n color: var(--learning-purple-dark);\n cursor: pointer;\n font-size: 11px;\n font-weight: 750;\n }\n .skill-source pre {\n margin: 10px 0 0;\n padding: 12px;\n color: var(--learning-code);\n background: var(--learning-soft);\n border: 1px solid var(--learning-line);\n border-radius: 6px;\n font:\n 11px/1.5 ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n .list-header {\n display: flex;\n align-items: center;\n padding: 10px 14px;\n color: var(--learning-muted-strong);\n background: var(--learning-surface-muted);\n border-bottom: 1px solid var(--learning-line);\n font-size: 10px;\n font-weight: 800;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n }\n .list-header span:last-child {\n margin-left: auto;\n }\n .insight-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 18px;\n width: 100%;\n padding: 16px;\n color: inherit;\n background: var(--learning-surface);\n border: 0;\n border-bottom: 1px solid var(--learning-line);\n text-align: left;\n cursor: pointer;\n }\n .insight-row:last-child {\n border-bottom: 0;\n }\n .insight-row:hover,\n .insight-row[data-selected=\"true\"] {\n background: var(--learning-surface-hover);\n }\n .insight-row h3 {\n margin: 0 0 6px;\n font-size: 14px;\n line-height: 1.35;\n }\n .insight-row p {\n margin: 0;\n color: var(--learning-muted);\n font-size: 12px;\n line-height: 1.45;\n }\n .evidence-count {\n min-width: 90px;\n color: var(--learning-purple-dark);\n font-size: 11px;\n font-weight: 750;\n text-align: right;\n }\n .detail-panel {\n margin-top: 14px;\n padding: 18px;\n background: var(--learning-surface-hover);\n border: 1px solid var(--learning-line-accent);\n border-radius: 8px;\n }\n .detail-head {\n display: flex;\n align-items: start;\n gap: 14px;\n }\n .detail-head div {\n flex: 1;\n }\n .detail-head h3 {\n margin: 0 0 5px;\n font-size: 14px;\n }\n .detail-head p {\n margin: 0;\n color: var(--learning-muted);\n font-size: 12px;\n line-height: 1.45;\n }\n .close-detail {\n width: 28px;\n height: 28px;\n color: var(--learning-muted);\n background: var(--learning-surface);\n border: 1px solid var(--learning-line);\n border-radius: 5px;\n cursor: pointer;\n }\n .evidence-list {\n display: grid;\n gap: 7px;\n margin-top: 14px;\n }\n .evidence-link,\n .evidence-unavailable {\n display: flex;\n align-items: center;\n gap: 10px;\n min-height: 38px;\n padding: 10px;\n color: var(--learning-code);\n background: var(--learning-surface);\n border: 1px solid var(--learning-line);\n border-radius: 6px;\n font-size: 11px;\n text-align: left;\n }\n .evidence-link {\n width: 100%;\n cursor: pointer;\n }\n .evidence-link span {\n margin-left: auto;\n color: var(--learning-muted-strong);\n }\n .evidence-unavailable {\n color: var(--learning-muted-strong);\n font-style: italic;\n }\n .pagination {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 10px;\n }\n .pagination span {\n margin-right: auto;\n color: var(--learning-muted);\n font-size: 11px;\n }\n .pagination button {\n min-height: 30px;\n padding: 0 10px;\n color: var(--learning-ink);\n background: var(--learning-surface);\n border: 1px solid var(--learning-line);\n border-radius: 5px;\n font-size: 11px;\n font-weight: 700;\n cursor: pointer;\n }\n .pagination button:disabled {\n color: var(--learning-disabled-ink);\n background: var(--learning-surface-muted);\n cursor: default;\n }\n .skeleton {\n display: grid;\n gap: 10px;\n }\n .skeleton span {\n height: 74px;\n background: linear-gradient(\n 90deg,\n var(--learning-skeleton-edge),\n var(--learning-skeleton-center),\n var(--learning-skeleton-edge)\n );\n background-size: 200% 100%;\n border-radius: 8px;\n animation: shimmer 1.3s infinite;\n }\n @keyframes shimmer {\n to {\n background-position: -200% 0;\n }\n }\n .dialog-backdrop {\n position: fixed;\n z-index: 50;\n inset: 0;\n display: grid;\n place-items: center;\n padding: 24px;\n background: rgba(15, 15, 20, 0.42);\n }\n .dialog {\n display: flex;\n width: min(620px, 100%);\n max-height: min(680px, 90vh);\n flex-direction: column;\n background: var(--learning-surface);\n border: 1px solid var(--learning-dialog-line);\n border-radius: 13px;\n box-shadow: 0 22px 70px rgba(0, 0, 0, 0.22);\n }\n .dialog header {\n display: flex;\n align-items: start;\n justify-content: space-between;\n padding: 18px 19px 13px;\n }\n .dialog h2 {\n margin: 0;\n font-size: 16px;\n }\n .dialog header p {\n margin: 4px 0 0;\n color: var(--learning-muted);\n font-size: 11px;\n }\n .dialog-close {\n color: var(--learning-muted);\n background: transparent;\n border: 0;\n font-size: 20px;\n cursor: pointer;\n }\n .dialog pre {\n max-height: 420px;\n overflow: auto;\n margin: 0 19px;\n padding: 12px;\n background: var(--learning-soft);\n border: 1px solid var(--learning-line);\n border-radius: 6px;\n font:\n 11px/1.5 ui-monospace,\n SFMono-Regular,\n Menlo,\n monospace;\n white-space: pre-wrap;\n }\n .dialog footer {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 14px 19px 18px;\n }\n .copy-error {\n margin: 10px 19px 0;\n color: var(--learning-danger);\n font-size: 11px;\n }\n @media (max-width: 900px) {\n .steps {\n grid-template-columns: 1fr;\n }\n .step {\n min-height: auto;\n }\n }\n @media (max-width: 640px) {\n .pane-inner {\n padding: 24px 18px 60px;\n }\n .analysis-row,\n .collection-summary {\n align-items: flex-start;\n flex-wrap: wrap;\n }\n .insight-row {\n grid-template-columns: 1fr;\n gap: 8px;\n }\n .evidence-count {\n text-align: left;\n }\n .review-link {\n width: 100%;\n margin: 4px 0 0;\n }\n }\n `;\n\n private emit(name: string, detail?: unknown) {\n this.dispatchEvent(\n new CustomEvent(name, { detail, bubbles: true, composed: true }),\n );\n }\n\n private externalLink(\n url: string | null,\n label: string,\n className = \"primary\",\n category: \"learning\" | \"runs\" | \"candidates\" = \"learning\",\n ) {\n return url\n ? html`<a\n class=${className}\n href=${url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n @click=${() => this.emit(\"learning-web-link\", { category })}\n >${label}</a\n >`\n : nothing;\n }\n\n private openPrompt(event?: Event) {\n const trigger = event?.currentTarget;\n this.promptTrigger = trigger instanceof HTMLElement ? trigger : null;\n this.promptOpen = true;\n this.requestUpdate();\n void this.updateComplete.then(() => {\n this.renderRoot\n .querySelector<HTMLButtonElement>(\".dialog-close\")\n ?.focus();\n });\n }\n\n private closePrompt(): void {\n this.promptOpen = false;\n this.requestUpdate();\n void this.updateComplete.then(() => this.promptTrigger?.focus());\n }\n\n private handlePromptKeydown = (event: KeyboardEvent): void => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n this.closePrompt();\n return;\n }\n if (event.key !== \"Tab\") return;\n const dialog = event.currentTarget;\n if (!(dialog instanceof HTMLElement)) return;\n const root = dialog.getRootNode();\n const activeElement =\n root instanceof ShadowRoot ? root.activeElement : document.activeElement;\n const focusable = [\n ...dialog.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ),\n ];\n const first = focusable[0];\n const last = focusable.at(-1);\n if (!first || !last) return;\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n };\n\n private setupPromptButton(label = \"Copy the setup prompt\") {\n return html`<button\n class=\"primary\"\n type=\"button\"\n @click=${(event: Event) =>\n label === \"Open the setup prompt\"\n ? this.openPrompt(event)\n : this.emit(\"learning-copy-setup\")}\n >\n ${this.copyState === \"copied\" ? \"Prompt copied\" : label}\n </button>`;\n }\n\n private renderSetupProgress(\n mode: \"setup\" | \"ready\" | \"running\" | \"attention\",\n ) {\n const ready = mode === \"ready\";\n const running = mode === \"running\";\n const attention = mode === \"attention\";\n const waitingForLearningSetup =\n mode === \"setup\" &&\n this.setupActive &&\n (this.snapshot === null ||\n this.snapshot.configuration.state === \"not_configured\");\n const completedSteps = ready || running ? 2 : 1;\n const pendingThreads = ready ? (this.snapshot?.pendingThreadCount ?? 0) : 0;\n const title = attention\n ? \"Learning setup needs attention\"\n : mode === \"setup\"\n ? waitingForLearningSetup\n ? \"Waiting for Learning setup\"\n : \"Waiting for the first Thread\"\n : ready\n ? \"Threads ready to analyze\"\n : \"Analysis is running in the web app.\";\n const container =\n this.snapshot?.configuration.state === \"configured\"\n ? this.snapshot.configuration.container\n : null;\n\n return html`<section\n class=\"setup-card\"\n aria-labelledby=\"learning-setup-title\"\n >\n <div class=\"setup-top\">\n <h2 id=\"learning-setup-title\">Set up Learning</h2>\n <span class=\"progress-count\">${completedSteps} of 3 steps</span>\n </div>\n <div class=\"progress-track\" aria-hidden=\"true\">\n <div\n class=\"progress-fill\"\n style=\"width: ${(completedSteps / 3) * 100}%\"\n ></div>\n </div>\n <ol class=\"steps\">\n <li class=\"step complete\">\n <div class=\"step-header\"><span class=\"step-number\">✓</span></div>\n <h3>Copy the setup prompt</h3>\n <p>Nice work. You’ve completed the first step.</p>\n </li>\n <li\n class=\"step ${\n attention\n ? \"error current\"\n : mode === \"setup\"\n ? \"current\"\n : \"complete\"\n }\"\n >\n <div class=\"step-header\">\n <span class=\"step-number\">${ready || running ? \"✓\" : \"2\"}</span>\n ${\n attention\n ? html`\n <span class=\"step-state\">Needs attention</span>\n `\n : nothing\n }\n </div>\n <h3>\n ${\n waitingForLearningSetup\n ? \"Set up Learning\"\n : \"Create your first Thread\"\n }\n </h3>\n <p>\n ${\n waitingForLearningSetup\n ? \"Run the copied prompt in your coding agent. This page will continue when Learning is ready.\"\n : \"Open Checkout Assistant and complete a conversation.\"\n }\n </p>\n </li>\n <li class=\"step ${ready || running ? \"current\" : \"\"}\">\n <div class=\"step-header\"><span class=\"step-number\">3</span></div>\n <h3>Analyze Threads</h3>\n <p>We'll find patterns and turn them into insights and skills</p>\n </li>\n </ol>\n <div class=\"setup-support\">\n <section class=\"collection-panel\">\n <div class=\"support-heading\"><h3>${title}</h3></div>\n ${\n attention\n ? html`<div class=\"error-alert\" role=\"alert\">\n <p>\n Inspector did not find the Learning container or app\n instrumentation. Open the setup prompt, run it in your coding\n agent, then try again.\n </p>\n <button\n class=\"prompt-link\"\n type=\"button\"\n @click=${(event: Event) => this.openPrompt(event)}\n >\n Open the setup prompt ↗\n </button>\n </div>`\n : html`<div class=\"collection-summary\">\n <div class=\"collection-stat\">\n <strong class=\"captured-count\">${pendingThreads}</strong>\n <span>New Threads</span>\n </div>\n ${\n ready || running\n ? this.externalLink(\n this.snapshot?.links.runs ?? null,\n \"Open in web app\",\n \"primary setup-cta\",\n \"runs\",\n )\n : html`\n <button class=\"primary setup-cta\" disabled>Analyze Threads</button>\n `\n }\n </div>`\n }\n ${\n attention\n ? nothing\n : html`<details class=\"technical-details\">\n <summary>Technical details</summary>\n <dl>\n <dt>Container</dt>\n <dd>${container?.id ?? \"Waiting for setup\"}</dd>\n <dt>Status</dt>\n <dd>\n ${\n ready\n ? \"Threads available\"\n : running\n ? \"Analysis running\"\n : waitingForLearningSetup\n ? \"Waiting for Learning setup\"\n : \"Waiting for first Thread\"\n }\n </dd>\n </dl>\n </details>`\n }\n </section>\n </div>\n <div class=\"outcome-preview\" aria-label=\"Learning flow\">\n <span>Threads</span><b>→</b><span>Insights</span><b>→</b\n ><span>Skills</span>\n </div>\n </section>`;\n }\n\n private renderPagination(\n section: \"skills\" | \"insights\",\n page: number,\n totalPages: number,\n ) {\n if (totalPages <= 1) return nothing;\n return html`<nav class=\"pagination\" aria-label=\"${section} pages\">\n <span aria-live=\"polite\">Page ${page} of ${totalPages}</span>\n <button\n ?disabled=${page <= 1}\n @click=${() => this.emit(\"learning-page\", { section, page: page - 1 })}\n >\n Previous\n </button>\n <button\n ?disabled=${page >= totalPages}\n @click=${() => this.emit(\"learning-page\", { section, page: page + 1 })}\n >\n Next\n </button>\n </nav>`;\n }\n\n private renderEvidence(insight: InspectorLearningInsight) {\n return html`<section class=\"detail-panel\" aria-label=\"Insight evidence\">\n <div class=\"detail-head\">\n <div>\n <h3>Evidence</h3>\n <p>${insight.statement}</p>\n </div>\n <button\n class=\"close-detail\"\n type=\"button\"\n aria-label=\"Close evidence\"\n @click=${() => {\n this.selectedInsightId = null;\n this.requestUpdate();\n }}\n >\n ×\n </button>\n </div>\n <div class=\"evidence-list\">\n ${\n insight.evidence.length === 0\n ? html`\n <div class=\"evidence-unavailable\">Evidence is no longer available</div>\n `\n : insight.evidence.map((evidence) =>\n evidence.status === \"unavailable\"\n ? html`\n <div class=\"evidence-unavailable\">Evidence is no longer available</div>\n `\n : html`<button\n class=\"evidence-link\"\n type=\"button\"\n @click=${() =>\n this.emit(\"learning-open-evidence\", {\n threadId: evidence.threadId,\n messageId: evidence.messageIds[0],\n })}\n >\n ⌁\n ${\n evidence.threadName ??\n `Thread ${evidence.threadId.slice(0, 8)}`\n }\n <span>Open Thread →</span>\n </button>`,\n )\n }\n </div>\n ${\n insight.evidenceTruncated\n ? html`\n <p class=\"supporting-unavailable\">Evidence response shortened</p>\n `\n : nothing\n }\n </section>`;\n }\n\n private selectInsight(insight: InspectorLearningInsight) {\n this.selectedInsightId = insight.id;\n this.emit(\"learning-evidence-opened\");\n this.requestUpdate();\n }\n\n private supportingInsightLabel(statement: string): string {\n const firstStop = statement.indexOf(\".\");\n return firstStop === -1 ? statement : statement.slice(0, firstStop + 1);\n }\n\n private renderSkills(snapshot: InspectorLearningSnapshotV1) {\n const firstSkillId = snapshot.skillsPage.items[0]?.id ?? null;\n const containerId =\n snapshot.configuration.state === \"configured\"\n ? snapshot.configuration.container.id\n : \"\";\n const skillPageKey = `${snapshot.projectKey}|${containerId}|${snapshot.skillsPage.page}|${snapshot.skillsPage.items.map((skill) => skill.id).join(\",\")}`;\n if (skillPageKey !== this.skillPageKey) {\n this.skillPageKey = skillPageKey;\n this.expandedSkillId =\n snapshot.skillsPage.page === 1 ? firstSkillId : null;\n }\n return html`<section class=\"result-section\" aria-labelledby=\"skills-title\">\n <div class=\"result-section-heading\">\n <h2 id=\"skills-title\">Skills in registry</h2>\n <span class=\"result-count\">${snapshot.skillsPage.total}</span>\n ${\n snapshot.pendingCandidateCount > 0\n ? this.externalLink(\n snapshot.links.candidates,\n `${snapshot.pendingCandidateCount} ${snapshot.pendingCandidateCount === 1 ? \"Skill\" : \"Skills\"} for review in web app ↗`,\n \"review-link\",\n \"candidates\",\n )\n : nothing\n }\n </div>\n ${\n snapshot.skillsPage.items.length === 0\n ? html`\n <div class=\"empty-card compact\">\n <h3>No Skills in registry yet</h3>\n <p>\n No Insight has produced a Skill that was approved into the registry yet.\n </p>\n </div>\n `\n : html`<div class=\"content-card\">\n ${snapshot.skillsPage.items.map((skill) => {\n const open = this.expandedSkillId === skill.id;\n return html`<article class=\"active-skill\">\n <h3>${skill.name}</h3>\n <p>${skill.description}</p>\n <div class=\"skill-lineage\">\n <span>Supporting Insight</span>\n ${\n skill.sourceInsight\n ? html`<button\n type=\"button\"\n @click=${() => this.selectInsight(skill.sourceInsight!)}\n >\n ${this.supportingInsightLabel(\n skill.sourceInsight.statement,\n )}<small\n >${skill.sourceInsight.totalThreadCount}\n ${\n skill.sourceInsight.totalThreadCount === 1\n ? \"Thread\"\n : \"Threads\"\n }</small\n >\n </button>`\n : html`\n <div class=\"supporting-unavailable\">Supporting Insight unavailable</div>\n `\n }\n </div>\n <details\n class=\"skill-source\"\n ?open=${open}\n @toggle=${(event: Event) => {\n const nextOpen = (event.currentTarget as HTMLDetailsElement)\n .open;\n if (nextOpen === open) return;\n this.expandedSkillId = nextOpen ? skill.id : \"\";\n this.emit(\"learning-skill-toggle\", {\n action: nextOpen ? \"expanded\" : \"collapsed\",\n });\n this.requestUpdate();\n }}\n >\n <summary>View SKILL.md</summary>\n <pre>${skill.skillMd}</pre>\n </details>\n </article>`;\n })}\n </div>`\n }\n ${this.renderPagination(\n \"skills\",\n snapshot.skillsPage.page,\n snapshot.skillsPage.totalPages,\n )}\n </section>`;\n }\n\n private renderInsights(snapshot: InspectorLearningSnapshotV1) {\n const selected = snapshot.insightsPage.items.find(\n (insight) => insight.id === this.selectedInsightId,\n );\n return html`<section\n class=\"result-section\"\n aria-labelledby=\"insights-title\"\n >\n <div class=\"result-section-heading\">\n <h2 id=\"insights-title\">\n ${snapshot.skillsPage.total > 0 ? \"More Insights\" : \"Insights\"}\n </h2>\n <span class=\"result-count\">${snapshot.insightsPage.total}</span>\n </div>\n ${\n snapshot.insightsPage.items.length === 0\n ? html`\n <div class=\"empty-card compact\"><h3>No active Insights</h3></div>\n `\n : html`<div class=\"content-card\">\n <div class=\"list-header\">\n <span>Pattern</span><span>Evidence</span>\n </div>\n ${snapshot.insightsPage.items.map(\n (insight) => html`<button\n class=\"insight-row\"\n data-selected=${selected?.id === insight.id}\n type=\"button\"\n @click=${() =>\n selected?.id === insight.id\n ? ((this.selectedInsightId = null), this.requestUpdate())\n : this.selectInsight(insight)}\n >\n <div>\n <h3>${insight.statement}</h3>\n <p>${insight.impact}</p>\n </div>\n <span class=\"evidence-count\"\n >${insight.totalThreadCount}\n ${insight.totalThreadCount === 1 ? \"Thread\" : \"Threads\"}</span\n >\n </button>`,\n )}\n </div>`\n }\n ${selected ? this.renderEvidence(selected) : nothing}\n ${this.renderPagination(\n \"insights\",\n snapshot.insightsPage.page,\n snapshot.insightsPage.totalPages,\n )}\n </section>`;\n }\n\n private renderResults(snapshot: InspectorLearningSnapshotV1) {\n const sourceInsight = snapshot.skillsPage.items\n .map((skill) => skill.sourceInsight)\n .find((insight) => insight?.id === this.selectedInsightId);\n return html`\n ${\n snapshot.pendingThreadCount > 0\n ? html`<section class=\"analysis-card ready\">\n <div class=\"analysis-row\">\n <div class=\"analysis-copy\">\n <h2>Find new Insights and Skills</h2>\n <p>You have new threads ready to be analyzed.</p>\n </div>\n ${this.externalLink(\n snapshot.links.runs,\n \"Open in web app\",\n \"primary results-cta\",\n \"runs\",\n )}\n </div>\n </section>`\n : nothing\n }\n ${this.renderSkills(snapshot)}\n ${sourceInsight ? this.renderEvidence(sourceInsight) : nothing}\n ${this.renderInsights(snapshot)}\n `;\n }\n\n private renderRetryStrip() {\n if (!this.error) return nothing;\n return html`<div class=\"retry-strip\" role=\"status\">\n <span>${this.error}</span>\n <button\n class=\"secondary\"\n type=\"button\"\n @click=${() => this.emit(\"learning-retry\")}\n >\n Retry\n </button>\n </div>`;\n }\n\n private renderEmptyResults(snapshot: InspectorLearningSnapshotV1) {\n return html`<section class=\"analysis-card\">\n <div class=\"analysis-row\">\n <div class=\"analysis-copy\">\n <p class=\"eyebrow\">Analysis complete</p>\n <h2>No new Insights or Skills</h2>\n <p>\n Create more Threads with Checkout Assistant. You can run Learning\n again when new Threads are available.\n </p>\n </div>\n </div>\n </section>\n <section class=\"result-section\">\n <div class=\"result-section-heading\">\n <h2>Skills in registry</h2><span class=\"result-count\">0</span>\n </div>\n <div class=\"empty-card\">\n <h3>No Skills from this analysis</h3>\n <p>Learning did not generate a Skill for review.</p>\n </div>\n </section>\n <section class=\"result-section\">\n <div class=\"result-section-heading\">\n <h2>Insights</h2><span class=\"result-count\">0</span>\n </div>\n <div class=\"empty-card\">\n <h3>No Insights from this analysis</h3>\n <p>Learning did not find a useful pattern in these Threads.</p>\n </div>\n </section>\n ${this.externalLink(\n snapshot.links.learning,\n \"Open in web app ↗\",\n \"quiet-link\",\n \"learning\",\n )}`;\n }\n\n private renderCompactState(input: {\n readonly title: string;\n readonly copy?: string;\n readonly action?: unknown;\n readonly error?: boolean;\n }) {\n return html`<section class=\"analysis-card ${input.error ? \"error\" : \"\"}\">\n <div class=\"analysis-row\">\n <div class=\"analysis-copy\">\n <h2>${input.title}</h2>\n ${input.copy ? html`<p>${input.copy}</p>` : nothing}\n </div>\n ${input.action ?? nothing}\n </div>\n </section>`;\n }\n\n render() {\n const state = deriveLearningViewState({\n supported: this.supported,\n loading: this.loading,\n error: this.error,\n snapshot: this.snapshot,\n setupActive: this.setupActive,\n });\n let content: unknown;\n if (state === \"loading\") {\n content = html`\n <div class=\"skeleton\" aria-label=\"Loading Learning\">\n <span></span><span></span><span></span>\n </div>\n `;\n } else if (state === \"error\") {\n content = this.renderCompactState({\n title: \"Learning data is unavailable\",\n copy: this.error ?? undefined,\n error: true,\n action: html`<button\n class=\"secondary\"\n type=\"button\"\n @click=${() => this.emit(\"learning-retry\")}\n >\n Retry\n </button>`,\n });\n } else if (state === \"selection_required\") {\n content = this.renderCompactState({\n title: \"Inspector cannot choose a Learning container for this agent.\",\n action: this.externalLink(\n this.snapshot!.links.learning,\n \"Open in web app\",\n \"primary\",\n \"learning\",\n ),\n });\n } else if (state === \"invalid\") {\n content = this.renderSetupProgress(\"attention\");\n } else if (state === \"landing\") {\n // The parent Inspector preserves the existing locked-feature marketing\n // surface for Landing. The v5 pane begins only after its copy action.\n content = nothing;\n } else if (state === \"setup\") {\n content = this.renderSetupProgress(\"setup\");\n } else if (state === \"first_run\") {\n content = this.renderSetupProgress(\"running\");\n } else if (state === \"ready\") {\n content = this.renderSetupProgress(\"ready\");\n } else if (state === \"empty\") {\n content = this.renderEmptyResults(this.snapshot!);\n } else {\n content = this.renderResults(this.snapshot!);\n }\n\n const retry =\n state === \"error\" || !this.snapshot ? nothing : this.renderRetryStrip();\n\n return html`<main class=\"pane-inner\" data-learning-state=${state}>\n <header class=\"pane-heading\">\n <div>\n <h1>Learning</h1>\n <p>Your Agent learns from conversations and improves over time.</p>\n </div>\n ${\n this.refreshing\n ? html`\n <span class=\"refreshing\" role=\"status\">Refreshing</span>\n `\n : nothing\n }\n </header>\n ${retry}\n ${content}\n </main>\n ${\n this.promptOpen\n ? html`<div class=\"dialog-backdrop\">\n <section\n class=\"dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"learning-prompt-title\"\n @keydown=${this.handlePromptKeydown}\n >\n <header>\n <div>\n <h2 id=\"learning-prompt-title\">Set up Rich Threads</h2>\n <p>Paste this prompt into your coding agent.</p>\n </div>\n <button\n class=\"dialog-close\"\n aria-label=\"Close setup prompt\"\n @click=${() => this.closePrompt()}\n >\n ×\n </button>\n </header>\n <pre>${this.setupPrompt}</pre>\n ${\n this.copyState === \"error\"\n ? html`\n <p class=\"copy-error\" role=\"alert\">\n Clipboard access failed. Retry to continue.\n </p>\n `\n : nothing\n }\n <footer>\n <button\n class=\"secondary\"\n @click=${() => this.closePrompt()}\n >\n Close\n </button>\n <button\n class=\"primary\"\n @click=${() => this.emit(\"learning-copy-setup\")}\n >\n ${\n this.copyState === \"copied\"\n ? \"Prompt copied\"\n : \"Copy the setup prompt\"\n }\n </button>\n </footer>\n </section>\n </div>`\n : nothing\n }`;\n }\n}\n\nif (!customElements.get(\"cpk-learning-view\")) {\n customElements.define(\"cpk-learning-view\", CpkLearningView);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"learning-view.mjs","names":[],"sources":["../../src/components/learning-view.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport type {\n InspectorLearningInsight,\n InspectorLearningSnapshotV1,\n} from \"@copilotkit/shared\";\n\nexport type LearningViewState =\n | \"loading\"\n | \"error\"\n | \"selection_required\"\n | \"invalid\"\n | \"results\"\n | \"first_run\"\n | \"ready\"\n | \"empty\"\n | \"setup\"\n | \"landing\";\n\nexport function deriveLearningViewState(input: {\n readonly supported: boolean;\n readonly loading: boolean;\n readonly error: string | null;\n readonly snapshot: InspectorLearningSnapshotV1 | null;\n readonly setupActive: boolean;\n}): LearningViewState {\n // A Runtime that has not opted into Learning is still a valid product\n // onboarding state. The parent Inspector renders the Learning preview for\n // `landing`; after the setup prompt is copied, keep the user in the setup\n // flow while the Runtime is updated and reconnects.\n if (!input.supported) return input.setupActive ? \"setup\" : \"landing\";\n if (!input.snapshot && input.loading) return \"loading\";\n if (!input.snapshot && input.error) return \"error\";\n const snapshot = input.snapshot;\n if (!snapshot) return \"loading\";\n if (snapshot.configuration.state === \"selection_required\")\n return \"selection_required\";\n if (snapshot.configuration.state === \"invalid\") return \"invalid\";\n const hasResults =\n snapshot.skillsPage.total > 0 || snapshot.insightsPage.total > 0;\n if (hasResults || snapshot.pendingCandidateCount > 0) return \"results\";\n if (snapshot.run.hasActiveRun) return \"first_run\";\n if (snapshot.run.hasEverSucceeded && snapshot.pendingThreadCount === 0)\n return \"empty\";\n if (\n snapshot.configuration.state === \"configured\" &&\n snapshot.pendingThreadCount > 0\n )\n return \"ready\";\n if (input.setupActive || snapshot.configuration.state === \"configured\")\n return \"setup\";\n return \"landing\";\n}\n\nexport class CpkLearningView extends LitElement {\n static properties = {\n supported: { type: Boolean },\n loading: { type: Boolean },\n refreshing: { type: Boolean },\n error: { attribute: false },\n snapshot: { attribute: false },\n setupActive: { type: Boolean },\n copyState: { attribute: false },\n recopyState: { attribute: false },\n setupPrompt: { attribute: false },\n };\n\n supported = false;\n loading = false;\n refreshing = false;\n error: string | null = null;\n snapshot: InspectorLearningSnapshotV1 | null = null;\n setupActive = false;\n copyState: \"idle\" | \"copied\" | \"error\" = \"idle\";\n recopyState: \"idle\" | \"copied\" | \"error\" = \"idle\";\n setupPrompt = \"\";\n private promptOpen = false;\n private promptTrigger: HTMLElement | null = null;\n private expandedSkillId: string | null = null;\n private selectedInsightId: string | null = null;\n private skillPageKey = \"\";\n\n static styles = css`\n :host {\n --learning-ink: #202127;\n --learning-muted: #64656f;\n --learning-muted-strong: #858690;\n --learning-line: #dcdce4;\n --learning-line-secondary: #cfcfd7;\n --learning-line-accent: #dcd9ff;\n --learning-soft: #f7f7fa;\n --learning-canvas: #fff;\n --learning-surface: #fff;\n --learning-surface-subtle: #fbfbfd;\n --learning-surface-muted: #f8f8fb;\n --learning-surface-hover: #fafaff;\n --learning-purple: #7567ff;\n --learning-purple-dark: #5549e8;\n --learning-soft-purple: #f0edff;\n --learning-purple-border: #cfc8ff;\n --learning-green: #168b69;\n --learning-soft-green: #f7fbf9;\n --learning-green-border: #b9dfd1;\n --learning-soft-danger: #fff4f4;\n --learning-soft-danger-alt: #fff8f8;\n --learning-danger: #7e2929;\n --learning-danger-muted: #8c4a4a;\n --learning-danger-border: #efc7c7;\n --learning-danger-step-border: #d96a6a;\n --learning-track: #e9edf5;\n --learning-step-number: #edf0f5;\n --learning-step-number-ink: #555661;\n --learning-primary: #202127;\n --learning-primary-ink: #fff;\n --learning-secondary: #fff;\n --learning-secondary-ink: #31323a;\n --learning-disabled: #e5e5ea;\n --learning-disabled-ink: #9a9ba3;\n --learning-on-accent: #fff;\n --learning-outcome: #888993;\n --learning-outcome-dash: #cfd0d8;\n --learning-outcome-arrow: #b0b1b9;\n --learning-code: #34353d;\n --learning-dialog-line: #d9d9e1;\n --learning-skeleton-edge: #eeeef2;\n --learning-skeleton-center: #f8f8fa;\n display: block;\n height: 100%;\n overflow: auto;\n color: var(--learning-ink);\n background: var(--learning-canvas);\n font-family: Inter, ui-sans-serif, system-ui, sans-serif;\n }\n :host([data-color-scheme=\"dark\"]) {\n color-scheme: dark;\n --learning-ink: #f3f4f8;\n --learning-muted: #b0b3be;\n --learning-muted-strong: #b8bbc5;\n --learning-line: #3a3e4b;\n --learning-line-secondary: #4c5161;\n --learning-line-accent: #625f95;\n --learning-soft: #20232d;\n --learning-canvas: #15171e;\n --learning-surface: #1a1d25;\n --learning-surface-subtle: #1d2029;\n --learning-surface-muted: #20232d;\n --learning-surface-hover: #252837;\n --learning-purple: #a296ff;\n --learning-purple-dark: #c4baff;\n --learning-soft-purple: #2a2940;\n --learning-purple-border: #625f95;\n --learning-green: #4dc69d;\n --learning-soft-green: #172923;\n --learning-green-border: #28604d;\n --learning-soft-danger: #321f25;\n --learning-soft-danger-alt: #2d2026;\n --learning-danger: #ffabab;\n --learning-danger-muted: #f2b5ba;\n --learning-danger-border: #7a424e;\n --learning-danger-step-border: #a95464;\n --learning-track: #303440;\n --learning-step-number: #303440;\n --learning-step-number-ink: #d8dae4;\n --learning-primary: #f3f4f8;\n --learning-primary-ink: #16181f;\n --learning-secondary: #20232d;\n --learning-secondary-ink: #edf0f6;\n --learning-disabled: #363a46;\n --learning-disabled-ink: #a4a8b5;\n --learning-on-accent: #171920;\n --learning-outcome: #b0b3be;\n --learning-outcome-dash: #545969;\n --learning-outcome-arrow: #858a99;\n --learning-code: #e2e4ec;\n --learning-dialog-line: #484c5a;\n --learning-skeleton-edge: #2a2d38;\n --learning-skeleton-center: #333744;\n }\n * {\n box-sizing: border-box;\n }\n button,\n a,\n summary {\n font: inherit;\n }\n button:focus-visible,\n a:focus-visible,\n summary:focus-visible {\n outline: 2px solid var(--learning-purple);\n outline-offset: 2px;\n }\n .pane-inner {\n max-width: 880px;\n min-height: 100%;\n margin: 0 auto;\n padding: 32px 36px 70px;\n }\n .pane-heading {\n display: flex;\n align-items: start;\n justify-content: space-between;\n gap: 24px;\n margin-bottom: 24px;\n }\n .pane-heading h1 {\n margin: 0 0 7px;\n font-size: 25px;\n line-height: 1.2;\n letter-spacing: -0.035em;\n }\n .pane-heading p {\n max-width: 630px;\n margin: 0;\n color: var(--learning-muted);\n font-size: 14px;\n line-height: 1.5;\n }\n .pane-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n .refreshing {\n color: var(--learning-muted-strong);\n font-size: 11px;\n }\n .setup-card,\n .analysis-card,\n .content-card {\n border: 1px solid var(--learning-line);\n border-radius: 10px;\n background: var(--learning-surface);\n }\n .setup-card {\n padding: 24px;\n background: var(--learning-surface-subtle);\n }\n .setup-top {\n display: flex;\n align-items: start;\n justify-content: space-between;\n gap: 20px;\n }\n .setup-top h2,\n .analysis-card h2 {\n margin: 0;\n font-size: 19px;\n line-height: 1.25;\n letter-spacing: -0.02em;\n }\n .progress-count {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 13px;\n font-weight: 750;\n white-space: nowrap;\n }\n .progress-track {\n height: 8px;\n margin: 20px 0 18px;\n overflow: hidden;\n background: var(--learning-track);\n border-radius: 999px;\n }\n .progress-fill {\n height: 100%;\n background: var(--learning-purple);\n border-radius: inherit;\n }\n .steps {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 10px;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n .step {\n min-height: 142px;\n padding: 15px;\n background: var(--learning-surface);\n border: 1px solid var(--learning-line);\n border-radius: 8px;\n }\n .step.current {\n background: var(--learning-soft-purple);\n border-color: var(--learning-purple);\n }\n .step.error {\n background: var(--learning-soft-danger);\n border-color: var(--learning-danger-step-border);\n }\n .step.complete {\n background: var(--learning-soft-green);\n border-color: var(--learning-green-border);\n }\n .step-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 18px;\n }\n .step-number {\n display: grid;\n place-items: center;\n width: 26px;\n height: 26px;\n color: var(--learning-step-number-ink);\n background: var(--learning-step-number);\n border-radius: 50%;\n font-size: 12px;\n font-weight: 800;\n }\n .step.current .step-number {\n color: var(--learning-on-accent);\n background: var(--learning-purple);\n }\n .step.complete .step-number {\n color: var(--learning-on-accent);\n background: var(--learning-green);\n }\n .step-state {\n color: var(--learning-danger);\n font-size: 9px;\n font-weight: 850;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n }\n .step h3 {\n margin: 0 0 7px;\n font-size: 14px;\n }\n .step p {\n margin: 0;\n color: var(--learning-muted);\n font-size: 12px;\n line-height: 1.45;\n }\n .copy-again {\n margin-top: 12px;\n padding: 0;\n color: var(--learning-secondary-ink);\n background: none;\n border: 0;\n font-size: 11px;\n font-weight: 750;\n text-decoration: underline;\n cursor: pointer;\n }\n .setup-support {\n margin-top: 14px;\n }\n .collection-panel {\n padding: 15px;\n background: var(--learning-surface);\n border: 1px solid var(--learning-line);\n border-radius: 8px;\n }\n .support-heading {\n margin-bottom: 12px;\n }\n .support-heading h3 {\n margin: 0;\n font-size: 13px;\n }\n .error-alert {\n margin-bottom: 10px;\n padding: 11px 12px;\n color: var(--learning-danger);\n background: var(--learning-soft-danger);\n border: 1px solid var(--learning-danger-border);\n border-radius: 6px;\n }\n .error-alert p {\n margin: 0;\n color: var(--learning-danger-muted);\n font-size: 11px;\n line-height: 1.45;\n }\n .prompt-link {\n display: inline-block;\n margin-top: 7px;\n padding: 0;\n color: var(--learning-danger);\n background: none;\n border: 0;\n font-size: 11px;\n font-weight: 750;\n text-decoration: underline;\n cursor: pointer;\n }\n .collection-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 10px;\n background: var(--learning-soft);\n border-radius: 6px;\n }\n .collection-stat {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 9px;\n }\n .captured-count {\n color: var(--learning-ink);\n font-size: 28px;\n line-height: 1;\n }\n .collection-stat span {\n font-size: 12px;\n font-weight: 700;\n }\n .technical-details {\n margin-top: 10px;\n color: var(--learning-muted);\n font-size: 10px;\n }\n .technical-details summary {\n cursor: pointer;\n font-weight: 700;\n }\n .technical-details dl {\n display: grid;\n grid-template-columns: auto 1fr;\n gap: 5px 12px;\n margin: 9px 0 0;\n padding: 10px;\n background: var(--learning-soft);\n border-radius: 5px;\n }\n .technical-details dt {\n color: var(--learning-muted-strong);\n }\n .technical-details dd {\n margin: 0;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n overflow-wrap: anywhere;\n }\n .primary,\n .secondary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-height: 36px;\n padding: 0 14px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 750;\n text-decoration: none;\n cursor: pointer;\n }\n .primary {\n color: var(--learning-primary-ink);\n background: var(--learning-primary);\n border: 1px solid var(--learning-primary);\n }\n .secondary {\n color: var(--learning-secondary-ink);\n background: var(--learning-secondary);\n border: 1px solid var(--learning-line-secondary);\n }\n .primary:disabled,\n .primary[aria-disabled=\"true\"] {\n color: var(--learning-disabled-ink);\n background: var(--learning-disabled);\n border-color: var(--learning-disabled);\n cursor: not-allowed;\n pointer-events: none;\n }\n .setup-cta:not(:disabled),\n .results-cta {\n min-width: 170px;\n min-height: 40px;\n padding: 0 18px;\n box-shadow: 0 6px 14px rgba(23, 23, 27, 0.2);\n }\n .outcome-preview {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n margin-top: 16px;\n color: var(--learning-outcome);\n font-size: 11px;\n }\n .outcome-preview span {\n padding: 6px 9px;\n background: var(--learning-surface);\n border: 1px dashed var(--learning-outcome-dash);\n border-radius: 5px;\n }\n .outcome-preview b {\n color: var(--learning-outcome-arrow);\n }\n .analysis-card {\n padding: 18px 20px;\n background: var(--learning-surface-muted);\n }\n .analysis-card.ready {\n background: var(--learning-soft-purple);\n border-color: var(--learning-purple-border);\n }\n .analysis-card.error {\n background: var(--learning-soft-danger-alt);\n border-color: var(--learning-danger-border);\n }\n .analysis-row {\n display: flex;\n align-items: center;\n gap: 20px;\n }\n .analysis-copy {\n flex: 1;\n }\n .analysis-card h2 {\n margin-bottom: 7px;\n }\n .analysis-card p {\n margin: 0;\n color: var(--learning-muted);\n font-size: 13px;\n line-height: 1.5;\n }\n .eyebrow {\n margin: 0 0 6px !important;\n color: var(--learning-purple-dark) !important;\n font-size: 10px !important;\n font-weight: 850;\n letter-spacing: 0.09em;\n text-transform: uppercase;\n }\n .retry-strip {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 12px;\n padding: 11px 12px;\n color: var(--learning-danger);\n background: var(--learning-soft-danger);\n border: 1px solid var(--learning-danger-border);\n border-radius: 6px;\n font-size: 11px;\n }\n .result-section {\n margin-top: 14px;\n }\n .result-section-heading {\n display: flex;\n align-items: baseline;\n gap: 6px;\n margin-bottom: 10px;\n }\n .result-section-heading h2 {\n margin: 0;\n font-size: 14px;\n }\n .result-count {\n color: var(--learning-muted-strong);\n font-size: 10px;\n font-weight: 700;\n }\n .review-link {\n margin-left: auto;\n color: var(--learning-purple-dark);\n font-size: 11px;\n font-weight: 750;\n text-decoration: none;\n }\n .quiet-link {\n display: inline-flex;\n margin-top: 12px;\n color: var(--learning-purple-dark);\n font-size: 11px;\n font-weight: 750;\n text-decoration: none;\n }\n .quiet-link:hover,\n .review-link:hover {\n text-decoration: underline;\n }\n .content-card {\n overflow: hidden;\n }\n .empty-card {\n padding: 24px;\n color: var(--learning-muted);\n background: var(--learning-surface-subtle);\n border: 1px solid var(--learning-line);\n border-radius: 8px;\n }\n .empty-card.compact {\n padding: 15px 16px;\n }\n .empty-card h3 {\n margin: 0 0 6px;\n color: var(--learning-ink);\n font-size: 14px;\n }\n .empty-card p {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n }\n .active-skill {\n padding: 16px;\n }\n .active-skill + .active-skill {\n border-top: 1px solid var(--learning-line);\n }\n .active-skill h3 {\n margin: 0 0 6px;\n font-size: 14px;\n }\n .active-skill > p {\n margin: 0;\n color: var(--learning-muted);\n font-size: 12px;\n line-height: 1.45;\n }\n .skill-lineage {\n margin-top: 10px;\n padding: 10px 12px;\n background: var(--learning-surface-muted);\n border: 1px solid var(--learning-line);\n border-radius: 6px;\n }\n .skill-lineage > span {\n display: block;\n margin-bottom: 5px;\n color: var(--learning-muted-strong);\n font-size: 9px;\n font-weight: 800;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n }\n .skill-lineage button {\n display: flex;\n width: 100%;\n align-items: start;\n justify-content: space-between;\n gap: 14px;\n padding: 0;\n color: var(--learning-ink);\n background: none;\n border: 0;\n text-align: left;\n font-size: 11px;\n font-weight: 700;\n line-height: 1.4;\n cursor: pointer;\n }\n .skill-lineage button small {\n flex: 0 0 auto;\n color: var(--learning-purple-dark);\n font-size: 10px;\n font-weight: 750;\n }\n .supporting-unavailable {\n color: var(--learning-muted-strong);\n font-size: 11px;\n font-style: italic;\n }\n .skill-source {\n margin-top: 10px;\n }\n .skill-source summary {\n width: fit-content;\n color: var(--learning-purple-dark);\n cursor: pointer;\n font-size: 11px;\n font-weight: 750;\n }\n .skill-source pre {\n margin: 10px 0 0;\n padding: 12px;\n color: var(--learning-code);\n background: var(--learning-soft);\n border: 1px solid var(--learning-line);\n border-radius: 6px;\n font:\n 11px/1.5 ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n .list-header {\n display: flex;\n align-items: center;\n padding: 10px 14px;\n color: var(--learning-muted-strong);\n background: var(--learning-surface-muted);\n border-bottom: 1px solid var(--learning-line);\n font-size: 10px;\n font-weight: 800;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n }\n .list-header span:last-child {\n margin-left: auto;\n }\n .insight-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 18px;\n width: 100%;\n padding: 16px;\n color: inherit;\n background: var(--learning-surface);\n border: 0;\n border-bottom: 1px solid var(--learning-line);\n text-align: left;\n cursor: pointer;\n }\n .insight-row:last-child {\n border-bottom: 0;\n }\n .insight-row:hover,\n .insight-row[data-selected=\"true\"] {\n background: var(--learning-surface-hover);\n }\n .insight-row h3 {\n margin: 0 0 6px;\n font-size: 14px;\n line-height: 1.35;\n }\n .insight-row p {\n margin: 0;\n color: var(--learning-muted);\n font-size: 12px;\n line-height: 1.45;\n }\n .evidence-count {\n min-width: 90px;\n color: var(--learning-purple-dark);\n font-size: 11px;\n font-weight: 750;\n text-align: right;\n }\n .detail-panel {\n margin-top: 14px;\n padding: 18px;\n background: var(--learning-surface-hover);\n border: 1px solid var(--learning-line-accent);\n border-radius: 8px;\n }\n .detail-head {\n display: flex;\n align-items: start;\n gap: 14px;\n }\n .detail-head div {\n flex: 1;\n }\n .detail-head h3 {\n margin: 0 0 5px;\n font-size: 14px;\n }\n .detail-head p {\n margin: 0;\n color: var(--learning-muted);\n font-size: 12px;\n line-height: 1.45;\n }\n .close-detail {\n width: 28px;\n height: 28px;\n color: var(--learning-muted);\n background: var(--learning-surface);\n border: 1px solid var(--learning-line);\n border-radius: 5px;\n cursor: pointer;\n }\n .evidence-list {\n display: grid;\n gap: 7px;\n margin-top: 14px;\n }\n .evidence-link,\n .evidence-unavailable {\n display: flex;\n align-items: center;\n gap: 10px;\n min-height: 38px;\n padding: 10px;\n color: var(--learning-code);\n background: var(--learning-surface);\n border: 1px solid var(--learning-line);\n border-radius: 6px;\n font-size: 11px;\n text-align: left;\n }\n .evidence-link {\n width: 100%;\n cursor: pointer;\n }\n .evidence-link span {\n margin-left: auto;\n color: var(--learning-muted-strong);\n }\n .evidence-unavailable {\n color: var(--learning-muted-strong);\n font-style: italic;\n }\n .pagination {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 10px;\n }\n .pagination span {\n margin-right: auto;\n color: var(--learning-muted);\n font-size: 11px;\n }\n .pagination button {\n min-height: 30px;\n padding: 0 10px;\n color: var(--learning-ink);\n background: var(--learning-surface);\n border: 1px solid var(--learning-line);\n border-radius: 5px;\n font-size: 11px;\n font-weight: 700;\n cursor: pointer;\n }\n .pagination button:disabled {\n color: var(--learning-disabled-ink);\n background: var(--learning-surface-muted);\n cursor: default;\n }\n .skeleton {\n display: grid;\n gap: 10px;\n }\n .skeleton span {\n height: 74px;\n background: linear-gradient(\n 90deg,\n var(--learning-skeleton-edge),\n var(--learning-skeleton-center),\n var(--learning-skeleton-edge)\n );\n background-size: 200% 100%;\n border-radius: 8px;\n animation: shimmer 1.3s infinite;\n }\n @keyframes shimmer {\n to {\n background-position: -200% 0;\n }\n }\n .dialog-backdrop {\n position: fixed;\n z-index: 50;\n inset: 0;\n display: grid;\n place-items: center;\n padding: 24px;\n background: rgba(15, 15, 20, 0.42);\n }\n .dialog {\n display: flex;\n width: min(620px, 100%);\n max-height: min(680px, 90vh);\n flex-direction: column;\n background: var(--learning-surface);\n border: 1px solid var(--learning-dialog-line);\n border-radius: 13px;\n box-shadow: 0 22px 70px rgba(0, 0, 0, 0.22);\n }\n .dialog header {\n display: flex;\n align-items: start;\n justify-content: space-between;\n padding: 18px 19px 13px;\n }\n .dialog h2 {\n margin: 0;\n font-size: 16px;\n }\n .dialog header p {\n margin: 4px 0 0;\n color: var(--learning-muted);\n font-size: 11px;\n }\n .dialog-close {\n color: var(--learning-muted);\n background: transparent;\n border: 0;\n font-size: 20px;\n cursor: pointer;\n }\n .dialog pre {\n max-height: 420px;\n overflow: auto;\n margin: 0 19px;\n padding: 12px;\n background: var(--learning-soft);\n border: 1px solid var(--learning-line);\n border-radius: 6px;\n font:\n 11px/1.5 ui-monospace,\n SFMono-Regular,\n Menlo,\n monospace;\n white-space: pre-wrap;\n }\n .dialog footer {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 14px 19px 18px;\n }\n .copy-error {\n margin: 10px 19px 0;\n color: var(--learning-danger);\n font-size: 11px;\n }\n @media (max-width: 900px) {\n .steps {\n grid-template-columns: 1fr;\n }\n .step {\n min-height: auto;\n }\n }\n @media (max-width: 640px) {\n .pane-inner {\n padding: 24px 18px 60px;\n }\n .analysis-row,\n .collection-summary {\n align-items: flex-start;\n flex-wrap: wrap;\n }\n .insight-row {\n grid-template-columns: 1fr;\n gap: 8px;\n }\n .evidence-count {\n text-align: left;\n }\n .review-link {\n width: 100%;\n margin: 4px 0 0;\n }\n }\n `;\n\n private emit(name: string, detail?: unknown) {\n this.dispatchEvent(\n new CustomEvent(name, { detail, bubbles: true, composed: true }),\n );\n }\n\n private externalLink(\n url: string | null,\n label: string,\n className = \"primary\",\n category: \"learning\" | \"runs\" | \"candidates\" = \"learning\",\n ) {\n return url\n ? html`<a\n class=${className}\n href=${url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n @click=${() => this.emit(\"learning-web-link\", { category })}\n >${label}</a\n >`\n : nothing;\n }\n\n private openPrompt(event?: Event) {\n const trigger = event?.currentTarget;\n this.promptTrigger = trigger instanceof HTMLElement ? trigger : null;\n this.promptOpen = true;\n this.requestUpdate();\n void this.updateComplete.then(() => {\n this.renderRoot\n .querySelector<HTMLButtonElement>(\".dialog-close\")\n ?.focus();\n });\n }\n\n private closePrompt(): void {\n this.promptOpen = false;\n this.requestUpdate();\n void this.updateComplete.then(() => this.promptTrigger?.focus());\n }\n\n private handlePromptKeydown = (event: KeyboardEvent): void => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n this.closePrompt();\n return;\n }\n if (event.key !== \"Tab\") return;\n const dialog = event.currentTarget;\n if (!(dialog instanceof HTMLElement)) return;\n const root = dialog.getRootNode();\n const activeElement =\n root instanceof ShadowRoot ? root.activeElement : document.activeElement;\n const focusable = [\n ...dialog.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ),\n ];\n const first = focusable[0];\n const last = focusable.at(-1);\n if (!first || !last) return;\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n };\n\n private setupPromptButton(label = \"Copy the setup prompt\") {\n return html`<button\n class=\"primary\"\n type=\"button\"\n @click=${(event: Event) =>\n label === \"Open the setup prompt\"\n ? this.openPrompt(event)\n : this.emit(\"learning-copy-setup\")}\n >\n ${this.copyState === \"copied\" ? \"Prompt copied\" : label}\n </button>`;\n }\n\n private renderSetupProgress(\n mode: \"setup\" | \"ready\" | \"running\" | \"attention\",\n ) {\n const ready = mode === \"ready\";\n const running = mode === \"running\";\n const attention = mode === \"attention\";\n const waitingForLearningSetup =\n mode === \"setup\" &&\n this.setupActive &&\n (this.snapshot === null ||\n this.snapshot.configuration.state === \"not_configured\");\n const completedSteps = ready || running ? 2 : 1;\n const pendingThreads = ready ? (this.snapshot?.pendingThreadCount ?? 0) : 0;\n const title = attention\n ? \"Learning setup needs attention\"\n : mode === \"setup\"\n ? waitingForLearningSetup\n ? \"Waiting for Learning setup\"\n : \"Waiting for the first Thread\"\n : ready\n ? \"Threads ready to analyze\"\n : \"Analysis is running in the web app.\";\n const container =\n this.snapshot?.configuration.state === \"configured\"\n ? this.snapshot.configuration.container\n : null;\n\n return html`<section\n class=\"setup-card\"\n aria-labelledby=\"learning-setup-title\"\n >\n <div class=\"setup-top\">\n <h2 id=\"learning-setup-title\">Set up Learning</h2>\n <span class=\"progress-count\">${completedSteps} of 3 steps</span>\n </div>\n <div class=\"progress-track\" aria-hidden=\"true\">\n <div\n class=\"progress-fill\"\n style=\"width: ${(completedSteps / 3) * 100}%\"\n ></div>\n </div>\n <ol class=\"steps\">\n <li class=\"step complete\">\n <div class=\"step-header\"><span class=\"step-number\">✓</span></div>\n <h3>Copy the setup prompt</h3>\n <p>Nice work. You’ve completed the first step.</p>\n <button\n class=\"copy-again\"\n type=\"button\"\n aria-live=\"polite\"\n @click=${() => this.emit(\"learning-recopy-setup\")}\n >\n ${\n this.recopyState === \"copied\"\n ? \"✓ Copied!\"\n : this.recopyState === \"error\"\n ? \"Try copying again\"\n : \"Copy prompt again\"\n }\n </button>\n </li>\n <li\n class=\"step ${\n attention\n ? \"error current\"\n : mode === \"setup\"\n ? \"current\"\n : \"complete\"\n }\"\n >\n <div class=\"step-header\">\n <span class=\"step-number\">${ready || running ? \"✓\" : \"2\"}</span>\n ${\n attention\n ? html`\n <span class=\"step-state\">Needs attention</span>\n `\n : nothing\n }\n </div>\n <h3>\n ${\n waitingForLearningSetup\n ? \"Set up Learning\"\n : \"Create your first Thread\"\n }\n </h3>\n <p>\n ${\n waitingForLearningSetup\n ? \"Run the copied prompt in your coding agent. This page will continue when Learning is ready.\"\n : \"Open Checkout Assistant and complete a conversation.\"\n }\n </p>\n </li>\n <li class=\"step ${ready || running ? \"current\" : \"\"}\">\n <div class=\"step-header\"><span class=\"step-number\">3</span></div>\n <h3>Analyze Threads</h3>\n <p>We'll find patterns and turn them into insights and skills</p>\n </li>\n </ol>\n <div class=\"setup-support\">\n <section class=\"collection-panel\">\n <div class=\"support-heading\"><h3>${title}</h3></div>\n ${\n attention\n ? html`<div class=\"error-alert\" role=\"alert\">\n <p>\n Inspector did not find the Learning container or app\n instrumentation. Open the setup prompt, run it in your coding\n agent, then try again.\n </p>\n <button\n class=\"prompt-link\"\n type=\"button\"\n @click=${(event: Event) => this.openPrompt(event)}\n >\n Open the setup prompt ↗\n </button>\n </div>`\n : html`<div class=\"collection-summary\">\n <div class=\"collection-stat\">\n <strong class=\"captured-count\">${pendingThreads}</strong>\n <span>New Threads</span>\n </div>\n ${\n ready || running\n ? this.externalLink(\n this.snapshot?.links.runs ?? null,\n \"Open in web app\",\n \"primary setup-cta\",\n \"runs\",\n )\n : html`\n <button class=\"primary setup-cta\" disabled>Analyze Threads</button>\n `\n }\n </div>`\n }\n ${\n attention\n ? nothing\n : html`<details class=\"technical-details\">\n <summary>Technical details</summary>\n <dl>\n <dt>Container</dt>\n <dd>${container?.id ?? \"Waiting for setup\"}</dd>\n <dt>Status</dt>\n <dd>\n ${\n ready\n ? \"Threads available\"\n : running\n ? \"Analysis running\"\n : waitingForLearningSetup\n ? \"Waiting for Learning setup\"\n : \"Waiting for first Thread\"\n }\n </dd>\n </dl>\n </details>`\n }\n </section>\n </div>\n <div class=\"outcome-preview\" aria-label=\"Learning flow\">\n <span>Threads</span><b>→</b><span>Insights</span><b>→</b\n ><span>Skills</span>\n </div>\n </section>`;\n }\n\n private renderPagination(\n section: \"skills\" | \"insights\",\n page: number,\n totalPages: number,\n ) {\n if (totalPages <= 1) return nothing;\n return html`<nav class=\"pagination\" aria-label=\"${section} pages\">\n <span aria-live=\"polite\">Page ${page} of ${totalPages}</span>\n <button\n ?disabled=${page <= 1}\n @click=${() => this.emit(\"learning-page\", { section, page: page - 1 })}\n >\n Previous\n </button>\n <button\n ?disabled=${page >= totalPages}\n @click=${() => this.emit(\"learning-page\", { section, page: page + 1 })}\n >\n Next\n </button>\n </nav>`;\n }\n\n private renderEvidence(insight: InspectorLearningInsight) {\n return html`<section class=\"detail-panel\" aria-label=\"Insight evidence\">\n <div class=\"detail-head\">\n <div>\n <h3>Evidence</h3>\n <p>${insight.statement}</p>\n </div>\n <button\n class=\"close-detail\"\n type=\"button\"\n aria-label=\"Close evidence\"\n @click=${() => {\n this.selectedInsightId = null;\n this.requestUpdate();\n }}\n >\n ×\n </button>\n </div>\n <div class=\"evidence-list\">\n ${\n insight.evidence.length === 0\n ? html`\n <div class=\"evidence-unavailable\">Evidence is no longer available</div>\n `\n : insight.evidence.map((evidence) =>\n evidence.status === \"unavailable\"\n ? html`\n <div class=\"evidence-unavailable\">Evidence is no longer available</div>\n `\n : html`<button\n class=\"evidence-link\"\n type=\"button\"\n @click=${() =>\n this.emit(\"learning-open-evidence\", {\n threadId: evidence.threadId,\n messageId: evidence.messageIds[0],\n })}\n >\n ⌁\n ${\n evidence.threadName ??\n `Thread ${evidence.threadId.slice(0, 8)}`\n }\n <span>Open Thread →</span>\n </button>`,\n )\n }\n </div>\n ${\n insight.evidenceTruncated\n ? html`\n <p class=\"supporting-unavailable\">Evidence response shortened</p>\n `\n : nothing\n }\n </section>`;\n }\n\n private selectInsight(insight: InspectorLearningInsight) {\n this.selectedInsightId = insight.id;\n this.emit(\"learning-evidence-opened\");\n this.requestUpdate();\n }\n\n private supportingInsightLabel(statement: string): string {\n const firstStop = statement.indexOf(\".\");\n return firstStop === -1 ? statement : statement.slice(0, firstStop + 1);\n }\n\n private renderSkills(snapshot: InspectorLearningSnapshotV1) {\n const firstSkillId = snapshot.skillsPage.items[0]?.id ?? null;\n const containerId =\n snapshot.configuration.state === \"configured\"\n ? snapshot.configuration.container.id\n : \"\";\n const skillPageKey = `${snapshot.projectKey}|${containerId}|${snapshot.skillsPage.page}|${snapshot.skillsPage.items.map((skill) => skill.id).join(\",\")}`;\n if (skillPageKey !== this.skillPageKey) {\n this.skillPageKey = skillPageKey;\n this.expandedSkillId =\n snapshot.skillsPage.page === 1 ? firstSkillId : null;\n }\n return html`<section class=\"result-section\" aria-labelledby=\"skills-title\">\n <div class=\"result-section-heading\">\n <h2 id=\"skills-title\">Skills in registry</h2>\n <span class=\"result-count\">${snapshot.skillsPage.total}</span>\n ${\n snapshot.pendingCandidateCount > 0\n ? this.externalLink(\n snapshot.links.candidates,\n `${snapshot.pendingCandidateCount} ${snapshot.pendingCandidateCount === 1 ? \"Skill\" : \"Skills\"} for review in web app ↗`,\n \"review-link\",\n \"candidates\",\n )\n : nothing\n }\n </div>\n ${\n snapshot.skillsPage.items.length === 0\n ? html`\n <div class=\"empty-card compact\">\n <h3>No Skills in registry yet</h3>\n <p>\n No Insight has produced a Skill that was approved into the registry yet.\n </p>\n </div>\n `\n : html`<div class=\"content-card\">\n ${snapshot.skillsPage.items.map((skill) => {\n const open = this.expandedSkillId === skill.id;\n return html`<article class=\"active-skill\">\n <h3>${skill.name}</h3>\n <p>${skill.description}</p>\n <div class=\"skill-lineage\">\n <span>Supporting Insight</span>\n ${\n skill.sourceInsight\n ? html`<button\n type=\"button\"\n @click=${() => this.selectInsight(skill.sourceInsight!)}\n >\n ${this.supportingInsightLabel(\n skill.sourceInsight.statement,\n )}<small\n >${skill.sourceInsight.totalThreadCount}\n ${\n skill.sourceInsight.totalThreadCount === 1\n ? \"Thread\"\n : \"Threads\"\n }</small\n >\n </button>`\n : html`\n <div class=\"supporting-unavailable\">Supporting Insight unavailable</div>\n `\n }\n </div>\n <details\n class=\"skill-source\"\n ?open=${open}\n @toggle=${(event: Event) => {\n const nextOpen = (event.currentTarget as HTMLDetailsElement)\n .open;\n if (nextOpen === open) return;\n this.expandedSkillId = nextOpen ? skill.id : \"\";\n this.emit(\"learning-skill-toggle\", {\n action: nextOpen ? \"expanded\" : \"collapsed\",\n });\n this.requestUpdate();\n }}\n >\n <summary>View SKILL.md</summary>\n <pre>${skill.skillMd}</pre>\n </details>\n </article>`;\n })}\n </div>`\n }\n ${this.renderPagination(\n \"skills\",\n snapshot.skillsPage.page,\n snapshot.skillsPage.totalPages,\n )}\n </section>`;\n }\n\n private renderInsights(snapshot: InspectorLearningSnapshotV1) {\n const selected = snapshot.insightsPage.items.find(\n (insight) => insight.id === this.selectedInsightId,\n );\n return html`<section\n class=\"result-section\"\n aria-labelledby=\"insights-title\"\n >\n <div class=\"result-section-heading\">\n <h2 id=\"insights-title\">\n ${snapshot.skillsPage.total > 0 ? \"More Insights\" : \"Insights\"}\n </h2>\n <span class=\"result-count\">${snapshot.insightsPage.total}</span>\n </div>\n ${\n snapshot.insightsPage.items.length === 0\n ? html`\n <div class=\"empty-card compact\"><h3>No active Insights</h3></div>\n `\n : html`<div class=\"content-card\">\n <div class=\"list-header\">\n <span>Pattern</span><span>Evidence</span>\n </div>\n ${snapshot.insightsPage.items.map(\n (insight) => html`<button\n class=\"insight-row\"\n data-selected=${selected?.id === insight.id}\n type=\"button\"\n @click=${() =>\n selected?.id === insight.id\n ? ((this.selectedInsightId = null), this.requestUpdate())\n : this.selectInsight(insight)}\n >\n <div>\n <h3>${insight.statement}</h3>\n <p>${insight.impact}</p>\n </div>\n <span class=\"evidence-count\"\n >${insight.totalThreadCount}\n ${insight.totalThreadCount === 1 ? \"Thread\" : \"Threads\"}</span\n >\n </button>`,\n )}\n </div>`\n }\n ${selected ? this.renderEvidence(selected) : nothing}\n ${this.renderPagination(\n \"insights\",\n snapshot.insightsPage.page,\n snapshot.insightsPage.totalPages,\n )}\n </section>`;\n }\n\n private renderResults(snapshot: InspectorLearningSnapshotV1) {\n const sourceInsight = snapshot.skillsPage.items\n .map((skill) => skill.sourceInsight)\n .find((insight) => insight?.id === this.selectedInsightId);\n return html`\n ${\n snapshot.pendingThreadCount > 0\n ? html`<section class=\"analysis-card ready\">\n <div class=\"analysis-row\">\n <div class=\"analysis-copy\">\n <h2>Find new Insights and Skills</h2>\n <p>You have new threads ready to be analyzed.</p>\n </div>\n ${this.externalLink(\n snapshot.links.runs,\n \"Open in web app\",\n \"primary results-cta\",\n \"runs\",\n )}\n </div>\n </section>`\n : nothing\n }\n ${this.renderSkills(snapshot)}\n ${sourceInsight ? this.renderEvidence(sourceInsight) : nothing}\n ${this.renderInsights(snapshot)}\n `;\n }\n\n private renderRetryStrip() {\n if (!this.error) return nothing;\n return html`<div class=\"retry-strip\" role=\"status\">\n <span>${this.error}</span>\n <button\n class=\"secondary\"\n type=\"button\"\n @click=${() => this.emit(\"learning-retry\")}\n >\n Retry\n </button>\n </div>`;\n }\n\n private renderEmptyResults(snapshot: InspectorLearningSnapshotV1) {\n return html`<section class=\"analysis-card\">\n <div class=\"analysis-row\">\n <div class=\"analysis-copy\">\n <p class=\"eyebrow\">Analysis complete</p>\n <h2>No new Insights or Skills</h2>\n <p>\n Create more Threads with Checkout Assistant. You can run Learning\n again when new Threads are available.\n </p>\n </div>\n </div>\n </section>\n <section class=\"result-section\">\n <div class=\"result-section-heading\">\n <h2>Skills in registry</h2><span class=\"result-count\">0</span>\n </div>\n <div class=\"empty-card\">\n <h3>No Skills from this analysis</h3>\n <p>Learning did not generate a Skill for review.</p>\n </div>\n </section>\n <section class=\"result-section\">\n <div class=\"result-section-heading\">\n <h2>Insights</h2><span class=\"result-count\">0</span>\n </div>\n <div class=\"empty-card\">\n <h3>No Insights from this analysis</h3>\n <p>Learning did not find a useful pattern in these Threads.</p>\n </div>\n </section>\n ${this.externalLink(\n snapshot.links.learning,\n \"Open in web app ↗\",\n \"quiet-link\",\n \"learning\",\n )}`;\n }\n\n private renderCompactState(input: {\n readonly title: string;\n readonly copy?: string;\n readonly action?: unknown;\n readonly error?: boolean;\n }) {\n return html`<section class=\"analysis-card ${input.error ? \"error\" : \"\"}\">\n <div class=\"analysis-row\">\n <div class=\"analysis-copy\">\n <h2>${input.title}</h2>\n ${input.copy ? html`<p>${input.copy}</p>` : nothing}\n </div>\n ${input.action ?? nothing}\n </div>\n </section>`;\n }\n\n render() {\n const state = deriveLearningViewState({\n supported: this.supported,\n loading: this.loading,\n error: this.error,\n snapshot: this.snapshot,\n setupActive: this.setupActive,\n });\n let content: unknown;\n if (state === \"loading\") {\n content = html`\n <div class=\"skeleton\" aria-label=\"Loading Learning\">\n <span></span><span></span><span></span>\n </div>\n `;\n } else if (state === \"error\") {\n content = this.renderCompactState({\n title: \"Learning data is unavailable\",\n copy: this.error ?? undefined,\n error: true,\n action: html`<button\n class=\"secondary\"\n type=\"button\"\n @click=${() => this.emit(\"learning-retry\")}\n >\n Retry\n </button>`,\n });\n } else if (state === \"selection_required\") {\n content = this.renderCompactState({\n title: \"Inspector cannot choose a Learning container for this agent.\",\n action: this.externalLink(\n this.snapshot!.links.learning,\n \"Open in web app\",\n \"primary\",\n \"learning\",\n ),\n });\n } else if (state === \"invalid\") {\n content = this.renderSetupProgress(\"attention\");\n } else if (state === \"landing\") {\n // The parent Inspector preserves the existing locked-feature marketing\n // surface for Landing. The v5 pane begins only after its copy action.\n content = nothing;\n } else if (state === \"setup\") {\n content = this.renderSetupProgress(\"setup\");\n } else if (state === \"first_run\") {\n content = this.renderSetupProgress(\"running\");\n } else if (state === \"ready\") {\n content = this.renderSetupProgress(\"ready\");\n } else if (state === \"empty\") {\n content = this.renderEmptyResults(this.snapshot!);\n } else {\n content = this.renderResults(this.snapshot!);\n }\n\n const retry =\n state === \"error\" || !this.snapshot ? nothing : this.renderRetryStrip();\n\n return html`<main class=\"pane-inner\" data-learning-state=${state}>\n <header class=\"pane-heading\">\n <div>\n <h1>Learning</h1>\n <p>Your Agent learns from conversations and improves over time.</p>\n </div>\n <div class=\"pane-actions\">\n ${\n state === \"setup\" && this.setupActive\n ? html`<button\n class=\"secondary\"\n type=\"button\"\n @click=${() => this.emit(\"learning-go-back\")}\n >\n ← Go back\n </button>`\n : nothing\n }\n ${\n this.refreshing\n ? html`\n <span class=\"refreshing\" role=\"status\">Refreshing</span>\n `\n : nothing\n }\n </div>\n </header>\n ${retry}\n ${content}\n </main>\n ${\n this.promptOpen\n ? html`<div class=\"dialog-backdrop\">\n <section\n class=\"dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"learning-prompt-title\"\n @keydown=${this.handlePromptKeydown}\n >\n <header>\n <div>\n <h2 id=\"learning-prompt-title\">Set up Rich Threads</h2>\n <p>Paste this prompt into your coding agent.</p>\n </div>\n <button\n class=\"dialog-close\"\n aria-label=\"Close setup prompt\"\n @click=${() => this.closePrompt()}\n >\n ×\n </button>\n </header>\n <pre>${this.setupPrompt}</pre>\n ${\n this.copyState === \"error\"\n ? html`\n <p class=\"copy-error\" role=\"alert\">\n Clipboard access failed. Retry to continue.\n </p>\n `\n : nothing\n }\n <footer>\n <button\n class=\"secondary\"\n @click=${() => this.closePrompt()}\n >\n Close\n </button>\n <button\n class=\"primary\"\n @click=${() => this.emit(\"learning-copy-setup\")}\n >\n ${\n this.copyState === \"copied\"\n ? \"Prompt copied\"\n : \"Copy the setup prompt\"\n }\n </button>\n </footer>\n </section>\n </div>`\n : nothing\n }`;\n }\n}\n\nif (!customElements.get(\"cpk-learning-view\")) {\n customElements.define(\"cpk-learning-view\", CpkLearningView);\n}\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -29,6 +29,7 @@ const THREAD_INSPECTOR_TAG = "cpk-thread-inspector";
29
29
  * "memories" for persistence and telemetry stability.
30
30
  */
31
31
  const LEARNING_VIEW_LABEL = "Learning";
32
+ const LEARNING_RECOPY_CONFIRMATION_MS = 2e3;
32
33
  /**
33
34
  * User-facing label for the What's new view. Its menu key stays `whats-new`
34
35
  * for persistence and telemetry stability, following the `memories`/"Memory"
@@ -502,6 +503,10 @@ const AGENT_EVENT_TYPES = [
502
503
  "ACTIVITY_SNAPSHOT",
503
504
  "ACTIVITY_DELTA"
504
505
  ];
506
+ const THREADS_LOCKED_COPY = {
507
+ heading: "Production-grade chat threads without the complexity. Self hostable.",
508
+ description: "Chat threads that go beyond text with generative UI and multimodal inputs, built to replay missed events and stay in sync across tabs, sessions, and devices."
509
+ };
505
510
  const EMPTY_INSPECTOR_MESSAGES = [];
506
511
  function textFromUnknownContent(content) {
507
512
  if (typeof content === "string") return content;
@@ -4915,8 +4920,11 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
4915
4920
  this.learningPollTimer = null;
4916
4921
  this.learningPollFailureCount = 0;
4917
4922
  this.learningSetupMarker = null;
4923
+ this.learningSetupCopyRequest = 0;
4918
4924
  this.learningSetupUnsubscribe = null;
4919
4925
  this.learningPromptCopyState = "idle";
4926
+ this.learningPromptRecopyState = "idle";
4927
+ this.learningPromptRecopyTimer = null;
4920
4928
  this.learningViewedState = null;
4921
4929
  this._recallResults = null;
4922
4930
  this._recallLoading = false;
@@ -5080,6 +5088,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5080
5088
  this.launcherHudIntroStartTimer = null;
5081
5089
  this.launcherHudIntroEndTimer = null;
5082
5090
  this.inspectorDismissedUntil = null;
5091
+ this.lastReportedInspectorVisibility = null;
5083
5092
  this.inspectorDismissalTimer = null;
5084
5093
  this.hudLandingMenu = null;
5085
5094
  this.pillOutcome = null;
@@ -5256,23 +5265,36 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5256
5265
  const clipboard = this.getClipboard(event);
5257
5266
  if (!clipboard?.writeText) return false;
5258
5267
  try {
5259
- await clipboard.writeText(require_home_briefing.homeFeatureImplementationPrompt(service, { onboardingRunId }));
5268
+ await clipboard.writeText(require_onboarding_prompt.createFeatureOnboardingPrompt(service.id, onboardingRunId));
5260
5269
  return true;
5261
5270
  } catch {
5262
5271
  return false;
5263
5272
  }
5264
5273
  };
5265
- this.handleLearningSetupCopy = async (event) => {
5266
- const service = this.getHomeFeaturePromptTarget("threads");
5274
+ this.handleLearningSetupCopy = async (event, recopy = false) => {
5275
+ const service = this.getHomeFeaturePromptTarget("memory");
5267
5276
  if (!service || !this.core?.runtimeUrl) return;
5277
+ const request = ++this.learningSetupCopyRequest;
5268
5278
  const copied = await this.copyFeaturePromptToClipboard(service, event, this.getOnboardingRunId());
5279
+ if (request !== this.learningSetupCopyRequest) return;
5269
5280
  if (!this.core.telemetryDisabled) require_telemetry.trackLearningSetupPromptClicked({ outcome: copied ? "success" : "failure" });
5270
5281
  if (!copied) {
5271
- this.learningPromptCopyState = "error";
5282
+ if (recopy) {
5283
+ this.cancelLearningPromptRecopyReset();
5284
+ this.learningPromptRecopyState = "error";
5285
+ } else this.learningPromptCopyState = "error";
5272
5286
  this.requestUpdate();
5273
5287
  return;
5274
5288
  }
5275
- this.learningPromptCopyState = "copied";
5289
+ if (recopy) {
5290
+ this.cancelLearningPromptRecopyReset();
5291
+ this.learningPromptRecopyState = "copied";
5292
+ this.learningPromptRecopyTimer = setTimeout(() => {
5293
+ this.learningPromptRecopyTimer = null;
5294
+ this.learningPromptRecopyState = "idle";
5295
+ this.requestUpdate();
5296
+ }, LEARNING_RECOPY_CONFIRMATION_MS);
5297
+ } else this.learningPromptCopyState = "copied";
5276
5298
  this.learningSetupMarker = require_learning_setup.writeLearningSetupMarker({
5277
5299
  runtimeUrl: this.core.runtimeUrl,
5278
5300
  agentId: this.getLearningAgentId()
@@ -5282,6 +5304,17 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5282
5304
  this.requestUpdate();
5283
5305
  this.refreshLearningSnapshot({ preserve: false });
5284
5306
  };
5307
+ this.handleLearningGoBack = () => {
5308
+ this.learningSetupCopyRequest += 1;
5309
+ this.cancelLearningPromptRecopyReset();
5310
+ require_learning_setup.clearLearningSetupMarker();
5311
+ this.learningSetupMarker = null;
5312
+ this.learningPromptCopyState = "idle";
5313
+ this.learningPromptRecopyState = "idle";
5314
+ this.cancelLearningPoll();
5315
+ this.requestUpdate();
5316
+ this.trackLearningViewState();
5317
+ };
5285
5318
  this.handleLearningPage = (event) => {
5286
5319
  const { section, page } = event.detail;
5287
5320
  const currentPage = section === "skills" ? this.learningSnapshot?.skillsPage.page ?? 1 : this.learningSnapshot?.insightsPage.page ?? 1;
@@ -6728,6 +6761,12 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6728
6761
  this.learningAbortController?.abort();
6729
6762
  this.learningAbortController = null;
6730
6763
  }
6764
+ cancelLearningPromptRecopyReset() {
6765
+ if (this.learningPromptRecopyTimer !== null) {
6766
+ clearTimeout(this.learningPromptRecopyTimer);
6767
+ this.learningPromptRecopyTimer = null;
6768
+ }
6769
+ }
6731
6770
  detachFromCore() {
6732
6771
  this.threadCapabilityGeneration += 1;
6733
6772
  this.threadCapabilityEnabled = null;
@@ -6749,6 +6788,8 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6749
6788
  this._memoriesRealtimeStatus = "connecting";
6750
6789
  this._memorySubscribed = false;
6751
6790
  this._memoryStoreUnsupported = false;
6791
+ this.cancelLearningPromptRecopyReset();
6792
+ this.learningPromptRecopyState = "idle";
6752
6793
  this._recallSeq += 1;
6753
6794
  this._recallResults = null;
6754
6795
  this._recallLoading = false;
@@ -8503,6 +8544,24 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
8503
8544
  );
8504
8545
  }
8505
8546
 
8547
+ /* With no news or setup actions, the dismissal is the whole HUD. */
8548
+ .cpk-launcher-hud[data-cpk-hud-dismiss-only] {
8549
+ --hud-dismiss-day-height: 36px;
8550
+ width: max-content;
8551
+ }
8552
+
8553
+ .cpk-launcher-hud[data-cpk-hud-dismiss-only][data-cpk-hud-vertical="top"] {
8554
+ top: calc((var(--cpk-launcher-size) - var(--hud-dismiss-day-height)) / 2);
8555
+ }
8556
+
8557
+ .cpk-launcher-hud[data-cpk-hud-dismiss-only][data-cpk-hud-vertical="bottom"] {
8558
+ bottom: calc((var(--cpk-launcher-size) - var(--hud-dismiss-day-height)) / 2);
8559
+ }
8560
+
8561
+ .cpk-launcher-hud[data-cpk-hud-dismiss-only] .cpk-launcher-hud__card {
8562
+ width: max-content;
8563
+ }
8564
+
8506
8565
  .cpk-launcher-hud__list {
8507
8566
  margin: 0;
8508
8567
  padding: 0;
@@ -8669,6 +8728,11 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
8669
8728
  color 120ms ease;
8670
8729
  }
8671
8730
 
8731
+ .cpk-launcher-hud[data-cpk-hud-dismiss-only] .cpk-launcher-hud__dismiss-day {
8732
+ font-size: 11px;
8733
+ white-space: nowrap;
8734
+ }
8735
+
8672
8736
  .cpk-launcher-hud__dismiss-day:hover,
8673
8737
  .cpk-launcher-hud__dismiss-day:focus-visible {
8674
8738
  border-color: var(--hud-accent);
@@ -9570,6 +9634,11 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
9570
9634
  else this.removeAttribute("data-docked");
9571
9635
  }
9572
9636
  updated() {
9637
+ const visible = !this.isInspectorDismissed;
9638
+ if (visible !== this.lastReportedInspectorVisibility) {
9639
+ this.lastReportedInspectorVisibility = visible;
9640
+ this.dispatchEvent(new CustomEvent("cpk-inspector-visibility-change", { detail: { visible } }));
9641
+ }
9573
9642
  this.syncInspectorPortal();
9574
9643
  this.syncThreadsExampleOverviewVideo();
9575
9644
  this.maybeTrackInspectorMetadataViews();
@@ -9883,6 +9952,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
9883
9952
  return titleCharacters.length > HUD_ANNOUNCEMENT_TITLE_LIMIT ? `${titleCharacters.slice(0, HUD_ANNOUNCEMENT_TITLE_LIMIT).join("").trimEnd()}...` : title;
9884
9953
  }
9885
9954
  renderHudRow(args) {
9955
+ if (args.connected) return lit.nothing;
9886
9956
  const detailId = `cpk-hud-detail-${args.id}`;
9887
9957
  return lit.html`
9888
9958
  <li
@@ -9954,11 +10024,13 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
9954
10024
  const learningOn = homeModel.services.some((service) => service.id === "memory" && service.enabled);
9955
10025
  const announcementTitle = this.getUnreadAnnouncementTitle();
9956
10026
  const featureBlockIntroIndex = announcementTitle ? 1 : 0;
10027
+ const dismissOnly = !announcementTitle && threadsOn && learningOn;
9957
10028
  return lit.html`
9958
10029
  <div
9959
10030
  class="cpk-launcher-hud"
9960
10031
  id="cpk-launcher-hud"
9961
10032
  data-cpk-launcher-hud
10033
+ ?data-cpk-hud-dismiss-only=${dismissOnly}
9962
10034
  data-cpk-hud-side=${this.launcherHudSide}
9963
10035
  data-cpk-hud-vertical=${this.contextState.button.anchor.vertical}
9964
10036
  data-cpk-hud-intro=${this.launcherHudIntro ? "true" : lit.nothing}
@@ -9968,7 +10040,9 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
9968
10040
  "--cpk-launcher-hud-waterfall-duration": `${LAUNCHER_HUD_INTRO_MS.waterfallDuration}ms`
9969
10041
  })}
9970
10042
  >
9971
- <span class="cpk-launcher-hud__arrow" aria-hidden="true"></span>
10043
+ ${dismissOnly ? lit.nothing : lit.html`
10044
+ <span class="cpk-launcher-hud__arrow" aria-hidden="true"></span>
10045
+ `}
9972
10046
  <div class="cpk-launcher-hud__card">
9973
10047
  ${announcementTitle ? lit.html`
9974
10048
  <div
@@ -10007,31 +10081,33 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
10007
10081
  </div>
10008
10082
  </div>
10009
10083
  ` : lit.nothing}
10010
- <ul
10011
- class="cpk-launcher-hud__list cpk-launcher-hud__feature-list"
10012
- role="list"
10013
- style=${(0, lit_directives_style_map_js.styleMap)({ "--cpk-hud-waterfall-delay": launcherHudWaterfallDelay(featureBlockIntroIndex) })}
10014
- >
10015
- ${this.renderHudRow({
10084
+ ${threadsOn && learningOn ? lit.nothing : lit.html`
10085
+ <ul
10086
+ class="cpk-launcher-hud__list cpk-launcher-hud__feature-list"
10087
+ role="list"
10088
+ style=${(0, lit_directives_style_map_js.styleMap)({ "--cpk-hud-waterfall-delay": launcherHudWaterfallDelay(featureBlockIntroIndex) })}
10089
+ >
10090
+ ${this.renderHudRow({
10016
10091
  id: "threads",
10017
10092
  label: HUD_THREADS_LABEL,
10018
10093
  icon: "MessageSquare",
10019
10094
  connected: threadsOn,
10020
10095
  introIndex: featureBlockIntroIndex + 1
10021
10096
  })}
10022
- ${this.renderHudRow({
10097
+ ${this.renderHudRow({
10023
10098
  id: "learning",
10024
10099
  label: HUD_LEARNING_LABEL,
10025
10100
  icon: "Brain",
10026
10101
  connected: learningOn,
10027
- introIndex: featureBlockIntroIndex + 2
10102
+ introIndex: featureBlockIntroIndex + (threadsOn ? 1 : 2)
10028
10103
  })}
10029
- </ul>
10104
+ </ul>
10105
+ `}
10030
10106
  <button
10031
10107
  type="button"
10032
10108
  class="cpk-launcher-hud__dismiss-day"
10033
10109
  data-cpk-dismiss-inspector="day"
10034
- style=${(0, lit_directives_style_map_js.styleMap)({ "--cpk-hud-waterfall-delay": launcherHudWaterfallDelay(featureBlockIntroIndex + 3) })}
10110
+ style=${(0, lit_directives_style_map_js.styleMap)({ "--cpk-hud-waterfall-delay": launcherHudWaterfallDelay(dismissOnly ? 0 : featureBlockIntroIndex + Number(!threadsOn) + Number(!learningOn) + 1) })}
10035
10111
  @click=${this.handleHudDismissDayClick}
10036
10112
  @pointerdown=${(event) => event.stopPropagation()}
10037
10113
  >
@@ -13440,23 +13516,6 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
13440
13516
  </div>
13441
13517
  `;
13442
13518
  }
13443
- getThreadsLockedCopy() {
13444
- switch (this.inspectorMetadataProjection.licenseState) {
13445
- case "valid": return {
13446
- heading: "Finish setting up Rich Threads",
13447
- description: "Copy this prompt into your coding agent to finish the setup."
13448
- };
13449
- case "none":
13450
- case "unknown": return {
13451
- heading: "Production-grade chat threads without the complexity. Self hostable.",
13452
- description: "Chat threads that go beyond text with generative UI and multimodal inputs, built to replay missed events and stay in sync across tabs, sessions, and devices."
13453
- };
13454
- case "expired": return {
13455
- heading: "Renew Intelligence to inspect Threads.",
13456
- description: "Your Intelligence access has expired. Renew it to inspect saved thread history."
13457
- };
13458
- }
13459
- }
13460
13519
  /**
13461
13520
  * Renders the realtime-connection indicator in the memory-store header.
13462
13521
  * Only `"connected"` shows the live (green-dot) state; `"connecting"` shows a
@@ -13507,7 +13566,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
13507
13566
  videoTitle: "CopilotKit Learning overview",
13508
13567
  outlineItems: LEARNING_LOCKED_FEATURE_OUTLINE,
13509
13568
  setupPrompt: {
13510
- serviceId: "threads",
13569
+ serviceId: "memory",
13511
13570
  copyState: this.learningPromptCopyState,
13512
13571
  onClick: (event) => void this.handleLearningSetupCopy(event)
13513
13572
  }
@@ -13522,9 +13581,12 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
13522
13581
  .snapshot=${this.learningSnapshot}
13523
13582
  .setupActive=${this.isLearningSetupActive()}
13524
13583
  .copyState=${this.learningPromptCopyState}
13525
- .setupPrompt=${this.getHomeFeaturePromptTarget("threads") ? require_home_briefing.homeFeatureImplementationPrompt(this.getHomeFeaturePromptTarget("threads"), { onboardingRunId: this.getOnboardingRunId() }) : ""}
13584
+ .recopyState=${this.learningPromptRecopyState}
13585
+ .setupPrompt=${require_onboarding_prompt.createFeatureOnboardingPrompt("memory", this.getOnboardingRunId())}
13526
13586
  @learning-retry=${() => this.refreshLearningSnapshot({ preserve: this.learningSnapshot !== null })}
13527
13587
  @learning-copy-setup=${(event) => this.handleLearningSetupCopy(event)}
13588
+ @learning-recopy-setup=${(event) => this.handleLearningSetupCopy(event, true)}
13589
+ @learning-go-back=${this.handleLearningGoBack}
13528
13590
  @learning-page=${(event) => this.handleLearningPage(event)}
13529
13591
  @learning-open-evidence=${(event) => this.handleLearningEvidence(event)}
13530
13592
  @learning-evidence-opened=${() => {
@@ -13762,12 +13824,11 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
13762
13824
  renderThreadsView() {
13763
13825
  if (!this.areThreadEndpointsAvailable()) {
13764
13826
  this.trackThreadsViewStateOnce("locked");
13765
- const lockedCopy = this.getThreadsLockedCopy();
13766
13827
  return this.renderLockedFeatureOverview({
13767
13828
  serviceId: "threads",
13768
13829
  featureName: "Rich Threads",
13769
- heading: lockedCopy.heading,
13770
- description: lockedCopy.description,
13830
+ heading: THREADS_LOCKED_COPY.heading,
13831
+ description: THREADS_LOCKED_COPY.description,
13771
13832
  videoUrl: THREADS_LOCKED_VIDEO_URL,
13772
13833
  videoTitle: "Rich Threads overview",
13773
13834
  outlineItems: THREADS_LOCKED_FEATURE_OUTLINE