@copilotkit/web-inspector 1.70.2 → 1.71.0

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":";;;AAkBA,SAAgB,wBAAwB,OAMlB;AAKpB,KAAI,CAAC,MAAM,UAAW,QAAO,MAAM,cAAc,UAAU;AAC3D,KAAI,CAAC,MAAM,YAAY,MAAM,QAAS,QAAO;AAC7C,KAAI,CAAC,MAAM,YAAY,MAAM,MAAO,QAAO;CAC3C,MAAM,WAAW,MAAM;AACvB,KAAI,CAAC,SAAU,QAAO;AACtB,KAAI,SAAS,cAAc,UAAU,qBACnC,QAAO;AACT,KAAI,SAAS,cAAc,UAAU,UAAW,QAAO;AAGvD,KADE,SAAS,WAAW,QAAQ,KAAK,SAAS,aAAa,QAAQ,KAC/C,SAAS,wBAAwB,EAAG,QAAO;AAC7D,KAAI,SAAS,IAAI,aAAc,QAAO;AACtC,KAAI,SAAS,IAAI,oBAAoB,SAAS,uBAAuB,EACnE,QAAO;AACT,KACE,SAAS,cAAc,UAAU,gBACjC,SAAS,qBAAqB,EAE9B,QAAO;AACT,KAAI,MAAM,eAAe,SAAS,cAAc,UAAU,aACxD,QAAO;AACT,QAAO;;AAGT,IAAa,kBAAb,cAAqC,WAAW;;;mBAYlC;iBACF;oBACG;eACU;kBACwB;qBACjC;mBAC2B;qBAC3B;oBACO;uBACuB;yBACH;2BACE;sBACpB;8BAw4BQ,UAA+B;AAC5D,OAAI,MAAM,QAAQ,UAAU;AAC1B,UAAM,gBAAgB;AACtB,SAAK,aAAa;AAClB;;AAEF,OAAI,MAAM,QAAQ,MAAO;GACzB,MAAM,SAAS,MAAM;AACrB,OAAI,EAAE,kBAAkB,aAAc;GACtC,MAAM,OAAO,OAAO,aAAa;GACjC,MAAM,gBACJ,gBAAgB,aAAa,KAAK,gBAAgB,SAAS;GAC7D,MAAM,YAAY,CAChB,GAAG,OAAO,iBACR,6IACD,CACF;GACD,MAAM,QAAQ,UAAU;GACxB,MAAM,OAAO,UAAU,GAAG,GAAG;AAC7B,OAAI,CAAC,SAAS,CAAC,KAAM;AACrB,OAAI,MAAM,YAAY,kBAAkB,OAAO;AAC7C,UAAM,gBAAgB;AACtB,SAAK,OAAO;cACH,CAAC,MAAM,YAAY,kBAAkB,MAAM;AACpD,UAAM,gBAAgB;AACtB,UAAM,OAAO;;;;;oBAx7BG;GAClB,WAAW,EAAE,MAAM,SAAS;GAC5B,SAAS,EAAE,MAAM,SAAS;GAC1B,YAAY,EAAE,MAAM,SAAS;GAC7B,OAAO,EAAE,WAAW,OAAO;GAC3B,UAAU,EAAE,WAAW,OAAO;GAC9B,aAAa,EAAE,MAAM,SAAS;GAC9B,WAAW,EAAE,WAAW,OAAO;GAC/B,aAAa,EAAE,WAAW,OAAO;GAClC;;;gBAgBe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA41BnB,AAAQ,KAAK,MAAc,QAAkB;AAC3C,OAAK,cACH,IAAI,YAAY,MAAM;GAAE;GAAQ,SAAS;GAAM,UAAU;GAAM,CAAC,CACjE;;CAGH,AAAQ,aACN,KACA,OACA,YAAY,WACZ,WAA+C,YAC/C;AACA,SAAO,MACH,IAAI;kBACM,UAAU;iBACX,IAAI;;;yBAGI,KAAK,KAAK,qBAAqB,EAAE,UAAU,CAAC,CAAC;aACzD,MAAM;aAEX;;CAGN,AAAQ,WAAW,OAAe;EAChC,MAAM,UAAU,OAAO;AACvB,OAAK,gBAAgB,mBAAmB,cAAc,UAAU;AAChE,OAAK,aAAa;AAClB,OAAK,eAAe;AACpB,EAAK,KAAK,eAAe,WAAW;AAClC,QAAK,WACF,cAAiC,gBAAgB,EAChD,OAAO;IACX;;CAGJ,AAAQ,cAAoB;AAC1B,OAAK,aAAa;AAClB,OAAK,eAAe;AACpB,EAAK,KAAK,eAAe,WAAW,KAAK,eAAe,OAAO,CAAC;;CAgClE,AAAQ,kBAAkB,QAAQ,yBAAyB;AACzD,SAAO,IAAI;;;gBAGC,UACR,UAAU,0BACN,KAAK,WAAW,MAAM,GACtB,KAAK,KAAK,sBAAsB,CAAC;;QAErC,KAAK,cAAc,WAAW,kBAAkB,MAAM;;;CAI5D,AAAQ,oBACN,MACA;EACA,MAAM,QAAQ,SAAS;EACvB,MAAM,UAAU,SAAS;EACzB,MAAM,YAAY,SAAS;EAC3B,MAAM,0BACJ,SAAS,WACT,KAAK,gBACJ,KAAK,aAAa,QACjB,KAAK,SAAS,cAAc,UAAU;EAC1C,MAAM,iBAAiB,SAAS,UAAU,IAAI;EAC9C,MAAM,iBAAiB,QAAS,KAAK,UAAU,sBAAsB,IAAK;EAC1E,MAAM,QAAQ,YACV,mCACA,SAAS,UACP,0BACE,+BACA,iCACF,QACE,6BACA;EACR,MAAM,YACJ,KAAK,UAAU,cAAc,UAAU,eACnC,KAAK,SAAS,cAAc,YAC5B;AAEN,SAAO,IAAI;;;;;;uCAMwB,eAAe;;;;;0BAK3B,iBAAiB,IAAK,IAAI;;;;;;;;;;wBAWzC,YACI,kBACA,SAAS,UACP,YACA,WACP;;;wCAG6B,SAAS,UAAU,MAAM,IAAI;cAEvD,YACI,IAAI;;sBAGJ,QACL;;;cAIC,0BACI,oBACA,2BACL;;;cAIC,0BACI,gGACA,uDACL;;;0BAGa,SAAS,UAAU,YAAY,GAAG;;;;;;;;6CAQf,MAAM;YAEvC,YACI,IAAI;;;;;;;;;4BASQ,UAAiB,KAAK,WAAW,MAAM,CAAC;;;;wBAKpD,IAAI;;mDAE+B,eAAe;;;kBAIhD,SAAS,UACL,KAAK,aACH,KAAK,UAAU,MAAM,QAAQ,MAC7B,mBACA,qBACA,OACD,GACD,IAAI;;wBAGT;sBAEN;YAEC,YACI,UACA,IAAI;;;;wBAII,WAAW,MAAM,oBAAoB;;;sBAIvC,QACI,sBACA,UACE,qBACA,0BACE,+BACA,2BACT;;;0BAIV;;;;;;;;;CAUT,AAAQ,iBACN,SACA,MACA,YACA;AACA,MAAI,cAAc,EAAG,QAAO;AAC5B,SAAO,IAAI,uCAAuC,QAAQ;sCACxB,KAAK,MAAM,WAAW;;oBAExC,QAAQ,EAAE;uBACP,KAAK,KAAK,iBAAiB;GAAE;GAAS,MAAM,OAAO;GAAG,CAAC,CAAC;;;;;oBAK3D,QAAQ,WAAW;uBAChB,KAAK,KAAK,iBAAiB;GAAE;GAAS,MAAM,OAAO;GAAG,CAAC,CAAC;;;;;;CAO7E,AAAQ,eAAe,SAAmC;AACxD,SAAO,IAAI;;;;eAIA,QAAQ,UAAU;;;;;;yBAMR;AACb,QAAK,oBAAoB;AACzB,QAAK,eAAe;IACpB;;;;;;UAOF,QAAQ,SAAS,WAAW,IACxB,IAAI;;kBAGJ,QAAQ,SAAS,KAAK,aACpB,SAAS,WAAW,gBAChB,IAAI;;wBAGJ,IAAI;;;mCAIF,KAAK,KAAK,0BAA0B;GAClC,UAAU,SAAS;GACnB,WAAW,SAAS,WAAW;GAChC,CAAC,CAAC;;;sBAIH,SAAS,cACT,UAAU,SAAS,SAAS,MAAM,GAAG,EAAE,GACxC;;6BAGN,CACN;;QAGD,QAAQ,oBACJ,IAAI;;gBAGJ,QACL;;;CAIL,AAAQ,cAAc,SAAmC;AACvD,OAAK,oBAAoB,QAAQ;AACjC,OAAK,KAAK,2BAA2B;AACrC,OAAK,eAAe;;CAGtB,AAAQ,uBAAuB,WAA2B;EACxD,MAAM,YAAY,UAAU,QAAQ,IAAI;AACxC,SAAO,cAAc,KAAK,YAAY,UAAU,MAAM,GAAG,YAAY,EAAE;;CAGzE,AAAQ,aAAa,UAAuC;EAC1D,MAAM,eAAe,SAAS,WAAW,MAAM,IAAI,MAAM;EACzD,MAAM,cACJ,SAAS,cAAc,UAAU,eAC7B,SAAS,cAAc,UAAU,KACjC;EACN,MAAM,eAAe,GAAG,SAAS,WAAW,GAAG,YAAY,GAAG,SAAS,WAAW,KAAK,GAAG,SAAS,WAAW,MAAM,KAAK,UAAU,MAAM,GAAG,CAAC,KAAK,IAAI;AACtJ,MAAI,iBAAiB,KAAK,cAAc;AACtC,QAAK,eAAe;AACpB,QAAK,kBACH,SAAS,WAAW,SAAS,IAAI,eAAe;;AAEpD,SAAO,IAAI;;;qCAGsB,SAAS,WAAW,MAAM;UAErD,SAAS,wBAAwB,IAC7B,KAAK,aACH,SAAS,MAAM,YACf,GAAG,SAAS,sBAAsB,GAAG,SAAS,0BAA0B,IAAI,UAAU,SAAS,2BAC/F,eACA,aACD,GACD,QACL;;QAGD,SAAS,WAAW,MAAM,WAAW,IACjC,IAAI;;;;;;;gBAQJ,IAAI;cACF,SAAS,WAAW,MAAM,KAAK,UAAU;GACzC,MAAM,OAAO,KAAK,oBAAoB,MAAM;AAC5C,UAAO,IAAI;sBACH,MAAM,KAAK;qBACZ,MAAM,YAAY;;;oBAInB,MAAM,gBACF,IAAI;;uCAEW,KAAK,cAAc,MAAM,cAAe,CAAC;;0BAEtD,KAAK,uBACL,MAAM,cAAc,UACrB,CAAC;6BACG,MAAM,cAAc,iBAAiB;4BAEtC,MAAM,cAAc,qBAAqB,IACrC,WACA,UACL;;mCAGH,IAAI;;0BAGT;;;;0BAIO,KAAK;6BACF,UAAiB;IAC1B,MAAM,WAAY,MAAM,cACrB;AACH,QAAI,aAAa,KAAM;AACvB,SAAK,kBAAkB,WAAW,MAAM,KAAK;AAC7C,SAAK,KAAK,yBAAyB,EACjC,QAAQ,WAAW,aAAa,aACjC,CAAC;AACF,SAAK,eAAe;KACpB;;;yBAGK,MAAM,QAAQ;;;IAGzB,CAAC;kBAER;QACC,KAAK,iBACL,UACA,SAAS,WAAW,MACpB,SAAS,WAAW,WACrB,CAAC;;;CAIN,AAAQ,eAAe,UAAuC;EAC5D,MAAM,WAAW,SAAS,aAAa,MAAM,MAC1C,YAAY,QAAQ,OAAO,KAAK,kBAClC;AACD,SAAO,IAAI;;;;;;YAMH,SAAS,WAAW,QAAQ,IAAI,kBAAkB,WAAW;;qCAEpC,SAAS,aAAa,MAAM;;QAGzD,SAAS,aAAa,MAAM,WAAW,IACnC,IAAI;;gBAGJ,IAAI;;;;cAIF,SAAS,aAAa,MAAM,KAC3B,YAAY,IAAI;;gCAEC,UAAU,OAAO,QAAQ,GAAG;;+BAG1C,UAAU,OAAO,QAAQ,MACnB,KAAK,oBAAoB,MAAO,KAAK,eAAe,IACtD,KAAK,cAAc,QAAQ,CAAC;;;wBAG1B,QAAQ,UAAU;uBACnB,QAAQ,OAAO;;;qBAGjB,QAAQ,iBAAiB;oBAC1B,QAAQ,qBAAqB,IAAI,WAAW,UAAU;;yBAG7D,CAAC;kBAEP;QACC,WAAW,KAAK,eAAe,SAAS,GAAG,QAAQ;QACnD,KAAK,iBACL,YACA,SAAS,aAAa,MACtB,SAAS,aAAa,WACvB,CAAC;;;CAIN,AAAQ,cAAc,UAAuC;EAC3D,MAAM,gBAAgB,SAAS,WAAW,MACvC,KAAK,UAAU,MAAM,cAAc,CACnC,MAAM,YAAY,SAAS,OAAO,KAAK,kBAAkB;AAC5D,SAAO,IAAI;QAEP,SAAS,qBAAqB,IAC1B,IAAI;;;;;;gBAMA,KAAK,aACL,SAAS,MAAM,MACf,mBACA,uBACA,OACD,CAAC;;wBAGJ,QACL;QACC,KAAK,aAAa,SAAS,CAAC;QAC5B,gBAAgB,KAAK,eAAe,cAAc,GAAG,QAAQ;QAC7D,KAAK,eAAe,SAAS,CAAC;;;CAIpC,AAAQ,mBAAmB;AACzB,MAAI,CAAC,KAAK,MAAO,QAAO;AACxB,SAAO,IAAI;cACD,KAAK,MAAM;;;;uBAIF,KAAK,KAAK,iBAAiB,CAAC;;;;;;CAOjD,AAAQ,mBAAmB,UAAuC;AAChE,SAAO,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA8BP,KAAK,aACL,SAAS,MAAM,UACf,qBACA,cACA,WACD;;CAGL,AAAQ,mBAAmB,OAKxB;AACD,SAAO,IAAI,iCAAiC,MAAM,QAAQ,UAAU,GAAG;;;gBAG3D,MAAM,MAAM;YAChB,MAAM,OAAO,IAAI,MAAM,MAAM,KAAK,QAAQ,QAAQ;;UAEpD,MAAM,UAAU,QAAQ;;;;CAKhC,SAAS;EACP,MAAM,QAAQ,wBAAwB;GACpC,WAAW,KAAK;GAChB,SAAS,KAAK;GACd,OAAO,KAAK;GACZ,UAAU,KAAK;GACf,aAAa,KAAK;GACnB,CAAC;EACF,IAAI;AACJ,MAAI,UAAU,UACZ,WAAU,IAAI;;;;;WAKL,UAAU,QACnB,WAAU,KAAK,mBAAmB;GAChC,OAAO;GACP,MAAM,KAAK,SAAS;GACpB,OAAO;GACP,QAAQ,IAAI;;;yBAGK,KAAK,KAAK,iBAAiB,CAAC;;;;GAI9C,CAAC;WACO,UAAU,qBACnB,WAAU,KAAK,mBAAmB;GAChC,OAAO;GACP,QAAQ,KAAK,aACX,KAAK,SAAU,MAAM,UACrB,mBACA,WACA,WACD;GACF,CAAC;WACO,UAAU,UACnB,WAAU,KAAK,oBAAoB,YAAY;WACtC,UAAU,UAGnB,WAAU;WACD,UAAU,QACnB,WAAU,KAAK,oBAAoB,QAAQ;WAClC,UAAU,YACnB,WAAU,KAAK,oBAAoB,UAAU;WACpC,UAAU,QACnB,WAAU,KAAK,oBAAoB,QAAQ;WAClC,UAAU,QACnB,WAAU,KAAK,mBAAmB,KAAK,SAAU;MAEjD,WAAU,KAAK,cAAc,KAAK,SAAU;EAG9C,MAAM,QACJ,UAAU,WAAW,CAAC,KAAK,WAAW,UAAU,KAAK,kBAAkB;AAEzE,SAAO,IAAI,gDAAgD,MAAM;;;;;;YAOzD,KAAK,aACD,IAAI;;oBAGJ,QACL;;UAED,MAAM;UACN,QAAQ;;QAGV,KAAK,aACD,IAAI;;;;;;yBAMS,KAAK,oBAAoB;;;;;;;;;;iCAUjB,KAAK,aAAa,CAAC;;;;;qBAK/B,KAAK,YAAY;gBAEtB,KAAK,cAAc,UACf,IAAI;;;;wBAKJ,QACL;;;;iCAIkB,KAAK,aAAa,CAAC;;;;;;iCAMnB,KAAK,KAAK,sBAAsB,CAAC;;oBAG9C,KAAK,cAAc,WACf,kBACA,wBACL;;;;oBAKP;;;AAKZ,IAAI,CAAC,eAAe,IAAI,oBAAoB,CAC1C,gBAAe,OAAO,qBAAqB,gBAAgB"}
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"
@@ -4915,8 +4916,11 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
4915
4916
  this.learningPollTimer = null;
4916
4917
  this.learningPollFailureCount = 0;
4917
4918
  this.learningSetupMarker = null;
4919
+ this.learningSetupCopyRequest = 0;
4918
4920
  this.learningSetupUnsubscribe = null;
4919
4921
  this.learningPromptCopyState = "idle";
4922
+ this.learningPromptRecopyState = "idle";
4923
+ this.learningPromptRecopyTimer = null;
4920
4924
  this.learningViewedState = null;
4921
4925
  this._recallResults = null;
4922
4926
  this._recallLoading = false;
@@ -5080,6 +5084,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5080
5084
  this.launcherHudIntroStartTimer = null;
5081
5085
  this.launcherHudIntroEndTimer = null;
5082
5086
  this.inspectorDismissedUntil = null;
5087
+ this.lastReportedInspectorVisibility = null;
5083
5088
  this.inspectorDismissalTimer = null;
5084
5089
  this.hudLandingMenu = null;
5085
5090
  this.pillOutcome = null;
@@ -5262,17 +5267,30 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5262
5267
  return false;
5263
5268
  }
5264
5269
  };
5265
- this.handleLearningSetupCopy = async (event) => {
5270
+ this.handleLearningSetupCopy = async (event, recopy = false) => {
5266
5271
  const service = this.getHomeFeaturePromptTarget("threads");
5267
5272
  if (!service || !this.core?.runtimeUrl) return;
5273
+ const request = ++this.learningSetupCopyRequest;
5268
5274
  const copied = await this.copyFeaturePromptToClipboard(service, event, this.getOnboardingRunId());
5275
+ if (request !== this.learningSetupCopyRequest) return;
5269
5276
  if (!this.core.telemetryDisabled) require_telemetry.trackLearningSetupPromptClicked({ outcome: copied ? "success" : "failure" });
5270
5277
  if (!copied) {
5271
- this.learningPromptCopyState = "error";
5278
+ if (recopy) {
5279
+ this.cancelLearningPromptRecopyReset();
5280
+ this.learningPromptRecopyState = "error";
5281
+ } else this.learningPromptCopyState = "error";
5272
5282
  this.requestUpdate();
5273
5283
  return;
5274
5284
  }
5275
- this.learningPromptCopyState = "copied";
5285
+ if (recopy) {
5286
+ this.cancelLearningPromptRecopyReset();
5287
+ this.learningPromptRecopyState = "copied";
5288
+ this.learningPromptRecopyTimer = setTimeout(() => {
5289
+ this.learningPromptRecopyTimer = null;
5290
+ this.learningPromptRecopyState = "idle";
5291
+ this.requestUpdate();
5292
+ }, LEARNING_RECOPY_CONFIRMATION_MS);
5293
+ } else this.learningPromptCopyState = "copied";
5276
5294
  this.learningSetupMarker = require_learning_setup.writeLearningSetupMarker({
5277
5295
  runtimeUrl: this.core.runtimeUrl,
5278
5296
  agentId: this.getLearningAgentId()
@@ -5282,6 +5300,17 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5282
5300
  this.requestUpdate();
5283
5301
  this.refreshLearningSnapshot({ preserve: false });
5284
5302
  };
5303
+ this.handleLearningGoBack = () => {
5304
+ this.learningSetupCopyRequest += 1;
5305
+ this.cancelLearningPromptRecopyReset();
5306
+ require_learning_setup.clearLearningSetupMarker();
5307
+ this.learningSetupMarker = null;
5308
+ this.learningPromptCopyState = "idle";
5309
+ this.learningPromptRecopyState = "idle";
5310
+ this.cancelLearningPoll();
5311
+ this.requestUpdate();
5312
+ this.trackLearningViewState();
5313
+ };
5285
5314
  this.handleLearningPage = (event) => {
5286
5315
  const { section, page } = event.detail;
5287
5316
  const currentPage = section === "skills" ? this.learningSnapshot?.skillsPage.page ?? 1 : this.learningSnapshot?.insightsPage.page ?? 1;
@@ -6477,7 +6506,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6477
6506
  require_telemetry.maybeShowDisclosure();
6478
6507
  }
6479
6508
  this.flushPendingWhatsNewTelemetry();
6480
- if (this.isOpen && this.selectedMenu === "memories") {
6509
+ if (this.isLearningStatusVisible()) {
6481
6510
  this.clearLearningSnapshot();
6482
6511
  this.refreshLearningSnapshot({ preserve: false });
6483
6512
  }
@@ -6505,7 +6534,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6505
6534
  if (identity !== this.learningProjectIdentity) {
6506
6535
  this.learningProjectIdentity = identity;
6507
6536
  this.clearLearningSnapshot();
6508
- if (this.isOpen && this.selectedMenu === "memories") this.refreshLearningSnapshot({ preserve: false });
6537
+ if (this.isLearningStatusVisible()) this.refreshLearningSnapshot({ preserve: false });
6509
6538
  }
6510
6539
  this.requestUpdate();
6511
6540
  } } : {},
@@ -6670,6 +6699,10 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6670
6699
  if (this.selectedContext !== "all-agents" && this.core?.agents[this.selectedContext]) return this.selectedContext;
6671
6700
  return null;
6672
6701
  }
6702
+ /** Whether a visible surface needs the current Learning connection status. */
6703
+ isLearningStatusVisible() {
6704
+ return this.launcherHudOpen || this.isOpen && (this.selectedMenu === "home" || this.selectedMenu === "memories");
6705
+ }
6673
6706
  isLearningSetupActive() {
6674
6707
  const runtimeUrl = this.core?.runtimeUrl;
6675
6708
  if (!runtimeUrl) return false;
@@ -6724,6 +6757,12 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6724
6757
  this.learningAbortController?.abort();
6725
6758
  this.learningAbortController = null;
6726
6759
  }
6760
+ cancelLearningPromptRecopyReset() {
6761
+ if (this.learningPromptRecopyTimer !== null) {
6762
+ clearTimeout(this.learningPromptRecopyTimer);
6763
+ this.learningPromptRecopyTimer = null;
6764
+ }
6765
+ }
6727
6766
  detachFromCore() {
6728
6767
  this.threadCapabilityGeneration += 1;
6729
6768
  this.threadCapabilityEnabled = null;
@@ -6745,6 +6784,8 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6745
6784
  this._memoriesRealtimeStatus = "connecting";
6746
6785
  this._memorySubscribed = false;
6747
6786
  this._memoryStoreUnsupported = false;
6787
+ this.cancelLearningPromptRecopyReset();
6788
+ this.learningPromptRecopyState = "idle";
6748
6789
  this._recallSeq += 1;
6749
6790
  this._recallResults = null;
6750
6791
  this._recallLoading = false;
@@ -6799,7 +6840,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6799
6840
  runtimeUrl: this.core.runtimeUrl,
6800
6841
  agentId: learningAgentId
6801
6842
  });
6802
- if (previousLearningAgentId !== learningAgentId && this.isOpen && this.selectedMenu === "memories") {
6843
+ if (previousLearningAgentId !== learningAgentId && this.isLearningStatusVisible()) {
6803
6844
  this.clearLearningSnapshot();
6804
6845
  this.refreshLearningSnapshot({ preserve: false });
6805
6846
  }
@@ -8883,8 +8924,8 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
8883
8924
 
8884
8925
  .cpk-launcher-hud__toggle[data-enabled="true"]
8885
8926
  .cpk-launcher-hud__toggle-track {
8886
- border-color: var(--hud-accent);
8887
- background: color-mix(in srgb, var(--hud-accent) 76%, transparent);
8927
+ border-color: #087653;
8928
+ background: #087653;
8888
8929
  }
8889
8930
 
8890
8931
  .cpk-launcher-hud__toggle[data-enabled="true"]
@@ -8907,8 +8948,8 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
8907
8948
  .cpk-launcher-hud[data-color-scheme="light"]
8908
8949
  .cpk-launcher-hud__toggle[data-enabled="true"]
8909
8950
  .cpk-launcher-hud__toggle-track {
8910
- border-color: #6757b0;
8911
- background: #7563c7;
8951
+ border-color: #087653;
8952
+ background: #087653;
8912
8953
  }
8913
8954
 
8914
8955
  .cpk-launcher-hud[data-color-scheme="light"]
@@ -9566,6 +9607,11 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
9566
9607
  else this.removeAttribute("data-docked");
9567
9608
  }
9568
9609
  updated() {
9610
+ const visible = !this.isInspectorDismissed;
9611
+ if (visible !== this.lastReportedInspectorVisibility) {
9612
+ this.lastReportedInspectorVisibility = visible;
9613
+ this.dispatchEvent(new CustomEvent("cpk-inspector-visibility-change", { detail: { visible } }));
9614
+ }
9569
9615
  this.syncInspectorPortal();
9570
9616
  this.syncThreadsExampleOverviewVideo();
9571
9617
  this.maybeTrackInspectorMetadataViews();
@@ -9811,6 +9857,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
9811
9857
  this.resolveLauncherHudSide();
9812
9858
  this.launcherHudIntro = true;
9813
9859
  this.launcherHudOpen = true;
9860
+ this.refreshLearningSnapshot({ preserve: true });
9814
9861
  this.requestUpdate();
9815
9862
  this.launcherHudIntroEndTimer = setTimeout(() => {
9816
9863
  this.launcherHudIntroEndTimer = null;
@@ -9858,6 +9905,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
9858
9905
  }
9859
9906
  if (this.launcherHudOpen) return;
9860
9907
  this.launcherHudOpen = true;
9908
+ this.refreshLearningSnapshot({ preserve: true });
9861
9909
  this.requestUpdate();
9862
9910
  }
9863
9911
  closeLauncherHud() {
@@ -10252,7 +10300,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
10252
10300
  type: lastRuntimeEvent.type,
10253
10301
  timestamp: lastRuntimeEvent.timestamp
10254
10302
  } : void 0,
10255
- memoriesOn: this._memorySubscribed && !this._memoriesLoading && this._memoriesAvailable,
10303
+ learningOn: this.learningSupported && this.learningError === null && this.learningSnapshot?.configuration.state === "configured",
10256
10304
  a2uiOn: this._core?.a2uiEnabled === true,
10257
10305
  openGenUiOn: this._core?.openGenerativeUIEnabled === true,
10258
10306
  suggestionsOn: this._core?.suggestions === true,
@@ -11830,7 +11878,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
11830
11878
  }
11831
11879
  this.ensureAnnouncementLoading();
11832
11880
  this.isOpen = true;
11833
- if (this.selectedMenu === "memories") this.refreshLearningSnapshot({ preserve: this.learningSnapshot !== null });
11881
+ if (this.isLearningStatusVisible()) this.refreshLearningSnapshot({ preserve: this.learningSnapshot !== null });
11834
11882
  this.cancelGestureTail();
11835
11883
  this.persistState();
11836
11884
  this.trackOpened(source, hadUnseenAnnouncement, firstOpen, activeSignalAtOpen);
@@ -13516,9 +13564,12 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
13516
13564
  .snapshot=${this.learningSnapshot}
13517
13565
  .setupActive=${this.isLearningSetupActive()}
13518
13566
  .copyState=${this.learningPromptCopyState}
13567
+ .recopyState=${this.learningPromptRecopyState}
13519
13568
  .setupPrompt=${this.getHomeFeaturePromptTarget("threads") ? require_home_briefing.homeFeatureImplementationPrompt(this.getHomeFeaturePromptTarget("threads"), { onboardingRunId: this.getOnboardingRunId() }) : ""}
13520
13569
  @learning-retry=${() => this.refreshLearningSnapshot({ preserve: this.learningSnapshot !== null })}
13521
13570
  @learning-copy-setup=${(event) => this.handleLearningSetupCopy(event)}
13571
+ @learning-recopy-setup=${(event) => this.handleLearningSetupCopy(event, true)}
13572
+ @learning-go-back=${this.handleLearningGoBack}
13522
13573
  @learning-page=${(event) => this.handleLearningPage(event)}
13523
13574
  @learning-open-evidence=${(event) => this.handleLearningEvidence(event)}
13524
13575
  @learning-evidence-opened=${() => {
@@ -14575,7 +14626,10 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
14575
14626
  this.cancelLearningPoll();
14576
14627
  this.cancelLearningRequest();
14577
14628
  }
14578
- if (key === "home" && previousMenu !== "home") this.homeViewedThisOpen = false;
14629
+ if (key === "home" && previousMenu !== "home") {
14630
+ this.refreshLearningSnapshot({ preserve: true });
14631
+ this.homeViewedThisOpen = false;
14632
+ }
14579
14633
  if (key === "ag-ui-events" || key === "agents") {
14580
14634
  if (!(this.pendingScrollToEventId !== null || this.pendingScrollToToolCallId !== null)) requestAnimationFrame(() => {
14581
14635
  const scroller = this.activeRoot.querySelector("#cpk-main-scroll");
@@ -14607,7 +14661,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
14607
14661
  this.expandedRows.clear();
14608
14662
  this.autoSelectLatestThread();
14609
14663
  if (this.selectedMenu === "playground") this.startPlaygroundSession(false);
14610
- else if (this.selectedMenu === "memories") {
14664
+ else if (this.isLearningStatusVisible()) {
14611
14665
  this.clearLearningSnapshot();
14612
14666
  this.refreshLearningSnapshot({ preserve: false });
14613
14667
  }