@posthog/wizard 2.73.0 → 2.73.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{add-mcp-server-to-clients-B8t2xAPf.js → add-mcp-server-to-clients-D47ONFCD.js} +4 -4
- package/dist/{add-mcp-server-to-clients-B8t2xAPf.js.map → add-mcp-server-to-clients-D47ONFCD.js.map} +1 -1
- package/dist/{agent-interface-tcCEmyPQ.js → agent-interface-CQ_iz7g7.js} +7 -7
- package/dist/{agent-interface-tcCEmyPQ.js.map → agent-interface-CQ_iz7g7.js.map} +1 -1
- package/dist/{agent-prompt-loader-V2smIztP.js → agent-prompt-loader-Dh2CZEw4.js} +5 -5
- package/dist/{agent-prompt-loader-V2smIztP.js.map → agent-prompt-loader-Dh2CZEw4.js.map} +1 -1
- package/dist/{agent-runner-DUyO1Ehj.js → agent-runner-kj8juD_r.js} +14 -14
- package/dist/{agent-runner-DUyO1Ehj.js.map → agent-runner-kj8juD_r.js.map} +1 -1
- package/dist/analytics-BYknS_x4.js +2 -0
- package/dist/{analytics-DsMH06jo.js → analytics-DHkqXgxG.js} +2 -2
- package/dist/{analytics-DsMH06jo.js.map → analytics-DHkqXgxG.js.map} +1 -1
- package/dist/{api-R6bXIwII.js → api-BM5Gaf2x.js} +3 -3
- package/dist/{api-R6bXIwII.js.map → api-BM5Gaf2x.js.map} +1 -1
- package/dist/bin.js +45 -45
- package/dist/bin.js.map +1 -1
- package/dist/{bounded-fs-BV-KhOtU.js → bounded-fs-Byv2xRSy.js} +3 -3
- package/dist/{bounded-fs-BV-KhOtU.js.map → bounded-fs-Byv2xRSy.js.map} +1 -1
- package/dist/{ci-install-mR8CeIt2.js → ci-install-BUUD2hSG.js} +4 -4
- package/dist/{ci-install-mR8CeIt2.js.map → ci-install-BUUD2hSG.js.map} +1 -1
- package/dist/{debug-PfLVvLhT.js → debug-C14qe0b-.js} +1 -1
- package/dist/{debug-aXxgvtal.js → debug-D0k3Quos.js} +3 -3
- package/dist/{debug-aXxgvtal.js.map → debug-D0k3Quos.js.map} +1 -1
- package/dist/{env-api-key-_lBt9tHl.js → env-api-key-CBjWUJTZ.js} +2 -2
- package/dist/{env-api-key-_lBt9tHl.js.map → env-api-key-CBjWUJTZ.js.map} +1 -1
- package/dist/{environment-DRhZbhxU.js → environment-DqdmG3WX.js} +4 -4
- package/dist/{environment-DRhZbhxU.js.map → environment-DqdmG3WX.js.map} +1 -1
- package/dist/{file-watcher-BZw1_Y84.js → file-watcher-CxStDuTR.js} +2 -2
- package/dist/{file-watcher-BZw1_Y84.js.map → file-watcher-CxStDuTR.js.map} +1 -1
- package/dist/{headless-ui-Cdqfufhk.js → headless-ui-DC1Qus7M.js} +2 -2
- package/dist/{headless-ui-Cdqfufhk.js.map → headless-ui-DC1Qus7M.js.map} +1 -1
- package/dist/{interactive-BCI9b-dp.js → interactive-DeNrHRZE.js} +2 -2
- package/dist/{interactive-BCI9b-dp.js.map → interactive-DeNrHRZE.js.map} +1 -1
- package/dist/{mcp-CzB3lWsm.js → mcp-Bnjc-Qsz.js} +2 -2
- package/dist/{mcp-CzB3lWsm.js.map → mcp-Bnjc-Qsz.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-RZGAH4YO.js → mcp-prompt-streaming-Va6vRL7E.js} +4 -4
- package/dist/{mcp-prompt-streaming-RZGAH4YO.js.map → mcp-prompt-streaming-Va6vRL7E.js.map} +1 -1
- package/dist/{non-interactive-CgjTZZ9J.js → non-interactive-ZACUU6DC.js} +2 -2
- package/dist/{non-interactive-CgjTZZ9J.js.map → non-interactive-ZACUU6DC.js.map} +1 -1
- package/dist/{orchestrator-tools-OWgPinUt.js → orchestrator-tools-BI3suN6p.js} +3 -3
- package/dist/{orchestrator-tools-OWgPinUt.js.map → orchestrator-tools-BI3suN6p.js.map} +1 -1
- package/dist/{package-manager-B-Z3IVYu.js → package-manager-DgRcS6CY.js} +2 -2
- package/dist/{package-manager-B-Z3IVYu.js.map → package-manager-DgRcS6CY.js.map} +1 -1
- package/dist/{pi-CLLkGrND.js → pi-DbEYScTs.js} +11 -11
- package/dist/{pi-CLLkGrND.js.map → pi-DbEYScTs.js.map} +1 -1
- package/dist/{playground-D1TgX0EU.js → playground-xa1G6pym.js} +6 -6
- package/dist/{playground-D1TgX0EU.js.map → playground-xa1G6pym.js.map} +1 -1
- package/dist/{posthog-CMef8KLR.js → posthog-Dk8S5c6h.js} +2 -2
- package/dist/{posthog-CMef8KLR.js.map → posthog-Dk8S5c6h.js.map} +1 -1
- package/dist/{posthog-integration-wiunwp8X.js → posthog-integration-BG5Y9Fb4.js} +12 -12
- package/dist/{posthog-integration-wiunwp8X.js.map → posthog-integration-BG5Y9Fb4.js.map} +1 -1
- package/dist/{provisioning-94OneD64.js → provisioning-e7J3SvpF.js} +3 -3
- package/dist/{provisioning-94OneD64.js.map → provisioning-e7J3SvpF.js.map} +1 -1
- package/dist/{queue-tools--k2v8QYY.js → queue-tools-C3D_nwy_.js} +3 -3
- package/dist/{queue-tools--k2v8QYY.js.map → queue-tools-C3D_nwy_.js.map} +1 -1
- package/dist/{registry-C60oJv02.js → registry-Bw-e1Fes.js} +5 -5
- package/dist/{registry-C60oJv02.js.map → registry-Bw-e1Fes.js.map} +1 -1
- package/dist/{security-DnOP36w-.js → security-BUg5_2uC.js} +5 -5
- package/dist/{security-DnOP36w-.js.map → security-BUg5_2uC.js.map} +1 -1
- package/dist/{setup-utils-BwX6QmL_.js → setup-utils-CzMg2Vpy.js} +8 -8
- package/dist/{setup-utils-BwX6QmL_.js.map → setup-utils-CzMg2Vpy.js.map} +1 -1
- package/dist/{start-tui-C3PdKFtP.js → start-tui-Kt61g7LE.js} +20 -20
- package/dist/{start-tui-C3PdKFtP.js.map → start-tui-Kt61g7LE.js.map} +1 -1
- package/dist/{steps-BpCRk8Ef.js → steps-De2a1a0X.js} +7 -7
- package/dist/{steps-BpCRk8Ef.js.map → steps-De2a1a0X.js.map} +1 -1
- package/dist/{store-EzqWyb60.js → store-DDrR7nF6.js} +4 -4
- package/dist/{store-EzqWyb60.js.map → store-DDrR7nF6.js.map} +1 -1
- package/dist/{subagent-DwdrVprk.js → subagent-cD2JOzo1.js} +2 -2
- package/dist/{subagent-DwdrVprk.js.map → subagent-cD2JOzo1.js.map} +1 -1
- package/dist/{task-CrXgNEUB.js → task-FBY3mllc.js} +12 -12
- package/dist/{task-CrXgNEUB.js.map → task-FBY3mllc.js.map} +1 -1
- package/dist/{task-stream-ZBbfHo7l.js → task-stream-BjTFIY4l.js} +4 -4
- package/dist/{task-stream-ZBbfHo7l.js.map → task-stream-BjTFIY4l.js.map} +1 -1
- package/dist/{tasks-CbMEKWZ9.js → tasks-BjevyqMO.js} +2 -2
- package/dist/{tasks-CbMEKWZ9.js.map → tasks-BjevyqMO.js.map} +1 -1
- package/dist/{telemetry-B2dz2-PT.js → telemetry-Asp60nwm.js} +3 -3
- package/dist/{telemetry-B2dz2-PT.js.map → telemetry-Asp60nwm.js.map} +1 -1
- package/dist/{terminal-DTe59M4j.js → terminal-CVgx_zHz.js} +11 -11
- package/dist/{terminal-DTe59M4j.js.map → terminal-CVgx_zHz.js.map} +1 -1
- package/dist/{tools-DZ9lZgJI.js → tools-CPwnElLN.js} +6 -6
- package/dist/{tools-DZ9lZgJI.js.map → tools-CPwnElLN.js.map} +1 -1
- package/dist/{wizard-abort-CUT8MXXt.js → wizard-abort-DKpVH-t6.js} +3 -3
- package/dist/{wizard-abort-CUT8MXXt.js.map → wizard-abort-DKpVH-t6.js.map} +1 -1
- package/dist/{wizard-abort-CfKnrSlX.js → wizard-abort-owSE9WC8.js} +1 -1
- package/dist/{yara-hooks-VvwkZn5s.js → yara-hooks-D-QD1ZCB.js} +4 -4
- package/dist/{yara-hooks-VvwkZn5s.js.map → yara-hooks-D-QD1ZCB.js.map} +1 -1
- package/dist/yara-hooks-DPo3t8nU.js +2 -0
- package/package.json +2 -2
- package/dist/analytics-DEL7clQK.js +0 -2
- package/dist/yara-hooks-CLeMu2EY.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-tui-C3PdKFtP.js","names":["DetectErrorBody","DetectErrorBody","VARIANT_DISPLAY_NAME","MAX_ACTIVITY_LINES","projectLabel","VARIANT_DISPLAY_NAME","join","join","join","getSkillContentBlocks","join","runPluginInstall","runProbe","runSeed"],"sources":["../src/ui/tui/ink-ui.ts","../src/ui/tui/screens/health/HealthCheckScreen.tsx","../src/ui/tui/screens/doctor/DoctorIntroScreen.tsx","../src/ui/tui/screens/doctor/DoctorReportScreen.tsx","../src/ui/tui/screens/SettingsOverrideScreen.tsx","../src/ui/tui/screens/ManagedSettingsScreen.tsx","../src/ui/tui/screens/PortConflictScreen.tsx","../src/ui/tui/screens/TaskNoticeScreen.tsx","../src/ui/tui/screens/ManualAuthCodeScreen.tsx","../src/ui/tui/components/PrivacyPanel.tsx","../src/ui/tui/screens/IntroScreenLayout.tsx","../src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx","../src/ui/tui/screens/RevenueIntroScreen.tsx","../src/ui/tui/screens/WarehouseIntroScreen.tsx","../src/ui/tui/screens/MigrationIntroScreen.tsx","../src/ui/tui/screens/SourceMapsIntroScreen.tsx","../src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts","../src/ui/tui/screens/SourceMapsDetectScreen.tsx","../src/ui/tui/screens/SourceMapsOutroScreen.tsx","../src/ui/tui/screens/AgentSkillIntroScreen.tsx","../src/ui/tui/screens/AiObservabilityIntroScreen.tsx","../src/ui/tui/screens/MetricsIntroScreen.tsx","../src/ui/tui/screens/SelfDrivingIntroScreen.tsx","../src/ui/tui/screens/SelfDrivingIntegrationCheckScreen.tsx","../src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx","../src/ui/tui/screens/SelfDrivingHandoffScreen.tsx","../src/ui/tui/hooks/useGithubConnection.ts","../src/ui/tui/screens/SelfDrivingGitHubScreen.tsx","../src/ui/tui/screens/audit/AuditIntroScreen.tsx","../src/ui/tui/hooks/file-watcher.ts","../src/ui/tui/screens/audit/AuditAreaPane.tsx","../src/ui/tui/screens/audit/slides/events-audit/detectSdk.tsx","../src/ui/tui/screens/audit/slides/events-audit/scanSites.tsx","../src/ui/tui/screens/audit/slides/events-audit/enrichSites.tsx","../src/ui/tui/screens/audit/slides/events-audit/queryVolume.tsx","../src/ui/tui/screens/audit/slides/events-audit/writeReport.tsx","../src/ui/tui/screens/audit/slides/events-audit/createDashboard.tsx","../src/ui/tui/screens/audit/slides/events-audit/uploadNotebook.tsx","../src/ui/tui/screens/audit/slides/events-audit/index.ts","../src/ui/tui/screens/audit/PendingChecksList.tsx","../src/ui/tui/screens/audit/AuditRunScreen.tsx","../src/ui/tui/screens/audit/AuditChecksOutroSection.tsx","../src/ui/tui/screens/audit/AuditOutroScreen.tsx","../src/ui/tui/screens/SetupScreen.tsx","../src/utils/clipboard.ts","../src/ui/tui/screens/AuthScreen.tsx","../src/ui/tui/screens/RunScreen.tsx","../src/ui/tui/screens/KeepSkillsScreen.tsx","../src/ui/tui/screens/ExitScreen.tsx","../src/ui/tui/screens/AuthErrorScreen.tsx","../src/ui/tui/screens/SessionTimeoutScreen.tsx","../src/ui/tui/screens/WizardAskScreen.tsx","../src/steps/add-mcp-server-to-clients/login-client.ts","../src/steps/add-mcp-server-to-clients/browser-client.ts","../src/ui/tui/services/mcp-installer.ts","../src/ui/tui/services/mcp-suggested-prompts-services.ts","../src/ui/tui/screen-registry.tsx","../src/ui/tui/App.tsx","../src/ui/tui/exit-line.ts","../src/ui/tui/start-tui.ts"],"sourcesContent":["/**\n * InkUI — Ink-backed implementation of WizardUI.\n *\n * Translates business logic calls into store setter calls.\n * No direct session mutation. No imperative screen transitions.\n * The router derives the active screen from session state.\n */\n\nimport type {\n WizardUI,\n SpinnerHandle,\n AuthErrorDetail,\n TokenUsageDelta,\n} from '@ui/wizard-ui';\nimport type { WizardStore } from './store.js';\nimport type { SettingsConflict } from '@lib/agent/claude-settings';\nimport type { WizardReadinessResult } from '@lib/health-checks/readiness';\nimport type { ApiUser } from '@lib/api';\nimport type {\n AskAnswers,\n Credentials,\n OutroData,\n PendingQuestion,\n TaskNotice,\n} from '@lib/wizard-session';\nimport { RunPhase, OutroKind } from '@lib/wizard-session';\n\n// Strip ANSI escape codes (chalk formatting) from strings\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\nfunction stripAnsi(s: string): string {\n return s.replace(ANSI_RE, '');\n}\n\nexport class InkUI implements WizardUI {\n constructor(private store: WizardStore) {}\n\n intro(message: string): void {\n this.store.pushStatus(message);\n }\n\n outro(message: string): void {\n this.store.pushStatus(stripAnsi(message));\n\n // Outro data is pushed by agent-runner via setOutroData() above. If it\n // wasn't (e.g. CI path where outro is called directly with just a\n // message), fall back to a minimal success record so the screen still\n // renders something useful.\n const existing = this.store.session.outroData;\n if (!existing) {\n this.store.setOutroData({\n kind: OutroKind.Success,\n message: stripAnsi(message),\n });\n }\n\n // Signal that the main work is done — router resolves to outro\n if (this.store.session.runPhase === RunPhase.Running) {\n this.store.setRunPhase(RunPhase.Completed);\n }\n }\n\n outroError(data: OutroData): void {\n this.store.setOutroData(data);\n // Advance router past the run step so the outro screen renders\n if (this.store.session.runPhase !== RunPhase.Error) {\n this.store.setRunPhase(RunPhase.Error);\n }\n }\n\n waitForOutroDismissed(): Promise<void> {\n return new Promise((resolve) => {\n if (this.store.session.outroDismissed) {\n resolve();\n return;\n }\n const unsub = this.store.subscribe(() => {\n if (this.store.session.outroDismissed) {\n unsub();\n resolve();\n }\n });\n });\n }\n\n setCredentials(credentials: Credentials): void {\n this.store.setCredentials(credentials);\n }\n\n setAccessToken(credentials: Credentials): void {\n this.store.setAccessToken(credentials);\n }\n\n setRoleAtOrganization(role: string | null): void {\n this.store.setRoleAtOrganization(role);\n }\n\n setApiUser(user: ApiUser | null): void {\n this.store.setApiUser(user);\n }\n\n waitForAiOptIn(): Promise<void> {\n // Resolved immediately when no gate is registered (requiresAi: false,\n // no auth step, or CI). Otherwise parks until _checkGates sees the\n // org's approval flip to true — e.g. via [R]etry on the kill screen.\n return this.store.getGate('ai-opt-in');\n }\n\n waitForGate(stepId: string): Promise<void> {\n return this.store.getGate(stepId);\n }\n\n getFrameworkContext(key: string): unknown {\n return this.store.session.frameworkContext[key];\n }\n\n setDetectedFramework(label: string): void {\n this.store.setDetectedFramework(label);\n }\n\n onEnterScreen(screen: string, fn: () => void): void {\n this.store.onEnterScreen(\n screen as Parameters<WizardStore['onEnterScreen']>[0],\n fn,\n );\n }\n\n setLoginUrl(url: string | null): void {\n this.store.setLoginUrl(url);\n }\n\n setAuthorizeUrl(url: string | null): void {\n this.store.setAuthorizeUrl(url);\n }\n\n showBlockingOutage(result: WizardReadinessResult): Promise<void> {\n // In the TUI, the HealthCheckScreen handles outage display.\n // This is only called from agent-runner for the CI fallback path.\n this.store.setReadinessResult(result);\n return Promise.resolve();\n }\n\n setReadinessWarnings(result: WizardReadinessResult): void {\n this.store.setReadinessResult(result);\n }\n\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n port: number;\n user: string;\n }): Promise<void> {\n return this.store.showPortConflict(processInfo);\n }\n\n waitForManualAuthCode(): Promise<string> {\n return this.store.waitForManualAuthCode();\n }\n\n showTaskNotice(notice: TaskNotice): Promise<boolean> {\n return this.store.showTaskNotice(notice);\n }\n\n cancelTaskNotice(): void {\n // Same path as pressing Skip: closes the overlay and resolves the pending\n // showTaskNotice promise with false.\n this.store.resolveTaskNotice(false);\n }\n\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n return this.store.showSettingsOverride(conflicts, backupAndFix);\n }\n\n showAuthError(detail?: AuthErrorDetail): void {\n this.store.showAuthError(detail);\n }\n\n showSessionTimeout(): void {\n this.store.showSessionTimeout();\n }\n\n requestQuestion(question: PendingQuestion): Promise<AskAnswers> {\n return this.store.requestQuestion(question);\n }\n\n cancelPendingQuestion(): void {\n this.store.cancelPendingQuestion();\n }\n\n startRun(): void {\n this.store.setRunPhase(RunPhase.Running);\n }\n\n cancel(message: string): void {\n this.store.pushStatus(message);\n }\n\n log = {\n info: (message: string): void => {\n this.store.pushStatus(message);\n },\n warn: (message: string): void => {\n this.store.pushStatus(message);\n },\n error: (message: string): void => {\n this.store.pushStatus(message);\n },\n success: (message: string): void => {\n this.store.pushStatus(message);\n },\n step: (message: string): void => {\n this.store.pushStatus(message);\n },\n };\n\n note(message: string): void {\n this.store.pushStatus(message);\n }\n\n spinner(): SpinnerHandle {\n return {\n start: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n stop: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n message: (msg?: string) => {\n if (msg) this.store.pushStatus(msg);\n },\n };\n }\n\n pushStatus(message: string): void {\n this.store.pushStatus(message);\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n this.store.syncTodos(todos);\n }\n\n setEventPlan(events: Array<{ name: string; description: string }>): void {\n this.store.setEventPlan(events);\n }\n\n setDashboardUrl(url: string): void {\n this.store.setDashboardUrl(url);\n }\n\n setStage(stage: string): void {\n this.store.setCurrentStage(stage);\n }\n\n setNotebookUrl(url: string): void {\n this.store.setNotebookUrl(url);\n }\n\n setHandoffText(text: string): void {\n this.store.setHandoffText(text);\n }\n\n addTokenUsage(delta: TokenUsageDelta): void {\n this.store.addTokenUsage(delta);\n }\n\n setFinalTokenCostUsd(costUsd: number): void {\n this.store.setFinalTokenCostUsd(costUsd);\n }\n\n setOutroData(data: OutroData): void {\n // Merge in URLs the agent emitted via `[DASHBOARD_URL]` / `[NOTEBOOK_URL]`\n // markers. These land on the live store during the run; agent-runner's\n // `session` snapshot misses them (setKey forks the reference). The live\n // store wins over the `data` payload so a real emission always beats any\n // fallback the program's buildOutroData may have computed from the stale\n // snapshot (e.g. events-audit defaults dashboardUrl to `${cloudUrl}/dashboard`).\n const live = this.store.session;\n this.store.setOutroData({\n ...data,\n dashboardUrl: live.dashboardUrl ?? data.dashboardUrl ?? undefined,\n notebookUrl: live.notebookUrl ?? data.notebookUrl ?? undefined,\n });\n }\n\n setFrameworkContext(key: string, value: unknown): void {\n this.store.setFrameworkContext(key, value);\n }\n}\n","/**\n * HealthCheckScreen — Program screen between Intro and Auth.\n *\n * Three states:\n * 1. Checking: spinner while health check runs\n * 2. Healthy: isComplete returns true, router auto-advances to Auth\n * 3. Blocking outage: shows affected services with Continue/Exit\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport {\n ConfirmationInput,\n LoadingBox,\n ModalOverlay,\n} from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { ServiceHealthList } from '@ui/tui/components/ServiceHealthList';\nimport {\n getBlockingServiceKeys,\n SIGNUP_WIZARD_READINESS_CONFIG,\n} from '@lib/health-checks/readiness';\nimport { ServiceHealthStatus } from '@lib/health-checks/types';\nimport { wizardAbort } from '@utils/wizard-abort';\nimport { ErrorCodes } from '@lib/errors';\nimport { fetchSkillMenu, downloadSkill } from '@lib/wizard-tools';\nimport { GITHUB_SKILLS_BASE_URL } from '@lib/constants';\nimport { useDismissOnAnyKey } from '@ui/tui/hooks/useDismissOnAnyKey';\n\ninterface HealthCheckScreenProps {\n store: WizardStore;\n}\n\nconst EXAMPLE_PROMPT =\n 'Integrate PostHog into this project using the skill files in .posthog/skills/. Read SKILL.md first, then follow the numbered program files in order.';\n\nconst SkillsDownloadedScreen = () => {\n useDismissOnAnyKey(() => process.exit(0));\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text color=\"green\" bold>\n {Icons.check} Skills downloaded to .posthog/skills/\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>\n You can continue setup with another agent using this prompt:\n </Text>\n <Box marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">{EXAMPLE_PROMPT}</Text>\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to exit</Text>\n </Box>\n </Box>\n );\n};\n\nexport const HealthCheckScreen = ({ store }: HealthCheckScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [downloaded, setDownloaded] = useState(false);\n const [downloading, setDownloading] = useState(false);\n\n const result = store.session.readinessResult;\n\n if (downloaded) {\n return <SkillsDownloadedScreen />;\n }\n\n // Still checking — show spinner\n if (!result) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <LoadingBox message=\"Checking service status...\" />\n </Box>\n );\n }\n\n const isSignup = store.session.signup;\n const blockingKeys = getBlockingServiceKeys(\n result.health,\n isSignup ? SIGNUP_WIZARD_READINESS_CONFIG : undefined,\n );\n\n // Signup has a narrower block list (only posthog + llm-gateway), so\n // services like Anthropic can be degraded without blocking. Surface\n // those as dismissable warnings instead of silently proceeding.\n const warningKeys = isSignup\n ? getBlockingServiceKeys(result.health).filter(\n (k) => !blockingKeys.includes(k),\n )\n : [];\n\n const hasHardBlock = blockingKeys.length > 0;\n const displayKeys = hasHardBlock ? blockingKeys : warningKeys;\n if (displayKeys.length === 0) return null;\n\n const isSkillsOriginDown =\n hasHardBlock && blockingKeys.includes('skillsOrigin');\n const canDownloadSkills =\n result.health.skillsOrigin.status === ServiceHealthStatus.Healthy;\n const integration = store.session.integration;\n\n // If every blocking row is `NoConnection` (probe failed, no status-page\n // corroboration), reframe the screen to point at the user's network\n // instead of accusing PostHog of an outage. Mixed Down + NoConnection\n // falls through to the confirmed-outage framing because there's still\n // a real incident underneath.\n const allBlockingHaveNoConnection =\n hasHardBlock &&\n displayKeys.every(\n (k) => result.health[k].status === ServiceHealthStatus.NoConnection,\n );\n\n const title = isSkillsOriginDown\n ? 'Ongoing service disruptions'\n : allBlockingHaveNoConnection\n ? \"Couldn't reach PostHog\"\n : hasHardBlock\n ? 'Ongoing service disruptions'\n : 'Service disruption detected';\n\n const docsUrl = store.session.frameworkConfig?.metadata.docsUrl;\n const description = isSkillsOriginDown\n ? \"The Wizard can't download the skills it needs — neither GitHub Releases nor PostHog's mirror is reachable right now.\"\n : allBlockingHaveNoConnection\n ? \"We couldn't reach these services from this machine. PostHog's status page shows no incidents, so this is most likely a network issue — VPN, firewall, captive portal, or flaky Wi-Fi.\"\n : hasHardBlock\n ? 'The Wizard cannot start while these services are down.'\n : 'Some services are degraded. You can continue, but parts of the wizard may not work reliably.';\n\n const handleDownloadAndExit = async () => {\n if (downloading) return;\n setDownloading(true);\n // Primary origin — fetchSkillMenu/downloadSkill fail over to AWS themselves.\n const menu = await fetchSkillMenu(GITHUB_SKILLS_BASE_URL);\n if (menu) {\n const prefix = `integration-${integration}`;\n const skills = (menu.categories['integration'] ?? []).filter((s) =>\n s.id.startsWith(prefix),\n );\n for (const skill of skills) {\n // Pre-auth outage cache: no gateway, so a flagged skill fails closed.\n await downloadSkill(skill, store.session.installDir, {\n skillsRoot: '.posthog/skills',\n triage: undefined,\n });\n }\n }\n setDownloaded(true);\n };\n\n const handleCancel =\n canDownloadSkills && !isSkillsOriginDown\n ? () => void handleDownloadAndExit()\n : () =>\n void wizardAbort({\n code: ErrorCodes.EnvServiceOutage,\n message: 'Exited due to service outage.',\n });\n\n const cancelLabel =\n canDownloadSkills && !isSkillsOriginDown\n ? downloading\n ? 'Downloading...'\n : 'Download skills & Exit [Esc]'\n : 'Exit [Esc]';\n\n return (\n <ModalOverlay\n borderColor={\n hasHardBlock && !allBlockingHaveNoConnection ? 'red' : 'yellow'\n }\n title={title}\n width={72}\n footer={\n isSkillsOriginDown ? (\n <ConfirmationInput\n message=\"\"\n confirmLabel=\"\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() =>\n void wizardAbort({\n code: ErrorCodes.EnvServiceOutage,\n message: 'Exited due to service outage.',\n })\n }\n onCancel={() =>\n void wizardAbort({\n code: ErrorCodes.EnvServiceOutage,\n message: 'Exited due to service outage.',\n })\n }\n />\n ) : (\n <ConfirmationInput\n message=\"Continue anyway?\"\n confirmLabel=\"Continue [Enter]\"\n cancelLabel={cancelLabel}\n onConfirm={() => store.dismissOutage()}\n onCancel={handleCancel}\n />\n )\n }\n >\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box marginBottom={1}>\n <Text>\n <Text color=\"red\">{Icons.squareFilled}</Text>\n <Text dimColor> Down </Text>\n <Text color=\"#DC9300\">{Icons.squareFilled}</Text>\n <Text dimColor> Degraded </Text>\n <Text color=\"gray\">{Icons.squareFilled}</Text>\n <Text dimColor> No connection</Text>\n </Text>\n </Box>\n\n <ServiceHealthList\n health={result.health}\n filterKeys={displayKeys}\n showHealthy={false}\n />\n </Box>\n\n <Text dimColor>{description}</Text>\n\n {isSkillsOriginDown && docsUrl && (\n <Box marginTop={1}>\n <Text>\n Set up manually: <Text color=\"cyan\">{docsUrl}</Text>\n </Text>\n </Box>\n )}\n\n {canDownloadSkills && !isSkillsOriginDown && (\n <Box marginTop={1}>\n <Text>\n You can still download the PostHog integration skills and continue\n with another agent.\n </Text>\n </Box>\n )}\n </ModalOverlay>\n );\n};\n","import { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\n\ninterface DoctorIntroScreenProps {\n store: WizardStore;\n}\n\nexport const DoctorIntroScreen = ({ store }: DoctorIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n PostHog Doctor\n </Text>\n <Text dimColor>\n Scan your project configuration for issues that may need attention.\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text>The wizard will:</Text>\n <Box paddingLeft={2} flexDirection=\"column\">\n <Text>{Icons.bullet} Sign you in to PostHog</Text>\n <Text>\n {Icons.bullet} Fetch active health issues for your project\n </Text>\n <Text>\n {Icons.bullet} Show you what needs to be resolved, with docs links\n </Text>\n </Box>\n </Box>\n\n <PickerMenu\n options={[\n { label: 'Continue', value: 'continue' },\n { label: 'Cancel', value: 'cancel' },\n ]}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else {\n store.completeSetup();\n }\n }}\n />\n </Box>\n );\n};\n","import { Box, Text } from 'ink';\nimport { useEffect, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { LoadingBox, PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport {\n fetchHealthIssues,\n type HealthIssue,\n} from '@lib/programs/posthog-doctor/index';\nimport { OutroKind } from '@lib/wizard-session';\nimport { ApiError } from '@lib/api';\nimport { POSTHOG_DOCS_URL } from '@lib/constants';\nimport { IssueTable, SEVERITY_LABEL, SEVERITY_ORDER } from './IssueTable.js';\n\ninterface DoctorReportScreenProps {\n store: WizardStore;\n}\n\ntype FetchState =\n | { kind: 'loading' }\n | { kind: 'ready'; issues: HealthIssue[] }\n | { kind: 'error'; message: string };\n\nexport const DoctorReportScreen = ({ store }: DoctorReportScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { credentials } = store.session;\n const accessToken = credentials?.accessToken;\n const apiHost = credentials?.host.apiHost;\n const projectId = credentials?.projectId;\n\n const [state, setState] = useState<FetchState>({ kind: 'loading' });\n\n useEffect(() => {\n if (!accessToken || !apiHost || projectId == null) return;\n let cancelled = false;\n void (async () => {\n try {\n const issues = await fetchHealthIssues(accessToken, apiHost, projectId);\n if (!cancelled) {\n setState({ kind: 'ready', issues });\n }\n } catch (err) {\n if (!cancelled) {\n const message =\n err instanceof ApiError && err.statusCode === 401\n ? 'Your PostHog session has expired. Re-run the wizard to sign in again.'\n : err instanceof Error\n ? err.message\n : String(err);\n setState({ kind: 'error', message });\n }\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [accessToken, apiHost, projectId]);\n\n if (!credentials) {\n return <LoadingBox message=\"Waiting for authentication...\" />;\n }\n\n if (state.kind === 'loading') {\n return (\n <Box flexDirection=\"column\">\n <Header\n host={credentials.host.apiHost}\n projectId={credentials.projectId}\n />\n <LoadingBox message=\"Fetching health issues...\" />\n </Box>\n );\n }\n\n const healthUrl = `${credentials.host.appHost}/project/${credentials.projectId}/health`;\n\n if (state.kind === 'error') {\n return (\n <Box flexDirection=\"column\">\n <Header\n host={credentials.host.apiHost}\n projectId={credentials.projectId}\n />\n <Box flexDirection=\"column\" marginY={1}>\n <Text color={Colors.error} bold>\n {Icons.squareFilled} Failed to fetch health issues\n </Text>\n <Text dimColor>{state.message}</Text>\n </Box>\n <PickerMenu\n options={[{ label: 'Continue', value: 'continue' }]}\n onSelect={() => {\n store.setOutroData({\n kind: OutroKind.Error,\n message: 'Failed to fetch health issues',\n body: state.message,\n docsUrl: POSTHOG_DOCS_URL,\n });\n }}\n />\n </Box>\n );\n }\n\n const { issues } = state;\n\n if (issues.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Header\n host={credentials.host.apiHost}\n projectId={credentials.projectId}\n />\n <Box marginY={1}>\n <Text color={Colors.success} bold>\n {Icons.check} No active issues — you're all set!\n </Text>\n </Box>\n <PickerMenu\n options={[{ label: 'Continue', value: 'continue' }]}\n onSelect={() => {\n store.setOutroData({\n kind: OutroKind.Success,\n message: 'No active issues — your project looks healthy.',\n docsUrl: POSTHOG_DOCS_URL,\n continueUrl: healthUrl,\n });\n }}\n />\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Header\n host={credentials.host.apiHost}\n projectId={credentials.projectId}\n />\n <Box marginTop={1}>\n <Text>{formatSummaryLine(issues)}</Text>\n </Box>\n\n <Box flexDirection=\"column\" marginBottom={1}>\n <IssueTable issues={issues} />\n </Box>\n\n <PickerMenu\n options={[{ label: 'Continue', value: 'continue' }]}\n onSelect={() => {\n store.setOutroData({\n kind: OutroKind.Success,\n message: `Found ${issues.length} active issue${\n issues.length === 1 ? '' : 's'\n }.`,\n body: 'Open the dashboard in PostHog to dismiss or resolve issues.',\n docsUrl: POSTHOG_DOCS_URL,\n continueUrl: healthUrl,\n });\n }}\n />\n </Box>\n );\n};\n\nconst Header = ({ host, projectId }: { host: string; projectId: number }) => (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n PostHog Doctor Report\n </Text>\n <Text dimColor>\n Project {projectId} {Icons.bullet} {host}\n </Text>\n </Box>\n);\n\nfunction formatSummaryLine(issues: HealthIssue[]): string {\n const parts: string[] = [];\n for (const sev of SEVERITY_ORDER) {\n const n = issues.filter((i) => i.severity === sev).length;\n if (n > 0) parts.push(`${n} ${SEVERITY_LABEL[sev].toLowerCase()}`);\n }\n const suffix = parts.length > 0 ? `: ${parts.join(', ')}` : '';\n return `${issues.length} active issue${\n issues.length === 1 ? '' : 's'\n }${suffix}`;\n}\n","import { Box, Text } from 'ink';\nimport { useEffect, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { ConfirmationInput, ModalOverlay } from '@ui/tui/primitives/index';\nimport { Icons } from '@ui/tui/styles';\nimport { analytics } from '@utils/analytics';\n\ninterface SettingsOverrideScreenProps {\n store: WizardStore;\n}\n\nexport const SettingsOverrideScreen = ({\n store,\n}: SettingsOverrideScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [feedback, setFeedback] = useState<string | null>(null);\n const conflicts = store.session.settingsConflicts?.filter((c) => c.writable);\n\n const hasConflicts = Boolean(conflicts && conflicts.length > 0);\n useEffect(() => {\n if (hasConflicts) {\n analytics.wizardCapture('settings conflict shown', { kind: 'override' });\n }\n }, [hasConflicts]);\n\n if (!conflicts || conflicts.length === 0) {\n return null;\n }\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Settings conflict`}\n width={64}\n feedback={feedback ? `${Icons.warning} ${feedback}` : null}\n footer={\n <ConfirmationInput\n message=\"Back up to .wizard-backup and continue?\"\n confirmLabel=\"Backup & continue [Enter]\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => {\n analytics.wizardCapture('settings conflict accepted', {\n kind: 'override',\n });\n const ok = store.backupAndFixSettingsOverride();\n if (!ok) {\n setFeedback('Could not back up the settings file.');\n }\n }}\n onCancel={() => process.exit(1)}\n />\n }\n >\n {conflicts.map((conflict) => (\n <Box key={conflict.path} flexDirection=\"column\" marginBottom={1}>\n <Text>\n Your settings file at <Text bold>{conflict.path}</Text> sets:\n </Text>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {conflict.keys.map((key) => (\n <Text key={key}>\n {Icons.bullet}{' '}\n <Text color=\"yellow\" bold>\n {key}\n </Text>\n </Text>\n ))}\n </Box>\n </Box>\n ))}\n <Text dimColor>\n These settings override credentials and prevent the Wizard from reaching\n the PostHog LLM Gateway. We can back up the file and continue.\n </Text>\n </ModalOverlay>\n );\n};\n","/**\n * ManagedSettingsScreen — Modal for read-only settings conflicts that block\n * the Wizard from reaching the PostHog LLM Gateway: org-managed settings, the\n * user's global `~/.claude` config, and gitignored project-local overrides.\n *\n * Unlike SettingsOverrideScreen, the wizard cannot safely back up or remove\n * these files for the user, so it names the exact file and key and asks the\n * user to fix it and re-run. Managed (root-owned) files need an IT admin; the\n * rest the user can edit themselves.\n */\n\nimport { Box, Text } from 'ink';\nimport { useEffect, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { ConfirmationInput, ModalOverlay } from '@ui/tui/primitives/index';\nimport { Icons } from '@ui/tui/styles';\nimport type { SettingsConflict } from '@lib/agent/claude-settings';\nimport { analytics } from '@utils/analytics';\n\nfunction sourceLabel(source: SettingsConflict['source']): string {\n switch (source) {\n case 'managed':\n return 'Organization-managed settings';\n case 'user':\n return 'Your global Claude Code settings';\n case 'project-local':\n return 'Project-local settings';\n default:\n return source;\n }\n}\n\ninterface ManagedSettingsScreenProps {\n store: WizardStore;\n}\n\nexport const ManagedSettingsScreen = ({\n store,\n}: ManagedSettingsScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const conflicts = store.session.settingsConflicts;\n const readOnlyConflicts = conflicts?.filter((c) => !c.writable);\n\n const hasManaged = Boolean(\n readOnlyConflicts?.some((c) => c.source === 'managed'),\n );\n const hasReadOnly = Boolean(\n readOnlyConflicts && readOnlyConflicts.length > 0,\n );\n useEffect(() => {\n // Read-only conflict — nothing to accept, so impression only.\n if (hasReadOnly) {\n analytics.wizardCapture('settings conflict shown', {\n kind: 'managed',\n has_managed: hasManaged,\n });\n }\n }, [hasReadOnly, hasManaged]);\n\n if (!readOnlyConflicts || readOnlyConflicts.length === 0) {\n return null;\n }\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Settings conflict`}\n width={72}\n footer={\n <ConfirmationInput\n message=\"Fix the file(s) above, then re-run the Wizard.\"\n confirmLabel=\"\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => process.exit(1)}\n onCancel={() => process.exit(1)}\n />\n }\n >\n <Text dimColor>\n These Claude Code settings override credentials and prevent the Wizard\n from reaching the PostHog LLM Gateway.\n </Text>\n {readOnlyConflicts.map((conflict) => (\n <Box key={conflict.path} flexDirection=\"column\" marginTop={1}>\n <Text bold>{sourceLabel(conflict.source)}</Text>\n <Text dimColor>{conflict.path}</Text>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {conflict.keys.map((key) => (\n <Text key={key}>\n {Icons.bullet}{' '}\n <Text color=\"yellow\" bold>\n {key}\n </Text>\n </Text>\n ))}\n </Box>\n </Box>\n ))}\n <Box marginTop={1}>\n <Text dimColor>\n {hasManaged\n ? 'Remove these keys (or run \"claude auth logout\"). Managed files are root-owned — ask your IT administrator.'\n : 'Remove these keys, or run \"claude auth logout\", then re-run the Wizard.'}\n </Text>\n </Box>\n </ModalOverlay>\n );\n};\n","/**\n * PortConflictScreen — Modal when all OAuth port candidates are occupied.\n *\n * Shows every port the wizard tried and asks the user to free them manually.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { OAUTH_PORTS } from '@lib/constants';\nimport { ConfirmationInput, ModalOverlay } from '@ui/tui/primitives/index';\n\ninterface PortConflictScreenProps {\n store: WizardStore;\n}\n\nexport const PortConflictScreen = ({ store }: PortConflictScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const processInfo = store.session.portConflictProcess;\n\n if (!processInfo) return null;\n\n return (\n <ModalOverlay\n borderColor=\"#DC9300\"\n title=\"OAuth ports in use\"\n width={72}\n footer={\n <ConfirmationInput\n message=\"Retry after freeing ports?\"\n confirmLabel=\"Retry [Enter]\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => store.resolvePortConflict()}\n onCancel={() => process.exit(1)}\n />\n }\n >\n <Text>\n The wizard needs a local port for OAuth. We tried these ports which are\n all in use:\n </Text>\n <Box flexDirection=\"column\" marginY={1} paddingLeft={2} gap={0}>\n {OAUTH_PORTS.map((port) => (\n <Text key={port}>\n <Text dimColor>Port </Text>\n <Text bold>{port}</Text>\n </Text>\n ))}\n </Box>\n <Text dimColor>Please free one of these ports and retry.</Text>\n </ModalOverlay>\n );\n};\n","/**\n * TaskNoticeScreen — Modal shown before an optional step runs.\n *\n * Some steps stop to ask the user for something. This tells them so before the\n * step starts, and lets them decline it. The copy comes from the program that\n * owns the step; this screen only renders what it is given.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { Colors } from '@ui/tui/styles';\nimport { ConfirmationInput, ModalOverlay } from '@ui/tui/primitives/index';\n\ninterface TaskNoticeScreenProps {\n store: WizardStore;\n}\n\nexport const TaskNoticeScreen = ({ store }: TaskNoticeScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const notice = store.session.taskNotice;\n if (!notice) return null;\n\n return (\n <ModalOverlay\n borderColor={Colors.primary}\n title={notice.title}\n width={76}\n footer={\n <ConfirmationInput\n message={notice.prompt}\n confirmLabel={notice.confirmLabel}\n cancelLabel={notice.cancelLabel}\n onConfirm={() => store.resolveTaskNotice(true)}\n onCancel={() => store.resolveTaskNotice(false)}\n />\n }\n >\n <Box flexDirection=\"column\" gap={1}>\n {notice.body.map((paragraph) => (\n <Text key={paragraph}>{paragraph}</Text>\n ))}\n </Box>\n {notice.items && notice.items.length > 0 && (\n <Box marginTop={1} paddingLeft={2}>\n <Text bold>{notice.items.join(', ')}</Text>\n </Box>\n )}\n {notice.docsUrl && (\n <Box marginTop={1}>\n <Text dimColor>\n {notice.docsLabel ?? 'Learn more'}: {notice.docsUrl}\n </Text>\n </Box>\n )}\n </ModalOverlay>\n );\n};\n","/**\n * ManualAuthCodeScreen — Paste an OAuth authorization code by hand.\n *\n * Fallback for headless/remote shells where the browser can't reach the\n * wizard's local callback server. Shows the direct authorize URL (the localhost\n * one is unreachable from another machine), then the user pastes either the\n * full callback URL the browser was redirected to\n * (`http://localhost:8239/callback?code=...`) or just the code. On submit we\n * extract the code and resolve the in-flight OAuth flow; bad input shows inline\n * feedback without leaving the screen.\n *\n * Opened from AuthScreen via a keypress; Esc dismisses it.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { TextInput } from '@inkjs/ui';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { extractOAuthCode } from '@utils/oauth';\n\ninterface ManualAuthCodeScreenProps {\n store: WizardStore;\n}\n\nexport const ManualAuthCodeScreen = ({ store }: ManualAuthCodeScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { session } = store;\n const [error, setError] = useState<string | null>(null);\n\n // Esc cancels and returns to the waiting auth screen.\n useInput((_input, key) => {\n if (key.escape) {\n store.dismissManualAuthCode();\n }\n });\n\n const handleSubmit = (value: string): void => {\n const code = extractOAuthCode(value);\n if (!code) {\n setError(\n \"Couldn't find a code in that input. Paste the full callback URL or just the code.\",\n );\n return;\n }\n store.submitManualAuthCode(code);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box marginBottom={1}>\n <Text bold color={Colors.accent}>\n {Icons.diamond} Paste authorization code\n </Text>\n </Box>\n\n {session.authorizeUrl && (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text dimColor>\n On a remote/headless machine the local login link won't open. Open\n this URL in a browser on any machine to authorize:\n </Text>\n {/* No border + flexShrink={0}: Ink won't hard-wrap the URL, so it\n stays one continuous string the terminal soft-wraps — copies clean\n instead of being chopped across bordered, indented rows. */}\n <Box flexShrink={0} marginTop={1}>\n <Text color=\"cyan\">{session.authorizeUrl}</Text>\n </Box>\n </Box>\n )}\n\n <Text>\n After authorizing, paste the callback URL it lands on — or just the code\n from it — here:\n </Text>\n <Box marginTop={1} width=\"100%\">\n <TextInput\n placeholder=\"http://localhost:8239/callback?code=… or the code\"\n onSubmit={handleSubmit}\n />\n </Box>\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"yellow\">{error}</Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text>\n <Text color={Colors.accent}>ENTER</Text>\n <Text dimColor> submit</Text>\n <Text dimColor> · </Text>\n <Text color={Colors.accent}>ESC</Text>\n <Text dimColor> cancel</Text>\n </Text>\n </Box>\n </Box>\n );\n};\n","/**\n * PrivacyPanel — Shared disclosure component.\n *\n * Single source of truth for the wizard's privacy disclosure, rendered\n * identically from the intro screen (the `PRIVACY_PANEL_LABEL` menu option)\n * and as an overlay from the auth screen ([I] keystroke).\n *\n * Must fit in a default-sized macOS Terminal (~24 rows). Two condensed\n * paragraphs carry the top-level disclosure; the link footer follows.\n * Users who want the full legal text follow the Terms / Privacy URLs to\n * their browser.\n *\n * The scan paragraph is opt-in per caller. It ends by pointing at a control,\n * so it may only render on a screen that puts one below the panel — three of\n * the four callers show `Back` and nothing else, and would be promising a\n * choice that is not there.\n */\n\nimport { useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport {\n POSTHOG_ORG_AI_SETTINGS_URL,\n POSTHOG_PRIVACY_URL,\n POSTHOG_TERMS_URL,\n} from '@lib/constants';\nimport { analytics } from '@utils/analytics';\n\n/**\n * The panel's name everywhere it is referenced: intro menu, screen titles, and\n * the auth screen's [I] hint. One constant so the five spellings this replaced\n * cannot come back.\n */\nexport const PRIVACY_PANEL_LABEL = 'Privacy & data';\n\ninterface PrivacyPanelProps {\n /**\n * True only on a screen that renders the sharing choice below the panel.\n * Gates the scan paragraph, whose last sentence sends the reader to a\n * control that exists on one screen.\n */\n canOptOut?: boolean;\n}\n\nexport const PrivacyPanel = ({ canOptOut = false }: PrivacyPanelProps = {}) => {\n // Rendered from the intro menu and the auth-screen [I] overlay; either way,\n // count the impression once per mount.\n useEffect(() => {\n analytics.wizardCapture('privacy panel shown');\n }, []);\n\n return (\n <Box flexDirection=\"column\" width={64} flexShrink={0}>\n <Text>\n We use Anthropic and OpenAI models via the PostHog LLM gateway to read\n your source files as AI context. .env* file contents, secrets, and\n anything matched by the security scanner stay on your machine.\n </Text>\n\n <Box marginTop={1}>\n <Text>\n To use the wizard, AI features must be enabled in your organization's\n settings.\n </Text>\n </Box>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>\n Terms: <Text color=\"cyan\">{POSTHOG_TERMS_URL}</Text>\n </Text>\n <Text>\n Privacy: <Text color=\"cyan\">{POSTHOG_PRIVACY_URL}</Text>\n </Text>\n <Text>\n AI settings: <Text color=\"cyan\">{POSTHOG_ORG_AI_SETTINGS_URL}</Text>\n </Text>\n </Box>\n\n {canOptOut && (\n <Box marginTop={1}>\n <Text>\n We also read dependency files and .env variable names to discover\n tools we can connect to and integrate with. We share that list with\n PostHog to suggest features. You can opt out of sharing below.\n </Text>\n </Box>\n )}\n </Box>\n );\n};\n","/**\n * IntroScreenLayout ��� Shared visual shell for all program intro screens.\n *\n * Purely presentational — no store subscription. Parent components own\n * the store subscription and pass derived data as props.\n *\n * Slots:\n * body — free-form content below the title bar (copy, spinners, pickers, etc.)\n * children — between detection rows and menu (extra info, warnings)\n * errorView — replaces the entire body for fatal error states\n */\n\nimport path from 'path';\nimport { Box, Text } from 'ink';\nimport { useState, type ReactNode } from 'react';\nimport { PickerMenu, type PickerOption } from '@ui/tui/primitives/index';\nimport {\n PrivacyPanel,\n PRIVACY_PANEL_LABEL,\n} from '@ui/tui/components/PrivacyPanel';\n\nexport interface DetectionRow {\n label: string;\n value: string;\n suffix?: string;\n}\n\ninterface IntroScreenLayoutProps {\n /** Absolute path to the project directory */\n installDir: string;\n\n /** Title text after the colored blocks, e.g. \"PostHog Wizard 🦔\" */\n title?: string;\n\n /** Show the subtitle below the title. Default true. */\n showSubtitle?: boolean;\n\n /**\n * Custom subtitle content, rendered in place of the default\n * \"We'll use AI… / .env*…\" lines when `showSubtitle` is true. Pass the\n * inner <Text> lines — the layout owns the centered, top-margined\n * wrapper. Defaults to the generic subtitle when omitted.\n */\n subtitle?: ReactNode;\n\n /** Free-form content below the title (copy, spinners, pickers, notices) */\n body?: ReactNode;\n\n /** Show the detection block (Directory, detection rows, Program, Skill). Default true. */\n showDetection?: boolean;\n\n /** Extra detection row items rendered as \"Label ✔ value suffix\" */\n detectionRows?: DetectionRow[];\n\n /** Content rendered between detection rows and the menu */\n children?: ReactNode;\n\n /**\n * Menu options, forwarded to PickerMenu as-is — so a screen can mark a row\n * `disabled` (navigation skips it, which is how a blank spacer row works) or\n * give it an `icon`. Pass null to hide the menu entirely.\n */\n menuOptions?: PickerOption<string>[] | null;\n\n /**\n * Menu alignment. 'center' (default) matches the wizard's standard\n * intro menu. 'left' is for views like the privacy panel where the\n * menu should align with the panel content rather than viewport center.\n */\n menuAlign?: 'center' | 'left';\n\n /**\n * Adds the disclosure row to the menu and owns the view behind it, so every\n * program intro offers it at the top level rather than buried under More\n * info. Set false on screens that are not a program intro — the auth\n * overlay renders the panel itself and would otherwise nest inside itself.\n */\n showPrivacy?: boolean;\n\n /**\n * Rows shown above Back on the disclosure view, for a program that lets the\n * user act on what the panel describes. Their selections reach `onSelect`\n * like any other. Passing them also un-gates the panel's scan paragraph,\n * which points the reader at exactly these rows.\n */\n privacyOptions?: PickerOption<string>[];\n\n /** Called when the user picks a menu option */\n onSelect?: (value: string) => void;\n\n /** Program label shown at the bottom */\n programLabel?: string | null;\n\n /** Skill ID shown at the bottom */\n skillId?: string | null;\n\n /** Replaces the entire body (topContent + rows + children + menu) for fatal error views */\n errorView?: ReactNode;\n}\n\nconst WizardTitle = ({ title }: { title: string }) => (\n <Text bold>\n <Text color=\"#1D4AFF\">{'\\u2588'}</Text>\n <Text color=\"#F54E00\">{'\\u2588'}</Text>\n <Text color=\"#F9BD2B\">{'\\u2588'}</Text> {title}\n </Text>\n);\n\n/** Generic subtitle shown when a screen doesn't supply its own. */\nconst DEFAULT_SUBTITLE = (\n <>\n <Text dimColor>\n We'll use AI to analyze your project and complete work.\n </Text>\n <Text dimColor>.env* file contents will not leave your machine.</Text>\n </>\n);\n\n/** Default menu when a screen passes none. */\nconst DEFAULT_MENU: PickerOption<string>[] = [\n { label: 'Continue', value: 'continue' },\n { label: 'Cancel', value: 'cancel' },\n];\n\n/**\n * The menu for the current view. The disclosure row is appended here rather\n * than left to each screen: ten intro screens would otherwise carry the same\n * row, view and back handler, which is how this panel came to answer to five\n * different names and to sit two levels deep on the one screen that had it.\n *\n * Pure and exported so the guarantee is testable without a renderer.\n */\nexport function buildIntroMenu({\n menuOptions,\n showPrivacy = true,\n showingPrivacy = false,\n privacyOptions,\n}: {\n menuOptions?: PickerOption<string>[] | null;\n showPrivacy?: boolean;\n showingPrivacy?: boolean;\n privacyOptions?: PickerOption<string>[];\n}): PickerOption<string>[] | null {\n if (showingPrivacy) {\n // Always supplied here, so a program cannot strand the user by omitting\n // it. A blank glyph keeps its label on the same column as rows above that\n // carry one.\n const back = {\n label: 'Back',\n value: 'privacy-back',\n ...(privacyOptions?.some((o) => o.icon) ? { icon: { glyph: ' ' } } : {}),\n };\n return [...(privacyOptions ?? []), back];\n }\n\n const base = menuOptions === undefined ? DEFAULT_MENU : menuOptions;\n // A screen with no menu at all (a fatal state) gains nothing to select.\n if (base === null || !showPrivacy) return base;\n\n const row = { label: PRIVACY_PANEL_LABEL, value: 'privacy' };\n // Above a trailing Cancel: leaving the wizard stays the last thing offered.\n const insertAt =\n base.at(-1)?.value === 'cancel' ? base.length - 1 : base.length;\n return [...base.slice(0, insertAt), row, ...base.slice(insertAt)];\n}\n\nexport const IntroScreenLayout = ({\n installDir,\n title = 'PostHog Wizard 🦔',\n showSubtitle = true,\n subtitle,\n body,\n showDetection = true,\n detectionRows,\n children,\n menuOptions,\n menuAlign = 'center',\n showPrivacy = true,\n privacyOptions,\n onSelect,\n programLabel,\n skillId,\n errorView,\n}: IntroScreenLayoutProps) => {\n const [showingPrivacy, setShowingPrivacy] = useState(false);\n\n const resolvedMenuOptions = buildIntroMenu({\n menuOptions,\n showPrivacy,\n showingPrivacy,\n privacyOptions,\n });\n\n const handleSelect = (value: string) => {\n if (value === 'privacy') return setShowingPrivacy(true);\n if (value === 'privacy-back') return setShowingPrivacy(false);\n onSelect?.(value);\n };\n\n if (errorView) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Box flexDirection=\"column\" alignItems=\"center\" marginBottom={1}>\n <WizardTitle title={title} />\n </Box>\n {errorView}\n </Box>\n );\n }\n\n return (\n <>\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Box flexDirection=\"column\" alignItems=\"center\">\n <WizardTitle title={showingPrivacy ? PRIVACY_PANEL_LABEL : title} />\n\n {showSubtitle && !showingPrivacy && (\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n {subtitle ?? DEFAULT_SUBTITLE}\n </Box>\n )}\n\n {showingPrivacy ? (\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n {/* The paragraph ends by pointing below, so it only renders\n where this screen actually put a choice there. */}\n <PrivacyPanel canOptOut={privacyOptions !== undefined} />\n </Box>\n ) : (\n body && (\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n {body}\n </Box>\n )\n )}\n </Box>\n\n {!showingPrivacy && children}\n\n {showDetection && !showingPrivacy && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n <Text>\n Directory <Text color=\"green\">{'\\u2714'}</Text>{' '}\n </Text>\n <Text>\n {'/'}\n {path.basename(installDir)}\n </Text>\n </Text>\n\n {detectionRows?.map((row) => (\n <Text key={row.label}>\n <Text>\n {row.label} <Text color=\"green\">{'\\u2714'}</Text>{' '}\n </Text>\n <Text>\n {row.value}\n {row.suffix ? ` ${row.suffix}` : ''}\n </Text>\n </Text>\n ))}\n\n {programLabel && (\n <Text>\n Program{' '}\n <Text color=\"green\">{'\\u2714'}</Text> {programLabel}\n </Text>\n )}\n\n {programLabel === 'agent-skill' && skillId && (\n <Text>\n Skill{' '}\n <Text color=\"green\">{'\\u2714'}</Text> {skillId}\n </Text>\n )}\n </Box>\n )}\n\n <Box width={menuAlign === 'left' ? 64 : 24} marginTop={1}>\n {resolvedMenuOptions && onSelect && (\n <Box\n justifyContent={menuAlign === 'left' ? 'flex-start' : 'center'}\n >\n <PickerMenu\n key={resolvedMenuOptions.map((o) => o.value).join(',')}\n options={resolvedMenuOptions}\n onSelect={(value) => {\n const choice = Array.isArray(value) ? value[0] : value;\n handleSelect(choice);\n }}\n />\n </Box>\n )}\n </Box>\n </Box>\n </>\n );\n};\n","/**\n * PostHogIntegrationIntroScreen — Intro screen for the core PostHog integration.\n *\n * Composes IntroScreenLayout with framework-detection-specific state:\n * 1. Detecting: spinner while detection runs\n * 2. Detection failed: framework picker\n * 3. Unsupported version: upgrade prompt\n * 4. Detection succeeded: continue/change-framework/cancel\n */\n\nimport { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { Integration } from '@lib/constants';\nimport {\n PickerMenu,\n LoadingBox,\n type PickerOption,\n} from '@ui/tui/primitives/index';\nimport { IntroScreenLayout, type DetectionRow } from './IntroScreenLayout.js';\nimport { SkillSourceInfo, useSkillEntry } from './SkillSourceInfo.js';\nimport { ScanConsent } from '@lib/wizard-session';\nimport { Icons } from '@ui/tui/styles';\nimport { analytics } from '@utils/analytics';\nimport { PRIVACY_PANEL_LABEL } from '@ui/tui/components/PrivacyPanel';\n\ntype View = 'default' | 'more-info';\n\n/**\n * Replaces IntroScreenLayout's DEFAULT_SUBTITLE for this screen only. The\n * shared default (\".env* file contents will not leave your machine\") is true\n * of values and false of variable names, which this screen reads and reports.\n * Two lines carry the fact and name the screen that holds the detail, so the\n * disclosure reaches people who never open it.\n */\nconst SUBTITLE = (\n <>\n <Text dimColor>\n We'll use AI to analyze your project and complete work.\n </Text>\n <Text dimColor>Review what data is shared in \"{PRIVACY_PANEL_LABEL}.\"</Text>\n <Text dimColor>.env* values stay on your machine.</Text>\n </>\n);\n\n/**\n * Exported so a test can measure every label against the menu's column.\n * `Privacy & data` is not here: IntroScreenLayout appends it to every intro\n * menu, so no screen carries its own copy.\n */\nexport const CONTINUE_MENU_OPTIONS: { label: string; value: string }[] = [\n { label: 'Continue', value: 'continue' },\n { label: 'Change framework', value: 'framework' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n];\n\n/**\n * A blank, unselectable row. Navigation skips disabled options, so this is a\n * margin the menu can hold rather than one the layout has to special-case.\n */\nconst MENU_SPACER: PickerOption<string> = {\n label: '',\n value: 'spacer',\n disabled: true,\n};\n\n/**\n * The sharing choice, as two explicit rows rather than one toggle. A toggle\n * label has to describe either the current state or the next action, and a\n * reader cannot tell which; two rows with the filled diamond on the live one\n * say both at once. The trailing spacer separates them from the Back that\n * IntroScreenLayout appends, since leaving the screen is a different kind of\n * act from changing something on it.\n */\nexport function sharingOptions(sharing: boolean): PickerOption<string>[] {\n const mark = (on: boolean) => ({\n glyph: on ? Icons.diamond : Icons.diamondOpen,\n });\n return [\n { label: 'Share tools', value: 'share', icon: mark(sharing) },\n { label: \"Don't share tools\", value: 'no-share', icon: mark(!sharing) },\n MENU_SPACER,\n ];\n}\n\n/** Framework picker shown when auto-detection fails. */\nconst FrameworkPicker = ({\n store,\n onComplete,\n}: {\n store: WizardStore;\n onComplete?: () => void;\n}) => {\n const options = Object.values(Integration).map((value) => ({\n label: value,\n value,\n }));\n\n return (\n <PickerMenu<Integration>\n centered\n columns={2}\n message=\"Select your framework\"\n options={options}\n onSelect={(value) => {\n const integration = Array.isArray(value) ? value[0] : value;\n void import('@lib/registry').then(({ FRAMEWORK_REGISTRY }) => {\n const config = FRAMEWORK_REGISTRY[integration];\n store.setFrameworkConfig(integration, config);\n store.setDetectedFramework(config.metadata.name);\n onComplete?.();\n });\n }}\n />\n );\n};\n\ninterface PostHogIntegrationIntroScreenProps {\n store: WizardStore;\n}\n\nexport const PostHogIntegrationIntroScreen = ({\n store,\n}: PostHogIntegrationIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [pickingFramework, setPickingFramework] = useState(false);\n const [manuallySelected, setManuallySelected] = useState(false);\n const [view, setView] = useState<View>('default');\n\n const { session } = store;\n const sharing = session.scanConsent !== ScanConsent.Declined;\n const config = session.frameworkConfig;\n const frameworkLabel =\n session.detectedFrameworkLabel ?? config?.metadata.name;\n const { skillEntry, fetchFailed } = useSkillEntry(session.skillId);\n const detecting = !session.detectionComplete;\n const needsFrameworkPick =\n session.detectionComplete && !session.frameworkConfig;\n const unsupported = session.unsupportedVersion;\n const showContinue =\n session.frameworkConfig !== null &&\n !detecting &&\n !pickingFramework &&\n view === 'default' &&\n !unsupported;\n\n // ── Title ──────────────────────────────────────────────────────────\n\n const title = detecting ? 'PostHog Wizard starting up' : 'PostHog Wizard 🦔';\n\n // ── Description ────────────────────────────────────────────────────\n\n let body: ReactNode = null;\n\n if (detecting) {\n body = (\n <Box marginY={1}>\n <LoadingBox message=\"Detecting project framework...\" />\n </Box>\n );\n } else if (needsFrameworkPick && !pickingFramework) {\n body = (\n <>\n <Box marginY={1}>\n <Text dimColor>Could not auto-detect your framework.</Text>\n </Box>\n <FrameworkPicker\n store={store}\n onComplete={() => setPickingFramework(false)}\n />\n </>\n );\n } else if (pickingFramework) {\n body = (\n <FrameworkPicker\n store={store}\n onComplete={() => setPickingFramework(false)}\n />\n );\n } else if (view === 'more-info') {\n body = (\n <Box flexDirection=\"column\" width={64} flexShrink={0}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.programLabel}\n </Text>{' '}\n program installs the PostHog SDKs, instruments event tracking, and\n integrates the following dev tools for your application:\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={4}>\n <Text>{`•`} Product Analytics</Text>\n <Text>{`•`} Web Analytics</Text>\n <Text>{`•`} Session Replay</Text>\n <Text>{`•`} Error Tracking</Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>If you prefer your own AI setup, download the skill:</Text>\n <Box marginTop={1}>\n <SkillSourceInfo\n skillId={session.skillId}\n skillEntry={skillEntry}\n fetchFailed={fetchFailed}\n />\n </Box>\n </Box>\n </Box>\n );\n } else if (showContinue) {\n body = (\n <Box>\n <Text>Let's do two hours of work in eight minutes.</Text>\n </Box>\n );\n }\n\n // ── Detection rows ─────────────────────────────────────────────────\n\n const detectionRows: DetectionRow[] = [];\n if (frameworkLabel) {\n const suffixParts: string[] = [];\n if (!manuallySelected) suffixParts.push('(detected)');\n // Dead path today — every framework went GA. Kept for re-activation\n // when the next beta framework lands (set `beta: true` on its config).\n if (config?.metadata.beta) suffixParts.push('[BETA]');\n\n detectionRows.push({\n label: 'Framework',\n value: frameworkLabel,\n suffix: suffixParts.join(' ') || undefined,\n });\n }\n\n // ── Children (between rows and menu) ───────────────────────────────\n\n let bodyChildren: ReactNode = null;\n\n if (config?.metadata.preRunNotice) {\n bodyChildren = <Text color=\"yellow\">{config.metadata.preRunNotice}</Text>;\n }\n\n if (unsupported) {\n bodyChildren = (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"#DC9300\">\n Version {unsupported.current} is not supported by the wizard. Please\n upgrade to {unsupported.minimum} or later.\n </Text>\n <Text dimColor>Manual setup guide: {unsupported.docsUrl}</Text>\n <Box marginTop={1}>\n <Text dimColor>\n Did we get this wrong? You can also select another framework.\n </Text>\n </Box>\n <PickerMenu\n options={[\n { label: 'Select another framework', value: 'framework' },\n { label: 'Exit', value: 'exit' },\n ]}\n onSelect={(value) => {\n const choice = Array.isArray(value) ? value[0] : value;\n if (choice === 'framework') {\n setPickingFramework(true);\n setManuallySelected(true);\n } else {\n process.exit(0);\n }\n }}\n />\n </Box>\n );\n }\n\n // ── Menu ───────────────────────────────────────────────────────────\n\n let menuOptions: PickerOption<string>[] | null = null;\n\n if (view === 'more-info') {\n // No route to the panel from here: it has its own top-level menu item.\n menuOptions = [{ label: 'Back', value: 'back' }];\n } else if (showContinue) {\n menuOptions = CONTINUE_MENU_OPTIONS;\n }\n\n const handleSelect = (value: string) => {\n analytics.wizardCapture('intro menu selected', { value, view });\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'framework') {\n setPickingFramework(true);\n setManuallySelected(true);\n } else if (value === 'more-info') {\n setView('more-info');\n } else if (value === 'back') {\n setView('default');\n } else if (value === 'share') {\n store.grantSharing();\n } else if (value === 'no-share') {\n store.declineSharing();\n } else if (value === 'continue') {\n // Sharing is on by default, so consent nobody touched resolves to granted\n // here. A choice already made in the panel stands.\n if (session.scanConsent === ScanConsent.Undecided) store.grantSharing();\n store.completeSetup();\n }\n };\n\n // ── Render ─────────────────────────────────────────────────────────\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n title={title}\n showSubtitle={view === 'default'}\n subtitle={SUBTITLE}\n body={body}\n showDetection={showContinue}\n detectionRows={detectionRows}\n menuOptions={unsupported ? null : menuOptions}\n menuAlign=\"center\"\n // The one program whose disclosure view can be acted on.\n privacyOptions={sharingOptions(sharing)}\n onSelect={handleSelect}\n programLabel={session.programLabel}\n skillId={session.skillId}\n >\n {bodyChildren}\n </IntroScreenLayout>\n );\n};\n","/**\n * RevenueIntroScreen — Welcome screen for the revenue analytics flow.\n *\n * Composes IntroScreenLayout with SDK-detection-specific state:\n * - Detection succeeded: shows detected PostHog + Stripe SDKs, continue/cancel\n * - Detection failed: shows the error via errorView + exit prompt\n *\n * Reads `frameworkContext.detectError` and `frameworkContext.detectedPosthogSdks`\n * / `detectedStripeSdks` set by detectRevenuePrerequisites().\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { IntroScreenLayout, type DetectionRow } from './IntroScreenLayout.js';\nimport {\n POSTHOG_SDKS,\n STRIPE_SDKS,\n type RevenueDetectError,\n} from '@lib/programs/revenue-analytics/index';\n\ninterface RevenueIntroScreenProps {\n store: WizardStore;\n}\n\nexport const RevenueIntroScreen = ({ store }: RevenueIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n\n const { session } = store;\n const detectError = session.frameworkContext.detectError as\n | RevenueDetectError\n | undefined;\n const detectedPosthogSdks =\n (session.frameworkContext.detectedPosthogSdks as string[] | undefined) ??\n [];\n const detectedStripeSdks =\n (session.frameworkContext.detectedStripeSdks as string[] | undefined) ?? [];\n const detectedPackagePaths =\n (session.frameworkContext.detectedPackagePaths as string[] | undefined) ??\n [];\n\n // ── Detection rows ─────────────────────────────────────────────────\n\n const detectionRows: DetectionRow[] = [];\n if (detectedPosthogSdks.length > 0) {\n detectionRows.push({\n label: 'PostHog SDK',\n value: detectedPosthogSdks.join(', '),\n });\n }\n if (detectedStripeSdks.length > 0) {\n detectionRows.push({\n label: 'Stripe SDK',\n value: detectedStripeSdks.join(', '),\n });\n }\n\n // ── Body ────────────────────────────────────────────────────────────\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56} flexShrink={0}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>.\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.programLabel}\n </Text>{' '}\n program links Stripe customers and purchases to PostHog product data\n and persons. It unlocks insights like:\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={4}>\n <Text>{'\\u2022'} Revenue per user</Text>\n <Text>{'\\u2022'} Lifetime value</Text>\n <Text>{'\\u2022'} MRR / churn tracking</Text>\n </Box>\n </Box>\n ) : (\n <>\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>Let's create revenue analytics with Stripe and PostHog.</Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>Link purchases to product data.</Text>\n </Box>\n </Box>\n\n {detectedPackagePaths.length > 1 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text dimColor>Found in {detectedPackagePaths.length} packages:</Text>\n {detectedPackagePaths.map((p) => (\n <Text key={p} dimColor>\n {' '}\n {'\\u2022'} {p}\n </Text>\n ))}\n </Box>\n )}\n </>\n );\n\n // ── Error view ─────────────────────────────────────────────────────\n\n const errorView = detectError ? (\n <>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"red\" bold>\n {'\\u2718'} Cannot set up revenue analytics\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <DetectErrorBody error={detectError} />\n </Box>\n </Box>\n\n <PickerMenu\n options={[{ label: 'Exit', value: 'exit' }]}\n onSelect={() => process.exit(1)}\n />\n </>\n ) : undefined;\n\n // ── Menu ───────────────────────────────────────────────────────────\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n // ── Render ─────────────────────────────────────────────────────────\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n showSubtitle={!showingMoreInfo}\n body={body}\n showDetection={!showingMoreInfo}\n detectionRows={detectionRows}\n errorView={errorView}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'more-info') {\n setShowingMoreInfo(true);\n } else if (value === 'back') {\n setShowingMoreInfo(false);\n } else {\n store.completeSetup();\n }\n }}\n />\n );\n};\n\nconst DetectErrorBody = ({ error }: { error: RevenueDetectError }) => {\n switch (error.kind) {\n case 'bad-directory': {\n const reasonText = {\n missing: 'does not exist',\n 'not-dir': 'is not a directory',\n unreadable: 'could not be accessed',\n }[error.reason];\n return (\n <>\n <Text>This path {reasonText}:</Text>\n <Text dimColor>\n {' '}\n {error.path}\n </Text>\n </>\n );\n }\n\n case 'no-package-json':\n return (\n <>\n <Text>No package.json found in this directory.</Text>\n <Text dimColor>\n Revenue analytics currently supports Node.js / TypeScript projects.\n </Text>\n <Text dimColor>Run this command from your project root.</Text>\n </>\n );\n\n case 'no-sdks':\n return (\n <>\n <Text>\n Neither PostHog nor Stripe SDKs detected (scanned{' '}\n {error.scannedCount} package.json file\n {error.scannedCount === 1 ? '' : 's'}).\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text>Revenue analytics requires:</Text>\n <Text dimColor>\n {' \\u2022'} A PostHog SDK ({POSTHOG_SDKS.slice(0, 3).join(', ')},\n …)\n </Text>\n <Text dimColor>\n {' \\u2022'} A Stripe SDK ({STRIPE_SDKS.join(', ')})\n </Text>\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n Install Stripe and run <Text bold>npx @posthog/wizard</Text> to\n set up PostHog.\n </Text>\n </Box>\n </>\n );\n\n case 'missing-posthog':\n return (\n <>\n <Text>\n Found Stripe ({error.foundStripe.join(', ')}) but no PostHog SDK.\n </Text>\n <Box marginTop={1}>\n <Text dimColor>\n Run <Text bold>npx @posthog/wizard</Text> first to set up the base\n PostHog integration.\n </Text>\n </Box>\n </>\n );\n\n case 'missing-stripe':\n return (\n <>\n <Text>\n Found PostHog ({error.foundPosthog.join(', ')}) but no Stripe SDK.\n </Text>\n <Text dimColor>\n Revenue analytics currently supports Stripe only.\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>Install one of:</Text>\n {STRIPE_SDKS.map((sdk) => (\n <Text key={sdk} dimColor>\n {' \\u2022'} {sdk}\n </Text>\n ))}\n </Box>\n </>\n );\n }\n};\n","/**\n * WarehouseIntroScreen — Welcome screen for the data warehouse source flow.\n *\n * Composes IntroScreenLayout with detection-specific state:\n * - Detection succeeded: lists detected sources (grouped by creation mode),\n * continue/cancel.\n * - Detection failed: shows the error via errorView + exit prompt.\n *\n * Reads `frameworkContext.detectError` and `frameworkContext.detectedWarehouseSources`\n * set by detectWarehousePrerequisites().\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\nimport {\n getDetectedWarehouseSources,\n type WarehouseDetectError,\n} from '@lib/programs/warehouse-source/index';\n\ninterface WarehouseIntroScreenProps {\n store: WizardStore;\n}\n\nexport const WarehouseIntroScreen = ({ store }: WarehouseIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n\n const { session } = store;\n const detectError = session.frameworkContext.detectError as\n | WarehouseDetectError\n | undefined;\n const detected = getDetectedWarehouseSources(session);\n\n // ── Body ────────────────────────────────────────────────────────────\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56} flexShrink={0}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>.\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.programLabel}\n </Text>{' '}\n program connects your existing data sources to PostHog's data\n warehouse, so you can query them alongside product data.\n </Text>\n </Box>\n </Box>\n ) : (\n <>\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>Let's connect your data to PostHog's data warehouse.</Text>\n </Box>\n\n {detected.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text dimColor>Detected warehouse sources:</Text>\n {detected.map((s) => (\n <Text key={s.kind} dimColor>\n {' •'} {s.label}\n </Text>\n ))}\n </Box>\n )}\n </>\n );\n\n // ── Error view ─────────────────────────────────────────────────────\n\n const errorView = detectError ? (\n <>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"red\" bold>\n {'✘'}{' '}\n {detectError.kind === 'bad-directory'\n ? 'Invalid project directory'\n : 'No data warehouse source detected'}\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <DetectErrorBody error={detectError} />\n </Box>\n </Box>\n\n <PickerMenu\n options={[{ label: 'Exit', value: 'exit' }]}\n onSelect={() => process.exit(0)}\n />\n </>\n ) : undefined;\n\n // ── Menu ───────────────────────────────────────────────────────────\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n // ── Render ─────────────────────────────────────────────────────────\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n showSubtitle={!showingMoreInfo}\n body={body}\n showDetection={!showingMoreInfo}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n errorView={errorView}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'more-info') {\n setShowingMoreInfo(true);\n } else if (value === 'back') {\n setShowingMoreInfo(false);\n } else {\n store.completeSetup();\n }\n }}\n />\n );\n};\n\nconst DetectErrorBody = ({ error }: { error: WarehouseDetectError }) => {\n switch (error.kind) {\n case 'bad-directory': {\n const reasonText = {\n missing: 'does not exist',\n 'not-dir': 'is not a directory',\n unreadable: 'could not be accessed',\n }[error.reason];\n return (\n <>\n <Text>This path {reasonText}:</Text>\n <Text dimColor>\n {' '}\n {error.path}\n </Text>\n </>\n );\n }\n\n case 'no-sources':\n return (\n <>\n <Text>No supported data source was detected in this project.</Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>\n The wizard looks for databases (Postgres, MySQL, MongoDB, …) and\n API-key sources like Stripe in your dependencies and .env keys.\n </Text>\n <Text dimColor>\n Run this command from your project root, or set a source up\n directly at{' '}\n <Text color=\"cyan\">https://posthog.com/docs/data-warehouse</Text>.\n </Text>\n </Box>\n </>\n );\n }\n};\n","import { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\n\ninterface MigrationIntroScreenProps {\n store: WizardStore;\n}\n\nexport const MigrationIntroScreen = ({ store }: MigrationIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { session } = store;\n\n const body = (\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>Let's migrate this project to PostHog.</Text>\n </Box>\n );\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n body={body}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={[\n { label: 'Continue', value: 'continue' },\n { label: 'Cancel', value: 'cancel' },\n ]}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else {\n store.completeSetup();\n }\n }}\n />\n );\n};\n","/**\n * SourceMapsIntroScreen — Welcome screen for the source-maps upload flow.\n *\n * Static intro: detection now runs after login (on the source-maps-detect\n * screen), so this screen no longer shows a detected platform. Continue takes\n * the user straight to authentication.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\n\ntype View = 'default' | 'more-info';\n\ninterface SourceMapsIntroScreenProps {\n store: WizardStore;\n}\n\nexport const SourceMapsIntroScreen = ({\n store,\n}: SourceMapsIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [view, setView] = useState<View>('default');\n\n const { session } = store;\n\n const body =\n view === 'more-info' ? (\n <Box flexDirection=\"column\" width={56} flexShrink={0}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>.\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.programLabel}\n </Text>{' '}\n program sets up your project to upload source maps to PostHog, so\n Error Tracking shows production stack traces in your original source\n instead of minified bundles. It will:\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={4}>\n <Text>{'•'} Detect the framework(s) in your repo</Text>\n <Text>{'•'} Download the relevant docs for your stack</Text>\n <Text>{'•'} Wire map generation + upload into your build</Text>\n <Text>{'•'} Wire CI for deploys and offer a local test run</Text>\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n Maps upload to PostHog during the production build and never need to\n be served publicly.\n </Text>\n </Box>\n </Box>\n ) : (\n <Box flexDirection=\"column\" width={60}>\n <Text>\n The Wizard will run an agent to detect your project's framework(s),\n download the relevant docs, and implement source-map uploads for you.\n </Text>\n <Box marginTop={1}>\n <Text>Ready?</Text>\n </Box>\n </Box>\n );\n\n // No privacy row here: IntroScreenLayout appends it to every intro menu.\n const menuOptions =\n view === 'more-info'\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const title = 'PostHog Wizard 🦔';\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n title={title}\n showSubtitle={view === 'default'}\n body={body}\n showDetection={view === 'default'}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'more-info') {\n setView('more-info');\n } else if (value === 'back') {\n setView('default');\n } else {\n store.completeSetup();\n }\n }}\n />\n );\n};\n","/**\n * Source-maps adapter over the generic agentic detector\n * (`@lib/detection/agentic`). The detector itself is product-knowledge-free;\n * this file supplies the source-maps targets (the automatable skill variants),\n * maps the result back to variants, and classifies each project as\n * instrumentable or not. The screen renders the result and the run step\n * instruments the chosen project.\n */\n\nimport { existsSync, readFileSync, readdirSync } from 'fs';\nimport { join } from 'path';\nimport { IGNORED_DIRS, readProjectFile } from '@utils/bounded-fs';\nimport {\n detectProjectsWithAgent,\n coerceAgenticReport,\n type DetectTarget,\n type AgenticDetectionReport,\n type DetectEvent,\n} from '@lib/detection/agentic';\nimport type { WizardSession } from '@lib/wizard-session';\nimport {\n VARIANT_DISPLAY_NAME,\n AUTOMATABLE_VARIANTS,\n MANUAL_SDK_INSTALL,\n RUST_SDK_CRATE,\n GO_SDK_MODULE,\n type SkillVariant,\n} from './detect.js';\n\nexport type { DetectEvent };\n\n/** One project, classified for source-map upload. */\nexport type DetectedProject = {\n /** Path relative to the working directory (\".\" for the repo root). */\n path: string;\n /** Human-readable framework the agent detected (e.g. \"Next.js\"). */\n framework: string;\n /** A supported source-maps variant when it matches one, else null. */\n variant: SkillVariant | null;\n /** Whether a PostHog SDK is already installed in this project. */\n hasPostHog: boolean;\n /** variant != null && hasPostHog — source-map upload can be wired up here. */\n instrumentable: boolean;\n /** Why the project can't be instrumented (only when !instrumentable). */\n reason?: string;\n};\n\nexport type DetectionReport = {\n repoType: 'monorepo' | 'single';\n projects: DetectedProject[];\n};\n\n/**\n * Variant precedence for the agentic picker (most specific first). The detector\n * keeps the EARLIEST matching target. React Native and Flutter both outrank\n * Android and iOS: their repos carry `android/` and `ios/` folders with real\n * Gradle and Xcode manifests inside them, and must not be misclassified as\n * plain native apps. JS ordering mirrors `pickJsVariant` in detect.ts:\n * opinionated frameworks → bundlers → bare React → Node → generic web.\n */\nconst VARIANT_PRECEDENCE: readonly SkillVariant[] = [\n 'react-native',\n 'flutter',\n 'android',\n 'ios',\n 'nextjs',\n 'nuxt',\n 'angular',\n 'vite',\n 'webpack',\n 'rollup',\n 'react',\n 'node',\n // Native binaries: only chosen when no JS target matches the project, but\n // ahead of the generic web fallback so a go.mod / Cargo.toml project\n // resolves to its debug-symbols variant instead of `web`. Deliberate\n // tradeoff for the same-directory mixed case: a Go/Rust project with a\n // tooling-only package.json (common) beats a root-level JS app sharing a\n // directory with go.mod / Cargo.toml (rare — frontends usually live in a\n // subdirectory, which classifies as its own project).\n 'go',\n 'rust',\n 'web',\n];\n\nconst precedenceRank = (v: SkillVariant): number => {\n const i = VARIANT_PRECEDENCE.indexOf(v);\n return i === -1 ? Number.MAX_SAFE_INTEGER : i;\n};\n\n/** Source-map detection targets, ordered by VARIANT_PRECEDENCE. */\nexport const SOURCE_MAPS_TARGETS: DetectTarget[] = [...AUTOMATABLE_VARIANTS]\n .sort((a, b) => precedenceRank(a) - precedenceRank(b))\n .map((v) => ({ id: v, name: VARIANT_DISPLAY_NAME[v] }));\n\n// JS variants co-occur in one package.json (react+vite, node+rollup), so the\n// enumeration's priority winner may override the agent's pick among them.\n// Mobile/native stacks are mutually exclusive and stay pick-wins.\nconst JS_RERANK_VARIANTS: readonly SkillVariant[] = [\n 'nextjs',\n 'nuxt',\n 'angular',\n 'vite',\n 'webpack',\n 'rollup',\n 'react',\n 'node',\n 'web',\n];\n\n/** Comment-stripped substring check for the Rust SDK in one manifest. */\nfunction manifestMentionsSdk(manifestPath: string): boolean {\n const content = readProjectFile(manifestPath);\n return (\n content != null &&\n content.split('\\n').some((line) => {\n const code = line.split('#', 1)[0];\n return code.includes(RUST_SDK_CRATE);\n })\n );\n}\n\n/**\n * A workspace root is often a virtual manifest (`[workspace]` only, no\n * `[dependencies]`) — the SDK then lives in a member crate's manifest, so a\n * miss on the root must fall through to a bounded walk over nested\n * manifests. Depth 3 covers the common `crates/<name>/` layouts.\n */\nfunction anyNestedManifestMentionsSdk(dir: string, depth: number): boolean {\n if (depth > 3) return false;\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return false;\n }\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n if (IGNORED_DIRS.has(entry.name) || entry.name === 'target') continue;\n const child = join(dir, entry.name);\n if (manifestMentionsSdk(join(child, 'Cargo.toml'))) return true;\n if (anyNestedManifestMentionsSdk(child, depth + 1)) return true;\n }\n return false;\n}\n\n/**\n * Checks a project's Cargo manifests for the Rust SDK. The agentic detector\n * reports a single `hasPostHog` boolean for ANY PostHog dependency in the\n * project — for `rust` that could be satisfied by an unrelated JS SDK in the\n * same directory, so the deterministic manifest read is authoritative.\n * Comment-stripped substring matching, not TOML parsing: it still catches\n * renamed (`package = \"posthog-rs\"`) and workspace-inherited deps, while a\n * commented-out dependency no longer counts. Known miss: selecting a\n * workspace MEMBER whose dep is aliased at the workspace root\n * (`posthog.workspace = true` with the `package = \"posthog-rs\"` mapping only\n * in the root manifest, which sits above the member) — accepted; resolving\n * that needs full workspace metadata. Exported for testing.\n */\nexport function rustSdkVerifier(\n installDir: string,\n): (projectPath: string) => boolean {\n return (projectPath) => {\n const dir =\n projectPath === '.' ? installDir : join(installDir, projectPath);\n return (\n manifestMentionsSdk(join(dir, 'Cargo.toml')) ||\n anyNestedManifestMentionsSdk(dir, 0)\n );\n };\n}\n\n/**\n * True when go.mod actively `require`s the SDK — single-line requires and\n * `require ( … )` blocks only, so a `module` declaration, `replace`, or\n * `exclude` mention of the path never counts.\n */\nfunction goModRequiresSdk(content: string): boolean {\n let inBlock: 'require' | 'other' | null = null;\n for (const raw of content.split('\\n')) {\n const code = raw.split('//', 1)[0].trim();\n if (code === '') continue;\n if (inBlock != null) {\n if (code === ')') {\n inBlock = null;\n } else if (inBlock === 'require' && code.includes(GO_SDK_MODULE)) {\n return true;\n }\n continue;\n }\n if (code.endsWith('(')) {\n inBlock = code.startsWith('require') ? 'require' : 'other';\n continue;\n }\n if (code.startsWith('require ') && code.includes(GO_SDK_MODULE)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Checks a project's go.mod for the Go SDK — the same authoritative override\n * as `rustSdkVerifier`, for the same reason. Only `require` directives count;\n * no multi-module walk — unlike Cargo workspaces, a Go module's requirements\n * always live in the selected module's own go.mod. Exported for testing.\n */\nexport function goSdkVerifier(\n installDir: string,\n): (projectPath: string) => boolean {\n return (projectPath) => {\n const dir =\n projectPath === '.' ? installDir : join(installDir, projectPath);\n const content = readProjectFile(join(dir, 'go.mod'));\n return content != null && goModRequiresSdk(content);\n };\n}\n\nfunction isAutomatableVariant(value: string | null): value is SkillVariant {\n return value !== null && AUTOMATABLE_VARIANTS.includes(value as SkillVariant);\n}\n\nexport const FLUTTER_NO_BUILD_TARGET_REASON =\n 'Flutter project has no web, android or ios target — nothing to upload symbols for';\n\nexport const BARE_REACT_NATIVE_REASON =\n 'Bare React Native (without Expo) is not supported — source-map upload needs the Expo build pipeline';\n\n/**\n * Filesystem probes the classifier needs on top of what the agent reports.\n * Injected so `coerceReport` stays testable without touching disk. A missing\n * probe answers `false`, which blocks the variant it guards.\n */\nexport type ProjectProbes = {\n /**\n * Flutter: does the project have at least one platform target the wizard can\n * wire uploads into — web (dart2js source maps), android (R8 mapping files)\n * or ios (dSYMs)?\n */\n hasBuildTarget: (path: string) => boolean;\n /** React Native: is the `expo` package installed in the project? */\n isExpoProject: (path: string) => boolean;\n /**\n * Rust: does the project's Cargo manifest tree carry the posthog-rs crate?\n * Unlike the gate probes above, absence means \"trust the agent's\n * `hasPostHog`\", not `false` — the probe REPLACES the agent's boolean when\n * present, because any unrelated PostHog dependency can satisfy it.\n */\n verifyRustSdk?: (path: string) => boolean;\n /** Go: does the project's go.mod require posthog-go? Same semantics as `verifyRustSdk`. */\n verifyGoSdk?: (path: string) => boolean;\n};\n\nconst NO_PROBES: ProjectProbes = {\n hasBuildTarget: () => false,\n isExpoProject: () => false,\n};\n\n/**\n * True when the Flutter project at `projectPath` has at least one platform\n * target. `flutter create` scaffolds a directory per enabled platform, so their\n * absence means this is a pure Dart package or plugin — it produces no app\n * build, and there is nothing to upload.\n */\nfunction projectHasBuildTarget(\n installDir: string,\n projectPath: string,\n): boolean {\n const root = join(installDir, projectPath);\n return (\n existsSync(join(root, 'web', 'index.html')) ||\n existsSync(join(root, 'android')) ||\n existsSync(join(root, 'ios'))\n );\n}\n\n/** True when the project at `projectPath` has the `expo` package installed. */\nfunction projectHasExpo(installDir: string, projectPath: string): boolean {\n try {\n const pkg = JSON.parse(\n readFileSync(join(installDir, projectPath, 'package.json'), 'utf-8'),\n ) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n return (\n pkg.dependencies?.['expo'] != null ||\n pkg.devDependencies?.['expo'] != null\n );\n } catch {\n return false;\n }\n}\n\n/** Classify one agent-detected project for source-map upload. */\nfunction classifyProject(\n p: AgenticDetectionReport['projects'][number],\n probes: ProjectProbes,\n): DetectedProject {\n // For the native-binary variants the deterministic manifest read overrides\n // the agent's single hasPostHog boolean, which any unrelated PostHog\n // dependency can satisfy.\n const sdkVerifier =\n p.targetId === 'rust'\n ? probes.verifyRustSdk\n : p.targetId === 'go'\n ? probes.verifyGoSdk\n : undefined;\n const hasPostHog = sdkVerifier ? sdkVerifier(p.path) : p.hasPostHog;\n const base = {\n path: p.path,\n framework: p.framework,\n hasPostHog,\n };\n\n // A React Native or Flutter labelled project only counts when it resolved to\n // its own target — the nested Gradle and Xcode manifests inside those repos\n // must not claim android or ios.\n const namesForeignNativePlatform =\n (/\\b(?:react[\\s-]*native|expo)\\b/i.test(p.framework) &&\n p.targetId !== 'react-native') ||\n (/\\bflutter\\b/i.test(p.framework) && p.targetId !== 'flutter');\n if (!isAutomatableVariant(p.targetId) || namesForeignNativePlatform) {\n return {\n ...base,\n variant: null,\n instrumentable: false,\n reason: \"Source-map upload isn't supported for this stack yet\",\n };\n }\n\n // A Flutter package or plugin has no platform directories and never produces\n // an app build, so there are no symbols to upload for it.\n if (p.targetId === 'flutter' && !probes.hasBuildTarget(p.path)) {\n return {\n ...base,\n variant: null,\n instrumentable: false,\n reason: FLUTTER_NO_BUILD_TARGET_REASON,\n };\n }\n\n // Bare React Native (no expo package) is not supported: its Metro pipeline\n // can't inject chunk IDs, so uploads would never resolve.\n if (p.targetId === 'react-native' && !probes.isExpoProject(p.path)) {\n return {\n ...base,\n variant: null,\n instrumentable: false,\n reason: BARE_REACT_NATIVE_REASON,\n };\n }\n\n if (!hasPostHog) {\n // The wizard's default flow can't install the Go/Rust SDKs, so don't\n // point users at it for those stacks.\n const install =\n MANUAL_SDK_INSTALL[p.targetId] ?? 'run `npx @posthog/wizard` first';\n return {\n ...base,\n variant: p.targetId,\n instrumentable: false,\n reason: `No PostHog SDK installed yet — ${install}`,\n };\n }\n\n return { ...base, variant: p.targetId, instrumentable: true };\n}\n\n/** Map a generic detection report into source-maps projects. */\nfunction toSourceMapsReport(\n report: AgenticDetectionReport,\n probes: ProjectProbes,\n): DetectionReport {\n return {\n repoType: report.repoType,\n projects: report.projects.map((p) => classifyProject(p, probes)),\n };\n}\n\n/**\n * Validate the agent's raw JSON into a source-maps detection report. Exported\n * for testing — clamps projects the wizard cannot wire up to\n * non-instrumentable. Probes left out of `probes` answer `false`, so every\n * Flutter project is treated as target-less and every React Native project as\n * bare (both blocked).\n */\nexport function coerceReport(\n parsed: unknown,\n probes: Partial<ProjectProbes> = {},\n): DetectionReport {\n return toSourceMapsReport(\n coerceAgenticReport(\n parsed,\n SOURCE_MAPS_TARGETS.map((target) => target.id),\n ),\n { ...NO_PROBES, ...probes },\n );\n}\n\n/** Run the Haiku detector over the repo and classify projects for source maps. */\nexport async function detectSourceMapsProjects(\n session: WizardSession,\n onEvent?: DetectEvent,\n): Promise<DetectionReport> {\n const report = await detectProjectsWithAgent(session, {\n targets: SOURCE_MAPS_TARGETS,\n programId: 'error-tracking-upload-source-maps',\n purpose: 'set up PostHog Error Tracking source-map upload',\n rerankIds: JS_RERANK_VARIANTS,\n onEvent,\n });\n return toSourceMapsReport(report, {\n hasBuildTarget: (path) => projectHasBuildTarget(session.installDir, path),\n isExpoProject: (path) => projectHasExpo(session.installDir, path),\n verifyRustSdk: rustSdkVerifier(session.installDir),\n verifyGoSdk: goSdkVerifier(session.installDir),\n });\n}\n","/**\n * SourceMapsDetectScreen — runs the Haiku detection agent over the repo, shows\n * streaming progress, then renders a structured map of which projects can have\n * source-map upload wired up and which cannot. The user picks one project; the\n * choice is written to frameworkContext and the run step instruments it.\n *\n * Runs after auth — the detection agent needs credentials.\n */\n\nimport { Box, Text } from 'ink';\nimport { useEffect, useRef, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { LoadingBox, PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport {\n SOURCE_MAPS_CONTEXT_KEYS,\n VARIANT_DISPLAY_NAME,\n MANUAL_SDK_VARIANTS,\n} from '@lib/programs/error-tracking-upload-source-maps/index';\nimport {\n detectSourceMapsProjects,\n type DetectedProject,\n type DetectionReport,\n} from '@lib/programs/error-tracking-upload-source-maps/detect-agentic';\n\ninterface SourceMapsDetectScreenProps {\n store: WizardStore;\n}\n\ntype DetectState =\n | { kind: 'loading' }\n | { kind: 'ready'; report: DetectionReport }\n | { kind: 'error'; message: string };\n\nconst EXIT = '__exit';\nconst MAX_ACTIVITY_LINES = 8;\n\nfunction projectLabel(p: DetectedProject): string {\n const name = p.variant ? VARIANT_DISPLAY_NAME[p.variant] : p.framework;\n const where = p.path === '.' ? 'repo root' : p.path;\n return `${name} ${Icons.bullet} ${where}`;\n}\n\nexport const SourceMapsDetectScreen = ({\n store,\n}: SourceMapsDetectScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { credentials } = store.session;\n const accessToken = credentials?.accessToken;\n\n const [state, setState] = useState<DetectState>({ kind: 'loading' });\n const [activity, setActivity] = useState<string[]>([]);\n const started = useRef(false);\n\n useEffect(() => {\n if (!accessToken || started.current) return;\n started.current = true;\n let cancelled = false;\n void (async () => {\n try {\n const report = await detectSourceMapsProjects(store.session, (line) => {\n if (!cancelled) {\n setActivity((prev) => [...prev, line].slice(-MAX_ACTIVITY_LINES));\n }\n });\n if (!cancelled) setState({ kind: 'ready', report });\n } catch (err) {\n if (!cancelled) {\n setState({\n kind: 'error',\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [accessToken, store]);\n\n if (!credentials) {\n return <LoadingBox message=\"Waiting for authentication...\" />;\n }\n\n if (state.kind === 'loading') {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Detecting your project...\n </Text>\n <Box marginY={1}>\n <LoadingBox message=\"Scanning the repo for frameworks and PostHog SDKs...\" />\n </Box>\n <Box flexDirection=\"column\">\n {activity.length === 0 ? (\n <Text dimColor>{' '}Starting up the detection agent…</Text>\n ) : (\n activity.map((line, i) => (\n <Text\n key={`${i}-${line}`}\n dimColor={i < activity.length - 1}\n color={i === activity.length - 1 ? Colors.primary : undefined}\n >\n {' '}\n {Icons.triangleSmallRight} {line}\n </Text>\n ))\n )}\n </Box>\n </Box>\n );\n }\n\n if (state.kind === 'error') {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginY={1}>\n <Text color={Colors.error} bold>\n {Icons.squareFilled} Detection failed\n </Text>\n <Text dimColor>{state.message}</Text>\n </Box>\n <PickerMenu\n options={[{ label: 'Exit', value: EXIT }]}\n onSelect={() => process.exit(1)}\n />\n </Box>\n );\n }\n\n const { report } = state;\n const instrumentable = report.projects.filter((p) => p.instrumentable);\n const blocked = report.projects.filter((p) => !p.instrumentable);\n\n if (instrumentable.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color={Colors.error} bold>\n {Icons.squareFilled} Nothing to instrument yet\n </Text>\n <Text dimColor>\n None of the {report.projects.length} projects found can have\n source-map upload set up.\n </Text>\n </Box>\n <BlockedSummary blocked={blocked} />\n <Box marginTop={1}>\n <PickerMenu\n options={[{ label: 'Exit', value: EXIT }]}\n onSelect={() => process.exit(0)}\n />\n </Box>\n </Box>\n );\n }\n\n const options = [\n ...instrumentable.map((p) => ({\n label: projectLabel(p),\n value: p.path,\n })),\n { label: 'Cancel', value: EXIT },\n ];\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n {Icons.check} Found{' '}\n {report.repoType === 'monorepo' ? 'a monorepo' : 'your project'}\n </Text>\n </Box>\n\n <PickerMenu\n message=\"Which project would you like to set up source map uploads for?\"\n options={options}\n onSelect={(value) => {\n const path = Array.isArray(value) ? value[0] : value;\n if (path === EXIT) {\n process.exit(0);\n return;\n }\n const chosen = instrumentable.find((p) => p.path === path);\n if (!chosen || !chosen.variant) return;\n store.setFrameworkContext(\n SOURCE_MAPS_CONTEXT_KEYS.selectedVariant,\n chosen.variant,\n );\n store.setFrameworkContext(\n SOURCE_MAPS_CONTEXT_KEYS.selectedDisplayName,\n VARIANT_DISPLAY_NAME[chosen.variant],\n );\n store.setFrameworkContext(\n SOURCE_MAPS_CONTEXT_KEYS.selectedPath,\n chosen.path,\n );\n }}\n />\n\n <Box marginTop={1}>\n <BlockedSummary blocked={blocked} />\n </Box>\n </Box>\n );\n};\n\n/**\n * Collapses the non-instrumentable projects into a short count line (or two)\n * instead of listing every one — a monorepo can have dozens.\n */\nconst BlockedSummary = ({ blocked }: { blocked: DetectedProject[] }) => {\n const unsupported = blocked.filter((p) => p.variant == null).length;\n // The wizard can't install the Go/Rust SDKs, so their missing-SDK\n // remediation is a manual install, not `npx @posthog/wizard`.\n const manualSdk = blocked.filter(\n (p) => p.variant != null && MANUAL_SDK_VARIANTS.includes(p.variant),\n ).length;\n const missingSdk = blocked.length - unsupported - manualSdk;\n if (blocked.length === 0) return null;\n return (\n <Box flexDirection=\"column\">\n {unsupported > 0 && (\n <Text dimColor>\n (… {unsupported} other project{unsupported === 1 ? '' : 's'} not\n supported)\n </Text>\n )}\n {missingSdk > 0 && (\n <Text dimColor>\n (… {missingSdk} supported but missing the PostHog SDK — install it\n first with `npx @posthog/wizard`)\n </Text>\n )}\n {manualSdk > 0 && (\n <Text dimColor>\n (… {manualSdk} supported but missing the PostHog SDK — add it to the\n project first (posthog-go / posthog-rs), then re-run)\n </Text>\n )}\n </Box>\n );\n};\n","/**\n * SourceMapsOutroScreen — post-run summary for the source-maps upload flow.\n *\n * Unlike the generic OutroScreen, this spells out the operational facts a user\n * needs to actually get de-minified stack traces: that packages were installed\n * and upload credentials written to .env, plus the three gotchas (builds\n * upload, run the build, give CI the same credentials). All static guidance —\n * driven only by the program's `buildOutroData` (kind / message / report /\n * docs), no per-run data.\n */\n\nimport { join } from 'node:path';\nimport type { ReactNode } from 'react';\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { OutroKind } from '@lib/wizard-session';\nimport { Colors } from '@ui/tui/styles';\nimport { useDismissOnAnyKey } from '@ui/tui/hooks/useDismissOnAnyKey';\n\ninterface SourceMapsOutroScreenProps {\n store: WizardStore;\n}\n\nexport const SourceMapsOutroScreen = ({\n store,\n}: SourceMapsOutroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n useDismissOnAnyKey(() => store.setOutroDismissed());\n\n const outroData = store.session.outroData;\n\n if (!outroData) {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text dimColor>Finishing up...</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n {outroData.kind === OutroKind.Success && (\n <Box flexDirection=\"column\">\n <Text color={Colors.success} bold>\n ✔ {outroData.message || 'Source maps wired up!'}\n </Text>\n\n <Section title=\"What the wizard did\">\n <Text>• Installed the packages needed for source map upload.</Text>\n <Text>\n • Wrote the PostHog upload credentials to your{' '}\n <Text bold>.env</Text> file.\n </Text>\n </Section>\n\n <Section title=\"How uploads work now\">\n <Text>\n • Every <Text bold>build</Text> now uploads source maps to PostHog\n automatically — no extra command to remember.\n </Text>\n <Text>\n • Run your app from the <Text bold>built output</Text>. Source\n maps only resolve for errors thrown by the build that was\n uploaded.\n </Text>\n <Text>\n • In <Text bold>CI</Text>, the build job needs the same upload\n credentials. If the wizard wired your pipeline, add the referenced\n secrets to your CI provider (e.g. GitHub repo secrets) before your\n next deploy.\n </Text>\n </Section>\n\n {outroData.reportFile && (\n <Box marginTop={1}>\n <Text>\n Details in{' '}\n <Text bold>\n {join(store.session.installDir, outroData.reportFile)}\n </Text>\n </Text>\n </Box>\n )}\n\n {outroData.docsUrl && (\n <Box marginTop={1}>\n <Text>\n Learn more:{' '}\n <Text color={Colors.primary}>{outroData.docsUrl}</Text>\n </Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text dimColor>\n Note: This wizard uses an LLM agent to analyze and modify your\n project. Please review the changes made.\n </Text>\n </Box>\n <Text dimColor>\n How did this work for you? Drop us a line: wizard@posthog.com\n </Text>\n </Box>\n )}\n\n {outroData.kind === OutroKind.Error && (\n <Box flexDirection=\"column\">\n <Text color={Colors.error} bold>\n ✘ {outroData.message || 'An error occurred'}\n </Text>\n {outroData.body && (\n <Box marginTop={1}>\n <Text dimColor>{outroData.body}</Text>\n </Box>\n )}\n {outroData.docsUrl && (\n <Box marginTop={1}>\n <Text>\n Docs: <Text color={Colors.primary}>{outroData.docsUrl}</Text>\n </Text>\n </Box>\n )}\n </Box>\n )}\n\n {outroData.kind === OutroKind.Cancel && (\n <Text color=\"yellow\">■ {outroData.message || 'Cancelled'}</Text>\n )}\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to continue</Text>\n </Box>\n </Box>\n );\n};\n\nconst Section = ({\n title,\n children,\n}: {\n title: string;\n children: ReactNode;\n}) => (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={Colors.primary} bold>\n {title}:\n </Text>\n {children}\n </Box>\n);\n","/**\n * AgentSkillIntroScreen — Default intro for generic agent-skill programs.\n *\n * Programs that need a different intro ship their own screen component\n * (see audit/AuditIntroScreen.tsx).\n */\n\nimport { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\nimport { SkillSourceInfo, useSkillEntry } from './SkillSourceInfo.js';\n\ninterface AgentSkillIntroScreenProps {\n store: WizardStore;\n}\n\nexport const AgentSkillIntroScreen = ({\n store,\n}: AgentSkillIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n\n const { session } = store;\n const skillId = session.skillId ?? 'unknown';\n const { skillEntry, fetchFailed } = useSkillEntry(skillId);\n\n let body: ReactNode;\n\n if (showingMoreInfo) {\n body = (\n <Box flexDirection=\"column\" width={56} flexShrink={0}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n </Box>\n <SkillSourceInfo\n skillId={skillId}\n skillEntry={skillEntry}\n fetchFailed={fetchFailed}\n />\n <Box marginTop={1}>\n <Text dimColor>\n {skillEntry?.name ?? (fetchFailed ? skillId : 'Loading...')}\n </Text>\n </Box>\n </Box>\n );\n } else {\n body = (\n <Text>\n Let's run the{' '}\n <Text italic color=\"cyan\">\n {skillId}\n </Text>{' '}\n skill.\n </Text>\n );\n }\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const handleSelect = (value: string) => {\n if (value === 'cancel') process.exit(0);\n else if (value === 'more-info') setShowingMoreInfo(true);\n else if (value === 'back') setShowingMoreInfo(false);\n else store.completeSetup();\n };\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n showSubtitle={!showingMoreInfo}\n body={body}\n showDetection={!showingMoreInfo}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={handleSelect}\n />\n );\n};\n","import { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from '@ui/tui/screens/IntroScreenLayout';\nimport {\n SkillSourceInfo,\n useSkillEntry,\n} from '@ui/tui/screens/SkillSourceInfo';\n\ninterface AiObservabilityIntroScreenProps {\n store: WizardStore;\n}\n\nexport const AiObservabilityIntroScreen = ({\n store,\n}: AiObservabilityIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n const { session } = store;\n // ai-observability picks its skill variant at run time (openai-python,\n // anthropic-node, langchain-python, …), so there's no pre-seeded skillId\n // here. Fall back to the group id for the \"more info\" lookup.\n const skillId = session.skillId ?? 'ai-observability';\n const { skillEntry, fetchFailed } = useSkillEntry(skillId);\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56}>\n <Box marginBottom={1}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n </Box>\n\n <Text>\n The{' '}\n <Text color=\"cyan\" italic>\n ai-observability\n </Text>{' '}\n program wraps your LLM SDK calls with PostHog's OpenTelemetry-based\n tracing so every prompt, completion, tool call, token count, and cost\n lands in AI Observability. Supports OpenAI, Anthropic, Google,\n LangChain, Vercel AI, and other SDKs.\n </Text>\n <Box marginTop={1}>\n <SkillSourceInfo\n skillId={skillId}\n skillEntry={skillEntry}\n fetchFailed={fetchFailed}\n />\n </Box>\n </Box>\n ) : (\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>\n Let's instrument your LLM calls with PostHog AI Observability.\n </Text>\n </Box>\n );\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const handleSelect = (value: string) => {\n if (value === 'cancel') process.exit(0);\n else if (value === 'more-info') setShowingMoreInfo(true);\n else if (value === 'back') setShowingMoreInfo(false);\n else store.completeSetup();\n };\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n body={body}\n showDetection={!showingMoreInfo}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={handleSelect}\n />\n );\n};\n","import { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from '@ui/tui/screens/IntroScreenLayout';\nimport {\n SkillSourceInfo,\n useSkillEntry,\n} from '@ui/tui/screens/SkillSourceInfo';\n\ninterface MetricsIntroScreenProps {\n store: WizardStore;\n}\n\nexport const MetricsIntroScreen = ({ store }: MetricsIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n const { session } = store;\n // metrics picks its skill variant at run time (python, nodejs, javascript,\n // kubernetes, other), so there's no pre-seeded skillId here. Fall back to\n // the group id for the \"more info\" lookup.\n const skillId = session.skillId ?? 'metrics';\n const { skillEntry, fetchFailed } = useSkillEntry(skillId, session.localMcp);\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56}>\n <Box marginBottom={1}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n </Box>\n\n <Text>\n The{' '}\n <Text color=\"cyan\" italic>\n metrics\n </Text>{' '}\n program instruments your service with PostHog application metrics —\n counters, gauges, and histograms via{' '}\n <Text color=\"cyan\">posthog.metrics</Text> — at operational choke points:\n request middleware, background jobs, external calls, and business commit\n sites. Supports Python, Node.js, web JavaScript, Kubernetes, and any\n other language via OTLP.\n </Text>\n <Box marginTop={1}>\n <SkillSourceInfo\n skillId={skillId}\n skillEntry={skillEntry}\n fetchFailed={fetchFailed}\n />\n </Box>\n </Box>\n ) : (\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>\n Let's instrument your service with PostHog application metrics.\n </Text>\n </Box>\n );\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const handleSelect = (value: string) => {\n if (value === 'cancel') process.exit(0);\n else if (value === 'more-info') setShowingMoreInfo(true);\n else if (value === 'back') setShowingMoreInfo(false);\n else store.completeSetup();\n };\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n body={body}\n showDetection={!showingMoreInfo}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={handleSelect}\n />\n );\n};\n","/**\n * SelfDrivingIntroScreen — Welcome screen for the self-driving flow.\n *\n * Composes IntroScreenLayout with prerequisite-detection state:\n * - Detection succeeded: explains what Self-driving turns on, continue/cancel\n * - Detection failed: shows the error via errorView + exit prompt\n *\n * Reads `frameworkContext.detectError` set by\n * detectSelfDrivingPrerequisites().\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\nimport {\n NO_DEFAULT_LIMIT,\n PRICING_LONG,\n PRICING_SHORT,\n} from '@lib/programs/self-driving/content/pricing.js';\nimport type { SelfDrivingDetectError } from '@lib/programs/self-driving/index';\n\ninterface SelfDrivingIntroScreenProps {\n store: WizardStore;\n}\n\nexport const SelfDrivingIntroScreen = ({\n store,\n}: SelfDrivingIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n\n const { session } = store;\n const detectError = session.frameworkContext.detectError as\n | SelfDrivingDetectError\n | undefined;\n\n const subtitle = (\n <>\n <Text dimColor>\n We'll use AI to analyze your project and set up PostHog Self-driving.\n </Text>\n <Text dimColor>.env* file contents will not leave your machine.</Text>\n </>\n );\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56} flexShrink={0}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>.\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.programLabel}\n </Text>{' '}\n program turns on PostHog Self-driving for this project:\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={4}>\n <Text>\n {'•'} Watches your signal sources: errors, replays, connected tools\n </Text>\n <Text>{'•'} Runs scouts – scheduled agents that scan for issues</Text>\n <Text>{'•'} Groups signals into prioritized reports in your inbox</Text>\n <Text>{'•'} Researches findings in your code via GitHub</Text>\n <Text>\n {'•'} Measures shipped fixes, and reopens the loop if the pattern\n persists\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>{PRICING_LONG}</Text>\n <Text>{NO_DEFAULT_LIMIT}</Text>\n </Box>\n </Box>\n ) : (\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>Let's set up PostHog Self-driving.</Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n PostHog watches how people really use your product, finds issues, and\n proposes fixes.\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} alignItems=\"center\">\n <Text dimColor>\n An agent will connect GitHub, enable signal sources, and tune your\n scouts.\n </Text>\n <Text dimColor>\n About 10 minutes, with a few questions along the way.\n </Text>\n <Text dimColor>{PRICING_SHORT}</Text>\n </Box>\n </Box>\n );\n\n const errorView = detectError ? (\n <>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"red\" bold>\n {'✘'} Cannot set up PostHog Self-driving\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <DetectErrorBody error={detectError} />\n </Box>\n </Box>\n\n <PickerMenu\n options={[{ label: 'Exit', value: 'exit' }]}\n onSelect={() => process.exit(1)}\n />\n </>\n ) : undefined;\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n showSubtitle={!showingMoreInfo}\n subtitle={subtitle}\n body={body}\n showDetection={!showingMoreInfo}\n errorView={errorView}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'more-info') {\n setShowingMoreInfo(true);\n } else if (value === 'back') {\n setShowingMoreInfo(false);\n } else {\n store.completeSetup();\n }\n }}\n />\n );\n};\n\nconst DetectErrorBody = ({ error }: { error: SelfDrivingDetectError }) => {\n switch (error.kind) {\n case 'bad-directory': {\n const reasonText = {\n missing: 'does not exist',\n 'not-dir': 'is not a directory',\n unreadable: 'could not be accessed',\n }[error.reason];\n return (\n <>\n <Text>This path {reasonText}:</Text>\n <Text dimColor>\n {' '}\n {error.path}\n </Text>\n </>\n );\n }\n\n default:\n // Defensive fallback so a future SelfDrivingDetectError kind still\n // renders something useful instead of a blank screen.\n return (\n <Text>\n Self-driving could not start in this directory. Try again, or reach\n out to wizard@posthog.com.\n </Text>\n );\n }\n};\n","/**\n * SelfDrivingIntegrationCheckScreen — shown only when detection found no\n * PostHog in the project. Self-driving needs a PostHog SDK, so we always\n * integrate first; but a project with no SDK is often a project with no PostHog\n * account either, so this screen first asks whether the user already has one:\n *\n * - \"Yes — log me in\" → setIntegrate(true); auth runs the OAuth login.\n * - \"No — create one for me\" → collect email + region, then\n * chooseProvisionAccount(): auth provisions a new\n * account (and emails a login link) instead.\n *\n * Both answers integrate the SDK; they only differ in how auth gets credentials.\n * Skipped entirely when PostHog is already present (or under `--integrate`,\n * which forces integration + the default OAuth login).\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { TextInput } from '@inkjs/ui';\nimport { useState, useSyncExternalStore } from 'react';\n\nimport type { WizardStore } from '@ui/tui/store';\nimport type { CloudRegion } from '@lib/wizard-session';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport {\n PrivacyPanel,\n PRIVACY_PANEL_LABEL,\n} from '@ui/tui/components/PrivacyPanel';\nimport { IntroScreenLayout } from '@ui/tui/screens/IntroScreenLayout';\nimport { POSTHOG_PRIVACY_URL, POSTHOG_TERMS_URL } from '@lib/constants';\nimport { Colors } from '@ui/tui/styles';\n\ninterface SelfDrivingIntegrationCheckScreenProps {\n store: WizardStore;\n}\n\n/** Multi-step screen state: pick account status → email → region. */\ntype Stage = 'ask' | 'email' | 'region';\n\nconst EMAIL_RE = /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/;\n\nexport const SelfDrivingIntegrationCheckScreen = ({\n store,\n}: SelfDrivingIntegrationCheckScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [stage, setStage] = useState<Stage>('ask');\n // Pre-fill from `--email` when it was passed; tracked across stages so\n // the region step can hand both to the store in one commit.\n const [email, setEmail] = useState(store.session.email ?? '');\n const [emailError, setEmailError] = useState<string | null>(null);\n const [showPrivacy, setShowPrivacy] = useState(false);\n\n useInput((input, key) => {\n // While the privacy overlay is open, only Esc closes it; the overlay's own\n // Back menu handles the rest.\n if (showPrivacy) {\n if (key.escape) setShowPrivacy(false);\n return;\n }\n\n // [I] opens the full privacy panel. Skipped on the email stage so the\n // keystroke reaches the text field instead.\n if ((input === 'i' || input === 'I') && stage !== 'email') {\n setShowPrivacy(true);\n return;\n }\n\n // Esc steps back toward the account question (the picker owns input on 'ask').\n if (key.escape && stage !== 'ask') {\n setEmailError(null);\n setStage(stage === 'region' ? 'email' : 'ask');\n }\n });\n\n if (showPrivacy) {\n return (\n <IntroScreenLayout\n installDir={store.session.installDir}\n title={PRIVACY_PANEL_LABEL}\n showSubtitle={false}\n showDetection={false}\n body={<PrivacyPanel />}\n showPrivacy={false}\n menuOptions={[{ label: 'Back', value: 'back' }]}\n menuAlign=\"left\"\n onSelect={() => setShowPrivacy(false)}\n />\n );\n }\n\n if (stage === 'region') {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Where should we create your account?\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>\n We'll create your PostHog account for {email} in this region.\n </Text>\n </Box>\n <Box marginTop={1}>\n <PickerMenu\n message=\"Pick your cloud region\"\n options={[\n { label: 'US', value: 'us', hint: 'us.posthog.com' },\n { label: 'EU', value: 'eu', hint: 'eu.posthog.com' },\n ]}\n onSelect={(value) => {\n const region = (\n Array.isArray(value) ? value[0] : value\n ) as CloudRegion;\n store.chooseProvisionAccount(email.trim(), region);\n }}\n />\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>By creating an account you agree to our terms.</Text>\n <Text dimColor>\n Terms: <Text color=\"cyan\">{POSTHOG_TERMS_URL}</Text>\n </Text>\n <Text dimColor>\n Privacy: <Text color=\"cyan\">{POSTHOG_PRIVACY_URL}</Text>\n </Text>\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n <Text color={Colors.accent}>[Esc]</Text> back{' · '}\n <Text color={Colors.accent}>[I]</Text> {PRIVACY_PANEL_LABEL}\n </Text>\n </Box>\n </Box>\n );\n }\n\n if (stage === 'email') {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Create your PostHog account\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>\n We'll create your account and email you a login link. What\n email should we use?\n </Text>\n </Box>\n <Box marginTop={1} width=\"100%\">\n <TextInput\n placeholder=\"you@company.com\"\n defaultValue={email}\n onChange={setEmail}\n onSubmit={(value) => {\n const trimmed = value.trim();\n if (!EMAIL_RE.test(trimmed)) {\n setEmailError('Please enter a valid email address.');\n return;\n }\n setEmail(trimmed);\n setEmailError(null);\n setStage('region');\n }}\n />\n </Box>\n {emailError && (\n <Box marginTop={1}>\n <Text color=\"yellow\">{emailError}</Text>\n </Box>\n )}\n <Box marginTop={1}>\n <Text dimColor>\n <Text color={Colors.accent}>[Enter]</Text> continue{' · '}\n <Text color={Colors.accent}>[Esc]</Text> back\n </Text>\n </Box>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n No PostHog integration found\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>\n This will kick off an agent to explore your project and find existing\n PostHog integrations. Self-driving reads PostHog data, so we'll\n set that up first: it gives your signal sources something to watch. To\n do that we need to connect to PostHog — do you already have an\n account?\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <PickerMenu\n options={[\n {\n label: 'Yes, log me in',\n value: 'login',\n hint: 'opens PostHog to authorize',\n },\n {\n label: 'No, create one for me',\n value: 'provision',\n hint: \"we'll email you a login link\",\n },\n ]}\n onSelect={(value) => {\n const choice = Array.isArray(value) ? value[0] : value;\n if (choice === 'login') {\n store.setIntegrate(true);\n } else {\n setStage('email');\n }\n }}\n />\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n <Text color={Colors.accent}>[I]</Text> {PRIVACY_PANEL_LABEL}\n </Text>\n </Box>\n </Box>\n );\n};\n","/**\n * SelfDrivingIntegrationDetectScreen — runs the Haiku detector over the repo,\n * streams progress, then renders a picker of projects. Two kinds are offered:\n * set-up-here (supported framework, no SDK yet; writes framework + path for\n * the integrate-run phase) and continue-with-existing (already has PostHog;\n * sets integrate=false and skips straight to Self-driving). On a detection\n * error, falls back to a manual framework picker.\n *\n * Runs after auth — the detector needs credentials.\n */\n\nimport { Box, Text } from 'ink';\nimport { useEffect, useRef, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { LoadingBox, PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { Integration } from '@lib/constants';\nimport { FRAMEWORK_REGISTRY } from '@lib/registry';\nimport { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@lib/programs/self-driving/detect';\nimport {\n detectSelfDrivingIntegrationProjects,\n type IntegrationProject,\n type IntegrationDetectionReport,\n} from '@lib/programs/self-driving/detect-agentic';\n\ninterface SelfDrivingIntegrationDetectScreenProps {\n store: WizardStore;\n}\n\ntype DetectState =\n | { kind: 'loading' }\n | { kind: 'ready'; report: IntegrationDetectionReport }\n | { kind: 'error'; message: string };\n\nconst CANCEL = '__cancel';\nconst MAX_ACTIVITY_LINES = 8;\n\nfunction projectLabel(p: IntegrationProject): string {\n const where = p.path === '.' ? 'repo root' : p.path;\n return `${p.framework} ${Icons.bullet} ${where}`;\n}\n\nexport const SelfDrivingIntegrationDetectScreen = ({\n store,\n}: SelfDrivingIntegrationDetectScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { credentials } = store.session;\n const accessToken = credentials?.accessToken;\n\n const [state, setState] = useState<DetectState>({ kind: 'loading' });\n const [activity, setActivity] = useState<string[]>([]);\n const started = useRef(false);\n\n // Commit a chosen project to integrate: framework + path → session. The run\n // phase reads both (path scopes the install dir to the sub-app).\n const choose = (p: IntegrationProject) => {\n if (!p.integration) return;\n store.setFrameworkContext(SELF_DRIVING_INTEGRATE_PATH_KEY, p.path);\n store.setFrameworkConfig(p.integration, FRAMEWORK_REGISTRY[p.integration]);\n };\n\n // PostHog already installed here: integrate=false completes integrate-detect\n // and drops the integrate-run / handoff steps from the walk.\n const continueWithExisting = (p: IntegrationProject) => {\n store.setFrameworkContext(SELF_DRIVING_INTEGRATE_PATH_KEY, p.path);\n store.setIntegrate(false, {\n via: 'existing-integration-detected',\n path: p.path,\n });\n };\n\n // Run the detector once, after auth.\n useEffect(() => {\n if (!accessToken || started.current) return;\n started.current = true;\n let cancelled = false;\n void (async () => {\n try {\n const report = await detectSelfDrivingIntegrationProjects(\n store.session,\n (line) => {\n if (!cancelled) {\n setActivity((prev) => [...prev, line].slice(-MAX_ACTIVITY_LINES));\n }\n },\n );\n if (!cancelled) setState({ kind: 'ready', report });\n } catch (err) {\n if (!cancelled) {\n setState({\n kind: 'error',\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [accessToken, store]);\n\n if (!credentials) {\n return <LoadingBox message=\"Waiting for authentication...\" />;\n }\n\n if (state.kind === 'error') {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color={Colors.error} bold>\n {Icons.squareFilled} Detection failed\n </Text>\n <Text dimColor>{state.message}</Text>\n <Text dimColor>\n Pick your framework and we'll set PostHog up here.\n </Text>\n </Box>\n <PickerMenu<Integration>\n centered\n columns={2}\n message=\"Select your framework\"\n options={Object.values(Integration).map((v) => ({\n label: v,\n value: v,\n }))}\n onSelect={(value) => {\n const integration = Array.isArray(value) ? value[0] : value;\n store.setFrameworkContext(SELF_DRIVING_INTEGRATE_PATH_KEY, '.');\n store.setFrameworkConfig(\n integration,\n FRAMEWORK_REGISTRY[integration],\n );\n }}\n />\n </Box>\n );\n }\n\n if (state.kind === 'loading') {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Detecting your project. Stick around, this will take a few seconds...\n </Text>\n <Box marginY={1}>\n <LoadingBox message=\"Scanning the repo for frameworks and PostHog SDKs...\" />\n </Box>\n <Box flexDirection=\"column\">\n {activity.length === 0 ? (\n <Text dimColor>{' '}Starting up the detection agent…</Text>\n ) : (\n activity.map((line, i) => (\n <Text\n key={`${i}-${line}`}\n dimColor={i < activity.length - 1}\n color={i === activity.length - 1 ? Colors.primary : undefined}\n >\n {' '}\n {Icons.triangleSmallRight} {line}\n </Text>\n ))\n )}\n </Box>\n </Box>\n );\n }\n\n const { report } = state;\n const instrumentable = report.projects.filter((p) => p.instrumentable);\n // Already has PostHog → offer \"continue with existing\" instead of hiding it.\n const existing = report.projects.filter((p) => p.continuable);\n const unsupported = report.projects.filter(\n (p) => !p.instrumentable && !p.continuable,\n );\n\n // Values are prefixed so one picker can mix new: and existing: entries.\n const NEW = 'new:';\n const EXISTING = 'existing:';\n const dispatch = (value: string | string[]) => {\n const v = Array.isArray(value) ? value[0] : value;\n if (v === CANCEL) {\n process.exit(0);\n return;\n }\n if (v.startsWith(EXISTING)) {\n const p = existing.find((x) => x.path === v.slice(EXISTING.length));\n if (p) continueWithExisting(p);\n return;\n }\n const p = instrumentable.find((x) => x.path === v.slice(NEW.length));\n if (p) choose(p);\n };\n\n // Nothing to instrument, nothing already installed: a genuine dead end.\n if (instrumentable.length === 0 && existing.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color={Colors.error} bold>\n {Icons.squareFilled} Nothing to set up here\n </Text>\n <Text dimColor>\n None of the {report.projects.length} projects found can have PostHog\n set up.\n </Text>\n </Box>\n <UnsupportedSummary unsupported={unsupported} />\n <Box marginTop={1}>\n <PickerMenu\n options={[{ label: 'Exit', value: CANCEL }]}\n onSelect={() => process.exit(0)}\n />\n </Box>\n </Box>\n );\n }\n\n // Only already-installed projects: continue straight to Self-driving.\n if (instrumentable.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n {Icons.check} PostHog is already set up\n </Text>\n <Text dimColor>Continue straight to Self-driving.</Text>\n </Box>\n <PickerMenu\n message={\n existing.length === 1\n ? 'Continue with your existing PostHog install?'\n : 'Which project should Self-driving use?'\n }\n options={[\n ...existing.map((p) => ({\n label: projectLabel(p),\n value: `${EXISTING}${p.path}`,\n })),\n { label: 'Exit', value: CANCEL },\n ]}\n onSelect={dispatch}\n />\n <Box marginTop={1}>\n <UnsupportedSummary unsupported={unsupported} />\n </Box>\n </Box>\n );\n }\n\n const single = instrumentable.length === 1;\n // Disabled rows act as section headings + spacers — navigation skips them.\n const HEAD = 'head:';\n const spacer = (id: string) => ({\n label: ' ',\n value: `${HEAD}${id}`,\n disabled: true,\n });\n const heading = (id: string, label: string) => ({\n label,\n value: `${HEAD}${id}`,\n disabled: true,\n header: true,\n });\n const options = [\n heading('new', 'New PostHog integration:'),\n ...instrumentable.map((p) => ({\n label: projectLabel(p),\n value: `${NEW}${p.path}`,\n indent: true,\n })),\n ...(existing.length > 0\n ? [\n spacer('gap1'),\n heading('existing', 'Existing integrations:'),\n ...existing.map((p) => ({\n label: projectLabel(p),\n value: `${EXISTING}${p.path}`,\n indent: true,\n })),\n ]\n : []),\n spacer('gap2'),\n { label: 'Cancel', value: CANCEL },\n ];\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n {Icons.check} Found{' '}\n {report.repoType === 'monorepo' ? 'a monorepo' : 'your project'}\n </Text>\n </Box>\n\n <PickerMenu\n message={\n single && existing.length === 0\n ? 'Set up PostHog here? Confirm to continue.'\n : undefined\n }\n options={options}\n onSelect={dispatch}\n />\n\n <Box marginTop={1}>\n <UnsupportedSummary unsupported={unsupported} />\n </Box>\n </Box>\n );\n};\n\n/**\n * Collapses unsupported-stack projects into a count line (already-has-PostHog\n * projects are real picker options, not summarised).\n */\nconst UnsupportedSummary = ({\n unsupported,\n}: {\n unsupported: IntegrationProject[];\n}) => {\n if (unsupported.length === 0) return null;\n return (\n <Box flexDirection=\"column\">\n <Text dimColor>\n (… {unsupported.length} project{unsupported.length === 1 ? '' : 's'} not\n supported yet)\n </Text>\n </Box>\n );\n};\n","/**\n * SelfDrivingHandoffScreen — the bridge between the integration run and the\n * Self-driving run. Shown only in the integrate path (PostHog wasn't present, so\n * the wizard set it up first); the already-has-PostHog path skips straight to\n * Self-driving with no note. Confirms the SDK is in, then hands off to the\n * Self-driving run.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\n\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors } from '@ui/tui/styles';\nimport { SETUP_REPORT_FILE } from '@lib/programs/posthog-integration/index';\nimport { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@lib/programs/self-driving/detect';\n\ninterface SelfDrivingHandoffScreenProps {\n store: WizardStore;\n}\n\nexport const SelfDrivingHandoffScreen = ({\n store,\n}: SelfDrivingHandoffScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n // The integration ran in the picked project (a monorepo sub-app, or the\n // root), so the report sits under that path.\n const rel = store.session.frameworkContext[SELF_DRIVING_INTEGRATE_PATH_KEY];\n const dir = typeof rel === 'string' && rel !== '.' ? `${rel}/` : '';\n const reportPath = `./${dir}${SETUP_REPORT_FILE}`;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n ✔ PostHog is installed\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>Now let's make your product self-driving.</Text>\n <Box marginTop={1}>\n <Text dimColor>\n Next, the agent connects GitHub, turns on signal sources, and tunes\n the scouts that watch your product data.\n </Text>\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n About 10 more minutes, and it needs your input a few times. Keep\n this terminal open.\n </Text>\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <PickerMenu\n options={[{ label: 'Set up Self-driving [Enter]', value: 'go' }]}\n onSelect={() => store.confirmSelfDrivingHandoff()}\n />\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n You can find your PostHog integration report at{' '}\n <Text bold>{reportPath}</Text>\n </Text>\n </Box>\n </Box>\n );\n};\n","/**\n * Polls `/integrations/` until the PostHog GitHub App shows up, writing the\n * result to the session so the Self-driving GitHub gate can advance.\n *\n * Installing the App is a manual browser step, so polling is what flips the\n * gate once the user comes back. The first tick also resolves the session's\n * unknown (`null`) state.\n */\n\nimport { useEffect } from 'react';\n\nimport type { WizardStore } from '@ui/tui/store';\nimport type { WizardSession } from '@lib/wizard-session';\nimport { fetchGithubConnected } from '@lib/api';\nimport { requestDeepLink } from '@utils/provisioning';\nimport { analytics } from '@utils/analytics';\n\nconst POLL_INTERVAL_MS = 3000;\n\n// Provisioned signups have no browser session for the install link; deep link when the partner tier grants one, else the login page.\nexport async function fetchLoginUrl(\n session: WizardSession,\n): Promise<string | null> {\n if (!session.signup || !session.credentials) return null;\n const deepLink = await requestDeepLink(\n session.credentials.accessToken,\n session.credentials.host,\n );\n return deepLink ?? `${session.credentials.host.appHost}/login`;\n}\n\nexport function useGithubConnection(store: WizardStore): void {\n const credentials = store.session.credentials;\n const connected = store.session.githubConnected === true;\n\n useEffect(() => {\n if (!credentials || connected) return;\n\n const controller = new AbortController();\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let errorReported = false;\n\n /** A check that came back \"not connected\" — including a failed one. */\n const settleUnknown = (): void => {\n if (store.session.githubConnected === null) {\n store.setGithubConnected(false);\n }\n };\n\n const wait = (): Promise<void> =>\n new Promise((resolve) => {\n timer = setTimeout(resolve, POLL_INTERVAL_MS);\n });\n\n void (async () => {\n while (!stopped) {\n try {\n const isConnected = await fetchGithubConnected(\n credentials.accessToken,\n credentials.projectId,\n credentials.host.apiHost,\n controller.signal,\n );\n if (stopped) return;\n if (isConnected) {\n // Only a false→true flip means the user installed during this\n // screen; true on the first check means they arrived connected.\n if (store.session.githubConnected === false) {\n analytics.wizardCapture('github connect completed');\n }\n store.setGithubConnected(true);\n return;\n }\n settleUnknown();\n } catch (err) {\n if (stopped) return;\n // Report once, then keep polling. Unlike Slack's nudge, this gate\n // can't degrade to a skip — the run cannot proceed until it\n // resolves — so a transient API blip must not strand the user.\n if (!errorReported) {\n errorReported = true;\n analytics.captureException(\n err instanceof Error ? err : new Error(String(err)),\n { step: 'github_connected_check' },\n );\n }\n settleUnknown();\n }\n await wait();\n }\n })();\n\n return () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n controller.abort();\n };\n }, [credentials, connected, store]);\n}\n","/**\n * SelfDrivingGitHubScreen — the \"Connect GitHub\" gate, shown after the handoff\n * and before the Self-driving run.\n *\n * Self-driving cannot research findings or open fixes without code access, so\n * the GitHub App is a hard requirement. The agent used to ask for it mid-run\n * via `wizard_ask` and abort when the answer came back declined — but a\n * `wizard_ask` timeout resolves to the same cancelled value as a real decline,\n * so a user who stepped away had their run killed as if they had refused.\n * Gating here instead makes the requirement cheap (no agent has started),\n * unambiguous (declining is an explicit pick), and un-timeoutable (the screen\n * waits as long as the browser install takes).\n *\n * Unlike SlackConnectScreen this is not skippable: declining ends the run on\n * the outro rather than continuing without it. The connection poll lives in\n * {@link useGithubConnection}.\n */\n\nimport { Box, Text } from 'ink';\nimport { useEffect, useRef, useState, useSyncExternalStore } from 'react';\n\nimport type { WizardStore } from '@ui/tui/store';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { PickerMenu, LoadingBox } from '@ui/tui/primitives/index';\nimport { useKeyBindings, KeyMatch } from '@ui/tui/hooks/useKeyBindings';\nimport {\n useGithubConnection,\n fetchLoginUrl,\n} from '@ui/tui/hooks/useGithubConnection';\nimport { OutroKind } from '@lib/wizard-session';\nimport {\n GITHUB_REQUIRED_BODY,\n GITHUB_REQUIRED_MESSAGE,\n} from '@lib/programs/self-driving/detect';\nimport { analytics } from '@utils/analytics';\nimport { openTrackedLink } from '@utils/links';\nimport { getIntegrationAuthorizeUrl } from '@utils/urls';\n\ninterface SelfDrivingGitHubScreenProps {\n store: WizardStore;\n}\n\nenum ChoiceValue {\n Open = 'open',\n Decline = 'decline',\n}\n\nexport const SelfDrivingGitHubScreen = ({\n store,\n}: SelfDrivingGitHubScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const credentials = store.session.credentials;\n const connectedState = store.session.githubConnected;\n const connected = connectedState === true;\n\n const authorizeUrl = credentials\n ? getIntegrationAuthorizeUrl(\n credentials.host.appHost,\n credentials.projectId,\n 'github',\n )\n : null;\n\n useGithubConnection(store);\n\n // Once the install link has been opened, re-offering it as the headline CTA\n // is confusing — the poll flips the screen on its own when the install lands.\n const [installOpened, setInstallOpened] = useState(false);\n\n // One-time login link for browsers without a PostHog session (fresh provisioned accounts).\n const [loginUrl, setLoginUrl] = useState<string | null>(null);\n const loginUrlRequested = useRef(false);\n useEffect(() => {\n if (loginUrlRequested.current) return;\n loginUrlRequested.current = true;\n void fetchLoginUrl(store.session).then(setLoginUrl);\n }, [store]);\n\n // Impression fires once the connected state is known, so `already_connected`\n // is real: users who arrive connected segment apart from users who connect\n // during the screen.\n const impressionFired = useRef(false);\n useEffect(() => {\n if (connectedState === null || impressionFired.current) return;\n impressionFired.current = true;\n analytics.wizardCapture('github connect shown', {\n already_connected: connected,\n });\n }, [connectedState, connected]);\n\n const openInstall = (): void => {\n if (!authorizeUrl) return;\n analytics.wizardCapture('github connect opened');\n openTrackedLink(authorizeUrl, 'self-driving-github-connect');\n setInstallOpened(true);\n };\n\n // Declining ends the run here, before the agent starts. The outro carries the\n // same copy the abort case renders, so both paths read identically.\n const decline = (): void => {\n analytics.wizardCapture('github connect declined', {\n install_opened: installOpened,\n });\n store.declineGithub({\n kind: OutroKind.Cancel,\n message: GITHUB_REQUIRED_MESSAGE,\n body: GITHUB_REQUIRED_BODY,\n });\n };\n\n const handleSelect = (value: ChoiceValue | ChoiceValue[]): void => {\n const choice = Array.isArray(value) ? value[0] : value;\n if (choice === ChoiceValue.Open) openInstall();\n else decline();\n };\n\n useKeyBindings('self-driving-github', [\n {\n match: KeyMatch.Escape,\n label: 'esc',\n action: connected ? 'continue' : 'end setup',\n handler: () => {\n if (!connected) decline();\n },\n },\n ]);\n\n if (credentials && connectedState === null) {\n return (\n <Box flexDirection=\"column\" flexGrow={1} marginTop={1}>\n <LoadingBox message=\"Checking for an existing GitHub connection...\" />\n </Box>\n );\n }\n\n if (connected) {\n return (\n <Box flexDirection=\"column\" flexGrow={1} marginTop={1}>\n <Text bold color={Colors.success}>\n {Icons.check} GitHub connected\n </Text>\n <Box marginTop={1}>\n <Text>\n Self-driving can research findings in your code and open fixes.\n </Text>\n </Box>\n <Box marginTop={1}>\n <LoadingBox message=\"Starting Self-driving setup...\" />\n </Box>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n {installOpened ? 'Finish connecting GitHub' : 'Connect GitHub'}\n </Text>\n\n <Box marginTop={1}>\n <Text>\n {installOpened\n ? \"We've opened the PostHog GitHub App install in your browser. Approve access there — we'll detect it automatically and continue.\"\n : 'Self-driving needs GitHub access to research findings in your code and open fixes, so setup cannot finish without it.'}\n </Text>\n </Box>\n\n {!installOpened && (\n <Box marginTop={1}>\n <Text>\n <Text color=\"cyan\">{Icons.diamond} </Text>\n Grant it the repos you want Self-driving to work with — include\n this project's repo so it can also watch its issues.\n </Text>\n </Box>\n )}\n\n {loginUrl && (\n <Box marginTop={1}>\n <Text dimColor>\n {'Log in to your new account first: '}\n <Text color=\"cyan\">{loginUrl}</Text>\n </Text>\n </Box>\n )}\n\n {authorizeUrl && (\n <Box marginTop={1}>\n <Text dimColor>\n {installOpened ? 'Install page: ' : 'Install it: '}\n <Text color=\"cyan\">{authorizeUrl}</Text>\n </Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <PickerMenu\n options={[\n {\n label: installOpened\n ? 'Re-open GitHub App install'\n : 'Open GitHub App install',\n value: ChoiceValue.Open,\n },\n {\n label: \"I can't connect right now\",\n value: ChoiceValue.Decline,\n },\n ]}\n onSelect={handleSelect}\n />\n </Box>\n </Box>\n </Box>\n );\n};\n","import { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from '@ui/tui/screens/IntroScreenLayout';\nimport {\n SkillSourceInfo,\n useSkillEntry,\n} from '@ui/tui/screens/SkillSourceInfo';\n\ninterface AuditIntroScreenProps {\n store: WizardStore;\n}\n\nexport const AuditIntroScreen = ({ store }: AuditIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n const { session } = store;\n // bin.ts seeds session.skillId from ProgramConfig.skillId before render,\n // so audit and events-audit pick up their respective skill metadata here.\n const skillId = session.skillId ?? 'audit';\n const { skillEntry, fetchFailed } = useSkillEntry(skillId);\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56}>\n <Box marginBottom={1}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n </Box>\n\n <Text>\n The{' '}\n <Text color=\"cyan\" italic>\n {skillId}\n </Text>{' '}\n program reviews your project's PostHog integration against best\n practices to help you capture high-quality events and writes a report\n for suggested actions. Nothing in your project will be modified.\n </Text>\n <Box marginTop={1}>\n <SkillSourceInfo\n skillId={skillId}\n skillEntry={skillEntry}\n fetchFailed={fetchFailed}\n />\n </Box>\n </Box>\n ) : (\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>Let's review your existing PostHog setup for best practices.</Text>\n </Box>\n );\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const handleSelect = (value: string) => {\n if (value === 'cancel') process.exit(0);\n else if (value === 'more-info') setShowingMoreInfo(true);\n else if (value === 'back') setShowingMoreInfo(false);\n else store.completeSetup();\n };\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n body={body}\n showDetection={!showingMoreInfo}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={handleSelect}\n />\n );\n};\n","import { useEffect } from 'react';\nimport { startFileWatcher, type FileWatcherOptions } from '@lib/file-watcher';\n\nexport { startFileWatcher } from '@lib/file-watcher';\nexport type { FileWatcherHandle, FileWatcherOptions } from '@lib/file-watcher';\n\n/** React hook wrapping `startFileWatcher`. Starts on mount, stops on unmount\n * or when `path` changes. `onUpdate` and `options` are captured at mount\n * time — change `path` to restart with a new callback. */\nexport function useFileWatcher(\n path: string,\n onUpdate: (parsed: unknown) => void,\n options: FileWatcherOptions = {},\n): void {\n useEffect(() => {\n const handle = startFileWatcher(path, onUpdate, options);\n return () => handle.stop();\n // `onUpdate` and `options` are intentionally omitted from deps — the\n // watcher captures them at mount time and the path drives restarts.\n }, [path]);\n}\n","/**\n * AuditAreaPane — left-pane slide that follows whatever area the agent is\n * currently checking, plus a wrap-up state once every check is resolved\n * and the agent has moved on to writing the report.\n *\n * Three states, gated top-down on the ledger:\n * 1. firstPending defined → render the slide for that area\n * 2. checks empty → blank (the seed hook fires before\n * this screen mounts in practice;\n * this is just defensive)\n * 3. all checks non-pending → \"writing report\" wrap-up\n *\n * Pressing `O` opens the active slide's docs URL.\n */\n\nimport { Fragment } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { spawn } from 'node:child_process';\nimport { Colors } from '@ui/tui/styles';\nimport { type AuditCheck } from '@lib/programs/audit/types';\nimport { AUDIT_AREA_SLIDES, type AreaSlide } from './slides/index.js';\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nconst FINDING_STATUSES: AuditCheck['status'][] = [\n 'error',\n 'warning',\n 'suggestion',\n];\n\nconst isFinding = (c: AuditCheck) => FINDING_STATUSES.includes(c.status);\n\nconst fallbackSlide = (area: string): AreaSlide => ({\n area,\n intro: [`Verifying ${area.toLowerCase()}…`],\n docsUrl: '',\n});\n\nconst openLink = (url: string) => {\n const cmd =\n process.platform === 'darwin'\n ? 'open'\n : process.platform === 'win32'\n ? 'cmd'\n : 'xdg-open';\n const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url];\n spawn(cmd, args, { detached: true, stdio: 'ignore' }).unref();\n};\n\n// ── Component ────────────────────────────────────────────────────────\n\ninterface AuditAreaPaneProps {\n checks: AuditCheck[];\n reportPath: string;\n /** Slide registry to look the active area up in. Defaults to the doctor\n * (`audit` program) slides; events-audit passes its own 6-phase set. */\n slides?: AreaSlide[];\n /** Dashboard URL once the agent emits `[DASHBOARD_URL]`. Shown as a sticky\n * footer so the user can grab the link while later phases still run. */\n dashboardUrl?: string | null;\n /** Notebook URL once the agent emits `[NOTEBOOK_URL]`. Same sticky-footer\n * treatment as the dashboard URL. */\n notebookUrl?: string | null;\n}\n\nexport const AuditAreaPane = ({\n checks,\n reportPath,\n slides = AUDIT_AREA_SLIDES,\n dashboardUrl,\n notebookUrl,\n}: AuditAreaPaneProps) => {\n const pendingChecks = checks.filter((c) => c.status === 'pending');\n const activeArea = pendingChecks[0]?.area;\n const slide = activeArea\n ? slides.find((s) => s.area === activeArea) ?? fallbackSlide(activeArea)\n : null;\n\n useInput((input) => {\n if (input.toLowerCase() === 'o' && slide?.docsUrl) {\n openLink(slide.docsUrl);\n }\n });\n\n const urlsFooter =\n dashboardUrl || notebookUrl ? (\n <UrlsFooter dashboardUrl={dashboardUrl} notebookUrl={notebookUrl} />\n ) : null;\n\n // Active area — agent is still resolving checks for this slide's area.\n if (slide) {\n const hasFindings = checks.some(isFinding);\n return (\n <Box flexDirection=\"column\">\n <ActiveSlide slide={slide} hasFindings={hasFindings} />\n {urlsFooter}\n </Box>\n );\n }\n\n // Ledger empty — the seed hook fires synchronously at intro `onReady`,\n // so this only happens if the seed file write failed. Render nothing\n // rather than misleading the user with a \"wrapped up\" message.\n if (checks.length === 0) {\n return null;\n }\n\n // Every check is resolved and the agent is composing the report.\n return (\n <Box flexDirection=\"column\">\n <WritingReport reportPath={reportPath} />\n {urlsFooter}\n </Box>\n );\n};\n\n// ── States ───────────────────────────────────────────────────────────\n\nconst ActiveSlide = ({\n slide,\n hasFindings,\n}: {\n slide: AreaSlide;\n hasFindings: boolean;\n}) => (\n <Box flexDirection=\"column\" paddingX={1}>\n <Text bold color={Colors.accent}>\n Verifying {slide.area.toLowerCase()}\n </Text>\n <Box height={1} />\n\n {slide.visual}\n {slide.intro.map((paragraph, i) => (\n <Fragment key={i}>\n {i > 0 && <Box height={1} />}\n <Text>{paragraph}</Text>\n </Fragment>\n ))}\n\n <Box marginTop={1}>\n <Text dimColor>\n {slide.docsUrl && (\n <>\n [<Text color={Colors.accent}>O</Text>] Learn more\n </>\n )}\n {hasFindings && (\n <>\n {slide.docsUrl && ' '}[<Text color={Colors.accent}>→</Text>] View\n issues\n </>\n )}\n </Text>\n </Box>\n </Box>\n);\n\nconst UrlsFooter = ({\n dashboardUrl,\n notebookUrl,\n}: {\n dashboardUrl?: string | null;\n notebookUrl?: string | null;\n}) => (\n <Box flexDirection=\"column\" paddingX={1} marginTop={1}>\n <Text dimColor>{'─'.repeat(40)}</Text>\n {dashboardUrl && (\n <Text>\n Dashboard: <Text color=\"cyan\">{dashboardUrl}</Text>\n </Text>\n )}\n {notebookUrl && (\n <Text>\n Notebook: <Text color=\"cyan\">{notebookUrl}</Text>\n </Text>\n )}\n </Box>\n);\n\nconst WritingReport = ({ reportPath }: { reportPath: string }) => (\n <Box flexDirection=\"column\" paddingX={1}>\n <Text bold color={Colors.accent}>\n We've wrapped up the review.\n </Text>\n <Box height={1} />\n <Text>\n To help you get the most out of your PostHog integration, we're preparing\n a report for you at <Text color=\"cyan\">{reportPath}</Text>.\n </Text>\n <Box height={1} />\n <Text>\n We'll cover what we checked and suggest where we can improve the existing\n integration.\n </Text>\n <Box height={1} />\n <Text dimColor>Hang tight!</Text>\n </Box>\n);\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst DetectVisual = () => (\n <VisualBox>\n <Text dimColor>package.json</Text>\n <Text>\n <Text dimColor>{' └─ '}</Text>\n <Text color=\"green\">posthog-js</Text>\n <Text dimColor>{' ^1.200.0'}</Text>\n </Text>\n <Text dimColor>requirements.txt</Text>\n <Text>\n <Text dimColor>{' └─ '}</Text>\n <Text color=\"green\">posthog</Text>\n <Text dimColor>{' ==4.0.1'}</Text>\n </Text>\n </VisualBox>\n);\n\nexport const DetectSdkSlide: AreaSlide = {\n area: 'Detect SDK',\n intro: [\n 'First we find which PostHog SDKs your project uses. The audit needs to know the right languages and frameworks before it looks at any code.',\n 'Only dependency manifests get read here: package.json, requirements.txt, go.mod, and similar files. Source files come in a later step.',\n 'If your project is a monorepo with more than one SDK, we handle each one.',\n ],\n visual: <DetectVisual />,\n docsUrl: 'https://posthog.com/docs/libraries',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst ScanVisual = () => (\n <VisualBox>\n <Text dimColor>grep -rn 'posthog\\.(capture|identify|group)'</Text>\n <Text>\n <Text color=\"cyan\">src/checkout/Checkout.tsx:88</Text>\n <Text dimColor>{' posthog.capture(...)'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">src/auth/login.ts:42</Text>\n <Text dimColor>{' posthog.identify(...)'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">src/onboarding/step.tsx:17</Text>\n <Text dimColor>{' posthog.capture(...)'}</Text>\n </Text>\n </VisualBox>\n);\n\nexport const ScanSitesSlide: AreaSlide = {\n area: 'Scan capture sites',\n intro: [\n 'Next we map every place your code captures PostHog events. This is the inventory the rest of the audit builds on.',\n 'We search your project for PostHog SDK calls: capture, identify, group, and more. No source files are opened yet, that comes in the next step.',\n \"Test files are excluded so they don't pollute the inventory.\",\n ],\n visual: <ScanVisual />,\n docsUrl: 'https://posthog.com/docs/product-analytics/capture-events',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst EnrichVisual = () => (\n <VisualBox>\n <Text dimColor>orchestrator</Text>\n <Text dimColor>{' │'}</Text>\n <Text>\n <Text dimColor>{' ├─ '}</Text>\n <Text color=\"cyan\">subagent 1</Text>\n <Text dimColor>{' → part-1.json'}</Text>\n </Text>\n <Text>\n <Text dimColor>{' ├─ '}</Text>\n <Text color=\"cyan\">subagent 2</Text>\n <Text dimColor>{' → part-2.json'}</Text>\n </Text>\n <Text>\n <Text dimColor>{' └─ '}</Text>\n <Text color=\"cyan\">subagent N</Text>\n <Text dimColor>{' → part-N.json'}</Text>\n </Text>\n </VisualBox>\n);\n\nexport const EnrichSitesSlide: AreaSlide = {\n area: 'Enrich',\n intro: [\n 'Now we look inside each file that captures events. The goal is to know not just that an event fires, but what it is, where it lives, and what data goes with it.',\n 'For every capture site we pull out the event name, the properties, the area of your codebase it sits in, and the surrounding function or component.',\n 'This is the only step that opens source files. Large codebases run in parallel so it finishes in one pass.',\n ],\n visual: <EnrichVisual />,\n docsUrl: 'https://posthog.com/docs/product-analytics/best-practices',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst QueryVisual = () => (\n <VisualBox>\n <Text dimColor>{'SELECT event, count() AS volume_30d'}</Text>\n <Text dimColor>\n {'FROM events WHERE timestamp > now() - INTERVAL 30 DAY'}\n </Text>\n <Text dimColor>{'GROUP BY event ORDER BY volume_30d DESC'}</Text>\n <Text> </Text>\n <Text>\n <Text color=\"cyan\">{'pageview '}</Text>\n <Text color=\"green\">{'12,430'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">{'signup_completed '}</Text>\n <Text color=\"green\">{' 840'}</Text>\n </Text>\n </VisualBox>\n);\n\nexport const QueryVolumeSlide: AreaSlide = {\n area: 'Query PostHog',\n intro: [\n 'We ask PostHog how often each event in the inventory has fired in the last 30 days.',\n \"Events your code captures but PostHog has never seen are flagged as phantoms. Phantoms usually mean a typo, a dead code path, or instrumentation that hasn't shipped yet. Worth cleaning up.\",\n \"If PostHog isn't reachable the audit still finishes. The report just notes where volume numbers would have gone.\",\n ],\n visual: <QueryVisual />,\n docsUrl: 'https://posthog.com/docs/product-analytics/sql',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst ReportVisual = () => (\n <VisualBox>\n <Text dimColor>posthog-events-audit-report.md</Text>\n <Text>\n <Text dimColor>{' # '}</Text>\n <Text>Identity & segmentation</Text>\n </Text>\n <Text>\n <Text dimColor>{' # '}</Text>\n <Text>Coverage map</Text>\n </Text>\n <Text>\n <Text dimColor>{' # '}</Text>\n <Text>Data quality</Text>\n </Text>\n <Text>\n <Text dimColor>{' # '}</Text>\n <Text>Events by file & area</Text>\n </Text>\n </VisualBox>\n);\n\nexport const WriteReportSlide: AreaSlide = {\n area: 'Write report',\n intro: [\n 'We package everything we found into one report at ./posthog-events-audit-report.md. This is what you hand to the team.',\n 'The report covers how users get identified, which parts of your codebase capture which events, data quality issues like duplicates and phantoms, and a volume map of every event your code captures.',\n 'Nothing in your project is modified. The report is the only file you keep.',\n ],\n visual: <ReportVisual />,\n docsUrl: 'https://posthog.com/docs/product-analytics/best-practices',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst DashboardVisual = () => (\n <VisualBox>\n <Text dimColor>events audit dashboard</Text>\n <Text>\n <Text color=\"cyan\">{'pageview '}</Text>\n <Text color=\"green\">{'████████████'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">{'signup '}</Text>\n <Text color=\"green\">{'████████'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">{'activated '}</Text>\n <Text color=\"green\">{'█████'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">{'purchased '}</Text>\n <Text color=\"green\">{'██'}</Text>\n </Text>\n </VisualBox>\n);\n\nexport const CreateDashboardSlide: AreaSlide = {\n area: 'Create dashboard',\n intro: [\n 'Finally we build a live PostHog dashboard for the events your code captures. Use it to watch volume over time, spot new phantoms, and see how traffic shifts as you ship changes.',\n 'Open the dashboard from the wrap-up screen when the audit completes.',\n ],\n visual: <DashboardVisual />,\n docsUrl: 'https://posthog.com/docs/product-analytics/dashboards',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst NotebookVisual = () => (\n <VisualBox>\n <Text dimColor>posthog-events-audit-report.md</Text>\n <Text dimColor>{' │'}</Text>\n <Text>\n <Text dimColor>{' ▼ '}</Text>\n <Text color=\"cyan\">PostHog notebook</Text>\n </Text>\n <Text dimColor>{' # Identity & segmentation'}</Text>\n <Text dimColor>{' # Coverage map'}</Text>\n <Text dimColor>{' # Events by file & area'}</Text>\n </VisualBox>\n);\n\nexport const UploadNotebookSlide: AreaSlide = {\n area: 'Upload notebook',\n intro: [\n 'Next we upload the report into a PostHog notebook so you can share it with your team as a URL.',\n 'Hang tight.',\n 'The markdown file on disk is still there for you to read locally.',\n ],\n visual: <NotebookVisual />,\n docsUrl: 'https://posthog.com/docs/notebooks',\n};\n","/**\n * Slide registry for the events-audit program. Each entry is keyed by\n * `AuditCheck.area` and corresponds to one phase of the 6-phase pipeline.\n *\n * `AuditAreaPane` looks up the active phase's slide here when the active\n * program is events-audit.\n */\n\nimport type { AreaSlide } from '../shared.js';\nimport { DetectSdkSlide } from './detectSdk.js';\nimport { ScanSitesSlide } from './scanSites.js';\nimport { EnrichSitesSlide } from './enrichSites.js';\nimport { QueryVolumeSlide } from './queryVolume.js';\nimport { WriteReportSlide } from './writeReport.js';\nimport { CreateDashboardSlide } from './createDashboard.js';\nimport { UploadNotebookSlide } from './uploadNotebook.js';\n\nexport const EVENTS_AUDIT_AREA_SLIDES: AreaSlide[] = [\n DetectSdkSlide,\n ScanSitesSlide,\n EnrichSitesSlide,\n QueryVolumeSlide,\n WriteReportSlide,\n CreateDashboardSlide,\n UploadNotebookSlide,\n];\n","import { Box, Text } from 'ink';\nimport { Spinner } from '@inkjs/ui';\nimport {\n AUDIT_SEVERITY_STYLE,\n type AuditCheck,\n} from '@lib/programs/audit/types';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { LoadingBox } from '@ui/tui/primitives/index';\nimport { useStdoutDimensions } from '@ui/tui/hooks/useStdoutDimensions';\n\ninterface PendingChecksListProps {\n checks: AuditCheck[];\n}\n\ninterface Group {\n area: string;\n checks: AuditCheck[];\n}\n\nfunction groupByArea(checks: AuditCheck[]): Group[] {\n const order: string[] = [];\n const map = new Map<string, AuditCheck[]>();\n for (const c of checks) {\n if (!map.has(c.area)) {\n map.set(c.area, []);\n order.push(c.area);\n }\n map.get(c.area)!.push(c);\n }\n return order.map((area) => ({ area, checks: map.get(area)! }));\n}\n\nfunction groupIcon(group: Group): { icon: string; color: string } {\n const total = group.checks.length;\n const complete = group.checks.filter((c) => c.status !== 'pending').length;\n if (complete === 0) return { icon: Icons.squareOpen, color: Colors.muted };\n if (complete === total)\n return { icon: Icons.squareFilled, color: Colors.success };\n return { icon: Icons.triangleRight, color: Colors.primary };\n}\n\nconst GroupHeader = ({\n group,\n showIcon,\n isActive,\n}: {\n group: Group;\n showIcon: boolean;\n isActive: boolean;\n}) => {\n const complete = group.checks.filter((c) => c.status !== 'pending').length;\n const total = group.checks.length;\n const { icon, color } = groupIcon(group);\n return (\n <Box>\n {isActive ? (\n <Box marginRight={1}>\n <Spinner />\n </Box>\n ) : showIcon ? (\n <Text>\n <Text color={color}>{icon}</Text>{' '}\n </Text>\n ) : null}\n <Text>\n <Text bold>{group.area}</Text>{' '}\n <Text dimColor>\n ({complete}/{total})\n </Text>\n </Text>\n </Box>\n );\n};\n\nconst CheckRow = ({ check }: { check: AuditCheck }) => {\n const { glyph, color } = AUDIT_SEVERITY_STYLE[check.status];\n return (\n <Text>\n <Text color={color}>{glyph}</Text>\n <Text dimColor={check.status === 'pending'}> {check.label}</Text>\n </Text>\n );\n};\n\nconst COLLAPSE_BELOW_ROWS = 24;\n\nexport const PendingChecksList = ({ checks }: PendingChecksListProps) => {\n const [, termRows] = useStdoutDimensions();\n\n if (checks.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text bold>Checks</Text>\n <Text> </Text>\n <LoadingBox message=\"Seeding audit checklist...\" />\n </Box>\n );\n }\n\n const groups = groupByArea(checks);\n const activeIndex = groups.findIndex((g) =>\n g.checks.some((c) => c.status === 'pending'),\n );\n const collapsed = termRows < COLLAPSE_BELOW_ROWS;\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>Checks</Text>\n <Text> </Text>\n {collapsed\n ? groups.map((group, i) => (\n <GroupHeader\n key={group.area}\n group={group}\n showIcon\n isActive={i === activeIndex}\n />\n ))\n : groups.map((group, i) => (\n <Box\n key={group.area}\n flexDirection=\"column\"\n marginTop={i === 0 ? 0 : 1}\n >\n <GroupHeader\n group={group}\n showIcon={false}\n isActive={i === activeIndex}\n />\n {group.checks.map((c) => (\n <CheckRow key={c.id} check={c} />\n ))}\n </Box>\n ))}\n </Box>\n );\n};\n","import { useSyncExternalStore } from 'react';\nimport { join } from 'node:path';\nimport { Box } from 'ink';\nimport type { WizardStore } from '@ui/tui/store';\nimport {\n TabContainer,\n SplitView,\n LogViewer,\n HNViewer,\n} from '@ui/tui/primitives/index';\nimport { useStdoutDimensions } from '@ui/tui/hooks/useStdoutDimensions';\nimport { useFileWatcher } from '@ui/tui/hooks/file-watcher';\nimport { AuditChecksViewer } from './AuditChecksViewer/AuditChecksViewer.js';\nimport { AuditAreaPane } from './AuditAreaPane.js';\nimport { AUDIT_AREA_SLIDES } from './slides/index.js';\nimport { EVENTS_AUDIT_AREA_SLIDES } from './slides/events-audit/index.js';\nimport { PendingChecksList } from './PendingChecksList.js';\nimport {\n AUDIT_CHECKS_FILE,\n AUDIT_CHECKS_KEY,\n AUDIT_REPORT_FILE,\n coerceAuditChecks,\n getAuditChecks,\n} from '@lib/programs/audit/types';\nimport { getProgramConfig } from '@lib/programs/program-registry';\nimport { WIZARD_LOG_FILE } from '@utils/paths';\n\ninterface AuditRunScreenProps {\n store: WizardStore;\n}\n\nexport const AuditRunScreen = ({ store }: AuditRunScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n // Mirror the agent's audit ledger into the store.\n useFileWatcher(join(store.session.installDir, AUDIT_CHECKS_FILE), (parsed) =>\n store.setFrameworkContext(AUDIT_CHECKS_KEY, coerceAuditChecks(parsed)),\n );\n\n const statuses =\n store.statusMessages.length > 0 ? store.statusMessages : undefined;\n\n const [columns] = useStdoutDimensions();\n const checks = getAuditChecks(store.session);\n const reportFile =\n getProgramConfig(store.router.activeProgram).reportFile ??\n AUDIT_REPORT_FILE;\n const reportPath = `./${reportFile}`;\n const pendingChecksList = <PendingChecksList checks={checks} />;\n const slides =\n store.session.skillId === 'audit-events'\n ? EVENTS_AUDIT_AREA_SLIDES\n : AUDIT_AREA_SLIDES;\n const areaPane = (\n <AuditAreaPane\n checks={checks}\n reportPath={reportPath}\n slides={slides}\n dashboardUrl={store.session.dashboardUrl}\n notebookUrl={store.session.notebookUrl}\n />\n );\n\n // Narrow terminals: drop the area pane.\n const statusComponent =\n columns < 80 ? (\n <Box flexDirection=\"column\" flexGrow={1}>\n {pendingChecksList}\n </Box>\n ) : (\n <SplitView left={areaPane} right={pendingChecksList} />\n );\n\n const tabs = [\n { id: 'status', label: 'Status', component: statusComponent },\n {\n id: 'audit-checks',\n label: 'Audit plan',\n component: <AuditChecksViewer checks={checks} />,\n },\n {\n id: 'logs',\n label: 'Tail logs',\n component: <LogViewer filePath={WIZARD_LOG_FILE} />,\n },\n { id: 'hn', label: 'HN', component: <HNViewer /> },\n ];\n\n return (\n <TabContainer\n tabs={tabs}\n statusMessage={statuses}\n expandableStatus\n store={store}\n />\n );\n};\n","import { Box, Text } from 'ink';\nimport {\n AUDIT_SEVERITY_STYLE,\n type AuditCheck,\n} from '@lib/programs/audit/types';\nimport { relativeToInstallDir } from '@utils/paths';\n\ninterface AuditChecksOutroSectionProps {\n checks: AuditCheck[];\n installDir: string;\n}\n\nconst MAX_VISIBLE = 6;\n\nexport const AuditChecksOutroSection = ({\n checks,\n installDir,\n}: AuditChecksOutroSectionProps) => {\n if (checks.length === 0) return null;\n\n const errors = checks.filter((c) => c.status === 'error');\n const warnings = checks.filter((c) => c.status === 'warning');\n const suggestions = checks.filter((c) => c.status === 'suggestion');\n const problematic = [...errors, ...warnings, ...suggestions];\n\n const visible = problematic.slice(0, MAX_VISIBLE);\n const hidden = problematic.length - visible.length;\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"cyan\" bold>\n Items audited:\n </Text>\n <Text dimColor>\n {checks.length} checks · {errors.length} errors · {warnings.length}{' '}\n warnings · {suggestions.length} suggestions\n </Text>\n {problematic.length === 0 ? (\n <Text color=\"green\">{'•'} No issues found.</Text>\n ) : (\n <>\n {visible.map((item) => {\n const style = AUDIT_SEVERITY_STYLE[item.status];\n return (\n <Box key={item.id} flexDirection=\"column\" marginTop={1}>\n <Text>\n <Text color={style.color}>{style.glyph}</Text>{' '}\n <Text bold>{item.label}</Text>{' '}\n <Text dimColor>({item.area})</Text>\n </Text>\n {item.file && (\n <Text dimColor>\n {' '}\n {relativeToInstallDir(item.file, installDir)}\n </Text>\n )}\n </Box>\n );\n })}\n {hidden > 0 && (\n <Text dimColor>\n … and {hidden} more. See the report for details.\n </Text>\n )}\n </>\n )}\n </Box>\n );\n};\n","/**\n * AuditOutroScreen — Audit-specific post-run summary. Renders the standard\n * success / error / cancel views with the audit checks summary inlined into\n * the success body. The report path shown in the success headline comes from\n * the program's `successMessage`, so this screen is program-agnostic.\n */\n\nimport { join } from 'node:path';\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { OutroKind } from '@lib/wizard-session';\nimport { Colors } from '@ui/tui/styles';\nimport { getAuditChecks } from '@lib/programs/audit/types';\nimport { AuditChecksOutroSection } from './AuditChecksOutroSection.js';\nimport { useDismissOnAnyKey } from '@ui/tui/hooks/useDismissOnAnyKey';\n\ninterface AuditOutroScreenProps {\n store: WizardStore;\n}\n\nexport const AuditOutroScreen = ({ store }: AuditOutroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n useDismissOnAnyKey(() => store.setOutroDismissed());\n\n const outroData = store.session.outroData;\n\n if (!outroData) {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text dimColor>Finishing up...</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n {outroData.kind === OutroKind.Success && (\n <Box flexDirection=\"column\">\n <Text color=\"green\" bold>\n ✔ {outroData.message || 'Audit complete!'}\n </Text>\n\n {outroData.dashboardUrl && (\n <Box marginTop={1}>\n <Text>\n Dashboard: <Text color=\"cyan\">{outroData.dashboardUrl}</Text>\n </Text>\n </Box>\n )}\n\n {outroData.notebookUrl && (\n <Box marginTop={1}>\n <Text>\n Notebook: <Text color=\"cyan\">{outroData.notebookUrl}</Text>\n </Text>\n </Box>\n )}\n\n {outroData.reportFile && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"cyan\" bold>\n Report saved to:\n </Text>\n <Text>\n {join(store.session.installDir, outroData.reportFile)}\n </Text>\n <Text dimColor>\n A markdown file in your project folder. Open it in any editor to\n read the full audit.\n </Text>\n </Box>\n )}\n\n <AuditChecksOutroSection\n checks={getAuditChecks(store.session)}\n installDir={store.session.installDir}\n />\n\n {outroData.docsUrl && (\n <Box marginTop={1}>\n <Text>\n Learn more: <Text color=\"cyan\">{outroData.docsUrl}</Text>\n </Text>\n </Box>\n )}\n </Box>\n )}\n\n {outroData.kind === OutroKind.Error && (\n <Box flexDirection=\"column\">\n <Text color=\"red\" bold>\n ✘ {outroData.message || 'An error occurred'}\n </Text>\n {outroData.body && (\n <Box marginTop={1}>\n <Text dimColor>{outroData.body}</Text>\n </Box>\n )}\n </Box>\n )}\n\n {outroData.kind === OutroKind.Cancel && (\n <Text color=\"yellow\">■ {outroData.message || 'Cancelled'}</Text>\n )}\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to continue</Text>\n </Box>\n </Box>\n );\n};\n","/**\n * SetupScreen — Generic framework disambiguation.\n *\n * Iterates unresolved setup questions from the FrameworkConfig\n * and renders a PickerMenu for each. If all questions are auto-resolved,\n * this screen is skipped entirely (the router skips it via its show() predicate).\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors } from '@ui/tui/styles';\nimport type { SetupQuestion } from '@lib/framework-config';\n\ninterface SetupScreenProps {\n store: WizardStore;\n}\n\nexport const SetupScreen = ({ store }: SetupScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const config = store.session.frameworkConfig;\n const questions = config?.metadata.setup?.questions ?? [];\n\n // Track which question index we're currently showing\n const [currentIndex, setCurrentIndex] = useState(0);\n const [resolving, setResolving] = useState(true);\n\n // On mount, run auto-detection for all questions\n useEffect(() => {\n void (async () => {\n for (const q of questions) {\n // Skip if already resolved (e.g. by CLI arg)\n if (q.key in store.session.frameworkContext) continue;\n\n try {\n const detected = await q.detect({\n installDir: store.session.installDir,\n });\n if (detected !== null) {\n store.setFrameworkContext(q.key, detected);\n }\n } catch {\n // Detection failed — will ask the user\n }\n }\n setResolving(false);\n\n // If all resolved, the router's isComplete predicate will\n // resolve past this screen on the next render cycle.\n })();\n }, []);\n\n if (resolving) {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text dimColor>Detecting project configuration...</Text>\n </Box>\n );\n }\n\n // Get unresolved questions\n const unresolved = questions.filter(\n (q: SetupQuestion) => !(q.key in store.session.frameworkContext),\n );\n\n if (unresolved.length === 0) {\n // All resolved — should have already advanced\n return null;\n }\n\n const question = unresolved[currentIndex] ?? unresolved[0];\n if (!question) return null;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n Project Setup\n </Text>\n {config && (\n <Text dimColor>Configuring {config.metadata.name} integration</Text>\n )}\n </Box>\n\n <PickerMenu<string>\n message={question.message}\n options={question.options.map((o) => ({\n label: o.label,\n value: o.value,\n hint: o.hint,\n }))}\n onSelect={(value) => {\n const selected = Array.isArray(value) ? value[0] : value;\n store.setFrameworkContext(question.key, selected);\n\n // Check if more unresolved questions remain\n const remaining = unresolved.filter(\n (q: SetupQuestion) =>\n q.key !== question.key &&\n !(q.key in store.session.frameworkContext),\n );\n\n if (remaining.length > 0) {\n setCurrentIndex((i) => i + 1);\n }\n // When no remaining questions, setFrameworkContext already\n // triggered emitChange — router resolves past this screen.\n }}\n />\n </Box>\n );\n};\n","/**\n * Best-effort platform shell-outs for making a URL usable in any terminal —\n * no third-party dependency.\n *\n * Two helpers back the `wizard_ask` link overlay, for terminals that can't\n * linkify a wrapped URL (e.g. macOS Terminal.app, which lacks OSC 8 hyperlink\n * support):\n *\n * - `copyToClipboard` — pipe the URL to the platform clipboard binary so the\n * user can paste it into a browser.\n * - `openInBrowser` — hand the URL to the platform opener so it launches\n * directly, no copy/paste needed.\n *\n * Both shell out with `spawn` and never a shell, and pass the URL as an argv\n * (clipboard via stdin) — so there's no shell-injection surface. Neither throws:\n * they return false when no command is reachable (CI, headless, or the binary\n * isn't installed).\n */\nimport { spawn } from 'node:child_process';\nimport { logToFile } from './debug.js';\n\ninterface ClipboardCommand {\n cmd: string;\n args: string[];\n}\n\n/** Platform clipboard commands, in preference order. */\nfunction clipboardCommands(): ClipboardCommand[] {\n if (process.platform === 'darwin') return [{ cmd: 'pbcopy', args: [] }];\n if (process.platform === 'win32') return [{ cmd: 'clip', args: [] }];\n // Linux / BSD: try Wayland first, then the common X11 utilities.\n return [\n { cmd: 'wl-copy', args: [] },\n { cmd: 'xclip', args: ['-selection', 'clipboard'] },\n { cmd: 'xsel', args: ['--clipboard', '--input'] },\n ];\n}\n\nfunction writeWith(\n { cmd, args }: ClipboardCommand,\n text: string,\n): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n const child = spawn(cmd, args);\n // ENOENT (missing binary) and EPIPE surface as 'error' events.\n child.on('error', () => resolve(false));\n child.stdin.on('error', () => resolve(false));\n child.on('close', (code) => resolve(code === 0));\n child.stdin.end(text);\n } catch {\n resolve(false);\n }\n });\n}\n\nexport async function copyToClipboard(text: string): Promise<boolean> {\n for (const command of clipboardCommands()) {\n if (await writeWith(command, text)) return true;\n }\n logToFile('[clipboard] no working clipboard command found');\n return false;\n}\n\n/**\n * Platform browser-open commands, in preference order. The URL is one argv\n * element — never concatenated into a shell string — so a `?kind=…` query or\n * any other character can't escape into the command line.\n *\n * `win32` has no shell-free single binary for this: `start` is a `cmd` builtin,\n * so we invoke `cmd /c start \"\" <url>` (the empty `\"\"` is `start`'s window-title\n * argument, which would otherwise swallow the URL). The URL is still a discrete\n * argv element, not interpolated into the command string.\n *\n * Takes `platform` as an argument (defaulting to the host) so the mapping is a\n * pure function the tests can exercise across platforms.\n */\nexport function browserOpenCommands(\n url: string,\n platform: NodeJS.Platform = process.platform,\n): ClipboardCommand[] {\n if (platform === 'darwin') return [{ cmd: 'open', args: [url] }];\n if (platform === 'win32') {\n return [{ cmd: 'cmd', args: ['/c', 'start', '', url] }];\n }\n // Linux / BSD: xdg-open is the freedesktop standard; x-www-browser is the\n // Debian alternatives fallback.\n return [\n { cmd: 'xdg-open', args: [url] },\n { cmd: 'x-www-browser', args: [url] },\n ];\n}\n\nfunction spawnOpener({ cmd, args }: ClipboardCommand): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n // Detach the opener's stdio so it can't write over the Ink TUI, and\n // resolve on a clean exit. ENOENT (missing binary) surfaces as 'error'.\n const child = spawn(cmd, args, { stdio: 'ignore' });\n child.on('error', () => resolve(false));\n child.on('close', (code) => resolve(code === 0));\n } catch {\n resolve(false);\n }\n });\n}\n\nexport async function openInBrowser(url: string): Promise<boolean> {\n for (const command of browserOpenCommands(url)) {\n if (await spawnOpener(command)) return true;\n }\n logToFile('[clipboard] no working browser-open command found');\n return false;\n}\n","/**\n * AuthScreen — Shown while waiting for OAuth authentication.\n *\n * Displays framework detection, a compressed privacy summary, a waiting\n * spinner, and the login URL when available. [I] opens the full\n * PrivacyPanel as an overlay. [P] (when loginUrl is set) lets the user\n * paste the callback URL by hand. [C] copies the login URL to the\n * clipboard — the exact string, so it can't be chopped by a soft-wrap.\n *\n * The router resolves past this screen once session.credentials is set.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { LoadingBox } from '@ui/tui/primitives/index';\nimport { MAX_WIDTH } from '@ui/tui/primitives/ScreenContainer';\nimport {\n PrivacyPanel,\n PRIVACY_PANEL_LABEL,\n} from '@ui/tui/components/PrivacyPanel';\nimport { IntroScreenLayout } from '@ui/tui/screens/IntroScreenLayout';\nimport { useKeyBindings, type KeyBinding } from '@ui/tui/hooks/useKeyBindings';\nimport { useStdoutDimensions } from '@ui/tui/hooks/useStdoutDimensions';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { copyToClipboard } from '@utils/clipboard';\n\ninterface AuthScreenProps {\n store: WizardStore;\n}\n\nexport const AuthScreen = ({ store }: AuthScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showPrivacy, setShowPrivacy] = useState(false);\n const [copyStatus, setCopyStatus] = useState<'idle' | 'copied' | 'failed'>(\n 'idle',\n );\n const [columns] = useStdoutDimensions();\n const { session } = store;\n\n // While the OAuth flow is waiting (loginUrl set), let the user paste the\n // callback URL/code by hand — the fallback for headless/remote shells where\n // the browser can't reach the local callback server.\n const loginUrl = session.loginUrl;\n const canPasteCode = Boolean(loginUrl);\n\n // The URL renders on its own line; ScreenContainer clamps content to\n // MAX_WIDTH and pads one column each side, so this is the room a single\n // unwrapped line has. A URL wider than this soft-wraps, and a wrapped URL\n // copies with a line break baked in — the exact broken-link (\"invalid\n // scope\") breakage users hit on small terminals. Show a resize hint instead.\n const availableWidth = Math.min(columns, MAX_WIDTH) - 2;\n const urlFits = loginUrl ? loginUrl.length <= availableWidth : true;\n\n // Build bindings imperatively: while the privacy view is open, the\n // screen registers NO bindings (IntroScreenLayout's menu owns input).\n const bindings: KeyBinding[] = [];\n if (!showPrivacy) {\n if (canPasteCode && loginUrl) {\n bindings.push({\n match: ['p', 'P'],\n label: 'P',\n action: 'paste auth code',\n handler: () => store.showManualAuthCode(),\n });\n // Copy the exact URL string — immune to the soft-wrap that breaks\n // hand-selection on narrow terminals. May no-op on a remote shell with\n // no clipboard binary; the 'failed' status points the user to [P] then.\n bindings.push({\n match: ['c', 'C'],\n label: 'C',\n action: 'copy link',\n handler: () => {\n void copyToClipboard(loginUrl).then((ok) =>\n setCopyStatus(ok ? 'copied' : 'failed'),\n );\n },\n });\n }\n bindings.push({\n match: ['i', 'I'],\n label: 'I',\n action: PRIVACY_PANEL_LABEL.toLowerCase(),\n handler: () => setShowPrivacy(true),\n });\n }\n useKeyBindings('auth', bindings);\n\n if (showPrivacy) {\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n title={PRIVACY_PANEL_LABEL}\n showSubtitle={false}\n showDetection={false}\n body={<PrivacyPanel />}\n showPrivacy={false}\n menuOptions={[{ label: 'Back', value: 'back' }]}\n menuAlign=\"left\"\n onSelect={() => setShowPrivacy(false)}\n />\n );\n }\n\n const config = session.frameworkConfig;\n const frameworkLabel =\n session.detectedFrameworkLabel ?? config?.metadata.name;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n PostHog Setup Wizard\n </Text>\n\n {frameworkLabel && (\n <Text>\n <Text color=\"green\">{'✔'} </Text>\n <Text>Framework: {frameworkLabel}</Text>\n </Text>\n )}\n\n {/* Dead path today — every framework went GA, so no config has\n metadata.beta = true. Kept intentionally for the next time we\n ship a framework integration in beta. Set `beta: true` on the\n framework's config and this rendering re-activates. */}\n {config?.metadata.beta && (\n <Text color=\"yellow\">\n [BETA] The {config.metadata.name} wizard is in beta. Questions or\n feedback? Email wizard@posthog.com\n </Text>\n )}\n\n {config?.metadata.preRunNotice && (\n <Text color=\"yellow\">{config.metadata.preRunNotice}</Text>\n )}\n </Box>\n\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold dimColor>\n {PRIVACY_PANEL_LABEL}\n </Text>\n <Text dimColor>\n {'•'} Source files are read by Claude for AI context\n </Text>\n <Text dimColor>{'•'} .env* and secrets stay on your machine</Text>\n <Text dimColor>\n {'•'} Press <Text color={Colors.accent}>[I]</Text> for full privacy &\n usage info\n </Text>\n </Box>\n\n <LoadingBox message=\"Waiting for authentication...\" />\n\n {loginUrl && (\n <Box marginTop={1} marginBottom={1} flexDirection=\"column\">\n {urlFits ? (\n // Literal \\n — sibling <Box> spacers squeeze to 0 under flex\n // height pressure, letting cmd-click slurp /authorize + 'y'.\n <Text>\n <Text dimColor>\n If the browser didn't open, copy and paste this URL:\n </Text>\n {'\\n\\n'}\n <Text color=\"cyan\">{loginUrl}</Text>\n </Text>\n ) : (\n <Text color=\"yellow\">\n [This terminal is too small to show the full link for copying,\n resize your terminal]\n </Text>\n )}\n <Box marginTop={1}>\n <Text dimColor>\n Press <Text color={Colors.accent}>[C]</Text> to copy the link · on\n a remote machine or devbox? Press{' '}\n <Text color={Colors.accent}>[P]</Text> to paste the callback URL.\n </Text>\n </Box>\n {copyStatus === 'copied' && (\n <Box marginTop={1}>\n <Text color={Colors.success}>\n {Icons.check} Link copied to clipboard.\n </Text>\n </Box>\n )}\n {copyStatus === 'failed' && (\n <Box marginTop={1}>\n <Text color=\"yellow\">\n Couldn't reach a clipboard on this machine — press{' '}\n <Text color={Colors.accent}>[P]</Text> to paste the callback URL\n instead.\n </Text>\n </Box>\n )}\n </Box>\n )}\n </Box>\n );\n};\n","/**\n * RunScreen — Default observational view of the agent run.\n *\n * Tabs: Status (LearnCard + ProgressList), Event plan (when present),\n * Tail logs, HN. Programs that need a different tab list ship their own\n * screen component (see audit/AuditRunScreen.tsx).\n */\n\nimport { useMemo, useSyncExternalStore } from 'react';\nimport { Box } from 'ink';\nimport type { WizardStore } from '@ui/tui/store';\nimport {\n TabContainer,\n SplitView,\n ProgressList,\n LogViewer,\n EventPlanViewer,\n HNViewer,\n} from '@ui/tui/primitives/index';\nimport type { ProgressItem } from '@ui/tui/primitives/index';\nimport { ADDITIONAL_FEATURE_LABELS } from '@lib/wizard-session';\nimport { LearnCard } from '@ui/tui/components/LearnCard';\nimport { VisualizerTab } from '@ui/tui/components/PhaseVisuals';\nimport { TipsCard } from '@ui/tui/components/TipsCard';\nimport { useStdoutDimensions } from '@ui/tui/hooks/useStdoutDimensions';\n\nimport { getProgramConfig } from '@lib/programs/program-registry';\nimport { getContentBlocks as getSkillContentBlocks } from '@lib/programs/agent-skill/content/index';\n\nimport { WIZARD_LOG_FILE } from '@utils/paths';\n\ninterface RunScreenProps {\n store: WizardStore;\n}\n\nexport const RunScreen = ({ store }: RunScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [columns] = useStdoutDimensions();\n\n const progressItems: ProgressItem[] = store.tasks.map((t) => ({\n label: t.label,\n activeForm: t.activeForm,\n status: t.status,\n }));\n\n // When all tasks are done but the queue has features, show a transitional item\n const queue = store.session.additionalFeatureQueue;\n const allDone =\n progressItems.length > 0 &&\n progressItems.every((t) => t.status === 'completed');\n if (allDone && queue.length > 0) {\n const nextLabel = ADDITIONAL_FEATURE_LABELS[queue[0]];\n progressItems.push({\n label: `Set up ${nextLabel}`,\n activeForm: `Setting up ${nextLabel}...`,\n status: 'in_progress',\n });\n }\n\n const statuses =\n store.statusMessages.length > 0 ? store.statusMessages : undefined;\n\n // Each program owns its content deck (program/content/index.tsx)\n // and wires it onto its ProgramConfig.getContentBlocks. Fall back to the\n // agent-skill deck for runtime-created configs (e.g. `wizard skill <id>`)\n // that aren't in the static registry.\n const activeProgram = store.router.activeProgram;\n const learnBlocks = useMemo(() => {\n const getBlocks =\n getProgramConfig(activeProgram).getContentBlocks ?? getSkillContentBlocks;\n return getBlocks(store);\n }, [store, activeProgram]);\n\n // Program-supplied tips for the right pane; undefined falls back to\n // DEFAULT_TIPS inside TipsCard, so non-self-driving programs are unaffected.\n const programTips = getProgramConfig(activeProgram).getTips?.(store);\n\n const leftPane = store.learnCardComplete ? (\n <TipsCard store={store} tips={programTips} />\n ) : (\n <LearnCard\n store={store}\n blocks={learnBlocks}\n onComplete={() => store.setLearnCardComplete()}\n />\n );\n const progressList = <ProgressList items={progressItems} title=\"Tasks\" />;\n\n const statusComponent =\n columns < 80 ? (\n <Box flexDirection=\"column\" flexGrow={1}>\n {progressList}\n </Box>\n ) : (\n <SplitView left={leftPane} right={progressList} />\n );\n\n const tabs = [\n { id: 'status', label: 'Status', component: statusComponent },\n ...(store.eventPlan.length > 0\n ? [\n {\n id: 'events',\n label: 'Event plan',\n component: <EventPlanViewer events={store.eventPlan} />,\n },\n ]\n : []),\n {\n id: 'logs',\n label: 'Tail logs',\n component: <LogViewer filePath={WIZARD_LOG_FILE} />,\n },\n {\n id: 'visualizer',\n label: 'Visualizer',\n component: <VisualizerTab store={store} />,\n },\n { id: 'hn', label: 'HN', component: <HNViewer /> },\n ];\n\n return (\n <TabContainer\n tabs={tabs}\n statusMessage={statuses}\n expandableStatus\n store={store}\n />\n );\n};\n","/**\n * KeepSkillsScreen — Ask whether to keep installed skills in .claude/skills/.\n *\n * Shown after the outro summary so users see the agent's output first,\n * then decide whether to keep the skills that powered it.\n *\n * When done, calls store.setSkillsComplete() and exits the process.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport { readdir, rm, access } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nconst WIZARD_MARKER = '.posthog-wizard';\nimport type { WizardStore } from '@ui/tui/store';\nimport { ConfirmationInput } from '@ui/tui/primitives/index';\nimport { Colors } from '@ui/tui/styles';\nimport { CONTEXT_MILL_URL } from '@lib/constants';\n\ninterface KeepSkillsScreenProps {\n store: WizardStore;\n}\n\ninterface SkillEntry {\n name: string;\n children: string[];\n}\n\nenum Phase {\n Loading = 'loading',\n Ask = 'ask',\n Removing = 'removing',\n Done = 'done',\n}\n\nexport const KeepSkillsScreen = ({ store }: KeepSkillsScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [phase, setPhase] = useState<Phase>(Phase.Loading);\n const [skills, setSkills] = useState<SkillEntry[]>([]);\n\n const skillsDir = join(store.session.installDir, '.claude', 'skills');\n\n useEffect(() => {\n void (async () => {\n try {\n const entries = await readdir(skillsDir, { withFileTypes: true });\n const dirs = entries.filter((e) => e.isDirectory());\n const result: SkillEntry[] = [];\n for (const dir of dirs) {\n try {\n await access(join(skillsDir, dir.name, WIZARD_MARKER));\n } catch {\n continue;\n }\n const children = (await readdir(join(skillsDir, dir.name))).filter(\n (c) => c !== WIZARD_MARKER,\n );\n result.push({ name: dir.name, children });\n }\n if (result.length === 0) {\n store.setSkillsComplete(true);\n process.exit(0);\n }\n setSkills(result);\n setPhase(Phase.Ask);\n } catch {\n store.setSkillsComplete(true);\n process.exit(0);\n }\n })();\n }, []); // eslint-disable-line\n\n const handleKeep = () => {\n store.setSkillsComplete(true);\n process.exit(0);\n };\n\n const handleRemove = async () => {\n setPhase(Phase.Removing);\n for (const skill of skills) {\n try {\n await rm(join(skillsDir, skill.name), {\n recursive: true,\n force: true,\n });\n } catch {\n // Best-effort removal\n }\n }\n try {\n const remaining = await readdir(skillsDir);\n if (remaining.length === 0) {\n await rm(skillsDir, { recursive: true, force: true });\n }\n } catch {\n // Best-effort cleanup\n }\n setPhase(Phase.Done);\n // Give React a tick to paint the \"Skills removed.\" message before exit\n setTimeout(() => {\n store.setSkillsComplete(false);\n process.exit(0);\n }, 600);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Keep the skills?\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n {phase === Phase.Loading && (\n <Text dimColor>Checking installed skills...</Text>\n )}\n\n {phase === Phase.Ask && (\n <>\n <Text dimColor>\n The wizard installed open-source skills that help AI coding agents\n integrate PostHog into your project:\n </Text>\n <Box marginTop={1} flexDirection=\"column\" marginLeft={2}>\n <Text dimColor>.claude/</Text>\n <Text dimColor> skills/</Text>\n {skills.map((skill) => (\n <Box key={skill.name} flexDirection=\"column\">\n <Text dimColor> {skill.name}/</Text>\n {skill.children.map((child) => (\n <Text key={child} dimColor>\n {' '}\n {child}\n </Text>\n ))}\n </Box>\n ))}\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n Source: <Text color=\"cyan\">{CONTEXT_MILL_URL}</Text>\n </Text>\n </Box>\n <Box marginTop={1}>\n <ConfirmationInput\n message=\"Keep the installed skills?\"\n confirmLabel=\"Keep [Enter]\"\n cancelLabel=\"Remove [Esc]\"\n onConfirm={handleKeep}\n onCancel={() => void handleRemove()}\n />\n </Box>\n </>\n )}\n\n {phase === Phase.Removing && <Text dimColor>Removing skills...</Text>}\n\n {phase === Phase.Done && <Text dimColor>Skills removed.</Text>}\n </Box>\n </Box>\n );\n};\n","/**\n * ExitScreen — Final step in every program.\n *\n * Renders nothing. Immediately exits the process.\n * The cleanup handler in start-tui.ts handles the exit summary line.\n */\n\nimport { useEffect } from 'react';\n\nexport const ExitScreen = () => {\n useEffect(() => {\n process.exit(0);\n }, []);\n\n return null;\n};\n","/**\n * AuthErrorScreen — Shown when the PostHog LLM Gateway returns a 401.\n *\n * Distinct causes, most specific first:\n * 0. The OAuth grant is gone — a pre-run refresh already got `invalid_grant`\n * from the token endpoint. The only branch backed by a server verdict\n * rather than inference, so it wins; re-running is the whole fix.\n * 1. Claude Code settings.json / managed-settings overrides ANTHROPIC_*\n * env vars — auth conflict. Tell the user to log out of Claude Code.\n * 2. The PostHog API key itself was rejected — bad prefix, missing scope,\n * expired, or wrong region. Don't blame Claude Code in this case.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { Colors } from '@ui/tui/styles';\nimport { useDismissOnAnyKey } from '@ui/tui/hooks/useDismissOnAnyKey';\n\ninterface AuthErrorScreenProps {\n store: WizardStore;\n}\n\nexport const AuthErrorScreen = ({ store }: AuthErrorScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n useDismissOnAnyKey(() => process.exit(1));\n\n const detail = store.session.authErrorDetail;\n const hasSettingsConflict = detail?.hasSettingsConflict ?? true;\n const conflicts = detail?.conflicts ?? [];\n const usingManagedLogin = detail?.usingManagedLogin ?? false;\n const credentialPlaces = detail?.credentialPlaces ?? [];\n const sessionExpired = detail?.sessionExpired ?? false;\n const logFilePath = detail?.logFilePath;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text color=\"red\" bold>\n {'✘'} Authentication error\n </Text>\n\n {sessionExpired ? (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n Your PostHog login expired while the wizard was running, so the\n LLM Gateway rejected it (401). Nothing on this machine is\n misconfigured — the session simply ran out.\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>Re-run the wizard and log in again:</Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">npx @posthog/wizard</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n Any files the agent already wrote are still in your project.\n </Text>\n </Box>\n </>\n ) : usingManagedLogin ? (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n Conflicting Anthropic credentials. The agent signed in with an\n existing Claude login instead of the PostHog token the Wizard\n provided, so the LLM Gateway rejected it (401).\n </Text>\n </Box>\n\n {credentialPlaces.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text dimColor>Conflicting credentials may come from:</Text>\n {credentialPlaces.map((place) => (\n <Text key={place}>\n {'•'} {place}\n </Text>\n ))}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text dimColor>\n Log out of Claude Code (clears the stored login), then re-run the\n Wizard:\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">claude auth logout</Text>\n </Box>\n </>\n ) : hasSettingsConflict ? (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The Wizard couldn't connect to the PostHog LLM Gateway. Claude\n Code settings on this machine override the Wizard's credentials.\n </Text>\n </Box>\n\n {conflicts.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n {conflicts.map((conflict) => (\n <Text key={conflict.path}>\n {'•'} <Text bold>{conflict.path}</Text> sets{' '}\n <Text color=\"yellow\">{conflict.keys.join(', ')}</Text>\n </Text>\n ))}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text dimColor>\n Remove those keys from the file(s) above, or log out of Claude\n Code, then re-run the Wizard:\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">claude auth logout</Text>\n </Box>\n </>\n ) : (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The PostHog LLM Gateway rejected the API key. Common causes:\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text>\n {'•'} Wrong key type — pass a personal API key (\n <Text color=\"cyan\">phx_xxx</Text>).\n </Text>\n <Text dimColor>\n {' '}pha_ is an OAuth access token, phc_ is a project key.\n </Text>\n <Text>\n {'•'} Missing scope — the key needs{' '}\n <Text color=\"cyan\">llm_gateway:read</Text>.\n </Text>\n <Text>{'•'} Expired or revoked key.</Text>\n <Text>\n {'•'} Region mismatch — <Text color=\"cyan\">--region</Text> must\n match where the key was issued (us vs eu).\n </Text>\n </Box>\n </>\n )}\n\n {logFilePath && (\n <Box marginTop={1}>\n <Text dimColor>Verbose log: {logFilePath}</Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to exit</Text>\n </Box>\n </Box>\n );\n};\n","/**\n * SessionTimeoutScreen — shown when the OAuth login window expires before the\n * user completes authorization.\n *\n * Pushed as an overlay so it takes priority over the gated AuthScreen (which\n * never completes without credentials). Terminal state: any key exits, since\n * the only way forward is to re-run the wizard for a fresh login window.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { Colors } from '@ui/tui/styles';\nimport { OAUTH_TIMEOUT_MS } from '@lib/constants';\nimport { useDismissOnAnyKey } from '@ui/tui/hooks/useDismissOnAnyKey';\n\ninterface SessionTimeoutScreenProps {\n store: WizardStore;\n}\n\nconst TIMEOUT_MINUTES = Math.round(OAUTH_TIMEOUT_MS / 60_000);\n\nexport const SessionTimeoutScreen = ({ store }: SessionTimeoutScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n useDismissOnAnyKey(() => process.exit(1));\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text color=\"red\" bold>\n {'✘'} Login timed out\n </Text>\n\n <Box marginTop={1}>\n <Text>The OAuth link timed out after {TIMEOUT_MINUTES} minutes.</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text>Re-run the wizard to get a fresh link and try again.</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to exit</Text>\n </Box>\n </Box>\n );\n};\n","/**\n * WizardAskScreen — Overlay for the `wizard_ask` MCP tool.\n *\n * Walks the agent's question list one at a time and accumulates answers.\n * When the user submits the last question, the store resolves the\n * pending request and the overlay pops, returning the agent to its run.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { TextInput } from '@inkjs/ui';\nimport { useEffect, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport {\n LinkText,\n ModalOverlay,\n PickerMenu,\n extractUrls,\n} from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { copyToClipboard, openInBrowser } from '@utils/clipboard';\nimport { useKeyBindings } from '@ui/tui/hooks/useKeyBindings';\nimport type { AskAnswers, AskQuestion } from '@lib/wizard-session';\n\ninterface WizardAskScreenProps {\n store: WizardStore;\n}\n\n/**\n * Key policy for the ask overlay: Esc declines the whole request, everything\n * else is left to the focused input. Extracted so the wiring is unit-testable\n * without a live Ink render (the test suite stubs `useInput` to a no-op).\n */\nexport function handleAskKey(\n key: { escape?: boolean },\n store: Pick<WizardStore, 'cancelPendingQuestion'>,\n): void {\n if (key.escape) store.cancelPendingQuestion();\n}\n\n/**\n * Whether an answer would leave a required question effectively unanswered.\n *\n * The `wizard_ask` schema marks fields `required` (defaulting to true), but the\n * overlay used to submit whatever the input held — so pressing Enter on an empty\n * required credential field sent an empty string on to the agent. A blank host\n * or password is indistinguishable there from a real answer, so the warehouse\n * task ran on it, failed source creation, and dead-ended with no signal that the\n * user had in effect declined. Blocking the empty submit keeps the contract the\n * schema already advertises; Esc stays the way to skip. Optional fields\n * (`required === false`) are never blocked, and pickers always yield a value.\n */\nexport function isRequiredButEmpty(\n question: Pick<AskQuestion, 'required'>,\n value: string | string[],\n): boolean {\n if (question.required === false) return false;\n return Array.isArray(value) ? value.length === 0 : value.trim().length === 0;\n}\n\nexport const WizardAskScreen = ({ store }: WizardAskScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const pending = store.session.pendingQuestion;\n\n // Index of the question currently being answered. Resets when a fresh\n // pending request arrives.\n const [index, setIndex] = useState(0);\n const [answers, setAnswers] = useState<AskAnswers>({});\n const [lastPendingId, setLastPendingId] = useState<string | null>(null);\n // Set when the user tries to submit an empty required field, cleared once a\n // real answer goes through. Drives the inline \"this field is required\" nudge.\n const [requiredHint, setRequiredHint] = useState(false);\n // What the user last did with the link, so the overlay can confirm it. The\n // auto-copy below seeds 'copied'; pressing `o`/`c` overrides it.\n const [linkStatus, setLinkStatus] = useState<'idle' | 'copied' | 'opened'>(\n 'idle',\n );\n\n // For rich-link prompts (opt-in programs only) copy a lone URL to the\n // clipboard, so users on terminals without OSC 8 support can still paste it.\n // Only fires when the current question has exactly one URL, to avoid\n // clobbering the clipboard ambiguously. `soleUrl` is the sole effect dep.\n const richLinks = pending?.richLinks ?? false;\n const currentPrompt = pending?.questions[index]?.prompt ?? '';\n const promptUrls = richLinks ? extractUrls(currentPrompt) : [];\n const soleUrl = promptUrls.length === 1 ? promptUrls[0] : null;\n\n // The `o`/`c` keybinds would steal keystrokes from a free-text answer, so\n // only offer them on picker questions (where the user isn't typing).\n const isTextQuestion = pending?.questions[index]?.kind === 'text';\n const canActOnLink = !!soleUrl && !isTextQuestion;\n\n // Split the prompt at the link so the o/c hint sits right under it, with\n // trailing text below. Falls back to the whole prompt when there's no\n // single-link split.\n const linkSplitIndex =\n canActOnLink && soleUrl ? currentPrompt.indexOf(soleUrl) : -1;\n const splitLink = soleUrl !== null && linkSplitIndex !== -1;\n const linkEnd = splitLink && soleUrl ? linkSplitIndex + soleUrl.length : 0;\n const promptHead = splitLink\n ? currentPrompt.slice(0, linkEnd)\n : currentPrompt;\n const linkTrailingText = splitLink\n ? currentPrompt.slice(linkEnd).replace(/^\\s+/, '')\n : '';\n\n useEffect(() => {\n setLinkStatus('idle');\n if (!soleUrl) return;\n // Seed the clipboard silently for terminals without OSC 8. Status stays\n // 'idle' so the o/c hint shows until the user acts.\n void copyToClipboard(soleUrl);\n }, [soleUrl]);\n\n // Explicit, discoverable link actions. OSC 8 makes the link clickable only on\n // terminals that support it (not macOS Terminal.app), so `o` opens it in the\n // browser directly — the one path that works everywhere — and `c` copies it\n // as a fallback. Both register hints in the bar via useKeyBindings.\n useKeyBindings(\n 'wizard-ask-link',\n canActOnLink && soleUrl\n ? [\n {\n match: 'o',\n label: 'o',\n action: 'open in browser',\n handler: () => {\n void openInBrowser(soleUrl).then((ok) => {\n if (ok) setLinkStatus('opened');\n });\n },\n },\n {\n match: 'c',\n label: 'c',\n action: 'copy link',\n handler: () => {\n void copyToClipboard(soleUrl).then((ok) => {\n if (ok) setLinkStatus('copied');\n });\n },\n },\n ]\n : [],\n );\n\n // Esc declines the whole request. Cancellation is a first-class outcome the\n // ask bridge and the wizard_ask tool already expect (a task treats it as \"the\n // user declined\" and falls back — e.g. to a browser setup link), so without\n // this a user who can't answer has no exit but typing placeholders or waiting\n // out the multi-minute per-question timeout. Every field comes back cancelled.\n useInput((_input, key) => handleAskKey(key, store));\n\n if (!pending) return null;\n\n // Reset accumulator state when the agent opens a new request mid-session.\n if (pending.id !== lastPendingId) {\n setLastPendingId(pending.id);\n setIndex(0);\n setAnswers({});\n setRequiredHint(false);\n return null;\n }\n\n const question = pending.questions[index];\n if (!question) return null;\n\n const total = pending.questions.length;\n const progress = total > 1 ? `Question ${index + 1} of ${total}` : null;\n\n const submit = (value: string | string[]) => {\n // Don't let a required field go through empty — it would reach the agent as\n // a blank answer it can't tell from a real one. Nudge instead; Esc skips.\n if (isRequiredButEmpty(question, value)) {\n setRequiredHint(true);\n return;\n }\n setRequiredHint(false);\n const next: AskAnswers = { ...answers, [question.id]: value };\n if (index + 1 < total) {\n setAnswers(next);\n setIndex(index + 1);\n return;\n }\n store.resolvePendingQuestion(next);\n };\n\n return (\n <ModalOverlay\n borderColor={Colors.accent}\n title={`${Icons.diamond} ${pending.source}`}\n titleColor={Colors.accent}\n width={72}\n >\n {progress && (\n <Box marginBottom={1}>\n <Text dimColor>{progress}</Text>\n </Box>\n )}\n <Box flexDirection=\"column\">\n {pending.richLinks ? (\n <LinkText text={promptHead} />\n ) : (\n <Text>{question.prompt}</Text>\n )}\n </Box>\n {/* o/c hint until the user acts, then a confirmation. */}\n {canActOnLink && (\n <Box marginTop={1}>\n {linkStatus === 'idle' ? (\n <Text dimColor>\n Press <Text color={Colors.accent}>o</Text> to open it in your\n browser, or <Text color={Colors.accent}>c</Text> to copy the link.\n </Text>\n ) : linkStatus === 'opened' ? (\n <Text color={Colors.success}>\n {Icons.check} Opening the link in your browser…\n </Text>\n ) : (\n <Text color={Colors.success}>\n {Icons.check} Link copied to clipboard. Paste it in your browser.\n </Text>\n )}\n </Box>\n )}\n {/* Prompt text after the link */}\n {linkTrailingText && (\n <Box marginTop={1}>\n <Text>{linkTrailingText}</Text>\n </Box>\n )}\n <Box marginTop={1}>\n {/* `key` forces React to remount the input when the question changes\n so per-question internal state (typed buffer, picker focus) doesn't\n bleed across questions. */}\n <QuestionInput\n key={`${pending.id}:${question.id}`}\n question={question}\n onSubmit={submit}\n />\n </Box>\n {requiredHint && (\n <Box marginTop={1}>\n <Text color={Colors.accent}>\n {Icons.warning} This field is required — type an answer, or press\n ESC to skip.\n </Text>\n </Box>\n )}\n <Box marginTop={1}>\n <Text dimColor>\n <Text color={Colors.accent}>ESC</Text> skip\n </Text>\n </Box>\n </ModalOverlay>\n );\n};\n\ninterface QuestionInputProps {\n question: AskQuestion;\n onSubmit: (value: string | string[]) => void;\n}\n\nconst QuestionInput = ({ question, onSubmit }: QuestionInputProps) => {\n switch (question.kind) {\n case 'single':\n return (\n <PickerMenu<string>\n options={(question.options ?? []).map((o) => ({\n label: o.label,\n value: o.value,\n }))}\n onSelect={(value) => {\n const v = Array.isArray(value) ? value[0] : value;\n onSubmit(v);\n }}\n />\n );\n\n case 'multi': {\n const multiOptions = (question.options ?? []).map((o) => ({\n label: o.label,\n value: o.value,\n description: o.description,\n }));\n // Add vertical breathing room between options only when at least one\n // carries a description — keeps every description-less multi-select\n // (every other program) spaced exactly as before.\n const hasDescriptions = multiOptions.some((o) => o.description);\n return (\n <PickerMenu<string>\n mode=\"multi\"\n optionMarginBottom={hasDescriptions ? 1 : 0}\n options={multiOptions}\n onSelect={(value) => {\n const v = Array.isArray(value) ? value : [value];\n onSubmit(v);\n }}\n />\n );\n }\n\n case 'text':\n return (\n // `width=\"100%\"` on both the column and the hint row anchors them to\n // the modal's content width — without it, Ink/Yoga shrinks the column\n // to fit its widest child, so the right-aligned hint walks left/right\n // as the typed text changes width.\n <Box flexDirection=\"column\" width=\"100%\">\n <TextInput\n placeholder=\"Type your answer\"\n onSubmit={(value) => onSubmit(value)}\n />\n <Box marginTop={1} width=\"100%\" justifyContent=\"flex-end\">\n <Text>\n <Text color={Colors.accent}>ENTER</Text>\n <Text dimColor> submit</Text>\n </Text>\n </Box>\n </Box>\n );\n }\n};\n","/**\n * Capability for MCP clients whose editor CLI has its own login command\n * (`claude mcp login`, `codex mcp login`). The editor owns the OAuth token and\n * its refresh, and its login command requires a real terminal — so the wizard\n * never runs it, it surfaces the exact command for the user to run.\n */\nexport interface LoginCapable {\n /** The editor's login command (e.g. `claude mcp login posthog`), or null when unusable right now (CLI absent). */\n loginCommand(local?: boolean): string | null;\n /** The login command when the server comes from the editor's plugin (e.g. `plugin:posthog:posthog`), or null when unusable. */\n pluginLoginCommand?(): string | null;\n}\n\nexport function isLoginCapable<T>(client: T): client is T & LoginCapable {\n return (\n typeof client === 'object' && client !== null && 'loginCommand' in client\n );\n}\n","/**\n * Capability for MCP clients that are connected by opening a hosted page in\n * the browser rather than writing a local config or running a CLI install.\n *\n * Mirrors the PluginCapable pattern in plugin-client.ts: the client carries the\n * URL and instruction text (product knowledge); the TUI renders whatever the\n * capability surfaces (generic machinery).\n */\n\nexport interface BrowserFinishable {\n /** URL the user opens to finish connecting (also shown as copy-paste fallback). */\n connectorUrl: string;\n /** One-line instruction shown after the page opens. */\n finishInstruction: string;\n}\n\nexport function isBrowserFinishable<T>(c: T): c is T & BrowserFinishable {\n return (\n typeof c === 'object' &&\n c !== null &&\n 'connectorUrl' in c &&\n 'finishInstruction' in c\n );\n}\n","/**\n * McpInstaller — service layer between McpScreen and MCP business logic.\n *\n * Decouples the screen from step internals. Testable, swappable,\n * no dynamic imports in React components.\n */\n\nimport {\n getSupportedClients,\n removeMCPServer,\n getInstalledClients,\n getSupportedPluginClients,\n installPlugins as runPluginInstall,\n} from '@steps/add-mcp-server-to-clients/index';\nimport { ALL_FEATURE_VALUES } from '@steps/add-mcp-server-to-clients/defaults';\nimport {\n McpClientStatus,\n namesWithStatus,\n redactSecrets,\n toClientResult,\n type McpClientResult,\n} from '@steps/add-mcp-server-to-clients/results';\nimport { isPluginCapable } from '@steps/add-mcp-server-to-clients/plugin-client';\nimport { isLoginCapable } from '@steps/add-mcp-server-to-clients/login-client';\nimport { isBrowserFinishable } from '@steps/add-mcp-server-to-clients/browser-client';\nimport { logToFile } from '@utils/debug';\nimport { analytics } from '@utils/analytics';\n\nexport interface McpClientInfo {\n name: string;\n supportsPlugin: boolean;\n /** True when the plugin already ships the posthog MCP server (no direct entry needed). */\n pluginBundlesMcp: boolean;\n /**\n * Set for clients connected by opening a hosted page in the browser. The\n * Done screen renders this so the user knows to finish setup in the browser.\n */\n finish?: { url: string; instruction: string };\n /** The editor's own login command (e.g. `claude mcp login posthog`), the one manual step left. */\n loginCommand?: string;\n /** Same, for the plugin-provided server (e.g. `claude mcp login plugin:posthog:posthog`). */\n pluginLoginCommand?: string;\n}\n\nexport { McpClientStatus };\nexport type { McpClientResult };\n\nexport interface McpInstaller {\n /** Detect which MCP-capable editors are available on this machine. */\n detectClients(): Promise<McpClientInfo[]>;\n\n /**\n * Install the PostHog MCP server to the given clients. Returns one result per\n * client — including the ones that were already installed and the ones that\n * failed, so the screen can say which happened and why.\n */\n install(\n clientNames: string[],\n features?: string[],\n apiKey?: string,\n ): Promise<McpClientResult[]>;\n\n /**\n * Remove the PostHog MCP server from every client that has it. Returns one\n * result per client so a failed removal isn't reported as a success.\n */\n remove(local?: boolean): Promise<McpClientResult[]>;\n\n /** Install the PostHog AI plugin to supported clients. Best-effort: failures do not affect MCP outcome. */\n installPlugins(clientNames: string[]): Promise<McpClientResult[]>;\n}\n\n/**\n * Production McpInstaller backed by real MCP client detection and installation.\n */\nexport function createMcpInstaller(): McpInstaller {\n // Cache the raw MCPClient objects so install() can reference them by name\n let cachedClients: Array<{ name: string; raw: unknown }> = [];\n\n return {\n async detectClients(): Promise<McpClientInfo[]> {\n const supported = await getSupportedClients();\n cachedClients = supported.map((c) => ({ name: c.name, raw: c }));\n return supported.map((c) => ({\n name: c.name,\n supportsPlugin: isPluginCapable(c) && c.supportsPlugin(),\n pluginBundlesMcp: isPluginCapable(c) && c.pluginBundlesMcpServer(),\n finish: isBrowserFinishable(c)\n ? { url: c.connectorUrl, instruction: c.finishInstruction }\n : undefined,\n loginCommand: (isLoginCapable(c) && c.loginCommand(false)) || undefined,\n pluginLoginCommand:\n (isLoginCapable(c) && c.pluginLoginCommand?.()) || undefined,\n }));\n },\n\n async install(\n clientNames: string[],\n features?: string[],\n apiKey?: string,\n ): Promise<McpClientResult[]> {\n const resolvedFeatures = features ?? [...ALL_FEATURE_VALUES];\n const toInstall = cachedClients\n .filter((c) => clientNames.includes(c.name))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((c) => c.raw as any);\n\n if (toInstall.length === 0) {\n logToFile(\n `[McpInstaller] No clients matched. clientNames=${JSON.stringify(\n clientNames,\n )}, cached=${JSON.stringify(cachedClients.map((c) => c.name))}`,\n );\n return [];\n }\n\n const results: McpClientResult[] = [];\n for (const client of toInstall) {\n const name = client.name as string;\n try {\n const result = await client.addServer(\n apiKey,\n resolvedFeatures,\n false,\n );\n results.push(toClientResult(name, result));\n if (!result?.success) {\n // redactSecrets, not the raw reason: the CLIs we shell out to echo\n // the Authorization header back in their error output.\n logToFile(\n `[McpInstaller] addServer returned success=false for ${name}: ${redactSecrets(\n result?.reason ?? 'no reason given',\n )}`,\n );\n }\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n logToFile(\n `[McpInstaller] addServer threw for ${name}: ${redactSecrets(\n reason,\n )}`,\n );\n results.push(toClientResult(name, { success: false, reason }));\n }\n }\n return results;\n },\n\n async remove(local?: boolean): Promise<McpClientResult[]> {\n // `local` was dropped here, so `mcp remove --local` looked at (and\n // reported on) the wrong server name.\n const installed = await getInstalledClients(local);\n if (installed.length === 0) return [];\n return removeMCPServer(installed, local);\n },\n\n async installPlugins(clientNames: string[]): Promise<McpClientResult[]> {\n const rawClients = cachedClients\n .filter((c) => clientNames.includes(c.name))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((c) => c.raw as any);\n\n const pluginClients = getSupportedPluginClients(rawClients);\n const results = await runPluginInstall(pluginClients);\n\n const already = namesWithStatus(results, McpClientStatus.Unchanged);\n analytics.wizardCapture('mcp plugins installed', {\n // `clients` keeps its original meaning — every client that ended up with\n // the plugin — so existing insights don't dip when a re-run reports\n // already-installed instead of a fresh write.\n clients: [\n ...namesWithStatus(results, McpClientStatus.Changed),\n ...already,\n ],\n already_installed: already,\n attempted: pluginClients.map((c) => c.name),\n });\n\n return results;\n },\n };\n}\n","/**\n * McpSuggestedPromptsServices — service layer between\n * McpSuggestedPromptsScreen and the network. Decouples the screen from\n * OAuth and the streaming-agent run so the playground can inject mocks\n * (skip login, canned streaming responses) without a special-case\n * branch in the screen itself.\n *\n * Mirrors the McpInstaller pattern: thin interface, production factory\n * that wires the real implementation, no dynamic imports in the React\n * tree.\n */\n\nimport type { Credentials } from '@lib/wizard-session';\nimport { getOrAskForProjectData } from '@utils/setup-utils';\nimport { Program } from '@lib/programs/program-registry';\nimport type { WizardStore } from '@ui/tui/store';\nimport type { ApiUser } from '@lib/api';\nimport {\n probeProjectData as runProbe,\n type ProjectDataProfile,\n} from '@lib/mcp-project-profile';\nimport { seedDemoEvents as runSeed } from '@lib/mcp-seed-events';\n\n/**\n * Discriminated union covering every kind of streamed event the screen\n * needs to render. Production yields these from Claude SDK messages;\n * the playground yields them from canned scripts.\n */\nexport type AgentChunk =\n | { kind: 'text'; text: string }\n /** `command` carries CLI mode's exec command string (`call <tool> …`) so the\n * screen can recover the inner tool for context-aware follow-ups. */\n | { kind: 'tool-call'; toolName: string; detail: string; command?: string }\n | { kind: 'tool-result'; toolName: string; detail: string }\n | { kind: 'error'; text: string }\n /** Stream completed. `sessionId` is the SDK session ID of the just-\n * completed turn; pass it back as `resumeSessionId` on a follow-up\n * call to continue the conversation with full history. */\n | { kind: 'done'; sessionId?: string };\n\nexport interface McpSuggestedPromptsServices {\n /**\n * Kicks off the OAuth dance. Production wires this to\n * `getOrAskForProjectData`; the playground returns canned values\n * after a fake delay.\n *\n * While the promise is pending, the implementation is expected to set\n * `session.loginUrl` (via `store.setLoginUrl`) so the screen can\n * render the URL inline. Mocks may set/clear this URL too if they\n * want to exercise the spinner + URL layout.\n */\n performLogin(): Promise<{\n credentials: Credentials;\n roleAtOrganization: string | null;\n user: ApiUser | null;\n }>;\n\n /**\n * Run a prompt against Claude with the PostHog MCP server available\n * for tool use. Yields chunks as the agent streams. Caller is\n * responsible for honoring the abort signal — implementations should\n * also short-circuit when `signal.aborted` becomes true.\n *\n * In production this calls the Claude Agent SDK's `query()` with the\n * user's OAuth token as the MCP Bearer. In the playground, the demo\n * provides canned scripts.\n */\n runPromptStreaming(args: {\n prompt: string;\n credentials: Credentials;\n signal: AbortSignal;\n /** When set, resume the named SDK session so the agent sees the\n * earlier turns as context. Used by follow-up picks; omitted on\n * the first prompt and after `[p]` restarts the conversation. */\n resumeSessionId?: string;\n }): AsyncIterable<AgentChunk>;\n\n /**\n * Scout the project after auth: a cheap, best-effort probe of event\n * volume, the project's real event names, and which products have data.\n * Drives the data-aware picker so the tutorial never offers a prompt\n * that hits an empty result. Always resolves (degraded profile on\n * failure) — never throws, never blocks the tutorial.\n */\n probeProjectData(credentials: Credentials): Promise<ProjectDataProfile>;\n\n /**\n * Send a small, backdated demo dataset to an empty project so the read\n * quests have something to show. Resolves with the seeded profile;\n * rejects if the send fails so the screen can fall back to the\n * write-only empty path.\n */\n seedDemoEvents(args: {\n credentials: Credentials;\n baseProfile: ProjectDataProfile;\n signal: AbortSignal;\n }): Promise<ProjectDataProfile>;\n}\n\n/**\n * Production services. The `runPromptStreaming` implementation lives\n * in a separate module so the heavy SDK import is only paid when\n * actually invoked.\n */\nexport function createMcpSuggestedPromptsServices(\n store: WizardStore,\n): McpSuggestedPromptsServices {\n return {\n performLogin: async () => {\n const result = await getOrAskForProjectData({\n signup: false,\n ci: false,\n apiKey: undefined,\n projectId: undefined,\n email: undefined,\n region: undefined,\n baseUrl: store.session.baseUrl,\n // Widens the OAuth scope grant: base `WIZARD_OAUTH_SCOPES` plus\n // read on every product surface (flags, experiments, surveys,\n // replays, errors, web/LLM analytics, cohorts, persons) plus\n // annotation read/write. Persistence writes (dashboard, insight,\n // notebook) come for free from the base set. See\n // `src/lib/oauth/program-scopes.ts`.\n programId: Program.McpTutorial,\n });\n return {\n credentials: {\n accessToken: result.accessToken,\n projectApiKey: result.projectApiKey,\n host: result.host,\n projectId: result.projectId,\n },\n roleAtOrganization: result.roleAtOrganization,\n user: result.user,\n };\n },\n\n runPromptStreaming: (args) =>\n runProductionPromptStreaming({\n ...args,\n // Gateway cost attribution. Only the id crosses here; the rest of the\n // trace tags are built where the headers are, keeping the agent module\n // out of the TUI's startup graph.\n programId: store.analyticsProgramId,\n integration: store.session.integration ?? undefined,\n }),\n\n probeProjectData: (credentials) =>\n runProbe({\n accessToken: credentials.accessToken,\n projectId: credentials.projectId,\n apiHost: credentials.host.apiHost,\n }),\n\n seedDemoEvents: ({ credentials, baseProfile, signal }) =>\n runSeed({\n projectApiKey: credentials.projectApiKey,\n apiHost: credentials.host.apiHost,\n baseProfile,\n signal,\n }),\n };\n}\n\nasync function* runProductionPromptStreaming(args: {\n prompt: string;\n credentials: Credentials;\n signal: AbortSignal;\n resumeSessionId?: string;\n programId?: string;\n integration?: string;\n}): AsyncIterable<AgentChunk> {\n // Defer the SDK import to call time — the playground never hits\n // this path (it overrides the whole service object), so demo\n // sessions don't pay the SDK load cost.\n const { runMcpPromptViaSdk } = await import(\n '@lib/agent/mcp-prompt-streaming'\n );\n yield* runMcpPromptViaSdk(args);\n}\n","/**\n * ScreenId registry — maps screen names to React components.\n *\n * Adding a new screen:\n * 1. Create the component in screens/ (or screens/<program>/).\n * 2. Add a `ScreenId` enum entry in screen-sequences.ts.\n * 3. Add an entry here.\n * 4. Reference the screen by name in the program's `steps` array.\n */\n\nimport type { ReactNode } from 'react';\nimport type { WizardStore } from './store.js';\nimport { ScreenId, Overlay, type ScreenName } from './router.js';\n\nimport { HealthCheckScreen } from './screens/health/HealthCheckScreen.js';\nimport { DoctorIntroScreen } from './screens/doctor/DoctorIntroScreen.js';\nimport { DoctorReportScreen } from './screens/doctor/DoctorReportScreen.js';\nimport { SettingsOverrideScreen } from './screens/SettingsOverrideScreen.js';\nimport { ManagedSettingsScreen } from './screens/ManagedSettingsScreen.js';\nimport { PortConflictScreen } from './screens/PortConflictScreen.js';\nimport { TaskNoticeScreen } from './screens/TaskNoticeScreen.js';\nimport { ManualAuthCodeScreen } from './screens/ManualAuthCodeScreen.js';\nimport { PostHogIntegrationIntroScreen } from './screens/PostHogIntegrationIntroScreen.js';\nimport { RevenueIntroScreen } from './screens/RevenueIntroScreen.js';\nimport { WarehouseIntroScreen } from './screens/WarehouseIntroScreen.js';\nimport { MigrationIntroScreen } from './screens/MigrationIntroScreen.js';\nimport { SourceMapsIntroScreen } from './screens/SourceMapsIntroScreen.js';\nimport { SourceMapsDetectScreen } from './screens/SourceMapsDetectScreen.js';\nimport { SourceMapsOutroScreen } from './screens/SourceMapsOutroScreen.js';\nimport { AgentSkillIntroScreen } from './screens/AgentSkillIntroScreen.js';\nimport { AiObservabilityIntroScreen } from './screens/AiObservabilityIntroScreen.js';\nimport { MetricsIntroScreen } from './screens/MetricsIntroScreen.js';\nimport { SelfDrivingIntroScreen } from './screens/SelfDrivingIntroScreen.js';\nimport { SelfDrivingIntegrationCheckScreen } from './screens/SelfDrivingIntegrationCheckScreen.js';\nimport { SelfDrivingIntegrationDetectScreen } from './screens/SelfDrivingIntegrationDetectScreen.js';\nimport { SelfDrivingHandoffScreen } from './screens/SelfDrivingHandoffScreen.js';\nimport { SelfDrivingGitHubScreen } from '@ui/tui/screens/SelfDrivingGitHubScreen';\nimport { AuditIntroScreen } from './screens/audit/AuditIntroScreen.js';\nimport { AuditRunScreen } from './screens/audit/AuditRunScreen.js';\nimport { AuditOutroScreen } from './screens/audit/AuditOutroScreen.js';\nimport { SetupScreen } from './screens/SetupScreen.js';\nimport { AuthScreen } from './screens/AuthScreen.js';\nimport { AiOptInRequiredScreen } from './screens/AiOptInRequiredScreen.js';\nimport { RunScreen } from './screens/RunScreen.js';\nimport { McpScreen } from './screens/McpScreen.js';\nimport { McpSuggestedPromptsScreen } from './screens/McpSuggestedPromptsScreen.js';\nimport { SlackConnectScreen } from './screens/SlackConnectScreen.js';\nimport { KeepSkillsScreen } from './screens/KeepSkillsScreen.js';\nimport { OutroScreen } from './screens/OutroScreen.js';\nimport { ExitScreen } from './screens/ExitScreen.js';\nimport { AuthErrorScreen } from './screens/AuthErrorScreen.js';\nimport { SessionTimeoutScreen } from './screens/SessionTimeoutScreen.js';\nimport { WizardAskScreen } from './screens/WizardAskScreen.js';\nimport { createMcpInstaller } from './services/mcp-installer.js';\nimport type { McpInstaller } from './services/mcp-installer.js';\nimport { createMcpSuggestedPromptsServices } from './services/mcp-suggested-prompts-services.js';\nimport type { McpSuggestedPromptsServices } from './services/mcp-suggested-prompts-services.js';\n\nexport interface ScreenServices {\n mcpInstaller: McpInstaller;\n mcpSuggestedPromptsServices: McpSuggestedPromptsServices;\n}\n\nexport function createServices(store: WizardStore): ScreenServices {\n return {\n mcpInstaller: createMcpInstaller(),\n mcpSuggestedPromptsServices: createMcpSuggestedPromptsServices(store),\n };\n}\n\nexport function createScreens(\n store: WizardStore,\n services: ScreenServices,\n): Record<ScreenName, ReactNode> {\n return {\n // Overlays\n [Overlay.SettingsOverride]: <SettingsOverrideScreen store={store} />,\n [Overlay.ManagedSettings]: <ManagedSettingsScreen store={store} />,\n [Overlay.PortConflict]: <PortConflictScreen store={store} />,\n [Overlay.TaskNotice]: <TaskNoticeScreen store={store} />,\n [Overlay.ManualAuthCode]: <ManualAuthCodeScreen store={store} />,\n [Overlay.AuthError]: <AuthErrorScreen store={store} />,\n [Overlay.SessionTimeout]: <SessionTimeoutScreen store={store} />,\n [Overlay.WizardAsk]: <WizardAskScreen store={store} />,\n\n // Wizard flow\n [ScreenId.Intro]: <PostHogIntegrationIntroScreen store={store} />,\n [ScreenId.RevenueIntro]: <RevenueIntroScreen store={store} />,\n [ScreenId.WarehouseIntro]: <WarehouseIntroScreen store={store} />,\n [ScreenId.SourceMapsIntro]: <SourceMapsIntroScreen store={store} />,\n [ScreenId.SourceMapsDetect]: <SourceMapsDetectScreen store={store} />,\n [ScreenId.SourceMapsOutro]: <SourceMapsOutroScreen store={store} />,\n [ScreenId.MigrationIntro]: <MigrationIntroScreen store={store} />,\n [ScreenId.AgentSkillIntro]: <AgentSkillIntroScreen store={store} />,\n [ScreenId.AiObservabilityIntro]: (\n <AiObservabilityIntroScreen store={store} />\n ),\n [ScreenId.MetricsIntro]: <MetricsIntroScreen store={store} />,\n [ScreenId.SelfDrivingIntro]: <SelfDrivingIntroScreen store={store} />,\n [ScreenId.SelfDrivingIntegrationCheck]: (\n <SelfDrivingIntegrationCheckScreen store={store} />\n ),\n [ScreenId.SelfDrivingIntegrationDetect]: (\n <SelfDrivingIntegrationDetectScreen store={store} />\n ),\n [ScreenId.SelfDrivingHandoff]: <SelfDrivingHandoffScreen store={store} />,\n [ScreenId.SelfDrivingGithub]: <SelfDrivingGitHubScreen store={store} />,\n [ScreenId.AuditIntro]: <AuditIntroScreen store={store} />,\n [ScreenId.AuditRun]: <AuditRunScreen store={store} />,\n [ScreenId.AuditOutro]: <AuditOutroScreen store={store} />,\n [ScreenId.HealthCheck]: <HealthCheckScreen store={store} />,\n [ScreenId.DoctorIntro]: <DoctorIntroScreen store={store} />,\n [ScreenId.DoctorReport]: <DoctorReportScreen store={store} />,\n [ScreenId.Setup]: <SetupScreen store={store} />,\n [ScreenId.Auth]: <AuthScreen store={store} />,\n [ScreenId.AiOptIn]: <AiOptInRequiredScreen store={store} />,\n [ScreenId.Run]: <RunScreen store={store} />,\n [ScreenId.Mcp]: (\n <McpScreen store={store} installer={services.mcpInstaller} />\n ),\n [ScreenId.McpSuggestedPrompts]: (\n <McpSuggestedPromptsScreen\n store={store}\n services={services.mcpSuggestedPromptsServices}\n />\n ),\n [ScreenId.SlackConnect]: <SlackConnectScreen store={store} />,\n [ScreenId.KeepSkills]: <KeepSkillsScreen store={store} />,\n [ScreenId.Outro]: <OutroScreen store={store} />,\n [ScreenId.Exit]: <ExitScreen />,\n\n // Standalone MCP flows\n [ScreenId.McpAdd]: (\n <McpScreen store={store} installer={services.mcpInstaller} />\n ),\n [ScreenId.McpRemove]: (\n <McpScreen\n store={store}\n installer={services.mcpInstaller}\n mode=\"remove\"\n />\n ),\n };\n}\n","import { useMemo } from 'react';\nimport { ScreenContainer } from './primitives/index.js';\nimport type { WizardStore } from './store.js';\nimport { createScreens, createServices } from './screen-registry.js';\n\ninterface AppProps {\n store: WizardStore;\n}\n\nexport const App = ({ store }: AppProps) => {\n const services = useMemo(() => createServices(store), [store]);\n const screens = useMemo(\n () => createScreens(store, services),\n [store, services],\n );\n\n return <ScreenContainer store={store} screens={screens} />;\n};\n","/**\n * exit-line.ts — builds the text printed to the MAIN terminal buffer after the\n * wizard leaves the alternate screen on exit.\n *\n * The TUI renders in the alternate screen buffer, which is torn down on exit —\n * everything the wizard drew (including the outro screen) is wiped. This line,\n * printed AFTER releaseTerminal(), is the only output that survives into the\n * user's scrollback. So the coding-agent handoff prompt is echoed here, on its\n * own plain line (no border, no bullets), which is what a terminal can\n * triple-click-select cleanly.\n *\n * Kept free of `ink`/`@inkjs/ui` imports so it stays a pure, unit-testable\n * function (start-tui.ts itself pulls in the whole render tree).\n */\n\nimport { totalTokenCount, type WizardStore } from './store.js';\nimport { OutroKind } from '@lib/wizard-session';\nimport { formatTokenCount, formatCostUsd } from '@lib/agent/token-pricing';\n\nconst RESET_ATTRS = '\\x1b[0m';\nconst GREEN = '\\x1b[32m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\n\n/**\n * Mirrors the hidden Ctrl+T HUD's tally into post-exit scrollback — but only\n * when the HUD is actually visible at exit (`store.tokenHudVisible`, which\n * defaults on in dev/test and off in production; `useDismissOnAnyKey`\n * already keeps Ctrl+T from also dismissing the outro screen underneath\n * it). A production run where the user never toggled it on shouldn't have a\n * cost number appear from nowhere once the TUI tears down. `null` when the\n * HUD is hidden, or the run never produced any usage (e.g. non-agent\n * programs).\n */\nfunction tokenCostLine(store: WizardStore): string | null {\n if (!store.tokenHudVisible) return null;\n const usage = store.tokenUsage;\n if (totalTokenCount(usage) === 0) return null;\n\n const label = usage.costIsFinal ? 'Final cost' : 'Cost (estimate)';\n return (\n `${DIM}${label}: ${formatCostUsd(usage.costUsd)}` +\n ` (in ${formatTokenCount(usage.inputTokens)}` +\n ` · out ${formatTokenCount(usage.outputTokens)}` +\n ` · cache read ${formatTokenCount(usage.cacheReadTokens)}` +\n ` · cache write ${formatTokenCount(\n usage.cacheCreationTokens,\n )})${RESET_ATTRS}`\n );\n}\n\n/**\n * The one manual step the wizard can't do itself: the editor's own MCP login.\n * Echoed into scrollback like the handoff prompt — command on its own plain\n * line so a terminal can triple-click-select it.\n */\nfunction mcpLoginBlock(store: WizardStore): string | null {\n const commands = store.session.mcpLoginCommands;\n if (!commands || commands.length === 0) return null;\n return (\n `${GREEN}${BOLD}\\u2714 Authenticate to finish (opens your browser):${RESET_ATTRS}\\n` +\n commands.join('\\n')\n );\n}\n\nexport function getExitLine(store: WizardStore): string {\n const outro = store.session.outroData;\n const label = store.session.programLabel ?? 'Wizard';\n const costLine = tokenCostLine(store);\n const loginBlock = mcpLoginBlock(store);\n\n if (outro?.kind === OutroKind.Success) {\n const message = outro.message ?? `${label} completed successfully.`;\n const reportSuffix =\n outro.reportFile && !message.includes(outro.reportFile)\n ? ` Check ./${outro.reportFile} for details.`\n : '';\n const headline = `${GREEN}${BOLD}✔${RESET_ATTRS} ${message}${reportSuffix}`;\n\n const parts = [headline];\n\n // The alt-screen outro is wiped on exit, so a program's primary\n // next-action link (e.g. the Self-driving inbox) only survives in\n // scrollback if echoed here. URL on its own line → clean triple-click.\n if (outro.primaryLink) {\n parts.push(\n `${DIM}${outro.primaryLink.label}:${RESET_ATTRS}\\n${outro.primaryLink.url}`,\n );\n }\n\n if (outro.nextSteps) {\n const bullets = outro.nextSteps.items\n .map((item) => `${DIM} • ${item}${RESET_ATTRS}`)\n .join('\\n');\n parts.push(`${DIM}${outro.nextSteps.heading}${RESET_ATTRS}\\n${bullets}`);\n }\n\n if (outro.handoffPrompt) {\n parts.push(\n `${DIM}Hand this to your coding agent to finish up (triple-click to select):${RESET_ATTRS}\\n` +\n outro.handoffPrompt,\n );\n }\n\n if (loginBlock) parts.push(loginBlock);\n if (costLine) parts.push(costLine);\n\n return parts.join('\\n\\n');\n }\n\n const parts = loginBlock\n ? [loginBlock]\n : [`${DIM}${label} exited.${RESET_ATTRS}`];\n if (costLine) parts.push(costLine);\n return parts.join('\\n\\n');\n}\n","/**\n * start-tui.ts — Sets up the Ink TUI renderer and InkUI.\n *\n * Renders in the terminal's alternate screen buffer so the wizard\n * doesn't pollute scrollback history. On exit, the previous terminal\n * content is restored and a single exit summary line is printed.\n */\n\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { WizardStore, Program, type ProgramId } from './store.js';\nimport { InkUI } from './ink-ui.js';\nimport { setUI } from '@ui/index';\nimport { App } from './App.js';\nimport { enterDarkTerminal, releaseTerminal } from './terminal.js';\nimport { analytics } from '@utils/analytics';\nimport { logToFile } from '@utils/debug';\nimport { getExitLine } from './exit-line.js';\n\nexport { releaseTerminal };\n\nexport function startTUI(\n version: string,\n program: ProgramId = Program.PostHogIntegration,\n): {\n unmount: () => void;\n store: WizardStore;\n waitForSetup: () => Promise<void>;\n} {\n enterDarkTerminal();\n\n const store = new WizardStore(program);\n store.version = version;\n\n const inkUI = new InkUI(store);\n setUI(inkUI);\n\n const { unmount: inkUnmount, waitUntilExit } = render(\n createElement(App, { store }),\n );\n\n analytics.setTag('program_id', program);\n // The launch marker — the first event of every TUI run, captured under\n // the run's anonymous id and merged into the user once they log in.\n analytics.wizardCapture('started', { program_id: program });\n\n // Fire the program steps' init work (e.g. the health-check pre-flight)\n // now that the screens are rendering — store construction alone must\n // not trigger it.\n store.runInitHooks();\n\n // Tearing down raw mode with a TTY read still pending surfaces a\n // benign 'read EIO' on stdin (macOS); without a handler Node treats\n // it as an uncaught exception and prints a stack over the exit line.\n process.stdin.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code !== 'EIO') throw err;\n });\n\n // On exit: unmount Ink, leave alt screen (restores previous content),\n // then print exit summary line into the main buffer.\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n // Timestamp the teardown — everything printed into the alt screen dies here.\n logToFile(\n `[start-tui] unmounting TUI, leaving alt screen (exitCode=${\n process.exitCode ?? 'unset'\n })`,\n );\n inkUnmount();\n releaseTerminal();\n process.stdout.write(getExitLine(store) + '\\n');\n };\n process.on('exit', cleanup);\n\n // Ink unmounts itself on ctrl+c (exitOnCtrlC) but that alone doesn't\n // end the process — background handles (e.g. the OAuth callback\n // server) keep the event loop alive, leaving a zombie wizard with no\n // UI. Follow the app teardown with a real exit.\n void waitUntilExit().then(async () => {\n // `cleaned` still false here means Ink tore itself down (ctrl+c) rather\n // than a runner-driven exit — flush the terminal analytics event before\n // the process dies, or interrupted runs vanish from the funnel entirely.\n // shutdown() is a no-op when a runner already reported a real status.\n const interrupted = !cleaned;\n cleanup();\n if (interrupted) {\n try {\n await analytics.shutdown('cancelled');\n } catch {\n /* never block exit on a flush failure */\n }\n }\n process.exit(process.exitCode ?? 0);\n });\n\n return {\n unmount: cleanup,\n store,\n waitForSetup: () => store.getGate('intro'),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"start-tui-Kt61g7LE.js","names":["DetectErrorBody","DetectErrorBody","VARIANT_DISPLAY_NAME","MAX_ACTIVITY_LINES","projectLabel","VARIANT_DISPLAY_NAME","join","join","join","getSkillContentBlocks","join","runPluginInstall","runProbe","runSeed"],"sources":["../src/ui/tui/ink-ui.ts","../src/ui/tui/screens/health/HealthCheckScreen.tsx","../src/ui/tui/screens/doctor/DoctorIntroScreen.tsx","../src/ui/tui/screens/doctor/DoctorReportScreen.tsx","../src/ui/tui/screens/SettingsOverrideScreen.tsx","../src/ui/tui/screens/ManagedSettingsScreen.tsx","../src/ui/tui/screens/PortConflictScreen.tsx","../src/ui/tui/screens/TaskNoticeScreen.tsx","../src/ui/tui/screens/ManualAuthCodeScreen.tsx","../src/ui/tui/components/PrivacyPanel.tsx","../src/ui/tui/screens/IntroScreenLayout.tsx","../src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx","../src/ui/tui/screens/RevenueIntroScreen.tsx","../src/ui/tui/screens/WarehouseIntroScreen.tsx","../src/ui/tui/screens/MigrationIntroScreen.tsx","../src/ui/tui/screens/SourceMapsIntroScreen.tsx","../src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts","../src/ui/tui/screens/SourceMapsDetectScreen.tsx","../src/ui/tui/screens/SourceMapsOutroScreen.tsx","../src/ui/tui/screens/AgentSkillIntroScreen.tsx","../src/ui/tui/screens/AiObservabilityIntroScreen.tsx","../src/ui/tui/screens/MetricsIntroScreen.tsx","../src/ui/tui/screens/SelfDrivingIntroScreen.tsx","../src/ui/tui/screens/SelfDrivingIntegrationCheckScreen.tsx","../src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx","../src/ui/tui/screens/SelfDrivingHandoffScreen.tsx","../src/ui/tui/hooks/useGithubConnection.ts","../src/ui/tui/screens/SelfDrivingGitHubScreen.tsx","../src/ui/tui/screens/audit/AuditIntroScreen.tsx","../src/ui/tui/hooks/file-watcher.ts","../src/ui/tui/screens/audit/AuditAreaPane.tsx","../src/ui/tui/screens/audit/slides/events-audit/detectSdk.tsx","../src/ui/tui/screens/audit/slides/events-audit/scanSites.tsx","../src/ui/tui/screens/audit/slides/events-audit/enrichSites.tsx","../src/ui/tui/screens/audit/slides/events-audit/queryVolume.tsx","../src/ui/tui/screens/audit/slides/events-audit/writeReport.tsx","../src/ui/tui/screens/audit/slides/events-audit/createDashboard.tsx","../src/ui/tui/screens/audit/slides/events-audit/uploadNotebook.tsx","../src/ui/tui/screens/audit/slides/events-audit/index.ts","../src/ui/tui/screens/audit/PendingChecksList.tsx","../src/ui/tui/screens/audit/AuditRunScreen.tsx","../src/ui/tui/screens/audit/AuditChecksOutroSection.tsx","../src/ui/tui/screens/audit/AuditOutroScreen.tsx","../src/ui/tui/screens/SetupScreen.tsx","../src/utils/clipboard.ts","../src/ui/tui/screens/AuthScreen.tsx","../src/ui/tui/screens/RunScreen.tsx","../src/ui/tui/screens/KeepSkillsScreen.tsx","../src/ui/tui/screens/ExitScreen.tsx","../src/ui/tui/screens/AuthErrorScreen.tsx","../src/ui/tui/screens/SessionTimeoutScreen.tsx","../src/ui/tui/screens/WizardAskScreen.tsx","../src/steps/add-mcp-server-to-clients/login-client.ts","../src/steps/add-mcp-server-to-clients/browser-client.ts","../src/ui/tui/services/mcp-installer.ts","../src/ui/tui/services/mcp-suggested-prompts-services.ts","../src/ui/tui/screen-registry.tsx","../src/ui/tui/App.tsx","../src/ui/tui/exit-line.ts","../src/ui/tui/start-tui.ts"],"sourcesContent":["/**\n * InkUI — Ink-backed implementation of WizardUI.\n *\n * Translates business logic calls into store setter calls.\n * No direct session mutation. No imperative screen transitions.\n * The router derives the active screen from session state.\n */\n\nimport type {\n WizardUI,\n SpinnerHandle,\n AuthErrorDetail,\n TokenUsageDelta,\n} from '@ui/wizard-ui';\nimport type { WizardStore } from './store.js';\nimport type { SettingsConflict } from '@lib/agent/claude-settings';\nimport type { WizardReadinessResult } from '@lib/health-checks/readiness';\nimport type { ApiUser } from '@lib/api';\nimport type {\n AskAnswers,\n Credentials,\n OutroData,\n PendingQuestion,\n TaskNotice,\n} from '@lib/wizard-session';\nimport { RunPhase, OutroKind } from '@lib/wizard-session';\n\n// Strip ANSI escape codes (chalk formatting) from strings\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\nfunction stripAnsi(s: string): string {\n return s.replace(ANSI_RE, '');\n}\n\nexport class InkUI implements WizardUI {\n constructor(private store: WizardStore) {}\n\n intro(message: string): void {\n this.store.pushStatus(message);\n }\n\n outro(message: string): void {\n this.store.pushStatus(stripAnsi(message));\n\n // Outro data is pushed by agent-runner via setOutroData() above. If it\n // wasn't (e.g. CI path where outro is called directly with just a\n // message), fall back to a minimal success record so the screen still\n // renders something useful.\n const existing = this.store.session.outroData;\n if (!existing) {\n this.store.setOutroData({\n kind: OutroKind.Success,\n message: stripAnsi(message),\n });\n }\n\n // Signal that the main work is done — router resolves to outro\n if (this.store.session.runPhase === RunPhase.Running) {\n this.store.setRunPhase(RunPhase.Completed);\n }\n }\n\n outroError(data: OutroData): void {\n this.store.setOutroData(data);\n // Advance router past the run step so the outro screen renders\n if (this.store.session.runPhase !== RunPhase.Error) {\n this.store.setRunPhase(RunPhase.Error);\n }\n }\n\n waitForOutroDismissed(): Promise<void> {\n return new Promise((resolve) => {\n if (this.store.session.outroDismissed) {\n resolve();\n return;\n }\n const unsub = this.store.subscribe(() => {\n if (this.store.session.outroDismissed) {\n unsub();\n resolve();\n }\n });\n });\n }\n\n setCredentials(credentials: Credentials): void {\n this.store.setCredentials(credentials);\n }\n\n setAccessToken(credentials: Credentials): void {\n this.store.setAccessToken(credentials);\n }\n\n setRoleAtOrganization(role: string | null): void {\n this.store.setRoleAtOrganization(role);\n }\n\n setApiUser(user: ApiUser | null): void {\n this.store.setApiUser(user);\n }\n\n waitForAiOptIn(): Promise<void> {\n // Resolved immediately when no gate is registered (requiresAi: false,\n // no auth step, or CI). Otherwise parks until _checkGates sees the\n // org's approval flip to true — e.g. via [R]etry on the kill screen.\n return this.store.getGate('ai-opt-in');\n }\n\n waitForGate(stepId: string): Promise<void> {\n return this.store.getGate(stepId);\n }\n\n getFrameworkContext(key: string): unknown {\n return this.store.session.frameworkContext[key];\n }\n\n setDetectedFramework(label: string): void {\n this.store.setDetectedFramework(label);\n }\n\n onEnterScreen(screen: string, fn: () => void): void {\n this.store.onEnterScreen(\n screen as Parameters<WizardStore['onEnterScreen']>[0],\n fn,\n );\n }\n\n setLoginUrl(url: string | null): void {\n this.store.setLoginUrl(url);\n }\n\n setAuthorizeUrl(url: string | null): void {\n this.store.setAuthorizeUrl(url);\n }\n\n showBlockingOutage(result: WizardReadinessResult): Promise<void> {\n // In the TUI, the HealthCheckScreen handles outage display.\n // This is only called from agent-runner for the CI fallback path.\n this.store.setReadinessResult(result);\n return Promise.resolve();\n }\n\n setReadinessWarnings(result: WizardReadinessResult): void {\n this.store.setReadinessResult(result);\n }\n\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n port: number;\n user: string;\n }): Promise<void> {\n return this.store.showPortConflict(processInfo);\n }\n\n waitForManualAuthCode(): Promise<string> {\n return this.store.waitForManualAuthCode();\n }\n\n showTaskNotice(notice: TaskNotice): Promise<boolean> {\n return this.store.showTaskNotice(notice);\n }\n\n cancelTaskNotice(): void {\n // Same path as pressing Skip: closes the overlay and resolves the pending\n // showTaskNotice promise with false.\n this.store.resolveTaskNotice(false);\n }\n\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n return this.store.showSettingsOverride(conflicts, backupAndFix);\n }\n\n showAuthError(detail?: AuthErrorDetail): void {\n this.store.showAuthError(detail);\n }\n\n showSessionTimeout(): void {\n this.store.showSessionTimeout();\n }\n\n requestQuestion(question: PendingQuestion): Promise<AskAnswers> {\n return this.store.requestQuestion(question);\n }\n\n cancelPendingQuestion(): void {\n this.store.cancelPendingQuestion();\n }\n\n startRun(): void {\n this.store.setRunPhase(RunPhase.Running);\n }\n\n cancel(message: string): void {\n this.store.pushStatus(message);\n }\n\n log = {\n info: (message: string): void => {\n this.store.pushStatus(message);\n },\n warn: (message: string): void => {\n this.store.pushStatus(message);\n },\n error: (message: string): void => {\n this.store.pushStatus(message);\n },\n success: (message: string): void => {\n this.store.pushStatus(message);\n },\n step: (message: string): void => {\n this.store.pushStatus(message);\n },\n };\n\n note(message: string): void {\n this.store.pushStatus(message);\n }\n\n spinner(): SpinnerHandle {\n return {\n start: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n stop: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n message: (msg?: string) => {\n if (msg) this.store.pushStatus(msg);\n },\n };\n }\n\n pushStatus(message: string): void {\n this.store.pushStatus(message);\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n this.store.syncTodos(todos);\n }\n\n setEventPlan(events: Array<{ name: string; description: string }>): void {\n this.store.setEventPlan(events);\n }\n\n setDashboardUrl(url: string): void {\n this.store.setDashboardUrl(url);\n }\n\n setStage(stage: string): void {\n this.store.setCurrentStage(stage);\n }\n\n setNotebookUrl(url: string): void {\n this.store.setNotebookUrl(url);\n }\n\n setHandoffText(text: string): void {\n this.store.setHandoffText(text);\n }\n\n addTokenUsage(delta: TokenUsageDelta): void {\n this.store.addTokenUsage(delta);\n }\n\n setFinalTokenCostUsd(costUsd: number): void {\n this.store.setFinalTokenCostUsd(costUsd);\n }\n\n setOutroData(data: OutroData): void {\n // Merge in URLs the agent emitted via `[DASHBOARD_URL]` / `[NOTEBOOK_URL]`\n // markers. These land on the live store during the run; agent-runner's\n // `session` snapshot misses them (setKey forks the reference). The live\n // store wins over the `data` payload so a real emission always beats any\n // fallback the program's buildOutroData may have computed from the stale\n // snapshot (e.g. events-audit defaults dashboardUrl to `${cloudUrl}/dashboard`).\n const live = this.store.session;\n this.store.setOutroData({\n ...data,\n dashboardUrl: live.dashboardUrl ?? data.dashboardUrl ?? undefined,\n notebookUrl: live.notebookUrl ?? data.notebookUrl ?? undefined,\n });\n }\n\n setFrameworkContext(key: string, value: unknown): void {\n this.store.setFrameworkContext(key, value);\n }\n}\n","/**\n * HealthCheckScreen — Program screen between Intro and Auth.\n *\n * Three states:\n * 1. Checking: spinner while health check runs\n * 2. Healthy: isComplete returns true, router auto-advances to Auth\n * 3. Blocking outage: shows affected services with Continue/Exit\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport {\n ConfirmationInput,\n LoadingBox,\n ModalOverlay,\n} from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { ServiceHealthList } from '@ui/tui/components/ServiceHealthList';\nimport {\n getBlockingServiceKeys,\n SIGNUP_WIZARD_READINESS_CONFIG,\n} from '@lib/health-checks/readiness';\nimport { ServiceHealthStatus } from '@lib/health-checks/types';\nimport { wizardAbort } from '@utils/wizard-abort';\nimport { ErrorCodes } from '@lib/errors';\nimport { fetchSkillMenu, downloadSkill } from '@lib/wizard-tools';\nimport { GITHUB_SKILLS_BASE_URL } from '@lib/constants';\nimport { useDismissOnAnyKey } from '@ui/tui/hooks/useDismissOnAnyKey';\n\ninterface HealthCheckScreenProps {\n store: WizardStore;\n}\n\nconst EXAMPLE_PROMPT =\n 'Integrate PostHog into this project using the skill files in .posthog/skills/. Read SKILL.md first, then follow the numbered program files in order.';\n\nconst SkillsDownloadedScreen = () => {\n useDismissOnAnyKey(() => process.exit(0));\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text color=\"green\" bold>\n {Icons.check} Skills downloaded to .posthog/skills/\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>\n You can continue setup with another agent using this prompt:\n </Text>\n <Box marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">{EXAMPLE_PROMPT}</Text>\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to exit</Text>\n </Box>\n </Box>\n );\n};\n\nexport const HealthCheckScreen = ({ store }: HealthCheckScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [downloaded, setDownloaded] = useState(false);\n const [downloading, setDownloading] = useState(false);\n\n const result = store.session.readinessResult;\n\n if (downloaded) {\n return <SkillsDownloadedScreen />;\n }\n\n // Still checking — show spinner\n if (!result) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <LoadingBox message=\"Checking service status...\" />\n </Box>\n );\n }\n\n const isSignup = store.session.signup;\n const blockingKeys = getBlockingServiceKeys(\n result.health,\n isSignup ? SIGNUP_WIZARD_READINESS_CONFIG : undefined,\n );\n\n // Signup has a narrower block list (only posthog + llm-gateway), so\n // services like Anthropic can be degraded without blocking. Surface\n // those as dismissable warnings instead of silently proceeding.\n const warningKeys = isSignup\n ? getBlockingServiceKeys(result.health).filter(\n (k) => !blockingKeys.includes(k),\n )\n : [];\n\n const hasHardBlock = blockingKeys.length > 0;\n const displayKeys = hasHardBlock ? blockingKeys : warningKeys;\n if (displayKeys.length === 0) return null;\n\n const isSkillsOriginDown =\n hasHardBlock && blockingKeys.includes('skillsOrigin');\n const canDownloadSkills =\n result.health.skillsOrigin.status === ServiceHealthStatus.Healthy;\n const integration = store.session.integration;\n\n // If every blocking row is `NoConnection` (probe failed, no status-page\n // corroboration), reframe the screen to point at the user's network\n // instead of accusing PostHog of an outage. Mixed Down + NoConnection\n // falls through to the confirmed-outage framing because there's still\n // a real incident underneath.\n const allBlockingHaveNoConnection =\n hasHardBlock &&\n displayKeys.every(\n (k) => result.health[k].status === ServiceHealthStatus.NoConnection,\n );\n\n const title = isSkillsOriginDown\n ? 'Ongoing service disruptions'\n : allBlockingHaveNoConnection\n ? \"Couldn't reach PostHog\"\n : hasHardBlock\n ? 'Ongoing service disruptions'\n : 'Service disruption detected';\n\n const docsUrl = store.session.frameworkConfig?.metadata.docsUrl;\n const description = isSkillsOriginDown\n ? \"The Wizard can't download the skills it needs — neither GitHub Releases nor PostHog's mirror is reachable right now.\"\n : allBlockingHaveNoConnection\n ? \"We couldn't reach these services from this machine. PostHog's status page shows no incidents, so this is most likely a network issue — VPN, firewall, captive portal, or flaky Wi-Fi.\"\n : hasHardBlock\n ? 'The Wizard cannot start while these services are down.'\n : 'Some services are degraded. You can continue, but parts of the wizard may not work reliably.';\n\n const handleDownloadAndExit = async () => {\n if (downloading) return;\n setDownloading(true);\n // Primary origin — fetchSkillMenu/downloadSkill fail over to AWS themselves.\n const menu = await fetchSkillMenu(GITHUB_SKILLS_BASE_URL);\n if (menu) {\n const prefix = `integration-${integration}`;\n const skills = (menu.categories['integration'] ?? []).filter((s) =>\n s.id.startsWith(prefix),\n );\n for (const skill of skills) {\n // Pre-auth outage cache: no gateway, so a flagged skill fails closed.\n await downloadSkill(skill, store.session.installDir, {\n skillsRoot: '.posthog/skills',\n triage: undefined,\n });\n }\n }\n setDownloaded(true);\n };\n\n const handleCancel =\n canDownloadSkills && !isSkillsOriginDown\n ? () => void handleDownloadAndExit()\n : () =>\n void wizardAbort({\n code: ErrorCodes.EnvServiceOutage,\n message: 'Exited due to service outage.',\n });\n\n const cancelLabel =\n canDownloadSkills && !isSkillsOriginDown\n ? downloading\n ? 'Downloading...'\n : 'Download skills & Exit [Esc]'\n : 'Exit [Esc]';\n\n return (\n <ModalOverlay\n borderColor={\n hasHardBlock && !allBlockingHaveNoConnection ? 'red' : 'yellow'\n }\n title={title}\n width={72}\n footer={\n isSkillsOriginDown ? (\n <ConfirmationInput\n message=\"\"\n confirmLabel=\"\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() =>\n void wizardAbort({\n code: ErrorCodes.EnvServiceOutage,\n message: 'Exited due to service outage.',\n })\n }\n onCancel={() =>\n void wizardAbort({\n code: ErrorCodes.EnvServiceOutage,\n message: 'Exited due to service outage.',\n })\n }\n />\n ) : (\n <ConfirmationInput\n message=\"Continue anyway?\"\n confirmLabel=\"Continue [Enter]\"\n cancelLabel={cancelLabel}\n onConfirm={() => store.dismissOutage()}\n onCancel={handleCancel}\n />\n )\n }\n >\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box marginBottom={1}>\n <Text>\n <Text color=\"red\">{Icons.squareFilled}</Text>\n <Text dimColor> Down </Text>\n <Text color=\"#DC9300\">{Icons.squareFilled}</Text>\n <Text dimColor> Degraded </Text>\n <Text color=\"gray\">{Icons.squareFilled}</Text>\n <Text dimColor> No connection</Text>\n </Text>\n </Box>\n\n <ServiceHealthList\n health={result.health}\n filterKeys={displayKeys}\n showHealthy={false}\n />\n </Box>\n\n <Text dimColor>{description}</Text>\n\n {isSkillsOriginDown && docsUrl && (\n <Box marginTop={1}>\n <Text>\n Set up manually: <Text color=\"cyan\">{docsUrl}</Text>\n </Text>\n </Box>\n )}\n\n {canDownloadSkills && !isSkillsOriginDown && (\n <Box marginTop={1}>\n <Text>\n You can still download the PostHog integration skills and continue\n with another agent.\n </Text>\n </Box>\n )}\n </ModalOverlay>\n );\n};\n","import { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\n\ninterface DoctorIntroScreenProps {\n store: WizardStore;\n}\n\nexport const DoctorIntroScreen = ({ store }: DoctorIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n PostHog Doctor\n </Text>\n <Text dimColor>\n Scan your project configuration for issues that may need attention.\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text>The wizard will:</Text>\n <Box paddingLeft={2} flexDirection=\"column\">\n <Text>{Icons.bullet} Sign you in to PostHog</Text>\n <Text>\n {Icons.bullet} Fetch active health issues for your project\n </Text>\n <Text>\n {Icons.bullet} Show you what needs to be resolved, with docs links\n </Text>\n </Box>\n </Box>\n\n <PickerMenu\n options={[\n { label: 'Continue', value: 'continue' },\n { label: 'Cancel', value: 'cancel' },\n ]}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else {\n store.completeSetup();\n }\n }}\n />\n </Box>\n );\n};\n","import { Box, Text } from 'ink';\nimport { useEffect, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { LoadingBox, PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport {\n fetchHealthIssues,\n type HealthIssue,\n} from '@lib/programs/posthog-doctor/index';\nimport { OutroKind } from '@lib/wizard-session';\nimport { ApiError } from '@lib/api';\nimport { POSTHOG_DOCS_URL } from '@lib/constants';\nimport { IssueTable, SEVERITY_LABEL, SEVERITY_ORDER } from './IssueTable.js';\n\ninterface DoctorReportScreenProps {\n store: WizardStore;\n}\n\ntype FetchState =\n | { kind: 'loading' }\n | { kind: 'ready'; issues: HealthIssue[] }\n | { kind: 'error'; message: string };\n\nexport const DoctorReportScreen = ({ store }: DoctorReportScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { credentials } = store.session;\n const accessToken = credentials?.accessToken;\n const apiHost = credentials?.host.apiHost;\n const projectId = credentials?.projectId;\n\n const [state, setState] = useState<FetchState>({ kind: 'loading' });\n\n useEffect(() => {\n if (!accessToken || !apiHost || projectId == null) return;\n let cancelled = false;\n void (async () => {\n try {\n const issues = await fetchHealthIssues(accessToken, apiHost, projectId);\n if (!cancelled) {\n setState({ kind: 'ready', issues });\n }\n } catch (err) {\n if (!cancelled) {\n const message =\n err instanceof ApiError && err.statusCode === 401\n ? 'Your PostHog session has expired. Re-run the wizard to sign in again.'\n : err instanceof Error\n ? err.message\n : String(err);\n setState({ kind: 'error', message });\n }\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [accessToken, apiHost, projectId]);\n\n if (!credentials) {\n return <LoadingBox message=\"Waiting for authentication...\" />;\n }\n\n if (state.kind === 'loading') {\n return (\n <Box flexDirection=\"column\">\n <Header\n host={credentials.host.apiHost}\n projectId={credentials.projectId}\n />\n <LoadingBox message=\"Fetching health issues...\" />\n </Box>\n );\n }\n\n const healthUrl = `${credentials.host.appHost}/project/${credentials.projectId}/health`;\n\n if (state.kind === 'error') {\n return (\n <Box flexDirection=\"column\">\n <Header\n host={credentials.host.apiHost}\n projectId={credentials.projectId}\n />\n <Box flexDirection=\"column\" marginY={1}>\n <Text color={Colors.error} bold>\n {Icons.squareFilled} Failed to fetch health issues\n </Text>\n <Text dimColor>{state.message}</Text>\n </Box>\n <PickerMenu\n options={[{ label: 'Continue', value: 'continue' }]}\n onSelect={() => {\n store.setOutroData({\n kind: OutroKind.Error,\n message: 'Failed to fetch health issues',\n body: state.message,\n docsUrl: POSTHOG_DOCS_URL,\n });\n }}\n />\n </Box>\n );\n }\n\n const { issues } = state;\n\n if (issues.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Header\n host={credentials.host.apiHost}\n projectId={credentials.projectId}\n />\n <Box marginY={1}>\n <Text color={Colors.success} bold>\n {Icons.check} No active issues — you're all set!\n </Text>\n </Box>\n <PickerMenu\n options={[{ label: 'Continue', value: 'continue' }]}\n onSelect={() => {\n store.setOutroData({\n kind: OutroKind.Success,\n message: 'No active issues — your project looks healthy.',\n docsUrl: POSTHOG_DOCS_URL,\n continueUrl: healthUrl,\n });\n }}\n />\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Header\n host={credentials.host.apiHost}\n projectId={credentials.projectId}\n />\n <Box marginTop={1}>\n <Text>{formatSummaryLine(issues)}</Text>\n </Box>\n\n <Box flexDirection=\"column\" marginBottom={1}>\n <IssueTable issues={issues} />\n </Box>\n\n <PickerMenu\n options={[{ label: 'Continue', value: 'continue' }]}\n onSelect={() => {\n store.setOutroData({\n kind: OutroKind.Success,\n message: `Found ${issues.length} active issue${\n issues.length === 1 ? '' : 's'\n }.`,\n body: 'Open the dashboard in PostHog to dismiss or resolve issues.',\n docsUrl: POSTHOG_DOCS_URL,\n continueUrl: healthUrl,\n });\n }}\n />\n </Box>\n );\n};\n\nconst Header = ({ host, projectId }: { host: string; projectId: number }) => (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n PostHog Doctor Report\n </Text>\n <Text dimColor>\n Project {projectId} {Icons.bullet} {host}\n </Text>\n </Box>\n);\n\nfunction formatSummaryLine(issues: HealthIssue[]): string {\n const parts: string[] = [];\n for (const sev of SEVERITY_ORDER) {\n const n = issues.filter((i) => i.severity === sev).length;\n if (n > 0) parts.push(`${n} ${SEVERITY_LABEL[sev].toLowerCase()}`);\n }\n const suffix = parts.length > 0 ? `: ${parts.join(', ')}` : '';\n return `${issues.length} active issue${\n issues.length === 1 ? '' : 's'\n }${suffix}`;\n}\n","import { Box, Text } from 'ink';\nimport { useEffect, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { ConfirmationInput, ModalOverlay } from '@ui/tui/primitives/index';\nimport { Icons } from '@ui/tui/styles';\nimport { analytics } from '@utils/analytics';\n\ninterface SettingsOverrideScreenProps {\n store: WizardStore;\n}\n\nexport const SettingsOverrideScreen = ({\n store,\n}: SettingsOverrideScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [feedback, setFeedback] = useState<string | null>(null);\n const conflicts = store.session.settingsConflicts?.filter((c) => c.writable);\n\n const hasConflicts = Boolean(conflicts && conflicts.length > 0);\n useEffect(() => {\n if (hasConflicts) {\n analytics.wizardCapture('settings conflict shown', { kind: 'override' });\n }\n }, [hasConflicts]);\n\n if (!conflicts || conflicts.length === 0) {\n return null;\n }\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Settings conflict`}\n width={64}\n feedback={feedback ? `${Icons.warning} ${feedback}` : null}\n footer={\n <ConfirmationInput\n message=\"Back up to .wizard-backup and continue?\"\n confirmLabel=\"Backup & continue [Enter]\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => {\n analytics.wizardCapture('settings conflict accepted', {\n kind: 'override',\n });\n const ok = store.backupAndFixSettingsOverride();\n if (!ok) {\n setFeedback('Could not back up the settings file.');\n }\n }}\n onCancel={() => process.exit(1)}\n />\n }\n >\n {conflicts.map((conflict) => (\n <Box key={conflict.path} flexDirection=\"column\" marginBottom={1}>\n <Text>\n Your settings file at <Text bold>{conflict.path}</Text> sets:\n </Text>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {conflict.keys.map((key) => (\n <Text key={key}>\n {Icons.bullet}{' '}\n <Text color=\"yellow\" bold>\n {key}\n </Text>\n </Text>\n ))}\n </Box>\n </Box>\n ))}\n <Text dimColor>\n These settings override credentials and prevent the Wizard from reaching\n the PostHog LLM Gateway. We can back up the file and continue.\n </Text>\n </ModalOverlay>\n );\n};\n","/**\n * ManagedSettingsScreen — Modal for read-only settings conflicts that block\n * the Wizard from reaching the PostHog LLM Gateway: org-managed settings, the\n * user's global `~/.claude` config, and gitignored project-local overrides.\n *\n * Unlike SettingsOverrideScreen, the wizard cannot safely back up or remove\n * these files for the user, so it names the exact file and key and asks the\n * user to fix it and re-run. Managed (root-owned) files need an IT admin; the\n * rest the user can edit themselves.\n */\n\nimport { Box, Text } from 'ink';\nimport { useEffect, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { ConfirmationInput, ModalOverlay } from '@ui/tui/primitives/index';\nimport { Icons } from '@ui/tui/styles';\nimport type { SettingsConflict } from '@lib/agent/claude-settings';\nimport { analytics } from '@utils/analytics';\n\nfunction sourceLabel(source: SettingsConflict['source']): string {\n switch (source) {\n case 'managed':\n return 'Organization-managed settings';\n case 'user':\n return 'Your global Claude Code settings';\n case 'project-local':\n return 'Project-local settings';\n default:\n return source;\n }\n}\n\ninterface ManagedSettingsScreenProps {\n store: WizardStore;\n}\n\nexport const ManagedSettingsScreen = ({\n store,\n}: ManagedSettingsScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const conflicts = store.session.settingsConflicts;\n const readOnlyConflicts = conflicts?.filter((c) => !c.writable);\n\n const hasManaged = Boolean(\n readOnlyConflicts?.some((c) => c.source === 'managed'),\n );\n const hasReadOnly = Boolean(\n readOnlyConflicts && readOnlyConflicts.length > 0,\n );\n useEffect(() => {\n // Read-only conflict — nothing to accept, so impression only.\n if (hasReadOnly) {\n analytics.wizardCapture('settings conflict shown', {\n kind: 'managed',\n has_managed: hasManaged,\n });\n }\n }, [hasReadOnly, hasManaged]);\n\n if (!readOnlyConflicts || readOnlyConflicts.length === 0) {\n return null;\n }\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Settings conflict`}\n width={72}\n footer={\n <ConfirmationInput\n message=\"Fix the file(s) above, then re-run the Wizard.\"\n confirmLabel=\"\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => process.exit(1)}\n onCancel={() => process.exit(1)}\n />\n }\n >\n <Text dimColor>\n These Claude Code settings override credentials and prevent the Wizard\n from reaching the PostHog LLM Gateway.\n </Text>\n {readOnlyConflicts.map((conflict) => (\n <Box key={conflict.path} flexDirection=\"column\" marginTop={1}>\n <Text bold>{sourceLabel(conflict.source)}</Text>\n <Text dimColor>{conflict.path}</Text>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {conflict.keys.map((key) => (\n <Text key={key}>\n {Icons.bullet}{' '}\n <Text color=\"yellow\" bold>\n {key}\n </Text>\n </Text>\n ))}\n </Box>\n </Box>\n ))}\n <Box marginTop={1}>\n <Text dimColor>\n {hasManaged\n ? 'Remove these keys (or run \"claude auth logout\"). Managed files are root-owned — ask your IT administrator.'\n : 'Remove these keys, or run \"claude auth logout\", then re-run the Wizard.'}\n </Text>\n </Box>\n </ModalOverlay>\n );\n};\n","/**\n * PortConflictScreen — Modal when all OAuth port candidates are occupied.\n *\n * Shows every port the wizard tried and asks the user to free them manually.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { OAUTH_PORTS } from '@lib/constants';\nimport { ConfirmationInput, ModalOverlay } from '@ui/tui/primitives/index';\n\ninterface PortConflictScreenProps {\n store: WizardStore;\n}\n\nexport const PortConflictScreen = ({ store }: PortConflictScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const processInfo = store.session.portConflictProcess;\n\n if (!processInfo) return null;\n\n return (\n <ModalOverlay\n borderColor=\"#DC9300\"\n title=\"OAuth ports in use\"\n width={72}\n footer={\n <ConfirmationInput\n message=\"Retry after freeing ports?\"\n confirmLabel=\"Retry [Enter]\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => store.resolvePortConflict()}\n onCancel={() => process.exit(1)}\n />\n }\n >\n <Text>\n The wizard needs a local port for OAuth. We tried these ports which are\n all in use:\n </Text>\n <Box flexDirection=\"column\" marginY={1} paddingLeft={2} gap={0}>\n {OAUTH_PORTS.map((port) => (\n <Text key={port}>\n <Text dimColor>Port </Text>\n <Text bold>{port}</Text>\n </Text>\n ))}\n </Box>\n <Text dimColor>Please free one of these ports and retry.</Text>\n </ModalOverlay>\n );\n};\n","/**\n * TaskNoticeScreen — Modal shown before an optional step runs.\n *\n * Some steps stop to ask the user for something. This tells them so before the\n * step starts, and lets them decline it. The copy comes from the program that\n * owns the step; this screen only renders what it is given.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { Colors } from '@ui/tui/styles';\nimport { ConfirmationInput, ModalOverlay } from '@ui/tui/primitives/index';\n\ninterface TaskNoticeScreenProps {\n store: WizardStore;\n}\n\nexport const TaskNoticeScreen = ({ store }: TaskNoticeScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const notice = store.session.taskNotice;\n if (!notice) return null;\n\n return (\n <ModalOverlay\n borderColor={Colors.primary}\n title={notice.title}\n width={76}\n footer={\n <ConfirmationInput\n message={notice.prompt}\n confirmLabel={notice.confirmLabel}\n cancelLabel={notice.cancelLabel}\n onConfirm={() => store.resolveTaskNotice(true)}\n onCancel={() => store.resolveTaskNotice(false)}\n />\n }\n >\n <Box flexDirection=\"column\" gap={1}>\n {notice.body.map((paragraph) => (\n <Text key={paragraph}>{paragraph}</Text>\n ))}\n </Box>\n {notice.items && notice.items.length > 0 && (\n <Box marginTop={1} paddingLeft={2}>\n <Text bold>{notice.items.join(', ')}</Text>\n </Box>\n )}\n {notice.docsUrl && (\n <Box marginTop={1}>\n <Text dimColor>\n {notice.docsLabel ?? 'Learn more'}: {notice.docsUrl}\n </Text>\n </Box>\n )}\n </ModalOverlay>\n );\n};\n","/**\n * ManualAuthCodeScreen — Paste an OAuth authorization code by hand.\n *\n * Fallback for headless/remote shells where the browser can't reach the\n * wizard's local callback server. Shows the direct authorize URL (the localhost\n * one is unreachable from another machine), then the user pastes either the\n * full callback URL the browser was redirected to\n * (`http://localhost:8239/callback?code=...`) or just the code. On submit we\n * extract the code and resolve the in-flight OAuth flow; bad input shows inline\n * feedback without leaving the screen.\n *\n * Opened from AuthScreen via a keypress; Esc dismisses it.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { TextInput } from '@inkjs/ui';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { extractOAuthCode } from '@utils/oauth';\n\ninterface ManualAuthCodeScreenProps {\n store: WizardStore;\n}\n\nexport const ManualAuthCodeScreen = ({ store }: ManualAuthCodeScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { session } = store;\n const [error, setError] = useState<string | null>(null);\n\n // Esc cancels and returns to the waiting auth screen.\n useInput((_input, key) => {\n if (key.escape) {\n store.dismissManualAuthCode();\n }\n });\n\n const handleSubmit = (value: string): void => {\n const code = extractOAuthCode(value);\n if (!code) {\n setError(\n \"Couldn't find a code in that input. Paste the full callback URL or just the code.\",\n );\n return;\n }\n store.submitManualAuthCode(code);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box marginBottom={1}>\n <Text bold color={Colors.accent}>\n {Icons.diamond} Paste authorization code\n </Text>\n </Box>\n\n {session.authorizeUrl && (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text dimColor>\n On a remote/headless machine the local login link won't open. Open\n this URL in a browser on any machine to authorize:\n </Text>\n {/* No border + flexShrink={0}: Ink won't hard-wrap the URL, so it\n stays one continuous string the terminal soft-wraps — copies clean\n instead of being chopped across bordered, indented rows. */}\n <Box flexShrink={0} marginTop={1}>\n <Text color=\"cyan\">{session.authorizeUrl}</Text>\n </Box>\n </Box>\n )}\n\n <Text>\n After authorizing, paste the callback URL it lands on — or just the code\n from it — here:\n </Text>\n <Box marginTop={1} width=\"100%\">\n <TextInput\n placeholder=\"http://localhost:8239/callback?code=… or the code\"\n onSubmit={handleSubmit}\n />\n </Box>\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"yellow\">{error}</Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text>\n <Text color={Colors.accent}>ENTER</Text>\n <Text dimColor> submit</Text>\n <Text dimColor> · </Text>\n <Text color={Colors.accent}>ESC</Text>\n <Text dimColor> cancel</Text>\n </Text>\n </Box>\n </Box>\n );\n};\n","/**\n * PrivacyPanel — Shared disclosure component.\n *\n * Single source of truth for the wizard's privacy disclosure, rendered\n * identically from the intro screen (the `PRIVACY_PANEL_LABEL` menu option)\n * and as an overlay from the auth screen ([I] keystroke).\n *\n * Must fit in a default-sized macOS Terminal (~24 rows). Two condensed\n * paragraphs carry the top-level disclosure; the link footer follows.\n * Users who want the full legal text follow the Terms / Privacy URLs to\n * their browser.\n *\n * The scan paragraph is opt-in per caller. It ends by pointing at a control,\n * so it may only render on a screen that puts one below the panel — three of\n * the four callers show `Back` and nothing else, and would be promising a\n * choice that is not there.\n */\n\nimport { useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport {\n POSTHOG_ORG_AI_SETTINGS_URL,\n POSTHOG_PRIVACY_URL,\n POSTHOG_TERMS_URL,\n} from '@lib/constants';\nimport { analytics } from '@utils/analytics';\n\n/**\n * The panel's name everywhere it is referenced: intro menu, screen titles, and\n * the auth screen's [I] hint. One constant so the five spellings this replaced\n * cannot come back.\n */\nexport const PRIVACY_PANEL_LABEL = 'Privacy & data';\n\ninterface PrivacyPanelProps {\n /**\n * True only on a screen that renders the sharing choice below the panel.\n * Gates the scan paragraph, whose last sentence sends the reader to a\n * control that exists on one screen.\n */\n canOptOut?: boolean;\n}\n\nexport const PrivacyPanel = ({ canOptOut = false }: PrivacyPanelProps = {}) => {\n // Rendered from the intro menu and the auth-screen [I] overlay; either way,\n // count the impression once per mount.\n useEffect(() => {\n analytics.wizardCapture('privacy panel shown');\n }, []);\n\n return (\n <Box flexDirection=\"column\" width={64} flexShrink={0}>\n <Text>\n We use Anthropic and OpenAI models via the PostHog LLM gateway to read\n your source files as AI context. .env* file contents, secrets, and\n anything matched by the security scanner stay on your machine.\n </Text>\n\n <Box marginTop={1}>\n <Text>\n To use the wizard, AI features must be enabled in your organization's\n settings.\n </Text>\n </Box>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>\n Terms: <Text color=\"cyan\">{POSTHOG_TERMS_URL}</Text>\n </Text>\n <Text>\n Privacy: <Text color=\"cyan\">{POSTHOG_PRIVACY_URL}</Text>\n </Text>\n <Text>\n AI settings: <Text color=\"cyan\">{POSTHOG_ORG_AI_SETTINGS_URL}</Text>\n </Text>\n </Box>\n\n {canOptOut && (\n <Box marginTop={1}>\n <Text>\n We also read dependency files and .env variable names to discover\n tools we can connect to and integrate with. We share that list with\n PostHog to suggest features. You can opt out of sharing below.\n </Text>\n </Box>\n )}\n </Box>\n );\n};\n","/**\n * IntroScreenLayout ��� Shared visual shell for all program intro screens.\n *\n * Purely presentational — no store subscription. Parent components own\n * the store subscription and pass derived data as props.\n *\n * Slots:\n * body — free-form content below the title bar (copy, spinners, pickers, etc.)\n * children — between detection rows and menu (extra info, warnings)\n * errorView — replaces the entire body for fatal error states\n */\n\nimport path from 'path';\nimport { Box, Text } from 'ink';\nimport { useState, type ReactNode } from 'react';\nimport { PickerMenu, type PickerOption } from '@ui/tui/primitives/index';\nimport {\n PrivacyPanel,\n PRIVACY_PANEL_LABEL,\n} from '@ui/tui/components/PrivacyPanel';\n\nexport interface DetectionRow {\n label: string;\n value: string;\n suffix?: string;\n}\n\ninterface IntroScreenLayoutProps {\n /** Absolute path to the project directory */\n installDir: string;\n\n /** Title text after the colored blocks, e.g. \"PostHog Wizard 🦔\" */\n title?: string;\n\n /** Show the subtitle below the title. Default true. */\n showSubtitle?: boolean;\n\n /**\n * Custom subtitle content, rendered in place of the default\n * \"We'll use AI… / .env*…\" lines when `showSubtitle` is true. Pass the\n * inner <Text> lines — the layout owns the centered, top-margined\n * wrapper. Defaults to the generic subtitle when omitted.\n */\n subtitle?: ReactNode;\n\n /** Free-form content below the title (copy, spinners, pickers, notices) */\n body?: ReactNode;\n\n /** Show the detection block (Directory, detection rows, Program, Skill). Default true. */\n showDetection?: boolean;\n\n /** Extra detection row items rendered as \"Label ✔ value suffix\" */\n detectionRows?: DetectionRow[];\n\n /** Content rendered between detection rows and the menu */\n children?: ReactNode;\n\n /**\n * Menu options, forwarded to PickerMenu as-is — so a screen can mark a row\n * `disabled` (navigation skips it, which is how a blank spacer row works) or\n * give it an `icon`. Pass null to hide the menu entirely.\n */\n menuOptions?: PickerOption<string>[] | null;\n\n /**\n * Menu alignment. 'center' (default) matches the wizard's standard\n * intro menu. 'left' is for views like the privacy panel where the\n * menu should align with the panel content rather than viewport center.\n */\n menuAlign?: 'center' | 'left';\n\n /**\n * Adds the disclosure row to the menu and owns the view behind it, so every\n * program intro offers it at the top level rather than buried under More\n * info. Set false on screens that are not a program intro — the auth\n * overlay renders the panel itself and would otherwise nest inside itself.\n */\n showPrivacy?: boolean;\n\n /**\n * Rows shown above Back on the disclosure view, for a program that lets the\n * user act on what the panel describes. Their selections reach `onSelect`\n * like any other. Passing them also un-gates the panel's scan paragraph,\n * which points the reader at exactly these rows.\n */\n privacyOptions?: PickerOption<string>[];\n\n /** Called when the user picks a menu option */\n onSelect?: (value: string) => void;\n\n /** Program label shown at the bottom */\n programLabel?: string | null;\n\n /** Skill ID shown at the bottom */\n skillId?: string | null;\n\n /** Replaces the entire body (topContent + rows + children + menu) for fatal error views */\n errorView?: ReactNode;\n}\n\nconst WizardTitle = ({ title }: { title: string }) => (\n <Text bold>\n <Text color=\"#1D4AFF\">{'\\u2588'}</Text>\n <Text color=\"#F54E00\">{'\\u2588'}</Text>\n <Text color=\"#F9BD2B\">{'\\u2588'}</Text> {title}\n </Text>\n);\n\n/** Generic subtitle shown when a screen doesn't supply its own. */\nconst DEFAULT_SUBTITLE = (\n <>\n <Text dimColor>\n We'll use AI to analyze your project and complete work.\n </Text>\n <Text dimColor>.env* file contents will not leave your machine.</Text>\n </>\n);\n\n/** Default menu when a screen passes none. */\nconst DEFAULT_MENU: PickerOption<string>[] = [\n { label: 'Continue', value: 'continue' },\n { label: 'Cancel', value: 'cancel' },\n];\n\n/**\n * The menu for the current view. The disclosure row is appended here rather\n * than left to each screen: ten intro screens would otherwise carry the same\n * row, view and back handler, which is how this panel came to answer to five\n * different names and to sit two levels deep on the one screen that had it.\n *\n * Pure and exported so the guarantee is testable without a renderer.\n */\nexport function buildIntroMenu({\n menuOptions,\n showPrivacy = true,\n showingPrivacy = false,\n privacyOptions,\n}: {\n menuOptions?: PickerOption<string>[] | null;\n showPrivacy?: boolean;\n showingPrivacy?: boolean;\n privacyOptions?: PickerOption<string>[];\n}): PickerOption<string>[] | null {\n if (showingPrivacy) {\n // Always supplied here, so a program cannot strand the user by omitting\n // it. A blank glyph keeps its label on the same column as rows above that\n // carry one.\n const back = {\n label: 'Back',\n value: 'privacy-back',\n ...(privacyOptions?.some((o) => o.icon) ? { icon: { glyph: ' ' } } : {}),\n };\n return [...(privacyOptions ?? []), back];\n }\n\n const base = menuOptions === undefined ? DEFAULT_MENU : menuOptions;\n // A screen with no menu at all (a fatal state) gains nothing to select.\n if (base === null || !showPrivacy) return base;\n\n const row = { label: PRIVACY_PANEL_LABEL, value: 'privacy' };\n // Above a trailing Cancel: leaving the wizard stays the last thing offered.\n const insertAt =\n base.at(-1)?.value === 'cancel' ? base.length - 1 : base.length;\n return [...base.slice(0, insertAt), row, ...base.slice(insertAt)];\n}\n\nexport const IntroScreenLayout = ({\n installDir,\n title = 'PostHog Wizard 🦔',\n showSubtitle = true,\n subtitle,\n body,\n showDetection = true,\n detectionRows,\n children,\n menuOptions,\n menuAlign = 'center',\n showPrivacy = true,\n privacyOptions,\n onSelect,\n programLabel,\n skillId,\n errorView,\n}: IntroScreenLayoutProps) => {\n const [showingPrivacy, setShowingPrivacy] = useState(false);\n\n const resolvedMenuOptions = buildIntroMenu({\n menuOptions,\n showPrivacy,\n showingPrivacy,\n privacyOptions,\n });\n\n const handleSelect = (value: string) => {\n if (value === 'privacy') return setShowingPrivacy(true);\n if (value === 'privacy-back') return setShowingPrivacy(false);\n onSelect?.(value);\n };\n\n if (errorView) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Box flexDirection=\"column\" alignItems=\"center\" marginBottom={1}>\n <WizardTitle title={title} />\n </Box>\n {errorView}\n </Box>\n );\n }\n\n return (\n <>\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Box flexDirection=\"column\" alignItems=\"center\">\n <WizardTitle title={showingPrivacy ? PRIVACY_PANEL_LABEL : title} />\n\n {showSubtitle && !showingPrivacy && (\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n {subtitle ?? DEFAULT_SUBTITLE}\n </Box>\n )}\n\n {showingPrivacy ? (\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n {/* The paragraph ends by pointing below, so it only renders\n where this screen actually put a choice there. */}\n <PrivacyPanel canOptOut={privacyOptions !== undefined} />\n </Box>\n ) : (\n body && (\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n {body}\n </Box>\n )\n )}\n </Box>\n\n {!showingPrivacy && children}\n\n {showDetection && !showingPrivacy && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n <Text>\n Directory <Text color=\"green\">{'\\u2714'}</Text>{' '}\n </Text>\n <Text>\n {'/'}\n {path.basename(installDir)}\n </Text>\n </Text>\n\n {detectionRows?.map((row) => (\n <Text key={row.label}>\n <Text>\n {row.label} <Text color=\"green\">{'\\u2714'}</Text>{' '}\n </Text>\n <Text>\n {row.value}\n {row.suffix ? ` ${row.suffix}` : ''}\n </Text>\n </Text>\n ))}\n\n {programLabel && (\n <Text>\n Program{' '}\n <Text color=\"green\">{'\\u2714'}</Text> {programLabel}\n </Text>\n )}\n\n {programLabel === 'agent-skill' && skillId && (\n <Text>\n Skill{' '}\n <Text color=\"green\">{'\\u2714'}</Text> {skillId}\n </Text>\n )}\n </Box>\n )}\n\n <Box width={menuAlign === 'left' ? 64 : 24} marginTop={1}>\n {resolvedMenuOptions && onSelect && (\n <Box\n justifyContent={menuAlign === 'left' ? 'flex-start' : 'center'}\n >\n <PickerMenu\n key={resolvedMenuOptions.map((o) => o.value).join(',')}\n options={resolvedMenuOptions}\n onSelect={(value) => {\n const choice = Array.isArray(value) ? value[0] : value;\n handleSelect(choice);\n }}\n />\n </Box>\n )}\n </Box>\n </Box>\n </>\n );\n};\n","/**\n * PostHogIntegrationIntroScreen — Intro screen for the core PostHog integration.\n *\n * Composes IntroScreenLayout with framework-detection-specific state:\n * 1. Detecting: spinner while detection runs\n * 2. Detection failed: framework picker\n * 3. Unsupported version: upgrade prompt\n * 4. Detection succeeded: continue/change-framework/cancel\n */\n\nimport { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { Integration } from '@lib/constants';\nimport {\n PickerMenu,\n LoadingBox,\n type PickerOption,\n} from '@ui/tui/primitives/index';\nimport { IntroScreenLayout, type DetectionRow } from './IntroScreenLayout.js';\nimport { SkillSourceInfo, useSkillEntry } from './SkillSourceInfo.js';\nimport { ScanConsent } from '@lib/wizard-session';\nimport { Icons } from '@ui/tui/styles';\nimport { analytics } from '@utils/analytics';\nimport { PRIVACY_PANEL_LABEL } from '@ui/tui/components/PrivacyPanel';\n\ntype View = 'default' | 'more-info';\n\n/**\n * Replaces IntroScreenLayout's DEFAULT_SUBTITLE for this screen only. The\n * shared default (\".env* file contents will not leave your machine\") is true\n * of values and false of variable names, which this screen reads and reports.\n * Two lines carry the fact and name the screen that holds the detail, so the\n * disclosure reaches people who never open it.\n */\nconst SUBTITLE = (\n <>\n <Text dimColor>\n We'll use AI to analyze your project and complete work.\n </Text>\n <Text dimColor>Review what data is shared in \"{PRIVACY_PANEL_LABEL}.\"</Text>\n <Text dimColor>.env* values stay on your machine.</Text>\n </>\n);\n\n/**\n * Exported so a test can measure every label against the menu's column.\n * `Privacy & data` is not here: IntroScreenLayout appends it to every intro\n * menu, so no screen carries its own copy.\n */\nexport const CONTINUE_MENU_OPTIONS: { label: string; value: string }[] = [\n { label: 'Continue', value: 'continue' },\n { label: 'Change framework', value: 'framework' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n];\n\n/**\n * A blank, unselectable row. Navigation skips disabled options, so this is a\n * margin the menu can hold rather than one the layout has to special-case.\n */\nconst MENU_SPACER: PickerOption<string> = {\n label: '',\n value: 'spacer',\n disabled: true,\n};\n\n/**\n * The sharing choice, as two explicit rows rather than one toggle. A toggle\n * label has to describe either the current state or the next action, and a\n * reader cannot tell which; two rows with the filled diamond on the live one\n * say both at once. The trailing spacer separates them from the Back that\n * IntroScreenLayout appends, since leaving the screen is a different kind of\n * act from changing something on it.\n */\nexport function sharingOptions(sharing: boolean): PickerOption<string>[] {\n const mark = (on: boolean) => ({\n glyph: on ? Icons.diamond : Icons.diamondOpen,\n });\n return [\n { label: 'Share tools', value: 'share', icon: mark(sharing) },\n { label: \"Don't share tools\", value: 'no-share', icon: mark(!sharing) },\n MENU_SPACER,\n ];\n}\n\n/** Framework picker shown when auto-detection fails. */\nconst FrameworkPicker = ({\n store,\n onComplete,\n}: {\n store: WizardStore;\n onComplete?: () => void;\n}) => {\n const options = Object.values(Integration).map((value) => ({\n label: value,\n value,\n }));\n\n return (\n <PickerMenu<Integration>\n centered\n columns={2}\n message=\"Select your framework\"\n options={options}\n onSelect={(value) => {\n const integration = Array.isArray(value) ? value[0] : value;\n void import('@lib/registry').then(({ FRAMEWORK_REGISTRY }) => {\n const config = FRAMEWORK_REGISTRY[integration];\n store.setFrameworkConfig(integration, config);\n store.setDetectedFramework(config.metadata.name);\n onComplete?.();\n });\n }}\n />\n );\n};\n\ninterface PostHogIntegrationIntroScreenProps {\n store: WizardStore;\n}\n\nexport const PostHogIntegrationIntroScreen = ({\n store,\n}: PostHogIntegrationIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [pickingFramework, setPickingFramework] = useState(false);\n const [manuallySelected, setManuallySelected] = useState(false);\n const [view, setView] = useState<View>('default');\n\n const { session } = store;\n const sharing = session.scanConsent !== ScanConsent.Declined;\n const config = session.frameworkConfig;\n const frameworkLabel =\n session.detectedFrameworkLabel ?? config?.metadata.name;\n const { skillEntry, fetchFailed } = useSkillEntry(session.skillId);\n const detecting = !session.detectionComplete;\n const needsFrameworkPick =\n session.detectionComplete && !session.frameworkConfig;\n const unsupported = session.unsupportedVersion;\n const showContinue =\n session.frameworkConfig !== null &&\n !detecting &&\n !pickingFramework &&\n view === 'default' &&\n !unsupported;\n\n // ── Title ──────────────────────────────────────────────────────────\n\n const title = detecting ? 'PostHog Wizard starting up' : 'PostHog Wizard 🦔';\n\n // ── Description ────────────────────────────────────────────────────\n\n let body: ReactNode = null;\n\n if (detecting) {\n body = (\n <Box marginY={1}>\n <LoadingBox message=\"Detecting project framework...\" />\n </Box>\n );\n } else if (needsFrameworkPick && !pickingFramework) {\n body = (\n <>\n <Box marginY={1}>\n <Text dimColor>Could not auto-detect your framework.</Text>\n </Box>\n <FrameworkPicker\n store={store}\n onComplete={() => setPickingFramework(false)}\n />\n </>\n );\n } else if (pickingFramework) {\n body = (\n <FrameworkPicker\n store={store}\n onComplete={() => setPickingFramework(false)}\n />\n );\n } else if (view === 'more-info') {\n body = (\n <Box flexDirection=\"column\" width={64} flexShrink={0}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.programLabel}\n </Text>{' '}\n program installs the PostHog SDKs, instruments event tracking, and\n integrates the following dev tools for your application:\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={4}>\n <Text>{`•`} Product Analytics</Text>\n <Text>{`•`} Web Analytics</Text>\n <Text>{`•`} Session Replay</Text>\n <Text>{`•`} Error Tracking</Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>If you prefer your own AI setup, download the skill:</Text>\n <Box marginTop={1}>\n <SkillSourceInfo\n skillId={session.skillId}\n skillEntry={skillEntry}\n fetchFailed={fetchFailed}\n />\n </Box>\n </Box>\n </Box>\n );\n } else if (showContinue) {\n body = (\n <Box>\n <Text>Let's do two hours of work in eight minutes.</Text>\n </Box>\n );\n }\n\n // ── Detection rows ─────────────────────────────────────────────────\n\n const detectionRows: DetectionRow[] = [];\n if (frameworkLabel) {\n const suffixParts: string[] = [];\n if (!manuallySelected) suffixParts.push('(detected)');\n // Dead path today — every framework went GA. Kept for re-activation\n // when the next beta framework lands (set `beta: true` on its config).\n if (config?.metadata.beta) suffixParts.push('[BETA]');\n\n detectionRows.push({\n label: 'Framework',\n value: frameworkLabel,\n suffix: suffixParts.join(' ') || undefined,\n });\n }\n\n // ── Children (between rows and menu) ───────────────────────────────\n\n let bodyChildren: ReactNode = null;\n\n if (config?.metadata.preRunNotice) {\n bodyChildren = <Text color=\"yellow\">{config.metadata.preRunNotice}</Text>;\n }\n\n if (unsupported) {\n bodyChildren = (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"#DC9300\">\n Version {unsupported.current} is not supported by the wizard. Please\n upgrade to {unsupported.minimum} or later.\n </Text>\n <Text dimColor>Manual setup guide: {unsupported.docsUrl}</Text>\n <Box marginTop={1}>\n <Text dimColor>\n Did we get this wrong? You can also select another framework.\n </Text>\n </Box>\n <PickerMenu\n options={[\n { label: 'Select another framework', value: 'framework' },\n { label: 'Exit', value: 'exit' },\n ]}\n onSelect={(value) => {\n const choice = Array.isArray(value) ? value[0] : value;\n if (choice === 'framework') {\n setPickingFramework(true);\n setManuallySelected(true);\n } else {\n process.exit(0);\n }\n }}\n />\n </Box>\n );\n }\n\n // ── Menu ───────────────────────────────────────────────────────────\n\n let menuOptions: PickerOption<string>[] | null = null;\n\n if (view === 'more-info') {\n // No route to the panel from here: it has its own top-level menu item.\n menuOptions = [{ label: 'Back', value: 'back' }];\n } else if (showContinue) {\n menuOptions = CONTINUE_MENU_OPTIONS;\n }\n\n const handleSelect = (value: string) => {\n analytics.wizardCapture('intro menu selected', { value, view });\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'framework') {\n setPickingFramework(true);\n setManuallySelected(true);\n } else if (value === 'more-info') {\n setView('more-info');\n } else if (value === 'back') {\n setView('default');\n } else if (value === 'share') {\n store.grantSharing();\n } else if (value === 'no-share') {\n store.declineSharing();\n } else if (value === 'continue') {\n // Sharing is on by default, so consent nobody touched resolves to granted\n // here. A choice already made in the panel stands.\n if (session.scanConsent === ScanConsent.Undecided) store.grantSharing();\n store.completeSetup();\n }\n };\n\n // ── Render ─────────────────────────────────────────────────────────\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n title={title}\n showSubtitle={view === 'default'}\n subtitle={SUBTITLE}\n body={body}\n showDetection={showContinue}\n detectionRows={detectionRows}\n menuOptions={unsupported ? null : menuOptions}\n menuAlign=\"center\"\n // The one program whose disclosure view can be acted on.\n privacyOptions={sharingOptions(sharing)}\n onSelect={handleSelect}\n programLabel={session.programLabel}\n skillId={session.skillId}\n >\n {bodyChildren}\n </IntroScreenLayout>\n );\n};\n","/**\n * RevenueIntroScreen — Welcome screen for the revenue analytics flow.\n *\n * Composes IntroScreenLayout with SDK-detection-specific state:\n * - Detection succeeded: shows detected PostHog + Stripe SDKs, continue/cancel\n * - Detection failed: shows the error via errorView + exit prompt\n *\n * Reads `frameworkContext.detectError` and `frameworkContext.detectedPosthogSdks`\n * / `detectedStripeSdks` set by detectRevenuePrerequisites().\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { IntroScreenLayout, type DetectionRow } from './IntroScreenLayout.js';\nimport {\n POSTHOG_SDKS,\n STRIPE_SDKS,\n type RevenueDetectError,\n} from '@lib/programs/revenue-analytics/index';\n\ninterface RevenueIntroScreenProps {\n store: WizardStore;\n}\n\nexport const RevenueIntroScreen = ({ store }: RevenueIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n\n const { session } = store;\n const detectError = session.frameworkContext.detectError as\n | RevenueDetectError\n | undefined;\n const detectedPosthogSdks =\n (session.frameworkContext.detectedPosthogSdks as string[] | undefined) ??\n [];\n const detectedStripeSdks =\n (session.frameworkContext.detectedStripeSdks as string[] | undefined) ?? [];\n const detectedPackagePaths =\n (session.frameworkContext.detectedPackagePaths as string[] | undefined) ??\n [];\n\n // ── Detection rows ─────────────────────────────────────────────────\n\n const detectionRows: DetectionRow[] = [];\n if (detectedPosthogSdks.length > 0) {\n detectionRows.push({\n label: 'PostHog SDK',\n value: detectedPosthogSdks.join(', '),\n });\n }\n if (detectedStripeSdks.length > 0) {\n detectionRows.push({\n label: 'Stripe SDK',\n value: detectedStripeSdks.join(', '),\n });\n }\n\n // ── Body ────────────────────────────────────────────────────────────\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56} flexShrink={0}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>.\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.programLabel}\n </Text>{' '}\n program links Stripe customers and purchases to PostHog product data\n and persons. It unlocks insights like:\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={4}>\n <Text>{'\\u2022'} Revenue per user</Text>\n <Text>{'\\u2022'} Lifetime value</Text>\n <Text>{'\\u2022'} MRR / churn tracking</Text>\n </Box>\n </Box>\n ) : (\n <>\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>Let's create revenue analytics with Stripe and PostHog.</Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>Link purchases to product data.</Text>\n </Box>\n </Box>\n\n {detectedPackagePaths.length > 1 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text dimColor>Found in {detectedPackagePaths.length} packages:</Text>\n {detectedPackagePaths.map((p) => (\n <Text key={p} dimColor>\n {' '}\n {'\\u2022'} {p}\n </Text>\n ))}\n </Box>\n )}\n </>\n );\n\n // ── Error view ─────────────────────────────────────────────────────\n\n const errorView = detectError ? (\n <>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"red\" bold>\n {'\\u2718'} Cannot set up revenue analytics\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <DetectErrorBody error={detectError} />\n </Box>\n </Box>\n\n <PickerMenu\n options={[{ label: 'Exit', value: 'exit' }]}\n onSelect={() => process.exit(1)}\n />\n </>\n ) : undefined;\n\n // ── Menu ───────────────────────────────────────────────────────────\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n // ── Render ─────────────────────────────────────────────────────────\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n showSubtitle={!showingMoreInfo}\n body={body}\n showDetection={!showingMoreInfo}\n detectionRows={detectionRows}\n errorView={errorView}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'more-info') {\n setShowingMoreInfo(true);\n } else if (value === 'back') {\n setShowingMoreInfo(false);\n } else {\n store.completeSetup();\n }\n }}\n />\n );\n};\n\nconst DetectErrorBody = ({ error }: { error: RevenueDetectError }) => {\n switch (error.kind) {\n case 'bad-directory': {\n const reasonText = {\n missing: 'does not exist',\n 'not-dir': 'is not a directory',\n unreadable: 'could not be accessed',\n }[error.reason];\n return (\n <>\n <Text>This path {reasonText}:</Text>\n <Text dimColor>\n {' '}\n {error.path}\n </Text>\n </>\n );\n }\n\n case 'no-package-json':\n return (\n <>\n <Text>No package.json found in this directory.</Text>\n <Text dimColor>\n Revenue analytics currently supports Node.js / TypeScript projects.\n </Text>\n <Text dimColor>Run this command from your project root.</Text>\n </>\n );\n\n case 'no-sdks':\n return (\n <>\n <Text>\n Neither PostHog nor Stripe SDKs detected (scanned{' '}\n {error.scannedCount} package.json file\n {error.scannedCount === 1 ? '' : 's'}).\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text>Revenue analytics requires:</Text>\n <Text dimColor>\n {' \\u2022'} A PostHog SDK ({POSTHOG_SDKS.slice(0, 3).join(', ')},\n …)\n </Text>\n <Text dimColor>\n {' \\u2022'} A Stripe SDK ({STRIPE_SDKS.join(', ')})\n </Text>\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n Install Stripe and run <Text bold>npx @posthog/wizard</Text> to\n set up PostHog.\n </Text>\n </Box>\n </>\n );\n\n case 'missing-posthog':\n return (\n <>\n <Text>\n Found Stripe ({error.foundStripe.join(', ')}) but no PostHog SDK.\n </Text>\n <Box marginTop={1}>\n <Text dimColor>\n Run <Text bold>npx @posthog/wizard</Text> first to set up the base\n PostHog integration.\n </Text>\n </Box>\n </>\n );\n\n case 'missing-stripe':\n return (\n <>\n <Text>\n Found PostHog ({error.foundPosthog.join(', ')}) but no Stripe SDK.\n </Text>\n <Text dimColor>\n Revenue analytics currently supports Stripe only.\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>Install one of:</Text>\n {STRIPE_SDKS.map((sdk) => (\n <Text key={sdk} dimColor>\n {' \\u2022'} {sdk}\n </Text>\n ))}\n </Box>\n </>\n );\n }\n};\n","/**\n * WarehouseIntroScreen — Welcome screen for the data warehouse source flow.\n *\n * Composes IntroScreenLayout with detection-specific state:\n * - Detection succeeded: lists detected sources (grouped by creation mode),\n * continue/cancel.\n * - Detection failed: shows the error via errorView + exit prompt.\n *\n * Reads `frameworkContext.detectError` and `frameworkContext.detectedWarehouseSources`\n * set by detectWarehousePrerequisites().\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\nimport {\n getDetectedWarehouseSources,\n type WarehouseDetectError,\n} from '@lib/programs/warehouse-source/index';\n\ninterface WarehouseIntroScreenProps {\n store: WizardStore;\n}\n\nexport const WarehouseIntroScreen = ({ store }: WarehouseIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n\n const { session } = store;\n const detectError = session.frameworkContext.detectError as\n | WarehouseDetectError\n | undefined;\n const detected = getDetectedWarehouseSources(session);\n\n // ── Body ────────────────────────────────────────────────────────────\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56} flexShrink={0}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>.\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.programLabel}\n </Text>{' '}\n program connects your existing data sources to PostHog's data\n warehouse, so you can query them alongside product data.\n </Text>\n </Box>\n </Box>\n ) : (\n <>\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>Let's connect your data to PostHog's data warehouse.</Text>\n </Box>\n\n {detected.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text dimColor>Detected warehouse sources:</Text>\n {detected.map((s) => (\n <Text key={s.kind} dimColor>\n {' •'} {s.label}\n </Text>\n ))}\n </Box>\n )}\n </>\n );\n\n // ── Error view ─────────────────────────────────────────────────────\n\n const errorView = detectError ? (\n <>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"red\" bold>\n {'✘'}{' '}\n {detectError.kind === 'bad-directory'\n ? 'Invalid project directory'\n : 'No data warehouse source detected'}\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <DetectErrorBody error={detectError} />\n </Box>\n </Box>\n\n <PickerMenu\n options={[{ label: 'Exit', value: 'exit' }]}\n onSelect={() => process.exit(0)}\n />\n </>\n ) : undefined;\n\n // ── Menu ───────────────────────────────────────────────────────────\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n // ── Render ─────────────────────────────────────────────────────────\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n showSubtitle={!showingMoreInfo}\n body={body}\n showDetection={!showingMoreInfo}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n errorView={errorView}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'more-info') {\n setShowingMoreInfo(true);\n } else if (value === 'back') {\n setShowingMoreInfo(false);\n } else {\n store.completeSetup();\n }\n }}\n />\n );\n};\n\nconst DetectErrorBody = ({ error }: { error: WarehouseDetectError }) => {\n switch (error.kind) {\n case 'bad-directory': {\n const reasonText = {\n missing: 'does not exist',\n 'not-dir': 'is not a directory',\n unreadable: 'could not be accessed',\n }[error.reason];\n return (\n <>\n <Text>This path {reasonText}:</Text>\n <Text dimColor>\n {' '}\n {error.path}\n </Text>\n </>\n );\n }\n\n case 'no-sources':\n return (\n <>\n <Text>No supported data source was detected in this project.</Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>\n The wizard looks for databases (Postgres, MySQL, MongoDB, …) and\n API-key sources like Stripe in your dependencies and .env keys.\n </Text>\n <Text dimColor>\n Run this command from your project root, or set a source up\n directly at{' '}\n <Text color=\"cyan\">https://posthog.com/docs/data-warehouse</Text>.\n </Text>\n </Box>\n </>\n );\n }\n};\n","import { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\n\ninterface MigrationIntroScreenProps {\n store: WizardStore;\n}\n\nexport const MigrationIntroScreen = ({ store }: MigrationIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { session } = store;\n\n const body = (\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>Let's migrate this project to PostHog.</Text>\n </Box>\n );\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n body={body}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={[\n { label: 'Continue', value: 'continue' },\n { label: 'Cancel', value: 'cancel' },\n ]}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else {\n store.completeSetup();\n }\n }}\n />\n );\n};\n","/**\n * SourceMapsIntroScreen — Welcome screen for the source-maps upload flow.\n *\n * Static intro: detection now runs after login (on the source-maps-detect\n * screen), so this screen no longer shows a detected platform. Continue takes\n * the user straight to authentication.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\n\ntype View = 'default' | 'more-info';\n\ninterface SourceMapsIntroScreenProps {\n store: WizardStore;\n}\n\nexport const SourceMapsIntroScreen = ({\n store,\n}: SourceMapsIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [view, setView] = useState<View>('default');\n\n const { session } = store;\n\n const body =\n view === 'more-info' ? (\n <Box flexDirection=\"column\" width={56} flexShrink={0}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>.\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.programLabel}\n </Text>{' '}\n program sets up your project to upload source maps to PostHog, so\n Error Tracking shows production stack traces in your original source\n instead of minified bundles. It will:\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={4}>\n <Text>{'•'} Detect the framework(s) in your repo</Text>\n <Text>{'•'} Download the relevant docs for your stack</Text>\n <Text>{'•'} Wire map generation + upload into your build</Text>\n <Text>{'•'} Wire CI for deploys and offer a local test run</Text>\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n Maps upload to PostHog during the production build and never need to\n be served publicly.\n </Text>\n </Box>\n </Box>\n ) : (\n <Box flexDirection=\"column\" width={60}>\n <Text>\n The Wizard will run an agent to detect your project's framework(s),\n download the relevant docs, and implement source-map uploads for you.\n </Text>\n <Box marginTop={1}>\n <Text>Ready?</Text>\n </Box>\n </Box>\n );\n\n // No privacy row here: IntroScreenLayout appends it to every intro menu.\n const menuOptions =\n view === 'more-info'\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const title = 'PostHog Wizard 🦔';\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n title={title}\n showSubtitle={view === 'default'}\n body={body}\n showDetection={view === 'default'}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'more-info') {\n setView('more-info');\n } else if (value === 'back') {\n setView('default');\n } else {\n store.completeSetup();\n }\n }}\n />\n );\n};\n","/**\n * Source-maps adapter over the generic agentic detector\n * (`@lib/detection/agentic`). The detector itself is product-knowledge-free;\n * this file supplies the source-maps targets (the automatable skill variants),\n * maps the result back to variants, and classifies each project as\n * instrumentable or not. The screen renders the result and the run step\n * instruments the chosen project.\n */\n\nimport { existsSync, readFileSync, readdirSync } from 'fs';\nimport { join } from 'path';\nimport { IGNORED_DIRS, readProjectFile } from '@utils/bounded-fs';\nimport {\n detectProjectsWithAgent,\n coerceAgenticReport,\n type DetectTarget,\n type AgenticDetectionReport,\n type DetectEvent,\n} from '@lib/detection/agentic';\nimport type { WizardSession } from '@lib/wizard-session';\nimport {\n VARIANT_DISPLAY_NAME,\n AUTOMATABLE_VARIANTS,\n MANUAL_SDK_INSTALL,\n RUST_SDK_CRATE,\n GO_SDK_MODULE,\n type SkillVariant,\n} from './detect.js';\n\nexport type { DetectEvent };\n\n/** One project, classified for source-map upload. */\nexport type DetectedProject = {\n /** Path relative to the working directory (\".\" for the repo root). */\n path: string;\n /** Human-readable framework the agent detected (e.g. \"Next.js\"). */\n framework: string;\n /** A supported source-maps variant when it matches one, else null. */\n variant: SkillVariant | null;\n /** Whether a PostHog SDK is already installed in this project. */\n hasPostHog: boolean;\n /** variant != null && hasPostHog — source-map upload can be wired up here. */\n instrumentable: boolean;\n /** Why the project can't be instrumented (only when !instrumentable). */\n reason?: string;\n};\n\nexport type DetectionReport = {\n repoType: 'monorepo' | 'single';\n projects: DetectedProject[];\n};\n\n/**\n * Variant precedence for the agentic picker (most specific first). The detector\n * keeps the EARLIEST matching target. React Native and Flutter both outrank\n * Android and iOS: their repos carry `android/` and `ios/` folders with real\n * Gradle and Xcode manifests inside them, and must not be misclassified as\n * plain native apps. JS ordering mirrors `pickJsVariant` in detect.ts:\n * opinionated frameworks → bundlers → bare React → Node → generic web.\n */\nconst VARIANT_PRECEDENCE: readonly SkillVariant[] = [\n 'react-native',\n 'flutter',\n 'android',\n 'ios',\n 'nextjs',\n 'nuxt',\n 'angular',\n 'vite',\n 'webpack',\n 'rollup',\n 'react',\n 'node',\n // Native binaries: only chosen when no JS target matches the project, but\n // ahead of the generic web fallback so a go.mod / Cargo.toml project\n // resolves to its debug-symbols variant instead of `web`. Deliberate\n // tradeoff for the same-directory mixed case: a Go/Rust project with a\n // tooling-only package.json (common) beats a root-level JS app sharing a\n // directory with go.mod / Cargo.toml (rare — frontends usually live in a\n // subdirectory, which classifies as its own project).\n 'go',\n 'rust',\n 'web',\n];\n\nconst precedenceRank = (v: SkillVariant): number => {\n const i = VARIANT_PRECEDENCE.indexOf(v);\n return i === -1 ? Number.MAX_SAFE_INTEGER : i;\n};\n\n/** Source-map detection targets, ordered by VARIANT_PRECEDENCE. */\nexport const SOURCE_MAPS_TARGETS: DetectTarget[] = [...AUTOMATABLE_VARIANTS]\n .sort((a, b) => precedenceRank(a) - precedenceRank(b))\n .map((v) => ({ id: v, name: VARIANT_DISPLAY_NAME[v] }));\n\n// JS variants co-occur in one package.json (react+vite, node+rollup), so the\n// enumeration's priority winner may override the agent's pick among them.\n// Mobile/native stacks are mutually exclusive and stay pick-wins.\nconst JS_RERANK_VARIANTS: readonly SkillVariant[] = [\n 'nextjs',\n 'nuxt',\n 'angular',\n 'vite',\n 'webpack',\n 'rollup',\n 'react',\n 'node',\n 'web',\n];\n\n/** Comment-stripped substring check for the Rust SDK in one manifest. */\nfunction manifestMentionsSdk(manifestPath: string): boolean {\n const content = readProjectFile(manifestPath);\n return (\n content != null &&\n content.split('\\n').some((line) => {\n const code = line.split('#', 1)[0];\n return code.includes(RUST_SDK_CRATE);\n })\n );\n}\n\n/**\n * A workspace root is often a virtual manifest (`[workspace]` only, no\n * `[dependencies]`) — the SDK then lives in a member crate's manifest, so a\n * miss on the root must fall through to a bounded walk over nested\n * manifests. Depth 3 covers the common `crates/<name>/` layouts.\n */\nfunction anyNestedManifestMentionsSdk(dir: string, depth: number): boolean {\n if (depth > 3) return false;\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return false;\n }\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n if (IGNORED_DIRS.has(entry.name) || entry.name === 'target') continue;\n const child = join(dir, entry.name);\n if (manifestMentionsSdk(join(child, 'Cargo.toml'))) return true;\n if (anyNestedManifestMentionsSdk(child, depth + 1)) return true;\n }\n return false;\n}\n\n/**\n * Checks a project's Cargo manifests for the Rust SDK. The agentic detector\n * reports a single `hasPostHog` boolean for ANY PostHog dependency in the\n * project — for `rust` that could be satisfied by an unrelated JS SDK in the\n * same directory, so the deterministic manifest read is authoritative.\n * Comment-stripped substring matching, not TOML parsing: it still catches\n * renamed (`package = \"posthog-rs\"`) and workspace-inherited deps, while a\n * commented-out dependency no longer counts. Known miss: selecting a\n * workspace MEMBER whose dep is aliased at the workspace root\n * (`posthog.workspace = true` with the `package = \"posthog-rs\"` mapping only\n * in the root manifest, which sits above the member) — accepted; resolving\n * that needs full workspace metadata. Exported for testing.\n */\nexport function rustSdkVerifier(\n installDir: string,\n): (projectPath: string) => boolean {\n return (projectPath) => {\n const dir =\n projectPath === '.' ? installDir : join(installDir, projectPath);\n return (\n manifestMentionsSdk(join(dir, 'Cargo.toml')) ||\n anyNestedManifestMentionsSdk(dir, 0)\n );\n };\n}\n\n/**\n * True when go.mod actively `require`s the SDK — single-line requires and\n * `require ( … )` blocks only, so a `module` declaration, `replace`, or\n * `exclude` mention of the path never counts.\n */\nfunction goModRequiresSdk(content: string): boolean {\n let inBlock: 'require' | 'other' | null = null;\n for (const raw of content.split('\\n')) {\n const code = raw.split('//', 1)[0].trim();\n if (code === '') continue;\n if (inBlock != null) {\n if (code === ')') {\n inBlock = null;\n } else if (inBlock === 'require' && code.includes(GO_SDK_MODULE)) {\n return true;\n }\n continue;\n }\n if (code.endsWith('(')) {\n inBlock = code.startsWith('require') ? 'require' : 'other';\n continue;\n }\n if (code.startsWith('require ') && code.includes(GO_SDK_MODULE)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Checks a project's go.mod for the Go SDK — the same authoritative override\n * as `rustSdkVerifier`, for the same reason. Only `require` directives count;\n * no multi-module walk — unlike Cargo workspaces, a Go module's requirements\n * always live in the selected module's own go.mod. Exported for testing.\n */\nexport function goSdkVerifier(\n installDir: string,\n): (projectPath: string) => boolean {\n return (projectPath) => {\n const dir =\n projectPath === '.' ? installDir : join(installDir, projectPath);\n const content = readProjectFile(join(dir, 'go.mod'));\n return content != null && goModRequiresSdk(content);\n };\n}\n\nfunction isAutomatableVariant(value: string | null): value is SkillVariant {\n return value !== null && AUTOMATABLE_VARIANTS.includes(value as SkillVariant);\n}\n\nexport const FLUTTER_NO_BUILD_TARGET_REASON =\n 'Flutter project has no web, android or ios target — nothing to upload symbols for';\n\nexport const BARE_REACT_NATIVE_REASON =\n 'Bare React Native (without Expo) is not supported — source-map upload needs the Expo build pipeline';\n\n/**\n * Filesystem probes the classifier needs on top of what the agent reports.\n * Injected so `coerceReport` stays testable without touching disk. A missing\n * probe answers `false`, which blocks the variant it guards.\n */\nexport type ProjectProbes = {\n /**\n * Flutter: does the project have at least one platform target the wizard can\n * wire uploads into — web (dart2js source maps), android (R8 mapping files)\n * or ios (dSYMs)?\n */\n hasBuildTarget: (path: string) => boolean;\n /** React Native: is the `expo` package installed in the project? */\n isExpoProject: (path: string) => boolean;\n /**\n * Rust: does the project's Cargo manifest tree carry the posthog-rs crate?\n * Unlike the gate probes above, absence means \"trust the agent's\n * `hasPostHog`\", not `false` — the probe REPLACES the agent's boolean when\n * present, because any unrelated PostHog dependency can satisfy it.\n */\n verifyRustSdk?: (path: string) => boolean;\n /** Go: does the project's go.mod require posthog-go? Same semantics as `verifyRustSdk`. */\n verifyGoSdk?: (path: string) => boolean;\n};\n\nconst NO_PROBES: ProjectProbes = {\n hasBuildTarget: () => false,\n isExpoProject: () => false,\n};\n\n/**\n * True when the Flutter project at `projectPath` has at least one platform\n * target. `flutter create` scaffolds a directory per enabled platform, so their\n * absence means this is a pure Dart package or plugin — it produces no app\n * build, and there is nothing to upload.\n */\nfunction projectHasBuildTarget(\n installDir: string,\n projectPath: string,\n): boolean {\n const root = join(installDir, projectPath);\n return (\n existsSync(join(root, 'web', 'index.html')) ||\n existsSync(join(root, 'android')) ||\n existsSync(join(root, 'ios'))\n );\n}\n\n/** True when the project at `projectPath` has the `expo` package installed. */\nfunction projectHasExpo(installDir: string, projectPath: string): boolean {\n try {\n const pkg = JSON.parse(\n readFileSync(join(installDir, projectPath, 'package.json'), 'utf-8'),\n ) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n return (\n pkg.dependencies?.['expo'] != null ||\n pkg.devDependencies?.['expo'] != null\n );\n } catch {\n return false;\n }\n}\n\n/** Classify one agent-detected project for source-map upload. */\nfunction classifyProject(\n p: AgenticDetectionReport['projects'][number],\n probes: ProjectProbes,\n): DetectedProject {\n // For the native-binary variants the deterministic manifest read overrides\n // the agent's single hasPostHog boolean, which any unrelated PostHog\n // dependency can satisfy.\n const sdkVerifier =\n p.targetId === 'rust'\n ? probes.verifyRustSdk\n : p.targetId === 'go'\n ? probes.verifyGoSdk\n : undefined;\n const hasPostHog = sdkVerifier ? sdkVerifier(p.path) : p.hasPostHog;\n const base = {\n path: p.path,\n framework: p.framework,\n hasPostHog,\n };\n\n // A React Native or Flutter labelled project only counts when it resolved to\n // its own target — the nested Gradle and Xcode manifests inside those repos\n // must not claim android or ios.\n const namesForeignNativePlatform =\n (/\\b(?:react[\\s-]*native|expo)\\b/i.test(p.framework) &&\n p.targetId !== 'react-native') ||\n (/\\bflutter\\b/i.test(p.framework) && p.targetId !== 'flutter');\n if (!isAutomatableVariant(p.targetId) || namesForeignNativePlatform) {\n return {\n ...base,\n variant: null,\n instrumentable: false,\n reason: \"Source-map upload isn't supported for this stack yet\",\n };\n }\n\n // A Flutter package or plugin has no platform directories and never produces\n // an app build, so there are no symbols to upload for it.\n if (p.targetId === 'flutter' && !probes.hasBuildTarget(p.path)) {\n return {\n ...base,\n variant: null,\n instrumentable: false,\n reason: FLUTTER_NO_BUILD_TARGET_REASON,\n };\n }\n\n // Bare React Native (no expo package) is not supported: its Metro pipeline\n // can't inject chunk IDs, so uploads would never resolve.\n if (p.targetId === 'react-native' && !probes.isExpoProject(p.path)) {\n return {\n ...base,\n variant: null,\n instrumentable: false,\n reason: BARE_REACT_NATIVE_REASON,\n };\n }\n\n if (!hasPostHog) {\n // The wizard's default flow can't install the Go/Rust SDKs, so don't\n // point users at it for those stacks.\n const install =\n MANUAL_SDK_INSTALL[p.targetId] ?? 'run `npx @posthog/wizard` first';\n return {\n ...base,\n variant: p.targetId,\n instrumentable: false,\n reason: `No PostHog SDK installed yet — ${install}`,\n };\n }\n\n return { ...base, variant: p.targetId, instrumentable: true };\n}\n\n/** Map a generic detection report into source-maps projects. */\nfunction toSourceMapsReport(\n report: AgenticDetectionReport,\n probes: ProjectProbes,\n): DetectionReport {\n return {\n repoType: report.repoType,\n projects: report.projects.map((p) => classifyProject(p, probes)),\n };\n}\n\n/**\n * Validate the agent's raw JSON into a source-maps detection report. Exported\n * for testing — clamps projects the wizard cannot wire up to\n * non-instrumentable. Probes left out of `probes` answer `false`, so every\n * Flutter project is treated as target-less and every React Native project as\n * bare (both blocked).\n */\nexport function coerceReport(\n parsed: unknown,\n probes: Partial<ProjectProbes> = {},\n): DetectionReport {\n return toSourceMapsReport(\n coerceAgenticReport(\n parsed,\n SOURCE_MAPS_TARGETS.map((target) => target.id),\n ),\n { ...NO_PROBES, ...probes },\n );\n}\n\n/** Run the Haiku detector over the repo and classify projects for source maps. */\nexport async function detectSourceMapsProjects(\n session: WizardSession,\n onEvent?: DetectEvent,\n): Promise<DetectionReport> {\n const report = await detectProjectsWithAgent(session, {\n targets: SOURCE_MAPS_TARGETS,\n programId: 'error-tracking-upload-source-maps',\n purpose: 'set up PostHog Error Tracking source-map upload',\n rerankIds: JS_RERANK_VARIANTS,\n onEvent,\n });\n return toSourceMapsReport(report, {\n hasBuildTarget: (path) => projectHasBuildTarget(session.installDir, path),\n isExpoProject: (path) => projectHasExpo(session.installDir, path),\n verifyRustSdk: rustSdkVerifier(session.installDir),\n verifyGoSdk: goSdkVerifier(session.installDir),\n });\n}\n","/**\n * SourceMapsDetectScreen — runs the Haiku detection agent over the repo, shows\n * streaming progress, then renders a structured map of which projects can have\n * source-map upload wired up and which cannot. The user picks one project; the\n * choice is written to frameworkContext and the run step instruments it.\n *\n * Runs after auth — the detection agent needs credentials.\n */\n\nimport { Box, Text } from 'ink';\nimport { useEffect, useRef, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { LoadingBox, PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport {\n SOURCE_MAPS_CONTEXT_KEYS,\n VARIANT_DISPLAY_NAME,\n MANUAL_SDK_VARIANTS,\n} from '@lib/programs/error-tracking-upload-source-maps/index';\nimport {\n detectSourceMapsProjects,\n type DetectedProject,\n type DetectionReport,\n} from '@lib/programs/error-tracking-upload-source-maps/detect-agentic';\n\ninterface SourceMapsDetectScreenProps {\n store: WizardStore;\n}\n\ntype DetectState =\n | { kind: 'loading' }\n | { kind: 'ready'; report: DetectionReport }\n | { kind: 'error'; message: string };\n\nconst EXIT = '__exit';\nconst MAX_ACTIVITY_LINES = 8;\n\nfunction projectLabel(p: DetectedProject): string {\n const name = p.variant ? VARIANT_DISPLAY_NAME[p.variant] : p.framework;\n const where = p.path === '.' ? 'repo root' : p.path;\n return `${name} ${Icons.bullet} ${where}`;\n}\n\nexport const SourceMapsDetectScreen = ({\n store,\n}: SourceMapsDetectScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { credentials } = store.session;\n const accessToken = credentials?.accessToken;\n\n const [state, setState] = useState<DetectState>({ kind: 'loading' });\n const [activity, setActivity] = useState<string[]>([]);\n const started = useRef(false);\n\n useEffect(() => {\n if (!accessToken || started.current) return;\n started.current = true;\n let cancelled = false;\n void (async () => {\n try {\n const report = await detectSourceMapsProjects(store.session, (line) => {\n if (!cancelled) {\n setActivity((prev) => [...prev, line].slice(-MAX_ACTIVITY_LINES));\n }\n });\n if (!cancelled) setState({ kind: 'ready', report });\n } catch (err) {\n if (!cancelled) {\n setState({\n kind: 'error',\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [accessToken, store]);\n\n if (!credentials) {\n return <LoadingBox message=\"Waiting for authentication...\" />;\n }\n\n if (state.kind === 'loading') {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Detecting your project...\n </Text>\n <Box marginY={1}>\n <LoadingBox message=\"Scanning the repo for frameworks and PostHog SDKs...\" />\n </Box>\n <Box flexDirection=\"column\">\n {activity.length === 0 ? (\n <Text dimColor>{' '}Starting up the detection agent…</Text>\n ) : (\n activity.map((line, i) => (\n <Text\n key={`${i}-${line}`}\n dimColor={i < activity.length - 1}\n color={i === activity.length - 1 ? Colors.primary : undefined}\n >\n {' '}\n {Icons.triangleSmallRight} {line}\n </Text>\n ))\n )}\n </Box>\n </Box>\n );\n }\n\n if (state.kind === 'error') {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginY={1}>\n <Text color={Colors.error} bold>\n {Icons.squareFilled} Detection failed\n </Text>\n <Text dimColor>{state.message}</Text>\n </Box>\n <PickerMenu\n options={[{ label: 'Exit', value: EXIT }]}\n onSelect={() => process.exit(1)}\n />\n </Box>\n );\n }\n\n const { report } = state;\n const instrumentable = report.projects.filter((p) => p.instrumentable);\n const blocked = report.projects.filter((p) => !p.instrumentable);\n\n if (instrumentable.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color={Colors.error} bold>\n {Icons.squareFilled} Nothing to instrument yet\n </Text>\n <Text dimColor>\n None of the {report.projects.length} projects found can have\n source-map upload set up.\n </Text>\n </Box>\n <BlockedSummary blocked={blocked} />\n <Box marginTop={1}>\n <PickerMenu\n options={[{ label: 'Exit', value: EXIT }]}\n onSelect={() => process.exit(0)}\n />\n </Box>\n </Box>\n );\n }\n\n const options = [\n ...instrumentable.map((p) => ({\n label: projectLabel(p),\n value: p.path,\n })),\n { label: 'Cancel', value: EXIT },\n ];\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n {Icons.check} Found{' '}\n {report.repoType === 'monorepo' ? 'a monorepo' : 'your project'}\n </Text>\n </Box>\n\n <PickerMenu\n message=\"Which project would you like to set up source map uploads for?\"\n options={options}\n onSelect={(value) => {\n const path = Array.isArray(value) ? value[0] : value;\n if (path === EXIT) {\n process.exit(0);\n return;\n }\n const chosen = instrumentable.find((p) => p.path === path);\n if (!chosen || !chosen.variant) return;\n store.setFrameworkContext(\n SOURCE_MAPS_CONTEXT_KEYS.selectedVariant,\n chosen.variant,\n );\n store.setFrameworkContext(\n SOURCE_MAPS_CONTEXT_KEYS.selectedDisplayName,\n VARIANT_DISPLAY_NAME[chosen.variant],\n );\n store.setFrameworkContext(\n SOURCE_MAPS_CONTEXT_KEYS.selectedPath,\n chosen.path,\n );\n }}\n />\n\n <Box marginTop={1}>\n <BlockedSummary blocked={blocked} />\n </Box>\n </Box>\n );\n};\n\n/**\n * Collapses the non-instrumentable projects into a short count line (or two)\n * instead of listing every one — a monorepo can have dozens.\n */\nconst BlockedSummary = ({ blocked }: { blocked: DetectedProject[] }) => {\n const unsupported = blocked.filter((p) => p.variant == null).length;\n // The wizard can't install the Go/Rust SDKs, so their missing-SDK\n // remediation is a manual install, not `npx @posthog/wizard`.\n const manualSdk = blocked.filter(\n (p) => p.variant != null && MANUAL_SDK_VARIANTS.includes(p.variant),\n ).length;\n const missingSdk = blocked.length - unsupported - manualSdk;\n if (blocked.length === 0) return null;\n return (\n <Box flexDirection=\"column\">\n {unsupported > 0 && (\n <Text dimColor>\n (… {unsupported} other project{unsupported === 1 ? '' : 's'} not\n supported)\n </Text>\n )}\n {missingSdk > 0 && (\n <Text dimColor>\n (… {missingSdk} supported but missing the PostHog SDK — install it\n first with `npx @posthog/wizard`)\n </Text>\n )}\n {manualSdk > 0 && (\n <Text dimColor>\n (… {manualSdk} supported but missing the PostHog SDK — add it to the\n project first (posthog-go / posthog-rs), then re-run)\n </Text>\n )}\n </Box>\n );\n};\n","/**\n * SourceMapsOutroScreen — post-run summary for the source-maps upload flow.\n *\n * Unlike the generic OutroScreen, this spells out the operational facts a user\n * needs to actually get de-minified stack traces: that packages were installed\n * and upload credentials written to .env, plus the three gotchas (builds\n * upload, run the build, give CI the same credentials). All static guidance —\n * driven only by the program's `buildOutroData` (kind / message / report /\n * docs), no per-run data.\n */\n\nimport { join } from 'node:path';\nimport type { ReactNode } from 'react';\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { OutroKind } from '@lib/wizard-session';\nimport { Colors } from '@ui/tui/styles';\nimport { useDismissOnAnyKey } from '@ui/tui/hooks/useDismissOnAnyKey';\n\ninterface SourceMapsOutroScreenProps {\n store: WizardStore;\n}\n\nexport const SourceMapsOutroScreen = ({\n store,\n}: SourceMapsOutroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n useDismissOnAnyKey(() => store.setOutroDismissed());\n\n const outroData = store.session.outroData;\n\n if (!outroData) {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text dimColor>Finishing up...</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n {outroData.kind === OutroKind.Success && (\n <Box flexDirection=\"column\">\n <Text color={Colors.success} bold>\n ✔ {outroData.message || 'Source maps wired up!'}\n </Text>\n\n <Section title=\"What the wizard did\">\n <Text>• Installed the packages needed for source map upload.</Text>\n <Text>\n • Wrote the PostHog upload credentials to your{' '}\n <Text bold>.env</Text> file.\n </Text>\n </Section>\n\n <Section title=\"How uploads work now\">\n <Text>\n • Every <Text bold>build</Text> now uploads source maps to PostHog\n automatically — no extra command to remember.\n </Text>\n <Text>\n • Run your app from the <Text bold>built output</Text>. Source\n maps only resolve for errors thrown by the build that was\n uploaded.\n </Text>\n <Text>\n • In <Text bold>CI</Text>, the build job needs the same upload\n credentials. If the wizard wired your pipeline, add the referenced\n secrets to your CI provider (e.g. GitHub repo secrets) before your\n next deploy.\n </Text>\n </Section>\n\n {outroData.reportFile && (\n <Box marginTop={1}>\n <Text>\n Details in{' '}\n <Text bold>\n {join(store.session.installDir, outroData.reportFile)}\n </Text>\n </Text>\n </Box>\n )}\n\n {outroData.docsUrl && (\n <Box marginTop={1}>\n <Text>\n Learn more:{' '}\n <Text color={Colors.primary}>{outroData.docsUrl}</Text>\n </Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text dimColor>\n Note: This wizard uses an LLM agent to analyze and modify your\n project. Please review the changes made.\n </Text>\n </Box>\n <Text dimColor>\n How did this work for you? Drop us a line: wizard@posthog.com\n </Text>\n </Box>\n )}\n\n {outroData.kind === OutroKind.Error && (\n <Box flexDirection=\"column\">\n <Text color={Colors.error} bold>\n ✘ {outroData.message || 'An error occurred'}\n </Text>\n {outroData.body && (\n <Box marginTop={1}>\n <Text dimColor>{outroData.body}</Text>\n </Box>\n )}\n {outroData.docsUrl && (\n <Box marginTop={1}>\n <Text>\n Docs: <Text color={Colors.primary}>{outroData.docsUrl}</Text>\n </Text>\n </Box>\n )}\n </Box>\n )}\n\n {outroData.kind === OutroKind.Cancel && (\n <Text color=\"yellow\">■ {outroData.message || 'Cancelled'}</Text>\n )}\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to continue</Text>\n </Box>\n </Box>\n );\n};\n\nconst Section = ({\n title,\n children,\n}: {\n title: string;\n children: ReactNode;\n}) => (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={Colors.primary} bold>\n {title}:\n </Text>\n {children}\n </Box>\n);\n","/**\n * AgentSkillIntroScreen — Default intro for generic agent-skill programs.\n *\n * Programs that need a different intro ship their own screen component\n * (see audit/AuditIntroScreen.tsx).\n */\n\nimport { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\nimport { SkillSourceInfo, useSkillEntry } from './SkillSourceInfo.js';\n\ninterface AgentSkillIntroScreenProps {\n store: WizardStore;\n}\n\nexport const AgentSkillIntroScreen = ({\n store,\n}: AgentSkillIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n\n const { session } = store;\n const skillId = session.skillId ?? 'unknown';\n const { skillEntry, fetchFailed } = useSkillEntry(skillId);\n\n let body: ReactNode;\n\n if (showingMoreInfo) {\n body = (\n <Box flexDirection=\"column\" width={56} flexShrink={0}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n </Box>\n <SkillSourceInfo\n skillId={skillId}\n skillEntry={skillEntry}\n fetchFailed={fetchFailed}\n />\n <Box marginTop={1}>\n <Text dimColor>\n {skillEntry?.name ?? (fetchFailed ? skillId : 'Loading...')}\n </Text>\n </Box>\n </Box>\n );\n } else {\n body = (\n <Text>\n Let's run the{' '}\n <Text italic color=\"cyan\">\n {skillId}\n </Text>{' '}\n skill.\n </Text>\n );\n }\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const handleSelect = (value: string) => {\n if (value === 'cancel') process.exit(0);\n else if (value === 'more-info') setShowingMoreInfo(true);\n else if (value === 'back') setShowingMoreInfo(false);\n else store.completeSetup();\n };\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n showSubtitle={!showingMoreInfo}\n body={body}\n showDetection={!showingMoreInfo}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={handleSelect}\n />\n );\n};\n","import { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from '@ui/tui/screens/IntroScreenLayout';\nimport {\n SkillSourceInfo,\n useSkillEntry,\n} from '@ui/tui/screens/SkillSourceInfo';\n\ninterface AiObservabilityIntroScreenProps {\n store: WizardStore;\n}\n\nexport const AiObservabilityIntroScreen = ({\n store,\n}: AiObservabilityIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n const { session } = store;\n // ai-observability picks its skill variant at run time (openai-python,\n // anthropic-node, langchain-python, …), so there's no pre-seeded skillId\n // here. Fall back to the group id for the \"more info\" lookup.\n const skillId = session.skillId ?? 'ai-observability';\n const { skillEntry, fetchFailed } = useSkillEntry(skillId);\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56}>\n <Box marginBottom={1}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n </Box>\n\n <Text>\n The{' '}\n <Text color=\"cyan\" italic>\n ai-observability\n </Text>{' '}\n program wraps your LLM SDK calls with PostHog's OpenTelemetry-based\n tracing so every prompt, completion, tool call, token count, and cost\n lands in AI Observability. Supports OpenAI, Anthropic, Google,\n LangChain, Vercel AI, and other SDKs.\n </Text>\n <Box marginTop={1}>\n <SkillSourceInfo\n skillId={skillId}\n skillEntry={skillEntry}\n fetchFailed={fetchFailed}\n />\n </Box>\n </Box>\n ) : (\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>\n Let's instrument your LLM calls with PostHog AI Observability.\n </Text>\n </Box>\n );\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const handleSelect = (value: string) => {\n if (value === 'cancel') process.exit(0);\n else if (value === 'more-info') setShowingMoreInfo(true);\n else if (value === 'back') setShowingMoreInfo(false);\n else store.completeSetup();\n };\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n body={body}\n showDetection={!showingMoreInfo}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={handleSelect}\n />\n );\n};\n","import { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from '@ui/tui/screens/IntroScreenLayout';\nimport {\n SkillSourceInfo,\n useSkillEntry,\n} from '@ui/tui/screens/SkillSourceInfo';\n\ninterface MetricsIntroScreenProps {\n store: WizardStore;\n}\n\nexport const MetricsIntroScreen = ({ store }: MetricsIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n const { session } = store;\n // metrics picks its skill variant at run time (python, nodejs, javascript,\n // kubernetes, other), so there's no pre-seeded skillId here. Fall back to\n // the group id for the \"more info\" lookup.\n const skillId = session.skillId ?? 'metrics';\n const { skillEntry, fetchFailed } = useSkillEntry(skillId, session.localMcp);\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56}>\n <Box marginBottom={1}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n </Box>\n\n <Text>\n The{' '}\n <Text color=\"cyan\" italic>\n metrics\n </Text>{' '}\n program instruments your service with PostHog application metrics —\n counters, gauges, and histograms via{' '}\n <Text color=\"cyan\">posthog.metrics</Text> — at operational choke points:\n request middleware, background jobs, external calls, and business commit\n sites. Supports Python, Node.js, web JavaScript, Kubernetes, and any\n other language via OTLP.\n </Text>\n <Box marginTop={1}>\n <SkillSourceInfo\n skillId={skillId}\n skillEntry={skillEntry}\n fetchFailed={fetchFailed}\n />\n </Box>\n </Box>\n ) : (\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>\n Let's instrument your service with PostHog application metrics.\n </Text>\n </Box>\n );\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const handleSelect = (value: string) => {\n if (value === 'cancel') process.exit(0);\n else if (value === 'more-info') setShowingMoreInfo(true);\n else if (value === 'back') setShowingMoreInfo(false);\n else store.completeSetup();\n };\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n body={body}\n showDetection={!showingMoreInfo}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={handleSelect}\n />\n );\n};\n","/**\n * SelfDrivingIntroScreen — Welcome screen for the self-driving flow.\n *\n * Composes IntroScreenLayout with prerequisite-detection state:\n * - Detection succeeded: explains what Self-driving turns on, continue/cancel\n * - Detection failed: shows the error via errorView + exit prompt\n *\n * Reads `frameworkContext.detectError` set by\n * detectSelfDrivingPrerequisites().\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\nimport {\n NO_DEFAULT_LIMIT,\n PRICING_LONG,\n PRICING_SHORT,\n} from '@lib/programs/self-driving/content/pricing.js';\nimport type { SelfDrivingDetectError } from '@lib/programs/self-driving/index';\n\ninterface SelfDrivingIntroScreenProps {\n store: WizardStore;\n}\n\nexport const SelfDrivingIntroScreen = ({\n store,\n}: SelfDrivingIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n\n const { session } = store;\n const detectError = session.frameworkContext.detectError as\n | SelfDrivingDetectError\n | undefined;\n\n const subtitle = (\n <>\n <Text dimColor>\n We'll use AI to analyze your project and set up PostHog Self-driving.\n </Text>\n <Text dimColor>.env* file contents will not leave your machine.</Text>\n </>\n );\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56} flexShrink={0}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>.\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.programLabel}\n </Text>{' '}\n program turns on PostHog Self-driving for this project:\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={4}>\n <Text>\n {'•'} Watches your signal sources: errors, replays, connected tools\n </Text>\n <Text>{'•'} Runs scouts – scheduled agents that scan for issues</Text>\n <Text>{'•'} Groups signals into prioritized reports in your inbox</Text>\n <Text>{'•'} Researches findings in your code via GitHub</Text>\n <Text>\n {'•'} Measures shipped fixes, and reopens the loop if the pattern\n persists\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>{PRICING_LONG}</Text>\n <Text>{NO_DEFAULT_LIMIT}</Text>\n </Box>\n </Box>\n ) : (\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>Let's set up PostHog Self-driving.</Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n PostHog watches how people really use your product, finds issues, and\n proposes fixes.\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} alignItems=\"center\">\n <Text dimColor>\n An agent will connect GitHub, enable signal sources, and tune your\n scouts.\n </Text>\n <Text dimColor>\n About 10 minutes, with a few questions along the way.\n </Text>\n <Text dimColor>{PRICING_SHORT}</Text>\n </Box>\n </Box>\n );\n\n const errorView = detectError ? (\n <>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"red\" bold>\n {'✘'} Cannot set up PostHog Self-driving\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <DetectErrorBody error={detectError} />\n </Box>\n </Box>\n\n <PickerMenu\n options={[{ label: 'Exit', value: 'exit' }]}\n onSelect={() => process.exit(1)}\n />\n </>\n ) : undefined;\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n showSubtitle={!showingMoreInfo}\n subtitle={subtitle}\n body={body}\n showDetection={!showingMoreInfo}\n errorView={errorView}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'more-info') {\n setShowingMoreInfo(true);\n } else if (value === 'back') {\n setShowingMoreInfo(false);\n } else {\n store.completeSetup();\n }\n }}\n />\n );\n};\n\nconst DetectErrorBody = ({ error }: { error: SelfDrivingDetectError }) => {\n switch (error.kind) {\n case 'bad-directory': {\n const reasonText = {\n missing: 'does not exist',\n 'not-dir': 'is not a directory',\n unreadable: 'could not be accessed',\n }[error.reason];\n return (\n <>\n <Text>This path {reasonText}:</Text>\n <Text dimColor>\n {' '}\n {error.path}\n </Text>\n </>\n );\n }\n\n default:\n // Defensive fallback so a future SelfDrivingDetectError kind still\n // renders something useful instead of a blank screen.\n return (\n <Text>\n Self-driving could not start in this directory. Try again, or reach\n out to wizard@posthog.com.\n </Text>\n );\n }\n};\n","/**\n * SelfDrivingIntegrationCheckScreen — shown only when detection found no\n * PostHog in the project. Self-driving needs a PostHog SDK, so we always\n * integrate first; but a project with no SDK is often a project with no PostHog\n * account either, so this screen first asks whether the user already has one:\n *\n * - \"Yes — log me in\" → setIntegrate(true); auth runs the OAuth login.\n * - \"No — create one for me\" → collect email + region, then\n * chooseProvisionAccount(): auth provisions a new\n * account (and emails a login link) instead.\n *\n * Both answers integrate the SDK; they only differ in how auth gets credentials.\n * Skipped entirely when PostHog is already present (or under `--integrate`,\n * which forces integration + the default OAuth login).\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { TextInput } from '@inkjs/ui';\nimport { useState, useSyncExternalStore } from 'react';\n\nimport type { WizardStore } from '@ui/tui/store';\nimport type { CloudRegion } from '@lib/wizard-session';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport {\n PrivacyPanel,\n PRIVACY_PANEL_LABEL,\n} from '@ui/tui/components/PrivacyPanel';\nimport { IntroScreenLayout } from '@ui/tui/screens/IntroScreenLayout';\nimport { POSTHOG_PRIVACY_URL, POSTHOG_TERMS_URL } from '@lib/constants';\nimport { Colors } from '@ui/tui/styles';\n\ninterface SelfDrivingIntegrationCheckScreenProps {\n store: WizardStore;\n}\n\n/** Multi-step screen state: pick account status → email → region. */\ntype Stage = 'ask' | 'email' | 'region';\n\nconst EMAIL_RE = /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/;\n\nexport const SelfDrivingIntegrationCheckScreen = ({\n store,\n}: SelfDrivingIntegrationCheckScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [stage, setStage] = useState<Stage>('ask');\n // Pre-fill from `--email` when it was passed; tracked across stages so\n // the region step can hand both to the store in one commit.\n const [email, setEmail] = useState(store.session.email ?? '');\n const [emailError, setEmailError] = useState<string | null>(null);\n const [showPrivacy, setShowPrivacy] = useState(false);\n\n useInput((input, key) => {\n // While the privacy overlay is open, only Esc closes it; the overlay's own\n // Back menu handles the rest.\n if (showPrivacy) {\n if (key.escape) setShowPrivacy(false);\n return;\n }\n\n // [I] opens the full privacy panel. Skipped on the email stage so the\n // keystroke reaches the text field instead.\n if ((input === 'i' || input === 'I') && stage !== 'email') {\n setShowPrivacy(true);\n return;\n }\n\n // Esc steps back toward the account question (the picker owns input on 'ask').\n if (key.escape && stage !== 'ask') {\n setEmailError(null);\n setStage(stage === 'region' ? 'email' : 'ask');\n }\n });\n\n if (showPrivacy) {\n return (\n <IntroScreenLayout\n installDir={store.session.installDir}\n title={PRIVACY_PANEL_LABEL}\n showSubtitle={false}\n showDetection={false}\n body={<PrivacyPanel />}\n showPrivacy={false}\n menuOptions={[{ label: 'Back', value: 'back' }]}\n menuAlign=\"left\"\n onSelect={() => setShowPrivacy(false)}\n />\n );\n }\n\n if (stage === 'region') {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Where should we create your account?\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>\n We'll create your PostHog account for {email} in this region.\n </Text>\n </Box>\n <Box marginTop={1}>\n <PickerMenu\n message=\"Pick your cloud region\"\n options={[\n { label: 'US', value: 'us', hint: 'us.posthog.com' },\n { label: 'EU', value: 'eu', hint: 'eu.posthog.com' },\n ]}\n onSelect={(value) => {\n const region = (\n Array.isArray(value) ? value[0] : value\n ) as CloudRegion;\n store.chooseProvisionAccount(email.trim(), region);\n }}\n />\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>By creating an account you agree to our terms.</Text>\n <Text dimColor>\n Terms: <Text color=\"cyan\">{POSTHOG_TERMS_URL}</Text>\n </Text>\n <Text dimColor>\n Privacy: <Text color=\"cyan\">{POSTHOG_PRIVACY_URL}</Text>\n </Text>\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n <Text color={Colors.accent}>[Esc]</Text> back{' · '}\n <Text color={Colors.accent}>[I]</Text> {PRIVACY_PANEL_LABEL}\n </Text>\n </Box>\n </Box>\n );\n }\n\n if (stage === 'email') {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Create your PostHog account\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>\n We'll create your account and email you a login link. What\n email should we use?\n </Text>\n </Box>\n <Box marginTop={1} width=\"100%\">\n <TextInput\n placeholder=\"you@company.com\"\n defaultValue={email}\n onChange={setEmail}\n onSubmit={(value) => {\n const trimmed = value.trim();\n if (!EMAIL_RE.test(trimmed)) {\n setEmailError('Please enter a valid email address.');\n return;\n }\n setEmail(trimmed);\n setEmailError(null);\n setStage('region');\n }}\n />\n </Box>\n {emailError && (\n <Box marginTop={1}>\n <Text color=\"yellow\">{emailError}</Text>\n </Box>\n )}\n <Box marginTop={1}>\n <Text dimColor>\n <Text color={Colors.accent}>[Enter]</Text> continue{' · '}\n <Text color={Colors.accent}>[Esc]</Text> back\n </Text>\n </Box>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n No PostHog integration found\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>\n This will kick off an agent to explore your project and find existing\n PostHog integrations. Self-driving reads PostHog data, so we'll\n set that up first: it gives your signal sources something to watch. To\n do that we need to connect to PostHog — do you already have an\n account?\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <PickerMenu\n options={[\n {\n label: 'Yes, log me in',\n value: 'login',\n hint: 'opens PostHog to authorize',\n },\n {\n label: 'No, create one for me',\n value: 'provision',\n hint: \"we'll email you a login link\",\n },\n ]}\n onSelect={(value) => {\n const choice = Array.isArray(value) ? value[0] : value;\n if (choice === 'login') {\n store.setIntegrate(true);\n } else {\n setStage('email');\n }\n }}\n />\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n <Text color={Colors.accent}>[I]</Text> {PRIVACY_PANEL_LABEL}\n </Text>\n </Box>\n </Box>\n );\n};\n","/**\n * SelfDrivingIntegrationDetectScreen — runs the Haiku detector over the repo,\n * streams progress, then renders a picker of projects. Two kinds are offered:\n * set-up-here (supported framework, no SDK yet; writes framework + path for\n * the integrate-run phase) and continue-with-existing (already has PostHog;\n * sets integrate=false and skips straight to Self-driving). On a detection\n * error, falls back to a manual framework picker.\n *\n * Runs after auth — the detector needs credentials.\n */\n\nimport { Box, Text } from 'ink';\nimport { useEffect, useRef, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { LoadingBox, PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { Integration } from '@lib/constants';\nimport { FRAMEWORK_REGISTRY } from '@lib/registry';\nimport { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@lib/programs/self-driving/detect';\nimport {\n detectSelfDrivingIntegrationProjects,\n type IntegrationProject,\n type IntegrationDetectionReport,\n} from '@lib/programs/self-driving/detect-agentic';\n\ninterface SelfDrivingIntegrationDetectScreenProps {\n store: WizardStore;\n}\n\ntype DetectState =\n | { kind: 'loading' }\n | { kind: 'ready'; report: IntegrationDetectionReport }\n | { kind: 'error'; message: string };\n\nconst CANCEL = '__cancel';\nconst MAX_ACTIVITY_LINES = 8;\n\nfunction projectLabel(p: IntegrationProject): string {\n const where = p.path === '.' ? 'repo root' : p.path;\n return `${p.framework} ${Icons.bullet} ${where}`;\n}\n\nexport const SelfDrivingIntegrationDetectScreen = ({\n store,\n}: SelfDrivingIntegrationDetectScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { credentials } = store.session;\n const accessToken = credentials?.accessToken;\n\n const [state, setState] = useState<DetectState>({ kind: 'loading' });\n const [activity, setActivity] = useState<string[]>([]);\n const started = useRef(false);\n\n // Commit a chosen project to integrate: framework + path → session. The run\n // phase reads both (path scopes the install dir to the sub-app).\n const choose = (p: IntegrationProject) => {\n if (!p.integration) return;\n store.setFrameworkContext(SELF_DRIVING_INTEGRATE_PATH_KEY, p.path);\n store.setFrameworkConfig(p.integration, FRAMEWORK_REGISTRY[p.integration]);\n };\n\n // PostHog already installed here: integrate=false completes integrate-detect\n // and drops the integrate-run / handoff steps from the walk.\n const continueWithExisting = (p: IntegrationProject) => {\n store.setFrameworkContext(SELF_DRIVING_INTEGRATE_PATH_KEY, p.path);\n store.setIntegrate(false, {\n via: 'existing-integration-detected',\n path: p.path,\n });\n };\n\n // Run the detector once, after auth.\n useEffect(() => {\n if (!accessToken || started.current) return;\n started.current = true;\n let cancelled = false;\n void (async () => {\n try {\n const report = await detectSelfDrivingIntegrationProjects(\n store.session,\n (line) => {\n if (!cancelled) {\n setActivity((prev) => [...prev, line].slice(-MAX_ACTIVITY_LINES));\n }\n },\n );\n if (!cancelled) setState({ kind: 'ready', report });\n } catch (err) {\n if (!cancelled) {\n setState({\n kind: 'error',\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [accessToken, store]);\n\n if (!credentials) {\n return <LoadingBox message=\"Waiting for authentication...\" />;\n }\n\n if (state.kind === 'error') {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color={Colors.error} bold>\n {Icons.squareFilled} Detection failed\n </Text>\n <Text dimColor>{state.message}</Text>\n <Text dimColor>\n Pick your framework and we'll set PostHog up here.\n </Text>\n </Box>\n <PickerMenu<Integration>\n centered\n columns={2}\n message=\"Select your framework\"\n options={Object.values(Integration).map((v) => ({\n label: v,\n value: v,\n }))}\n onSelect={(value) => {\n const integration = Array.isArray(value) ? value[0] : value;\n store.setFrameworkContext(SELF_DRIVING_INTEGRATE_PATH_KEY, '.');\n store.setFrameworkConfig(\n integration,\n FRAMEWORK_REGISTRY[integration],\n );\n }}\n />\n </Box>\n );\n }\n\n if (state.kind === 'loading') {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Detecting your project. Stick around, this will take a few seconds...\n </Text>\n <Box marginY={1}>\n <LoadingBox message=\"Scanning the repo for frameworks and PostHog SDKs...\" />\n </Box>\n <Box flexDirection=\"column\">\n {activity.length === 0 ? (\n <Text dimColor>{' '}Starting up the detection agent…</Text>\n ) : (\n activity.map((line, i) => (\n <Text\n key={`${i}-${line}`}\n dimColor={i < activity.length - 1}\n color={i === activity.length - 1 ? Colors.primary : undefined}\n >\n {' '}\n {Icons.triangleSmallRight} {line}\n </Text>\n ))\n )}\n </Box>\n </Box>\n );\n }\n\n const { report } = state;\n const instrumentable = report.projects.filter((p) => p.instrumentable);\n // Already has PostHog → offer \"continue with existing\" instead of hiding it.\n const existing = report.projects.filter((p) => p.continuable);\n const unsupported = report.projects.filter(\n (p) => !p.instrumentable && !p.continuable,\n );\n\n // Values are prefixed so one picker can mix new: and existing: entries.\n const NEW = 'new:';\n const EXISTING = 'existing:';\n const dispatch = (value: string | string[]) => {\n const v = Array.isArray(value) ? value[0] : value;\n if (v === CANCEL) {\n process.exit(0);\n return;\n }\n if (v.startsWith(EXISTING)) {\n const p = existing.find((x) => x.path === v.slice(EXISTING.length));\n if (p) continueWithExisting(p);\n return;\n }\n const p = instrumentable.find((x) => x.path === v.slice(NEW.length));\n if (p) choose(p);\n };\n\n // Nothing to instrument, nothing already installed: a genuine dead end.\n if (instrumentable.length === 0 && existing.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color={Colors.error} bold>\n {Icons.squareFilled} Nothing to set up here\n </Text>\n <Text dimColor>\n None of the {report.projects.length} projects found can have PostHog\n set up.\n </Text>\n </Box>\n <UnsupportedSummary unsupported={unsupported} />\n <Box marginTop={1}>\n <PickerMenu\n options={[{ label: 'Exit', value: CANCEL }]}\n onSelect={() => process.exit(0)}\n />\n </Box>\n </Box>\n );\n }\n\n // Only already-installed projects: continue straight to Self-driving.\n if (instrumentable.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n {Icons.check} PostHog is already set up\n </Text>\n <Text dimColor>Continue straight to Self-driving.</Text>\n </Box>\n <PickerMenu\n message={\n existing.length === 1\n ? 'Continue with your existing PostHog install?'\n : 'Which project should Self-driving use?'\n }\n options={[\n ...existing.map((p) => ({\n label: projectLabel(p),\n value: `${EXISTING}${p.path}`,\n })),\n { label: 'Exit', value: CANCEL },\n ]}\n onSelect={dispatch}\n />\n <Box marginTop={1}>\n <UnsupportedSummary unsupported={unsupported} />\n </Box>\n </Box>\n );\n }\n\n const single = instrumentable.length === 1;\n // Disabled rows act as section headings + spacers — navigation skips them.\n const HEAD = 'head:';\n const spacer = (id: string) => ({\n label: ' ',\n value: `${HEAD}${id}`,\n disabled: true,\n });\n const heading = (id: string, label: string) => ({\n label,\n value: `${HEAD}${id}`,\n disabled: true,\n header: true,\n });\n const options = [\n heading('new', 'New PostHog integration:'),\n ...instrumentable.map((p) => ({\n label: projectLabel(p),\n value: `${NEW}${p.path}`,\n indent: true,\n })),\n ...(existing.length > 0\n ? [\n spacer('gap1'),\n heading('existing', 'Existing integrations:'),\n ...existing.map((p) => ({\n label: projectLabel(p),\n value: `${EXISTING}${p.path}`,\n indent: true,\n })),\n ]\n : []),\n spacer('gap2'),\n { label: 'Cancel', value: CANCEL },\n ];\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n {Icons.check} Found{' '}\n {report.repoType === 'monorepo' ? 'a monorepo' : 'your project'}\n </Text>\n </Box>\n\n <PickerMenu\n message={\n single && existing.length === 0\n ? 'Set up PostHog here? Confirm to continue.'\n : undefined\n }\n options={options}\n onSelect={dispatch}\n />\n\n <Box marginTop={1}>\n <UnsupportedSummary unsupported={unsupported} />\n </Box>\n </Box>\n );\n};\n\n/**\n * Collapses unsupported-stack projects into a count line (already-has-PostHog\n * projects are real picker options, not summarised).\n */\nconst UnsupportedSummary = ({\n unsupported,\n}: {\n unsupported: IntegrationProject[];\n}) => {\n if (unsupported.length === 0) return null;\n return (\n <Box flexDirection=\"column\">\n <Text dimColor>\n (… {unsupported.length} project{unsupported.length === 1 ? '' : 's'} not\n supported yet)\n </Text>\n </Box>\n );\n};\n","/**\n * SelfDrivingHandoffScreen — the bridge between the integration run and the\n * Self-driving run. Shown only in the integrate path (PostHog wasn't present, so\n * the wizard set it up first); the already-has-PostHog path skips straight to\n * Self-driving with no note. Confirms the SDK is in, then hands off to the\n * Self-driving run.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\n\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors } from '@ui/tui/styles';\nimport { SETUP_REPORT_FILE } from '@lib/programs/posthog-integration/index';\nimport { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@lib/programs/self-driving/detect';\n\ninterface SelfDrivingHandoffScreenProps {\n store: WizardStore;\n}\n\nexport const SelfDrivingHandoffScreen = ({\n store,\n}: SelfDrivingHandoffScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n // The integration ran in the picked project (a monorepo sub-app, or the\n // root), so the report sits under that path.\n const rel = store.session.frameworkContext[SELF_DRIVING_INTEGRATE_PATH_KEY];\n const dir = typeof rel === 'string' && rel !== '.' ? `${rel}/` : '';\n const reportPath = `./${dir}${SETUP_REPORT_FILE}`;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n ✔ PostHog is installed\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>Now let's make your product self-driving.</Text>\n <Box marginTop={1}>\n <Text dimColor>\n Next, the agent connects GitHub, turns on signal sources, and tunes\n the scouts that watch your product data.\n </Text>\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n About 10 more minutes, and it needs your input a few times. Keep\n this terminal open.\n </Text>\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <PickerMenu\n options={[{ label: 'Set up Self-driving [Enter]', value: 'go' }]}\n onSelect={() => store.confirmSelfDrivingHandoff()}\n />\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n You can find your PostHog integration report at{' '}\n <Text bold>{reportPath}</Text>\n </Text>\n </Box>\n </Box>\n );\n};\n","/**\n * Polls `/integrations/` until the PostHog GitHub App shows up, writing the\n * result to the session so the Self-driving GitHub gate can advance.\n *\n * Installing the App is a manual browser step, so polling is what flips the\n * gate once the user comes back. The first tick also resolves the session's\n * unknown (`null`) state.\n */\n\nimport { useEffect } from 'react';\n\nimport type { WizardStore } from '@ui/tui/store';\nimport type { WizardSession } from '@lib/wizard-session';\nimport { fetchGithubConnected } from '@lib/api';\nimport { requestDeepLink } from '@utils/provisioning';\nimport { analytics } from '@utils/analytics';\n\nconst POLL_INTERVAL_MS = 3000;\n\n// Provisioned signups have no browser session for the install link; deep link when the partner tier grants one, else the login page.\nexport async function fetchLoginUrl(\n session: WizardSession,\n): Promise<string | null> {\n if (!session.signup || !session.credentials) return null;\n const deepLink = await requestDeepLink(\n session.credentials.accessToken,\n session.credentials.host,\n );\n return deepLink ?? `${session.credentials.host.appHost}/login`;\n}\n\nexport function useGithubConnection(store: WizardStore): void {\n const credentials = store.session.credentials;\n const connected = store.session.githubConnected === true;\n\n useEffect(() => {\n if (!credentials || connected) return;\n\n const controller = new AbortController();\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let errorReported = false;\n\n /** A check that came back \"not connected\" — including a failed one. */\n const settleUnknown = (): void => {\n if (store.session.githubConnected === null) {\n store.setGithubConnected(false);\n }\n };\n\n const wait = (): Promise<void> =>\n new Promise((resolve) => {\n timer = setTimeout(resolve, POLL_INTERVAL_MS);\n });\n\n void (async () => {\n while (!stopped) {\n try {\n const isConnected = await fetchGithubConnected(\n credentials.accessToken,\n credentials.projectId,\n credentials.host.apiHost,\n controller.signal,\n );\n if (stopped) return;\n if (isConnected) {\n // Only a false→true flip means the user installed during this\n // screen; true on the first check means they arrived connected.\n if (store.session.githubConnected === false) {\n analytics.wizardCapture('github connect completed');\n }\n store.setGithubConnected(true);\n return;\n }\n settleUnknown();\n } catch (err) {\n if (stopped) return;\n // Report once, then keep polling. Unlike Slack's nudge, this gate\n // can't degrade to a skip — the run cannot proceed until it\n // resolves — so a transient API blip must not strand the user.\n if (!errorReported) {\n errorReported = true;\n analytics.captureException(\n err instanceof Error ? err : new Error(String(err)),\n { step: 'github_connected_check' },\n );\n }\n settleUnknown();\n }\n await wait();\n }\n })();\n\n return () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n controller.abort();\n };\n }, [credentials, connected, store]);\n}\n","/**\n * SelfDrivingGitHubScreen — the \"Connect GitHub\" gate, shown after the handoff\n * and before the Self-driving run.\n *\n * Self-driving cannot research findings or open fixes without code access, so\n * the GitHub App is a hard requirement. The agent used to ask for it mid-run\n * via `wizard_ask` and abort when the answer came back declined — but a\n * `wizard_ask` timeout resolves to the same cancelled value as a real decline,\n * so a user who stepped away had their run killed as if they had refused.\n * Gating here instead makes the requirement cheap (no agent has started),\n * unambiguous (declining is an explicit pick), and un-timeoutable (the screen\n * waits as long as the browser install takes).\n *\n * Unlike SlackConnectScreen this is not skippable: declining ends the run on\n * the outro rather than continuing without it. The connection poll lives in\n * {@link useGithubConnection}.\n */\n\nimport { Box, Text } from 'ink';\nimport { useEffect, useRef, useState, useSyncExternalStore } from 'react';\n\nimport type { WizardStore } from '@ui/tui/store';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { PickerMenu, LoadingBox } from '@ui/tui/primitives/index';\nimport { useKeyBindings, KeyMatch } from '@ui/tui/hooks/useKeyBindings';\nimport {\n useGithubConnection,\n fetchLoginUrl,\n} from '@ui/tui/hooks/useGithubConnection';\nimport { OutroKind } from '@lib/wizard-session';\nimport {\n GITHUB_REQUIRED_BODY,\n GITHUB_REQUIRED_MESSAGE,\n} from '@lib/programs/self-driving/detect';\nimport { analytics } from '@utils/analytics';\nimport { openTrackedLink } from '@utils/links';\nimport { getIntegrationAuthorizeUrl } from '@utils/urls';\n\ninterface SelfDrivingGitHubScreenProps {\n store: WizardStore;\n}\n\nenum ChoiceValue {\n Open = 'open',\n Decline = 'decline',\n}\n\nexport const SelfDrivingGitHubScreen = ({\n store,\n}: SelfDrivingGitHubScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const credentials = store.session.credentials;\n const connectedState = store.session.githubConnected;\n const connected = connectedState === true;\n\n const authorizeUrl = credentials\n ? getIntegrationAuthorizeUrl(\n credentials.host.appHost,\n credentials.projectId,\n 'github',\n )\n : null;\n\n useGithubConnection(store);\n\n // Once the install link has been opened, re-offering it as the headline CTA\n // is confusing — the poll flips the screen on its own when the install lands.\n const [installOpened, setInstallOpened] = useState(false);\n\n // One-time login link for browsers without a PostHog session (fresh provisioned accounts).\n const [loginUrl, setLoginUrl] = useState<string | null>(null);\n const loginUrlRequested = useRef(false);\n useEffect(() => {\n if (loginUrlRequested.current) return;\n loginUrlRequested.current = true;\n void fetchLoginUrl(store.session).then(setLoginUrl);\n }, [store]);\n\n // Impression fires once the connected state is known, so `already_connected`\n // is real: users who arrive connected segment apart from users who connect\n // during the screen.\n const impressionFired = useRef(false);\n useEffect(() => {\n if (connectedState === null || impressionFired.current) return;\n impressionFired.current = true;\n analytics.wizardCapture('github connect shown', {\n already_connected: connected,\n });\n }, [connectedState, connected]);\n\n const openInstall = (): void => {\n if (!authorizeUrl) return;\n analytics.wizardCapture('github connect opened');\n openTrackedLink(authorizeUrl, 'self-driving-github-connect');\n setInstallOpened(true);\n };\n\n // Declining ends the run here, before the agent starts. The outro carries the\n // same copy the abort case renders, so both paths read identically.\n const decline = (): void => {\n analytics.wizardCapture('github connect declined', {\n install_opened: installOpened,\n });\n store.declineGithub({\n kind: OutroKind.Cancel,\n message: GITHUB_REQUIRED_MESSAGE,\n body: GITHUB_REQUIRED_BODY,\n });\n };\n\n const handleSelect = (value: ChoiceValue | ChoiceValue[]): void => {\n const choice = Array.isArray(value) ? value[0] : value;\n if (choice === ChoiceValue.Open) openInstall();\n else decline();\n };\n\n useKeyBindings('self-driving-github', [\n {\n match: KeyMatch.Escape,\n label: 'esc',\n action: connected ? 'continue' : 'end setup',\n handler: () => {\n if (!connected) decline();\n },\n },\n ]);\n\n if (credentials && connectedState === null) {\n return (\n <Box flexDirection=\"column\" flexGrow={1} marginTop={1}>\n <LoadingBox message=\"Checking for an existing GitHub connection...\" />\n </Box>\n );\n }\n\n if (connected) {\n return (\n <Box flexDirection=\"column\" flexGrow={1} marginTop={1}>\n <Text bold color={Colors.success}>\n {Icons.check} GitHub connected\n </Text>\n <Box marginTop={1}>\n <Text>\n Self-driving can research findings in your code and open fixes.\n </Text>\n </Box>\n <Box marginTop={1}>\n <LoadingBox message=\"Starting Self-driving setup...\" />\n </Box>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n {installOpened ? 'Finish connecting GitHub' : 'Connect GitHub'}\n </Text>\n\n <Box marginTop={1}>\n <Text>\n {installOpened\n ? \"We've opened the PostHog GitHub App install in your browser. Approve access there — we'll detect it automatically and continue.\"\n : 'Self-driving needs GitHub access to research findings in your code and open fixes, so setup cannot finish without it.'}\n </Text>\n </Box>\n\n {!installOpened && (\n <Box marginTop={1}>\n <Text>\n <Text color=\"cyan\">{Icons.diamond} </Text>\n Grant it the repos you want Self-driving to work with — include\n this project's repo so it can also watch its issues.\n </Text>\n </Box>\n )}\n\n {loginUrl && (\n <Box marginTop={1}>\n <Text dimColor>\n {'Log in to your new account first: '}\n <Text color=\"cyan\">{loginUrl}</Text>\n </Text>\n </Box>\n )}\n\n {authorizeUrl && (\n <Box marginTop={1}>\n <Text dimColor>\n {installOpened ? 'Install page: ' : 'Install it: '}\n <Text color=\"cyan\">{authorizeUrl}</Text>\n </Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <PickerMenu\n options={[\n {\n label: installOpened\n ? 'Re-open GitHub App install'\n : 'Open GitHub App install',\n value: ChoiceValue.Open,\n },\n {\n label: \"I can't connect right now\",\n value: ChoiceValue.Decline,\n },\n ]}\n onSelect={handleSelect}\n />\n </Box>\n </Box>\n </Box>\n );\n};\n","import { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { IntroScreenLayout } from '@ui/tui/screens/IntroScreenLayout';\nimport {\n SkillSourceInfo,\n useSkillEntry,\n} from '@ui/tui/screens/SkillSourceInfo';\n\ninterface AuditIntroScreenProps {\n store: WizardStore;\n}\n\nexport const AuditIntroScreen = ({ store }: AuditIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n const { session } = store;\n // bin.ts seeds session.skillId from ProgramConfig.skillId before render,\n // so audit and events-audit pick up their respective skill metadata here.\n const skillId = session.skillId ?? 'audit';\n const { skillEntry, fetchFailed } = useSkillEntry(skillId);\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56}>\n <Box marginBottom={1}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n </Box>\n\n <Text>\n The{' '}\n <Text color=\"cyan\" italic>\n {skillId}\n </Text>{' '}\n program reviews your project's PostHog integration against best\n practices to help you capture high-quality events and writes a report\n for suggested actions. Nothing in your project will be modified.\n </Text>\n <Box marginTop={1}>\n <SkillSourceInfo\n skillId={skillId}\n skillEntry={skillEntry}\n fetchFailed={fetchFailed}\n />\n </Box>\n </Box>\n ) : (\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>Let's review your existing PostHog setup for best practices.</Text>\n </Box>\n );\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const handleSelect = (value: string) => {\n if (value === 'cancel') process.exit(0);\n else if (value === 'more-info') setShowingMoreInfo(true);\n else if (value === 'back') setShowingMoreInfo(false);\n else store.completeSetup();\n };\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n body={body}\n showDetection={!showingMoreInfo}\n programLabel={session.programLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={handleSelect}\n />\n );\n};\n","import { useEffect } from 'react';\nimport { startFileWatcher, type FileWatcherOptions } from '@lib/file-watcher';\n\nexport { startFileWatcher } from '@lib/file-watcher';\nexport type { FileWatcherHandle, FileWatcherOptions } from '@lib/file-watcher';\n\n/** React hook wrapping `startFileWatcher`. Starts on mount, stops on unmount\n * or when `path` changes. `onUpdate` and `options` are captured at mount\n * time — change `path` to restart with a new callback. */\nexport function useFileWatcher(\n path: string,\n onUpdate: (parsed: unknown) => void,\n options: FileWatcherOptions = {},\n): void {\n useEffect(() => {\n const handle = startFileWatcher(path, onUpdate, options);\n return () => handle.stop();\n // `onUpdate` and `options` are intentionally omitted from deps — the\n // watcher captures them at mount time and the path drives restarts.\n }, [path]);\n}\n","/**\n * AuditAreaPane — left-pane slide that follows whatever area the agent is\n * currently checking, plus a wrap-up state once every check is resolved\n * and the agent has moved on to writing the report.\n *\n * Three states, gated top-down on the ledger:\n * 1. firstPending defined → render the slide for that area\n * 2. checks empty → blank (the seed hook fires before\n * this screen mounts in practice;\n * this is just defensive)\n * 3. all checks non-pending → \"writing report\" wrap-up\n *\n * Pressing `O` opens the active slide's docs URL.\n */\n\nimport { Fragment } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { spawn } from 'node:child_process';\nimport { Colors } from '@ui/tui/styles';\nimport { type AuditCheck } from '@lib/programs/audit/types';\nimport { AUDIT_AREA_SLIDES, type AreaSlide } from './slides/index.js';\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nconst FINDING_STATUSES: AuditCheck['status'][] = [\n 'error',\n 'warning',\n 'suggestion',\n];\n\nconst isFinding = (c: AuditCheck) => FINDING_STATUSES.includes(c.status);\n\nconst fallbackSlide = (area: string): AreaSlide => ({\n area,\n intro: [`Verifying ${area.toLowerCase()}…`],\n docsUrl: '',\n});\n\nconst openLink = (url: string) => {\n const cmd =\n process.platform === 'darwin'\n ? 'open'\n : process.platform === 'win32'\n ? 'cmd'\n : 'xdg-open';\n const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url];\n spawn(cmd, args, { detached: true, stdio: 'ignore' }).unref();\n};\n\n// ── Component ────────────────────────────────────────────────────────\n\ninterface AuditAreaPaneProps {\n checks: AuditCheck[];\n reportPath: string;\n /** Slide registry to look the active area up in. Defaults to the doctor\n * (`audit` program) slides; events-audit passes its own 6-phase set. */\n slides?: AreaSlide[];\n /** Dashboard URL once the agent emits `[DASHBOARD_URL]`. Shown as a sticky\n * footer so the user can grab the link while later phases still run. */\n dashboardUrl?: string | null;\n /** Notebook URL once the agent emits `[NOTEBOOK_URL]`. Same sticky-footer\n * treatment as the dashboard URL. */\n notebookUrl?: string | null;\n}\n\nexport const AuditAreaPane = ({\n checks,\n reportPath,\n slides = AUDIT_AREA_SLIDES,\n dashboardUrl,\n notebookUrl,\n}: AuditAreaPaneProps) => {\n const pendingChecks = checks.filter((c) => c.status === 'pending');\n const activeArea = pendingChecks[0]?.area;\n const slide = activeArea\n ? slides.find((s) => s.area === activeArea) ?? fallbackSlide(activeArea)\n : null;\n\n useInput((input) => {\n if (input.toLowerCase() === 'o' && slide?.docsUrl) {\n openLink(slide.docsUrl);\n }\n });\n\n const urlsFooter =\n dashboardUrl || notebookUrl ? (\n <UrlsFooter dashboardUrl={dashboardUrl} notebookUrl={notebookUrl} />\n ) : null;\n\n // Active area — agent is still resolving checks for this slide's area.\n if (slide) {\n const hasFindings = checks.some(isFinding);\n return (\n <Box flexDirection=\"column\">\n <ActiveSlide slide={slide} hasFindings={hasFindings} />\n {urlsFooter}\n </Box>\n );\n }\n\n // Ledger empty — the seed hook fires synchronously at intro `onReady`,\n // so this only happens if the seed file write failed. Render nothing\n // rather than misleading the user with a \"wrapped up\" message.\n if (checks.length === 0) {\n return null;\n }\n\n // Every check is resolved and the agent is composing the report.\n return (\n <Box flexDirection=\"column\">\n <WritingReport reportPath={reportPath} />\n {urlsFooter}\n </Box>\n );\n};\n\n// ── States ───────────────────────────────────────────────────────────\n\nconst ActiveSlide = ({\n slide,\n hasFindings,\n}: {\n slide: AreaSlide;\n hasFindings: boolean;\n}) => (\n <Box flexDirection=\"column\" paddingX={1}>\n <Text bold color={Colors.accent}>\n Verifying {slide.area.toLowerCase()}\n </Text>\n <Box height={1} />\n\n {slide.visual}\n {slide.intro.map((paragraph, i) => (\n <Fragment key={i}>\n {i > 0 && <Box height={1} />}\n <Text>{paragraph}</Text>\n </Fragment>\n ))}\n\n <Box marginTop={1}>\n <Text dimColor>\n {slide.docsUrl && (\n <>\n [<Text color={Colors.accent}>O</Text>] Learn more\n </>\n )}\n {hasFindings && (\n <>\n {slide.docsUrl && ' '}[<Text color={Colors.accent}>→</Text>] View\n issues\n </>\n )}\n </Text>\n </Box>\n </Box>\n);\n\nconst UrlsFooter = ({\n dashboardUrl,\n notebookUrl,\n}: {\n dashboardUrl?: string | null;\n notebookUrl?: string | null;\n}) => (\n <Box flexDirection=\"column\" paddingX={1} marginTop={1}>\n <Text dimColor>{'─'.repeat(40)}</Text>\n {dashboardUrl && (\n <Text>\n Dashboard: <Text color=\"cyan\">{dashboardUrl}</Text>\n </Text>\n )}\n {notebookUrl && (\n <Text>\n Notebook: <Text color=\"cyan\">{notebookUrl}</Text>\n </Text>\n )}\n </Box>\n);\n\nconst WritingReport = ({ reportPath }: { reportPath: string }) => (\n <Box flexDirection=\"column\" paddingX={1}>\n <Text bold color={Colors.accent}>\n We've wrapped up the review.\n </Text>\n <Box height={1} />\n <Text>\n To help you get the most out of your PostHog integration, we're preparing\n a report for you at <Text color=\"cyan\">{reportPath}</Text>.\n </Text>\n <Box height={1} />\n <Text>\n We'll cover what we checked and suggest where we can improve the existing\n integration.\n </Text>\n <Box height={1} />\n <Text dimColor>Hang tight!</Text>\n </Box>\n);\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst DetectVisual = () => (\n <VisualBox>\n <Text dimColor>package.json</Text>\n <Text>\n <Text dimColor>{' └─ '}</Text>\n <Text color=\"green\">posthog-js</Text>\n <Text dimColor>{' ^1.200.0'}</Text>\n </Text>\n <Text dimColor>requirements.txt</Text>\n <Text>\n <Text dimColor>{' └─ '}</Text>\n <Text color=\"green\">posthog</Text>\n <Text dimColor>{' ==4.0.1'}</Text>\n </Text>\n </VisualBox>\n);\n\nexport const DetectSdkSlide: AreaSlide = {\n area: 'Detect SDK',\n intro: [\n 'First we find which PostHog SDKs your project uses. The audit needs to know the right languages and frameworks before it looks at any code.',\n 'Only dependency manifests get read here: package.json, requirements.txt, go.mod, and similar files. Source files come in a later step.',\n 'If your project is a monorepo with more than one SDK, we handle each one.',\n ],\n visual: <DetectVisual />,\n docsUrl: 'https://posthog.com/docs/libraries',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst ScanVisual = () => (\n <VisualBox>\n <Text dimColor>grep -rn 'posthog\\.(capture|identify|group)'</Text>\n <Text>\n <Text color=\"cyan\">src/checkout/Checkout.tsx:88</Text>\n <Text dimColor>{' posthog.capture(...)'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">src/auth/login.ts:42</Text>\n <Text dimColor>{' posthog.identify(...)'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">src/onboarding/step.tsx:17</Text>\n <Text dimColor>{' posthog.capture(...)'}</Text>\n </Text>\n </VisualBox>\n);\n\nexport const ScanSitesSlide: AreaSlide = {\n area: 'Scan capture sites',\n intro: [\n 'Next we map every place your code captures PostHog events. This is the inventory the rest of the audit builds on.',\n 'We search your project for PostHog SDK calls: capture, identify, group, and more. No source files are opened yet, that comes in the next step.',\n \"Test files are excluded so they don't pollute the inventory.\",\n ],\n visual: <ScanVisual />,\n docsUrl: 'https://posthog.com/docs/product-analytics/capture-events',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst EnrichVisual = () => (\n <VisualBox>\n <Text dimColor>orchestrator</Text>\n <Text dimColor>{' │'}</Text>\n <Text>\n <Text dimColor>{' ├─ '}</Text>\n <Text color=\"cyan\">subagent 1</Text>\n <Text dimColor>{' → part-1.json'}</Text>\n </Text>\n <Text>\n <Text dimColor>{' ├─ '}</Text>\n <Text color=\"cyan\">subagent 2</Text>\n <Text dimColor>{' → part-2.json'}</Text>\n </Text>\n <Text>\n <Text dimColor>{' └─ '}</Text>\n <Text color=\"cyan\">subagent N</Text>\n <Text dimColor>{' → part-N.json'}</Text>\n </Text>\n </VisualBox>\n);\n\nexport const EnrichSitesSlide: AreaSlide = {\n area: 'Enrich',\n intro: [\n 'Now we look inside each file that captures events. The goal is to know not just that an event fires, but what it is, where it lives, and what data goes with it.',\n 'For every capture site we pull out the event name, the properties, the area of your codebase it sits in, and the surrounding function or component.',\n 'This is the only step that opens source files. Large codebases run in parallel so it finishes in one pass.',\n ],\n visual: <EnrichVisual />,\n docsUrl: 'https://posthog.com/docs/product-analytics/best-practices',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst QueryVisual = () => (\n <VisualBox>\n <Text dimColor>{'SELECT event, count() AS volume_30d'}</Text>\n <Text dimColor>\n {'FROM events WHERE timestamp > now() - INTERVAL 30 DAY'}\n </Text>\n <Text dimColor>{'GROUP BY event ORDER BY volume_30d DESC'}</Text>\n <Text> </Text>\n <Text>\n <Text color=\"cyan\">{'pageview '}</Text>\n <Text color=\"green\">{'12,430'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">{'signup_completed '}</Text>\n <Text color=\"green\">{' 840'}</Text>\n </Text>\n </VisualBox>\n);\n\nexport const QueryVolumeSlide: AreaSlide = {\n area: 'Query PostHog',\n intro: [\n 'We ask PostHog how often each event in the inventory has fired in the last 30 days.',\n \"Events your code captures but PostHog has never seen are flagged as phantoms. Phantoms usually mean a typo, a dead code path, or instrumentation that hasn't shipped yet. Worth cleaning up.\",\n \"If PostHog isn't reachable the audit still finishes. The report just notes where volume numbers would have gone.\",\n ],\n visual: <QueryVisual />,\n docsUrl: 'https://posthog.com/docs/product-analytics/sql',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst ReportVisual = () => (\n <VisualBox>\n <Text dimColor>posthog-events-audit-report.md</Text>\n <Text>\n <Text dimColor>{' # '}</Text>\n <Text>Identity & segmentation</Text>\n </Text>\n <Text>\n <Text dimColor>{' # '}</Text>\n <Text>Coverage map</Text>\n </Text>\n <Text>\n <Text dimColor>{' # '}</Text>\n <Text>Data quality</Text>\n </Text>\n <Text>\n <Text dimColor>{' # '}</Text>\n <Text>Events by file & area</Text>\n </Text>\n </VisualBox>\n);\n\nexport const WriteReportSlide: AreaSlide = {\n area: 'Write report',\n intro: [\n 'We package everything we found into one report at ./posthog-events-audit-report.md. This is what you hand to the team.',\n 'The report covers how users get identified, which parts of your codebase capture which events, data quality issues like duplicates and phantoms, and a volume map of every event your code captures.',\n 'Nothing in your project is modified. The report is the only file you keep.',\n ],\n visual: <ReportVisual />,\n docsUrl: 'https://posthog.com/docs/product-analytics/best-practices',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst DashboardVisual = () => (\n <VisualBox>\n <Text dimColor>events audit dashboard</Text>\n <Text>\n <Text color=\"cyan\">{'pageview '}</Text>\n <Text color=\"green\">{'████████████'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">{'signup '}</Text>\n <Text color=\"green\">{'████████'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">{'activated '}</Text>\n <Text color=\"green\">{'█████'}</Text>\n </Text>\n <Text>\n <Text color=\"cyan\">{'purchased '}</Text>\n <Text color=\"green\">{'██'}</Text>\n </Text>\n </VisualBox>\n);\n\nexport const CreateDashboardSlide: AreaSlide = {\n area: 'Create dashboard',\n intro: [\n 'Finally we build a live PostHog dashboard for the events your code captures. Use it to watch volume over time, spot new phantoms, and see how traffic shifts as you ship changes.',\n 'Open the dashboard from the wrap-up screen when the audit completes.',\n ],\n visual: <DashboardVisual />,\n docsUrl: 'https://posthog.com/docs/product-analytics/dashboards',\n};\n","import { Text } from 'ink';\nimport { VisualBox, type AreaSlide } from '../shared.js';\n\nconst NotebookVisual = () => (\n <VisualBox>\n <Text dimColor>posthog-events-audit-report.md</Text>\n <Text dimColor>{' │'}</Text>\n <Text>\n <Text dimColor>{' ▼ '}</Text>\n <Text color=\"cyan\">PostHog notebook</Text>\n </Text>\n <Text dimColor>{' # Identity & segmentation'}</Text>\n <Text dimColor>{' # Coverage map'}</Text>\n <Text dimColor>{' # Events by file & area'}</Text>\n </VisualBox>\n);\n\nexport const UploadNotebookSlide: AreaSlide = {\n area: 'Upload notebook',\n intro: [\n 'Next we upload the report into a PostHog notebook so you can share it with your team as a URL.',\n 'Hang tight.',\n 'The markdown file on disk is still there for you to read locally.',\n ],\n visual: <NotebookVisual />,\n docsUrl: 'https://posthog.com/docs/notebooks',\n};\n","/**\n * Slide registry for the events-audit program. Each entry is keyed by\n * `AuditCheck.area` and corresponds to one phase of the 6-phase pipeline.\n *\n * `AuditAreaPane` looks up the active phase's slide here when the active\n * program is events-audit.\n */\n\nimport type { AreaSlide } from '../shared.js';\nimport { DetectSdkSlide } from './detectSdk.js';\nimport { ScanSitesSlide } from './scanSites.js';\nimport { EnrichSitesSlide } from './enrichSites.js';\nimport { QueryVolumeSlide } from './queryVolume.js';\nimport { WriteReportSlide } from './writeReport.js';\nimport { CreateDashboardSlide } from './createDashboard.js';\nimport { UploadNotebookSlide } from './uploadNotebook.js';\n\nexport const EVENTS_AUDIT_AREA_SLIDES: AreaSlide[] = [\n DetectSdkSlide,\n ScanSitesSlide,\n EnrichSitesSlide,\n QueryVolumeSlide,\n WriteReportSlide,\n CreateDashboardSlide,\n UploadNotebookSlide,\n];\n","import { Box, Text } from 'ink';\nimport { Spinner } from '@inkjs/ui';\nimport {\n AUDIT_SEVERITY_STYLE,\n type AuditCheck,\n} from '@lib/programs/audit/types';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { LoadingBox } from '@ui/tui/primitives/index';\nimport { useStdoutDimensions } from '@ui/tui/hooks/useStdoutDimensions';\n\ninterface PendingChecksListProps {\n checks: AuditCheck[];\n}\n\ninterface Group {\n area: string;\n checks: AuditCheck[];\n}\n\nfunction groupByArea(checks: AuditCheck[]): Group[] {\n const order: string[] = [];\n const map = new Map<string, AuditCheck[]>();\n for (const c of checks) {\n if (!map.has(c.area)) {\n map.set(c.area, []);\n order.push(c.area);\n }\n map.get(c.area)!.push(c);\n }\n return order.map((area) => ({ area, checks: map.get(area)! }));\n}\n\nfunction groupIcon(group: Group): { icon: string; color: string } {\n const total = group.checks.length;\n const complete = group.checks.filter((c) => c.status !== 'pending').length;\n if (complete === 0) return { icon: Icons.squareOpen, color: Colors.muted };\n if (complete === total)\n return { icon: Icons.squareFilled, color: Colors.success };\n return { icon: Icons.triangleRight, color: Colors.primary };\n}\n\nconst GroupHeader = ({\n group,\n showIcon,\n isActive,\n}: {\n group: Group;\n showIcon: boolean;\n isActive: boolean;\n}) => {\n const complete = group.checks.filter((c) => c.status !== 'pending').length;\n const total = group.checks.length;\n const { icon, color } = groupIcon(group);\n return (\n <Box>\n {isActive ? (\n <Box marginRight={1}>\n <Spinner />\n </Box>\n ) : showIcon ? (\n <Text>\n <Text color={color}>{icon}</Text>{' '}\n </Text>\n ) : null}\n <Text>\n <Text bold>{group.area}</Text>{' '}\n <Text dimColor>\n ({complete}/{total})\n </Text>\n </Text>\n </Box>\n );\n};\n\nconst CheckRow = ({ check }: { check: AuditCheck }) => {\n const { glyph, color } = AUDIT_SEVERITY_STYLE[check.status];\n return (\n <Text>\n <Text color={color}>{glyph}</Text>\n <Text dimColor={check.status === 'pending'}> {check.label}</Text>\n </Text>\n );\n};\n\nconst COLLAPSE_BELOW_ROWS = 24;\n\nexport const PendingChecksList = ({ checks }: PendingChecksListProps) => {\n const [, termRows] = useStdoutDimensions();\n\n if (checks.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text bold>Checks</Text>\n <Text> </Text>\n <LoadingBox message=\"Seeding audit checklist...\" />\n </Box>\n );\n }\n\n const groups = groupByArea(checks);\n const activeIndex = groups.findIndex((g) =>\n g.checks.some((c) => c.status === 'pending'),\n );\n const collapsed = termRows < COLLAPSE_BELOW_ROWS;\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>Checks</Text>\n <Text> </Text>\n {collapsed\n ? groups.map((group, i) => (\n <GroupHeader\n key={group.area}\n group={group}\n showIcon\n isActive={i === activeIndex}\n />\n ))\n : groups.map((group, i) => (\n <Box\n key={group.area}\n flexDirection=\"column\"\n marginTop={i === 0 ? 0 : 1}\n >\n <GroupHeader\n group={group}\n showIcon={false}\n isActive={i === activeIndex}\n />\n {group.checks.map((c) => (\n <CheckRow key={c.id} check={c} />\n ))}\n </Box>\n ))}\n </Box>\n );\n};\n","import { useSyncExternalStore } from 'react';\nimport { join } from 'node:path';\nimport { Box } from 'ink';\nimport type { WizardStore } from '@ui/tui/store';\nimport {\n TabContainer,\n SplitView,\n LogViewer,\n HNViewer,\n} from '@ui/tui/primitives/index';\nimport { useStdoutDimensions } from '@ui/tui/hooks/useStdoutDimensions';\nimport { useFileWatcher } from '@ui/tui/hooks/file-watcher';\nimport { AuditChecksViewer } from './AuditChecksViewer/AuditChecksViewer.js';\nimport { AuditAreaPane } from './AuditAreaPane.js';\nimport { AUDIT_AREA_SLIDES } from './slides/index.js';\nimport { EVENTS_AUDIT_AREA_SLIDES } from './slides/events-audit/index.js';\nimport { PendingChecksList } from './PendingChecksList.js';\nimport {\n AUDIT_CHECKS_FILE,\n AUDIT_CHECKS_KEY,\n AUDIT_REPORT_FILE,\n coerceAuditChecks,\n getAuditChecks,\n} from '@lib/programs/audit/types';\nimport { getProgramConfig } from '@lib/programs/program-registry';\nimport { WIZARD_LOG_FILE } from '@utils/paths';\n\ninterface AuditRunScreenProps {\n store: WizardStore;\n}\n\nexport const AuditRunScreen = ({ store }: AuditRunScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n // Mirror the agent's audit ledger into the store.\n useFileWatcher(join(store.session.installDir, AUDIT_CHECKS_FILE), (parsed) =>\n store.setFrameworkContext(AUDIT_CHECKS_KEY, coerceAuditChecks(parsed)),\n );\n\n const statuses =\n store.statusMessages.length > 0 ? store.statusMessages : undefined;\n\n const [columns] = useStdoutDimensions();\n const checks = getAuditChecks(store.session);\n const reportFile =\n getProgramConfig(store.router.activeProgram).reportFile ??\n AUDIT_REPORT_FILE;\n const reportPath = `./${reportFile}`;\n const pendingChecksList = <PendingChecksList checks={checks} />;\n const slides =\n store.session.skillId === 'audit-events'\n ? EVENTS_AUDIT_AREA_SLIDES\n : AUDIT_AREA_SLIDES;\n const areaPane = (\n <AuditAreaPane\n checks={checks}\n reportPath={reportPath}\n slides={slides}\n dashboardUrl={store.session.dashboardUrl}\n notebookUrl={store.session.notebookUrl}\n />\n );\n\n // Narrow terminals: drop the area pane.\n const statusComponent =\n columns < 80 ? (\n <Box flexDirection=\"column\" flexGrow={1}>\n {pendingChecksList}\n </Box>\n ) : (\n <SplitView left={areaPane} right={pendingChecksList} />\n );\n\n const tabs = [\n { id: 'status', label: 'Status', component: statusComponent },\n {\n id: 'audit-checks',\n label: 'Audit plan',\n component: <AuditChecksViewer checks={checks} />,\n },\n {\n id: 'logs',\n label: 'Tail logs',\n component: <LogViewer filePath={WIZARD_LOG_FILE} />,\n },\n { id: 'hn', label: 'HN', component: <HNViewer /> },\n ];\n\n return (\n <TabContainer\n tabs={tabs}\n statusMessage={statuses}\n expandableStatus\n store={store}\n />\n );\n};\n","import { Box, Text } from 'ink';\nimport {\n AUDIT_SEVERITY_STYLE,\n type AuditCheck,\n} from '@lib/programs/audit/types';\nimport { relativeToInstallDir } from '@utils/paths';\n\ninterface AuditChecksOutroSectionProps {\n checks: AuditCheck[];\n installDir: string;\n}\n\nconst MAX_VISIBLE = 6;\n\nexport const AuditChecksOutroSection = ({\n checks,\n installDir,\n}: AuditChecksOutroSectionProps) => {\n if (checks.length === 0) return null;\n\n const errors = checks.filter((c) => c.status === 'error');\n const warnings = checks.filter((c) => c.status === 'warning');\n const suggestions = checks.filter((c) => c.status === 'suggestion');\n const problematic = [...errors, ...warnings, ...suggestions];\n\n const visible = problematic.slice(0, MAX_VISIBLE);\n const hidden = problematic.length - visible.length;\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"cyan\" bold>\n Items audited:\n </Text>\n <Text dimColor>\n {checks.length} checks · {errors.length} errors · {warnings.length}{' '}\n warnings · {suggestions.length} suggestions\n </Text>\n {problematic.length === 0 ? (\n <Text color=\"green\">{'•'} No issues found.</Text>\n ) : (\n <>\n {visible.map((item) => {\n const style = AUDIT_SEVERITY_STYLE[item.status];\n return (\n <Box key={item.id} flexDirection=\"column\" marginTop={1}>\n <Text>\n <Text color={style.color}>{style.glyph}</Text>{' '}\n <Text bold>{item.label}</Text>{' '}\n <Text dimColor>({item.area})</Text>\n </Text>\n {item.file && (\n <Text dimColor>\n {' '}\n {relativeToInstallDir(item.file, installDir)}\n </Text>\n )}\n </Box>\n );\n })}\n {hidden > 0 && (\n <Text dimColor>\n … and {hidden} more. See the report for details.\n </Text>\n )}\n </>\n )}\n </Box>\n );\n};\n","/**\n * AuditOutroScreen — Audit-specific post-run summary. Renders the standard\n * success / error / cancel views with the audit checks summary inlined into\n * the success body. The report path shown in the success headline comes from\n * the program's `successMessage`, so this screen is program-agnostic.\n */\n\nimport { join } from 'node:path';\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { OutroKind } from '@lib/wizard-session';\nimport { Colors } from '@ui/tui/styles';\nimport { getAuditChecks } from '@lib/programs/audit/types';\nimport { AuditChecksOutroSection } from './AuditChecksOutroSection.js';\nimport { useDismissOnAnyKey } from '@ui/tui/hooks/useDismissOnAnyKey';\n\ninterface AuditOutroScreenProps {\n store: WizardStore;\n}\n\nexport const AuditOutroScreen = ({ store }: AuditOutroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n useDismissOnAnyKey(() => store.setOutroDismissed());\n\n const outroData = store.session.outroData;\n\n if (!outroData) {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text dimColor>Finishing up...</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n {outroData.kind === OutroKind.Success && (\n <Box flexDirection=\"column\">\n <Text color=\"green\" bold>\n ✔ {outroData.message || 'Audit complete!'}\n </Text>\n\n {outroData.dashboardUrl && (\n <Box marginTop={1}>\n <Text>\n Dashboard: <Text color=\"cyan\">{outroData.dashboardUrl}</Text>\n </Text>\n </Box>\n )}\n\n {outroData.notebookUrl && (\n <Box marginTop={1}>\n <Text>\n Notebook: <Text color=\"cyan\">{outroData.notebookUrl}</Text>\n </Text>\n </Box>\n )}\n\n {outroData.reportFile && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"cyan\" bold>\n Report saved to:\n </Text>\n <Text>\n {join(store.session.installDir, outroData.reportFile)}\n </Text>\n <Text dimColor>\n A markdown file in your project folder. Open it in any editor to\n read the full audit.\n </Text>\n </Box>\n )}\n\n <AuditChecksOutroSection\n checks={getAuditChecks(store.session)}\n installDir={store.session.installDir}\n />\n\n {outroData.docsUrl && (\n <Box marginTop={1}>\n <Text>\n Learn more: <Text color=\"cyan\">{outroData.docsUrl}</Text>\n </Text>\n </Box>\n )}\n </Box>\n )}\n\n {outroData.kind === OutroKind.Error && (\n <Box flexDirection=\"column\">\n <Text color=\"red\" bold>\n ✘ {outroData.message || 'An error occurred'}\n </Text>\n {outroData.body && (\n <Box marginTop={1}>\n <Text dimColor>{outroData.body}</Text>\n </Box>\n )}\n </Box>\n )}\n\n {outroData.kind === OutroKind.Cancel && (\n <Text color=\"yellow\">■ {outroData.message || 'Cancelled'}</Text>\n )}\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to continue</Text>\n </Box>\n </Box>\n );\n};\n","/**\n * SetupScreen — Generic framework disambiguation.\n *\n * Iterates unresolved setup questions from the FrameworkConfig\n * and renders a PickerMenu for each. If all questions are auto-resolved,\n * this screen is skipped entirely (the router skips it via its show() predicate).\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { PickerMenu } from '@ui/tui/primitives/index';\nimport { Colors } from '@ui/tui/styles';\nimport type { SetupQuestion } from '@lib/framework-config';\n\ninterface SetupScreenProps {\n store: WizardStore;\n}\n\nexport const SetupScreen = ({ store }: SetupScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const config = store.session.frameworkConfig;\n const questions = config?.metadata.setup?.questions ?? [];\n\n // Track which question index we're currently showing\n const [currentIndex, setCurrentIndex] = useState(0);\n const [resolving, setResolving] = useState(true);\n\n // On mount, run auto-detection for all questions\n useEffect(() => {\n void (async () => {\n for (const q of questions) {\n // Skip if already resolved (e.g. by CLI arg)\n if (q.key in store.session.frameworkContext) continue;\n\n try {\n const detected = await q.detect({\n installDir: store.session.installDir,\n });\n if (detected !== null) {\n store.setFrameworkContext(q.key, detected);\n }\n } catch {\n // Detection failed — will ask the user\n }\n }\n setResolving(false);\n\n // If all resolved, the router's isComplete predicate will\n // resolve past this screen on the next render cycle.\n })();\n }, []);\n\n if (resolving) {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text dimColor>Detecting project configuration...</Text>\n </Box>\n );\n }\n\n // Get unresolved questions\n const unresolved = questions.filter(\n (q: SetupQuestion) => !(q.key in store.session.frameworkContext),\n );\n\n if (unresolved.length === 0) {\n // All resolved — should have already advanced\n return null;\n }\n\n const question = unresolved[currentIndex] ?? unresolved[0];\n if (!question) return null;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n Project Setup\n </Text>\n {config && (\n <Text dimColor>Configuring {config.metadata.name} integration</Text>\n )}\n </Box>\n\n <PickerMenu<string>\n message={question.message}\n options={question.options.map((o) => ({\n label: o.label,\n value: o.value,\n hint: o.hint,\n }))}\n onSelect={(value) => {\n const selected = Array.isArray(value) ? value[0] : value;\n store.setFrameworkContext(question.key, selected);\n\n // Check if more unresolved questions remain\n const remaining = unresolved.filter(\n (q: SetupQuestion) =>\n q.key !== question.key &&\n !(q.key in store.session.frameworkContext),\n );\n\n if (remaining.length > 0) {\n setCurrentIndex((i) => i + 1);\n }\n // When no remaining questions, setFrameworkContext already\n // triggered emitChange — router resolves past this screen.\n }}\n />\n </Box>\n );\n};\n","/**\n * Best-effort platform shell-outs for making a URL usable in any terminal —\n * no third-party dependency.\n *\n * Two helpers back the `wizard_ask` link overlay, for terminals that can't\n * linkify a wrapped URL (e.g. macOS Terminal.app, which lacks OSC 8 hyperlink\n * support):\n *\n * - `copyToClipboard` — pipe the URL to the platform clipboard binary so the\n * user can paste it into a browser.\n * - `openInBrowser` — hand the URL to the platform opener so it launches\n * directly, no copy/paste needed.\n *\n * Both shell out with `spawn` and never a shell, and pass the URL as an argv\n * (clipboard via stdin) — so there's no shell-injection surface. Neither throws:\n * they return false when no command is reachable (CI, headless, or the binary\n * isn't installed).\n */\nimport { spawn } from 'node:child_process';\nimport { logToFile } from './debug.js';\n\ninterface ClipboardCommand {\n cmd: string;\n args: string[];\n}\n\n/** Platform clipboard commands, in preference order. */\nfunction clipboardCommands(): ClipboardCommand[] {\n if (process.platform === 'darwin') return [{ cmd: 'pbcopy', args: [] }];\n if (process.platform === 'win32') return [{ cmd: 'clip', args: [] }];\n // Linux / BSD: try Wayland first, then the common X11 utilities.\n return [\n { cmd: 'wl-copy', args: [] },\n { cmd: 'xclip', args: ['-selection', 'clipboard'] },\n { cmd: 'xsel', args: ['--clipboard', '--input'] },\n ];\n}\n\nfunction writeWith(\n { cmd, args }: ClipboardCommand,\n text: string,\n): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n const child = spawn(cmd, args);\n // ENOENT (missing binary) and EPIPE surface as 'error' events.\n child.on('error', () => resolve(false));\n child.stdin.on('error', () => resolve(false));\n child.on('close', (code) => resolve(code === 0));\n child.stdin.end(text);\n } catch {\n resolve(false);\n }\n });\n}\n\nexport async function copyToClipboard(text: string): Promise<boolean> {\n for (const command of clipboardCommands()) {\n if (await writeWith(command, text)) return true;\n }\n logToFile('[clipboard] no working clipboard command found');\n return false;\n}\n\n/**\n * Platform browser-open commands, in preference order. The URL is one argv\n * element — never concatenated into a shell string — so a `?kind=…` query or\n * any other character can't escape into the command line.\n *\n * `win32` has no shell-free single binary for this: `start` is a `cmd` builtin,\n * so we invoke `cmd /c start \"\" <url>` (the empty `\"\"` is `start`'s window-title\n * argument, which would otherwise swallow the URL). The URL is still a discrete\n * argv element, not interpolated into the command string.\n *\n * Takes `platform` as an argument (defaulting to the host) so the mapping is a\n * pure function the tests can exercise across platforms.\n */\nexport function browserOpenCommands(\n url: string,\n platform: NodeJS.Platform = process.platform,\n): ClipboardCommand[] {\n if (platform === 'darwin') return [{ cmd: 'open', args: [url] }];\n if (platform === 'win32') {\n return [{ cmd: 'cmd', args: ['/c', 'start', '', url] }];\n }\n // Linux / BSD: xdg-open is the freedesktop standard; x-www-browser is the\n // Debian alternatives fallback.\n return [\n { cmd: 'xdg-open', args: [url] },\n { cmd: 'x-www-browser', args: [url] },\n ];\n}\n\nfunction spawnOpener({ cmd, args }: ClipboardCommand): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n // Detach the opener's stdio so it can't write over the Ink TUI, and\n // resolve on a clean exit. ENOENT (missing binary) surfaces as 'error'.\n const child = spawn(cmd, args, { stdio: 'ignore' });\n child.on('error', () => resolve(false));\n child.on('close', (code) => resolve(code === 0));\n } catch {\n resolve(false);\n }\n });\n}\n\nexport async function openInBrowser(url: string): Promise<boolean> {\n for (const command of browserOpenCommands(url)) {\n if (await spawnOpener(command)) return true;\n }\n logToFile('[clipboard] no working browser-open command found');\n return false;\n}\n","/**\n * AuthScreen — Shown while waiting for OAuth authentication.\n *\n * Displays framework detection, a compressed privacy summary, a waiting\n * spinner, and the login URL when available. [I] opens the full\n * PrivacyPanel as an overlay. [P] (when loginUrl is set) lets the user\n * paste the callback URL by hand. [C] copies the login URL to the\n * clipboard — the exact string, so it can't be chopped by a soft-wrap.\n *\n * The router resolves past this screen once session.credentials is set.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { LoadingBox } from '@ui/tui/primitives/index';\nimport { MAX_WIDTH } from '@ui/tui/primitives/ScreenContainer';\nimport {\n PrivacyPanel,\n PRIVACY_PANEL_LABEL,\n} from '@ui/tui/components/PrivacyPanel';\nimport { IntroScreenLayout } from '@ui/tui/screens/IntroScreenLayout';\nimport { useKeyBindings, type KeyBinding } from '@ui/tui/hooks/useKeyBindings';\nimport { useStdoutDimensions } from '@ui/tui/hooks/useStdoutDimensions';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { copyToClipboard } from '@utils/clipboard';\n\ninterface AuthScreenProps {\n store: WizardStore;\n}\n\nexport const AuthScreen = ({ store }: AuthScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showPrivacy, setShowPrivacy] = useState(false);\n const [copyStatus, setCopyStatus] = useState<'idle' | 'copied' | 'failed'>(\n 'idle',\n );\n const [columns] = useStdoutDimensions();\n const { session } = store;\n\n // While the OAuth flow is waiting (loginUrl set), let the user paste the\n // callback URL/code by hand — the fallback for headless/remote shells where\n // the browser can't reach the local callback server.\n const loginUrl = session.loginUrl;\n const canPasteCode = Boolean(loginUrl);\n\n // The URL renders on its own line; ScreenContainer clamps content to\n // MAX_WIDTH and pads one column each side, so this is the room a single\n // unwrapped line has. A URL wider than this soft-wraps, and a wrapped URL\n // copies with a line break baked in — the exact broken-link (\"invalid\n // scope\") breakage users hit on small terminals. Show a resize hint instead.\n const availableWidth = Math.min(columns, MAX_WIDTH) - 2;\n const urlFits = loginUrl ? loginUrl.length <= availableWidth : true;\n\n // Build bindings imperatively: while the privacy view is open, the\n // screen registers NO bindings (IntroScreenLayout's menu owns input).\n const bindings: KeyBinding[] = [];\n if (!showPrivacy) {\n if (canPasteCode && loginUrl) {\n bindings.push({\n match: ['p', 'P'],\n label: 'P',\n action: 'paste auth code',\n handler: () => store.showManualAuthCode(),\n });\n // Copy the exact URL string — immune to the soft-wrap that breaks\n // hand-selection on narrow terminals. May no-op on a remote shell with\n // no clipboard binary; the 'failed' status points the user to [P] then.\n bindings.push({\n match: ['c', 'C'],\n label: 'C',\n action: 'copy link',\n handler: () => {\n void copyToClipboard(loginUrl).then((ok) =>\n setCopyStatus(ok ? 'copied' : 'failed'),\n );\n },\n });\n }\n bindings.push({\n match: ['i', 'I'],\n label: 'I',\n action: PRIVACY_PANEL_LABEL.toLowerCase(),\n handler: () => setShowPrivacy(true),\n });\n }\n useKeyBindings('auth', bindings);\n\n if (showPrivacy) {\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n title={PRIVACY_PANEL_LABEL}\n showSubtitle={false}\n showDetection={false}\n body={<PrivacyPanel />}\n showPrivacy={false}\n menuOptions={[{ label: 'Back', value: 'back' }]}\n menuAlign=\"left\"\n onSelect={() => setShowPrivacy(false)}\n />\n );\n }\n\n const config = session.frameworkConfig;\n const frameworkLabel =\n session.detectedFrameworkLabel ?? config?.metadata.name;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n PostHog Setup Wizard\n </Text>\n\n {frameworkLabel && (\n <Text>\n <Text color=\"green\">{'✔'} </Text>\n <Text>Framework: {frameworkLabel}</Text>\n </Text>\n )}\n\n {/* Dead path today — every framework went GA, so no config has\n metadata.beta = true. Kept intentionally for the next time we\n ship a framework integration in beta. Set `beta: true` on the\n framework's config and this rendering re-activates. */}\n {config?.metadata.beta && (\n <Text color=\"yellow\">\n [BETA] The {config.metadata.name} wizard is in beta. Questions or\n feedback? Email wizard@posthog.com\n </Text>\n )}\n\n {config?.metadata.preRunNotice && (\n <Text color=\"yellow\">{config.metadata.preRunNotice}</Text>\n )}\n </Box>\n\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold dimColor>\n {PRIVACY_PANEL_LABEL}\n </Text>\n <Text dimColor>\n {'•'} Source files are read by Claude for AI context\n </Text>\n <Text dimColor>{'•'} .env* and secrets stay on your machine</Text>\n <Text dimColor>\n {'•'} Press <Text color={Colors.accent}>[I]</Text> for full privacy &\n usage info\n </Text>\n </Box>\n\n <LoadingBox message=\"Waiting for authentication...\" />\n\n {loginUrl && (\n <Box marginTop={1} marginBottom={1} flexDirection=\"column\">\n {urlFits ? (\n // Literal \\n — sibling <Box> spacers squeeze to 0 under flex\n // height pressure, letting cmd-click slurp /authorize + 'y'.\n <Text>\n <Text dimColor>\n If the browser didn't open, copy and paste this URL:\n </Text>\n {'\\n\\n'}\n <Text color=\"cyan\">{loginUrl}</Text>\n </Text>\n ) : (\n <Text color=\"yellow\">\n [This terminal is too small to show the full link for copying,\n resize your terminal]\n </Text>\n )}\n <Box marginTop={1}>\n <Text dimColor>\n Press <Text color={Colors.accent}>[C]</Text> to copy the link · on\n a remote machine or devbox? Press{' '}\n <Text color={Colors.accent}>[P]</Text> to paste the callback URL.\n </Text>\n </Box>\n {copyStatus === 'copied' && (\n <Box marginTop={1}>\n <Text color={Colors.success}>\n {Icons.check} Link copied to clipboard.\n </Text>\n </Box>\n )}\n {copyStatus === 'failed' && (\n <Box marginTop={1}>\n <Text color=\"yellow\">\n Couldn't reach a clipboard on this machine — press{' '}\n <Text color={Colors.accent}>[P]</Text> to paste the callback URL\n instead.\n </Text>\n </Box>\n )}\n </Box>\n )}\n </Box>\n );\n};\n","/**\n * RunScreen — Default observational view of the agent run.\n *\n * Tabs: Status (LearnCard + ProgressList), Event plan (when present),\n * Tail logs, HN. Programs that need a different tab list ship their own\n * screen component (see audit/AuditRunScreen.tsx).\n */\n\nimport { useMemo, useSyncExternalStore } from 'react';\nimport { Box } from 'ink';\nimport type { WizardStore } from '@ui/tui/store';\nimport {\n TabContainer,\n SplitView,\n ProgressList,\n LogViewer,\n EventPlanViewer,\n HNViewer,\n} from '@ui/tui/primitives/index';\nimport type { ProgressItem } from '@ui/tui/primitives/index';\nimport { ADDITIONAL_FEATURE_LABELS } from '@lib/wizard-session';\nimport { LearnCard } from '@ui/tui/components/LearnCard';\nimport { VisualizerTab } from '@ui/tui/components/PhaseVisuals';\nimport { TipsCard } from '@ui/tui/components/TipsCard';\nimport { useStdoutDimensions } from '@ui/tui/hooks/useStdoutDimensions';\n\nimport { getProgramConfig } from '@lib/programs/program-registry';\nimport { getContentBlocks as getSkillContentBlocks } from '@lib/programs/agent-skill/content/index';\n\nimport { WIZARD_LOG_FILE } from '@utils/paths';\n\ninterface RunScreenProps {\n store: WizardStore;\n}\n\nexport const RunScreen = ({ store }: RunScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [columns] = useStdoutDimensions();\n\n const progressItems: ProgressItem[] = store.tasks.map((t) => ({\n label: t.label,\n activeForm: t.activeForm,\n status: t.status,\n }));\n\n // When all tasks are done but the queue has features, show a transitional item\n const queue = store.session.additionalFeatureQueue;\n const allDone =\n progressItems.length > 0 &&\n progressItems.every((t) => t.status === 'completed');\n if (allDone && queue.length > 0) {\n const nextLabel = ADDITIONAL_FEATURE_LABELS[queue[0]];\n progressItems.push({\n label: `Set up ${nextLabel}`,\n activeForm: `Setting up ${nextLabel}...`,\n status: 'in_progress',\n });\n }\n\n const statuses =\n store.statusMessages.length > 0 ? store.statusMessages : undefined;\n\n // Each program owns its content deck (program/content/index.tsx)\n // and wires it onto its ProgramConfig.getContentBlocks. Fall back to the\n // agent-skill deck for runtime-created configs (e.g. `wizard skill <id>`)\n // that aren't in the static registry.\n const activeProgram = store.router.activeProgram;\n const learnBlocks = useMemo(() => {\n const getBlocks =\n getProgramConfig(activeProgram).getContentBlocks ?? getSkillContentBlocks;\n return getBlocks(store);\n }, [store, activeProgram]);\n\n // Program-supplied tips for the right pane; undefined falls back to\n // DEFAULT_TIPS inside TipsCard, so non-self-driving programs are unaffected.\n const programTips = getProgramConfig(activeProgram).getTips?.(store);\n\n const leftPane = store.learnCardComplete ? (\n <TipsCard store={store} tips={programTips} />\n ) : (\n <LearnCard\n store={store}\n blocks={learnBlocks}\n onComplete={() => store.setLearnCardComplete()}\n />\n );\n const progressList = <ProgressList items={progressItems} title=\"Tasks\" />;\n\n const statusComponent =\n columns < 80 ? (\n <Box flexDirection=\"column\" flexGrow={1}>\n {progressList}\n </Box>\n ) : (\n <SplitView left={leftPane} right={progressList} />\n );\n\n const tabs = [\n { id: 'status', label: 'Status', component: statusComponent },\n ...(store.eventPlan.length > 0\n ? [\n {\n id: 'events',\n label: 'Event plan',\n component: <EventPlanViewer events={store.eventPlan} />,\n },\n ]\n : []),\n {\n id: 'logs',\n label: 'Tail logs',\n component: <LogViewer filePath={WIZARD_LOG_FILE} />,\n },\n {\n id: 'visualizer',\n label: 'Visualizer',\n component: <VisualizerTab store={store} />,\n },\n { id: 'hn', label: 'HN', component: <HNViewer /> },\n ];\n\n return (\n <TabContainer\n tabs={tabs}\n statusMessage={statuses}\n expandableStatus\n store={store}\n />\n );\n};\n","/**\n * KeepSkillsScreen — Ask whether to keep installed skills in .claude/skills/.\n *\n * Shown after the outro summary so users see the agent's output first,\n * then decide whether to keep the skills that powered it.\n *\n * When done, calls store.setSkillsComplete() and exits the process.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport { readdir, rm, access } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nconst WIZARD_MARKER = '.posthog-wizard';\nimport type { WizardStore } from '@ui/tui/store';\nimport { ConfirmationInput } from '@ui/tui/primitives/index';\nimport { Colors } from '@ui/tui/styles';\nimport { CONTEXT_MILL_URL } from '@lib/constants';\n\ninterface KeepSkillsScreenProps {\n store: WizardStore;\n}\n\ninterface SkillEntry {\n name: string;\n children: string[];\n}\n\nenum Phase {\n Loading = 'loading',\n Ask = 'ask',\n Removing = 'removing',\n Done = 'done',\n}\n\nexport const KeepSkillsScreen = ({ store }: KeepSkillsScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [phase, setPhase] = useState<Phase>(Phase.Loading);\n const [skills, setSkills] = useState<SkillEntry[]>([]);\n\n const skillsDir = join(store.session.installDir, '.claude', 'skills');\n\n useEffect(() => {\n void (async () => {\n try {\n const entries = await readdir(skillsDir, { withFileTypes: true });\n const dirs = entries.filter((e) => e.isDirectory());\n const result: SkillEntry[] = [];\n for (const dir of dirs) {\n try {\n await access(join(skillsDir, dir.name, WIZARD_MARKER));\n } catch {\n continue;\n }\n const children = (await readdir(join(skillsDir, dir.name))).filter(\n (c) => c !== WIZARD_MARKER,\n );\n result.push({ name: dir.name, children });\n }\n if (result.length === 0) {\n store.setSkillsComplete(true);\n process.exit(0);\n }\n setSkills(result);\n setPhase(Phase.Ask);\n } catch {\n store.setSkillsComplete(true);\n process.exit(0);\n }\n })();\n }, []); // eslint-disable-line\n\n const handleKeep = () => {\n store.setSkillsComplete(true);\n process.exit(0);\n };\n\n const handleRemove = async () => {\n setPhase(Phase.Removing);\n for (const skill of skills) {\n try {\n await rm(join(skillsDir, skill.name), {\n recursive: true,\n force: true,\n });\n } catch {\n // Best-effort removal\n }\n }\n try {\n const remaining = await readdir(skillsDir);\n if (remaining.length === 0) {\n await rm(skillsDir, { recursive: true, force: true });\n }\n } catch {\n // Best-effort cleanup\n }\n setPhase(Phase.Done);\n // Give React a tick to paint the \"Skills removed.\" message before exit\n setTimeout(() => {\n store.setSkillsComplete(false);\n process.exit(0);\n }, 600);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Keep the skills?\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n {phase === Phase.Loading && (\n <Text dimColor>Checking installed skills...</Text>\n )}\n\n {phase === Phase.Ask && (\n <>\n <Text dimColor>\n The wizard installed open-source skills that help AI coding agents\n integrate PostHog into your project:\n </Text>\n <Box marginTop={1} flexDirection=\"column\" marginLeft={2}>\n <Text dimColor>.claude/</Text>\n <Text dimColor> skills/</Text>\n {skills.map((skill) => (\n <Box key={skill.name} flexDirection=\"column\">\n <Text dimColor> {skill.name}/</Text>\n {skill.children.map((child) => (\n <Text key={child} dimColor>\n {' '}\n {child}\n </Text>\n ))}\n </Box>\n ))}\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n Source: <Text color=\"cyan\">{CONTEXT_MILL_URL}</Text>\n </Text>\n </Box>\n <Box marginTop={1}>\n <ConfirmationInput\n message=\"Keep the installed skills?\"\n confirmLabel=\"Keep [Enter]\"\n cancelLabel=\"Remove [Esc]\"\n onConfirm={handleKeep}\n onCancel={() => void handleRemove()}\n />\n </Box>\n </>\n )}\n\n {phase === Phase.Removing && <Text dimColor>Removing skills...</Text>}\n\n {phase === Phase.Done && <Text dimColor>Skills removed.</Text>}\n </Box>\n </Box>\n );\n};\n","/**\n * ExitScreen — Final step in every program.\n *\n * Renders nothing. Immediately exits the process.\n * The cleanup handler in start-tui.ts handles the exit summary line.\n */\n\nimport { useEffect } from 'react';\n\nexport const ExitScreen = () => {\n useEffect(() => {\n process.exit(0);\n }, []);\n\n return null;\n};\n","/**\n * AuthErrorScreen — Shown when the PostHog LLM Gateway returns a 401.\n *\n * Distinct causes, most specific first:\n * 0. The OAuth grant is gone — a pre-run refresh already got `invalid_grant`\n * from the token endpoint. The only branch backed by a server verdict\n * rather than inference, so it wins; re-running is the whole fix.\n * 1. Claude Code settings.json / managed-settings overrides ANTHROPIC_*\n * env vars — auth conflict. Tell the user to log out of Claude Code.\n * 2. The PostHog API key itself was rejected — bad prefix, missing scope,\n * expired, or wrong region. Don't blame Claude Code in this case.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { Colors } from '@ui/tui/styles';\nimport { useDismissOnAnyKey } from '@ui/tui/hooks/useDismissOnAnyKey';\n\ninterface AuthErrorScreenProps {\n store: WizardStore;\n}\n\nexport const AuthErrorScreen = ({ store }: AuthErrorScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n useDismissOnAnyKey(() => process.exit(1));\n\n const detail = store.session.authErrorDetail;\n const hasSettingsConflict = detail?.hasSettingsConflict ?? true;\n const conflicts = detail?.conflicts ?? [];\n const usingManagedLogin = detail?.usingManagedLogin ?? false;\n const credentialPlaces = detail?.credentialPlaces ?? [];\n const sessionExpired = detail?.sessionExpired ?? false;\n const logFilePath = detail?.logFilePath;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text color=\"red\" bold>\n {'✘'} Authentication error\n </Text>\n\n {sessionExpired ? (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n Your PostHog login expired while the wizard was running, so the\n LLM Gateway rejected it (401). Nothing on this machine is\n misconfigured — the session simply ran out.\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>Re-run the wizard and log in again:</Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">npx @posthog/wizard</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n Any files the agent already wrote are still in your project.\n </Text>\n </Box>\n </>\n ) : usingManagedLogin ? (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n Conflicting Anthropic credentials. The agent signed in with an\n existing Claude login instead of the PostHog token the Wizard\n provided, so the LLM Gateway rejected it (401).\n </Text>\n </Box>\n\n {credentialPlaces.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text dimColor>Conflicting credentials may come from:</Text>\n {credentialPlaces.map((place) => (\n <Text key={place}>\n {'•'} {place}\n </Text>\n ))}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text dimColor>\n Log out of Claude Code (clears the stored login), then re-run the\n Wizard:\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">claude auth logout</Text>\n </Box>\n </>\n ) : hasSettingsConflict ? (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The Wizard couldn't connect to the PostHog LLM Gateway. Claude\n Code settings on this machine override the Wizard's credentials.\n </Text>\n </Box>\n\n {conflicts.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n {conflicts.map((conflict) => (\n <Text key={conflict.path}>\n {'•'} <Text bold>{conflict.path}</Text> sets{' '}\n <Text color=\"yellow\">{conflict.keys.join(', ')}</Text>\n </Text>\n ))}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text dimColor>\n Remove those keys from the file(s) above, or log out of Claude\n Code, then re-run the Wizard:\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">claude auth logout</Text>\n </Box>\n </>\n ) : (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The PostHog LLM Gateway rejected the API key. Common causes:\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text>\n {'•'} Wrong key type — pass a personal API key (\n <Text color=\"cyan\">phx_xxx</Text>).\n </Text>\n <Text dimColor>\n {' '}pha_ is an OAuth access token, phc_ is a project key.\n </Text>\n <Text>\n {'•'} Missing scope — the key needs{' '}\n <Text color=\"cyan\">llm_gateway:read</Text>.\n </Text>\n <Text>{'•'} Expired or revoked key.</Text>\n <Text>\n {'•'} Region mismatch — <Text color=\"cyan\">--region</Text> must\n match where the key was issued (us vs eu).\n </Text>\n </Box>\n </>\n )}\n\n {logFilePath && (\n <Box marginTop={1}>\n <Text dimColor>Verbose log: {logFilePath}</Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to exit</Text>\n </Box>\n </Box>\n );\n};\n","/**\n * SessionTimeoutScreen — shown when the OAuth login window expires before the\n * user completes authorization.\n *\n * Pushed as an overlay so it takes priority over the gated AuthScreen (which\n * never completes without credentials). Terminal state: any key exits, since\n * the only way forward is to re-run the wizard for a fresh login window.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport { Colors } from '@ui/tui/styles';\nimport { OAUTH_TIMEOUT_MS } from '@lib/constants';\nimport { useDismissOnAnyKey } from '@ui/tui/hooks/useDismissOnAnyKey';\n\ninterface SessionTimeoutScreenProps {\n store: WizardStore;\n}\n\nconst TIMEOUT_MINUTES = Math.round(OAUTH_TIMEOUT_MS / 60_000);\n\nexport const SessionTimeoutScreen = ({ store }: SessionTimeoutScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n useDismissOnAnyKey(() => process.exit(1));\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text color=\"red\" bold>\n {'✘'} Login timed out\n </Text>\n\n <Box marginTop={1}>\n <Text>The OAuth link timed out after {TIMEOUT_MINUTES} minutes.</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text>Re-run the wizard to get a fresh link and try again.</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to exit</Text>\n </Box>\n </Box>\n );\n};\n","/**\n * WizardAskScreen — Overlay for the `wizard_ask` MCP tool.\n *\n * Walks the agent's question list one at a time and accumulates answers.\n * When the user submits the last question, the store resolves the\n * pending request and the overlay pops, returning the agent to its run.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { TextInput } from '@inkjs/ui';\nimport { useEffect, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@ui/tui/store';\nimport {\n LinkText,\n ModalOverlay,\n PickerMenu,\n extractUrls,\n} from '@ui/tui/primitives/index';\nimport { Colors, Icons } from '@ui/tui/styles';\nimport { copyToClipboard, openInBrowser } from '@utils/clipboard';\nimport { useKeyBindings } from '@ui/tui/hooks/useKeyBindings';\nimport type { AskAnswers, AskQuestion } from '@lib/wizard-session';\n\ninterface WizardAskScreenProps {\n store: WizardStore;\n}\n\n/**\n * Key policy for the ask overlay: Esc declines the whole request, everything\n * else is left to the focused input. Extracted so the wiring is unit-testable\n * without a live Ink render (the test suite stubs `useInput` to a no-op).\n */\nexport function handleAskKey(\n key: { escape?: boolean },\n store: Pick<WizardStore, 'cancelPendingQuestion'>,\n): void {\n if (key.escape) store.cancelPendingQuestion();\n}\n\n/**\n * Whether an answer would leave a required question effectively unanswered.\n *\n * The `wizard_ask` schema marks fields `required` (defaulting to true), but the\n * overlay used to submit whatever the input held — so pressing Enter on an empty\n * required credential field sent an empty string on to the agent. A blank host\n * or password is indistinguishable there from a real answer, so the warehouse\n * task ran on it, failed source creation, and dead-ended with no signal that the\n * user had in effect declined. Blocking the empty submit keeps the contract the\n * schema already advertises; Esc stays the way to skip. Optional fields\n * (`required === false`) are never blocked, and pickers always yield a value.\n */\nexport function isRequiredButEmpty(\n question: Pick<AskQuestion, 'required'>,\n value: string | string[],\n): boolean {\n if (question.required === false) return false;\n return Array.isArray(value) ? value.length === 0 : value.trim().length === 0;\n}\n\nexport const WizardAskScreen = ({ store }: WizardAskScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const pending = store.session.pendingQuestion;\n\n // Index of the question currently being answered. Resets when a fresh\n // pending request arrives.\n const [index, setIndex] = useState(0);\n const [answers, setAnswers] = useState<AskAnswers>({});\n const [lastPendingId, setLastPendingId] = useState<string | null>(null);\n // Set when the user tries to submit an empty required field, cleared once a\n // real answer goes through. Drives the inline \"this field is required\" nudge.\n const [requiredHint, setRequiredHint] = useState(false);\n // What the user last did with the link, so the overlay can confirm it. The\n // auto-copy below seeds 'copied'; pressing `o`/`c` overrides it.\n const [linkStatus, setLinkStatus] = useState<'idle' | 'copied' | 'opened'>(\n 'idle',\n );\n\n // For rich-link prompts (opt-in programs only) copy a lone URL to the\n // clipboard, so users on terminals without OSC 8 support can still paste it.\n // Only fires when the current question has exactly one URL, to avoid\n // clobbering the clipboard ambiguously. `soleUrl` is the sole effect dep.\n const richLinks = pending?.richLinks ?? false;\n const currentPrompt = pending?.questions[index]?.prompt ?? '';\n const promptUrls = richLinks ? extractUrls(currentPrompt) : [];\n const soleUrl = promptUrls.length === 1 ? promptUrls[0] : null;\n\n // The `o`/`c` keybinds would steal keystrokes from a free-text answer, so\n // only offer them on picker questions (where the user isn't typing).\n const isTextQuestion = pending?.questions[index]?.kind === 'text';\n const canActOnLink = !!soleUrl && !isTextQuestion;\n\n // Split the prompt at the link so the o/c hint sits right under it, with\n // trailing text below. Falls back to the whole prompt when there's no\n // single-link split.\n const linkSplitIndex =\n canActOnLink && soleUrl ? currentPrompt.indexOf(soleUrl) : -1;\n const splitLink = soleUrl !== null && linkSplitIndex !== -1;\n const linkEnd = splitLink && soleUrl ? linkSplitIndex + soleUrl.length : 0;\n const promptHead = splitLink\n ? currentPrompt.slice(0, linkEnd)\n : currentPrompt;\n const linkTrailingText = splitLink\n ? currentPrompt.slice(linkEnd).replace(/^\\s+/, '')\n : '';\n\n useEffect(() => {\n setLinkStatus('idle');\n if (!soleUrl) return;\n // Seed the clipboard silently for terminals without OSC 8. Status stays\n // 'idle' so the o/c hint shows until the user acts.\n void copyToClipboard(soleUrl);\n }, [soleUrl]);\n\n // Explicit, discoverable link actions. OSC 8 makes the link clickable only on\n // terminals that support it (not macOS Terminal.app), so `o` opens it in the\n // browser directly — the one path that works everywhere — and `c` copies it\n // as a fallback. Both register hints in the bar via useKeyBindings.\n useKeyBindings(\n 'wizard-ask-link',\n canActOnLink && soleUrl\n ? [\n {\n match: 'o',\n label: 'o',\n action: 'open in browser',\n handler: () => {\n void openInBrowser(soleUrl).then((ok) => {\n if (ok) setLinkStatus('opened');\n });\n },\n },\n {\n match: 'c',\n label: 'c',\n action: 'copy link',\n handler: () => {\n void copyToClipboard(soleUrl).then((ok) => {\n if (ok) setLinkStatus('copied');\n });\n },\n },\n ]\n : [],\n );\n\n // Esc declines the whole request. Cancellation is a first-class outcome the\n // ask bridge and the wizard_ask tool already expect (a task treats it as \"the\n // user declined\" and falls back — e.g. to a browser setup link), so without\n // this a user who can't answer has no exit but typing placeholders or waiting\n // out the multi-minute per-question timeout. Every field comes back cancelled.\n useInput((_input, key) => handleAskKey(key, store));\n\n if (!pending) return null;\n\n // Reset accumulator state when the agent opens a new request mid-session.\n if (pending.id !== lastPendingId) {\n setLastPendingId(pending.id);\n setIndex(0);\n setAnswers({});\n setRequiredHint(false);\n return null;\n }\n\n const question = pending.questions[index];\n if (!question) return null;\n\n const total = pending.questions.length;\n const progress = total > 1 ? `Question ${index + 1} of ${total}` : null;\n\n const submit = (value: string | string[]) => {\n // Don't let a required field go through empty — it would reach the agent as\n // a blank answer it can't tell from a real one. Nudge instead; Esc skips.\n if (isRequiredButEmpty(question, value)) {\n setRequiredHint(true);\n return;\n }\n setRequiredHint(false);\n const next: AskAnswers = { ...answers, [question.id]: value };\n if (index + 1 < total) {\n setAnswers(next);\n setIndex(index + 1);\n return;\n }\n store.resolvePendingQuestion(next);\n };\n\n return (\n <ModalOverlay\n borderColor={Colors.accent}\n title={`${Icons.diamond} ${pending.source}`}\n titleColor={Colors.accent}\n width={72}\n >\n {progress && (\n <Box marginBottom={1}>\n <Text dimColor>{progress}</Text>\n </Box>\n )}\n <Box flexDirection=\"column\">\n {pending.richLinks ? (\n <LinkText text={promptHead} />\n ) : (\n <Text>{question.prompt}</Text>\n )}\n </Box>\n {/* o/c hint until the user acts, then a confirmation. */}\n {canActOnLink && (\n <Box marginTop={1}>\n {linkStatus === 'idle' ? (\n <Text dimColor>\n Press <Text color={Colors.accent}>o</Text> to open it in your\n browser, or <Text color={Colors.accent}>c</Text> to copy the link.\n </Text>\n ) : linkStatus === 'opened' ? (\n <Text color={Colors.success}>\n {Icons.check} Opening the link in your browser…\n </Text>\n ) : (\n <Text color={Colors.success}>\n {Icons.check} Link copied to clipboard. Paste it in your browser.\n </Text>\n )}\n </Box>\n )}\n {/* Prompt text after the link */}\n {linkTrailingText && (\n <Box marginTop={1}>\n <Text>{linkTrailingText}</Text>\n </Box>\n )}\n <Box marginTop={1}>\n {/* `key` forces React to remount the input when the question changes\n so per-question internal state (typed buffer, picker focus) doesn't\n bleed across questions. */}\n <QuestionInput\n key={`${pending.id}:${question.id}`}\n question={question}\n onSubmit={submit}\n />\n </Box>\n {requiredHint && (\n <Box marginTop={1}>\n <Text color={Colors.accent}>\n {Icons.warning} This field is required — type an answer, or press\n ESC to skip.\n </Text>\n </Box>\n )}\n <Box marginTop={1}>\n <Text dimColor>\n <Text color={Colors.accent}>ESC</Text> skip\n </Text>\n </Box>\n </ModalOverlay>\n );\n};\n\ninterface QuestionInputProps {\n question: AskQuestion;\n onSubmit: (value: string | string[]) => void;\n}\n\nconst QuestionInput = ({ question, onSubmit }: QuestionInputProps) => {\n switch (question.kind) {\n case 'single':\n return (\n <PickerMenu<string>\n options={(question.options ?? []).map((o) => ({\n label: o.label,\n value: o.value,\n }))}\n onSelect={(value) => {\n const v = Array.isArray(value) ? value[0] : value;\n onSubmit(v);\n }}\n />\n );\n\n case 'multi': {\n const multiOptions = (question.options ?? []).map((o) => ({\n label: o.label,\n value: o.value,\n description: o.description,\n }));\n // Add vertical breathing room between options only when at least one\n // carries a description — keeps every description-less multi-select\n // (every other program) spaced exactly as before.\n const hasDescriptions = multiOptions.some((o) => o.description);\n return (\n <PickerMenu<string>\n mode=\"multi\"\n optionMarginBottom={hasDescriptions ? 1 : 0}\n options={multiOptions}\n onSelect={(value) => {\n const v = Array.isArray(value) ? value : [value];\n onSubmit(v);\n }}\n />\n );\n }\n\n case 'text':\n return (\n // `width=\"100%\"` on both the column and the hint row anchors them to\n // the modal's content width — without it, Ink/Yoga shrinks the column\n // to fit its widest child, so the right-aligned hint walks left/right\n // as the typed text changes width.\n <Box flexDirection=\"column\" width=\"100%\">\n <TextInput\n placeholder=\"Type your answer\"\n onSubmit={(value) => onSubmit(value)}\n />\n <Box marginTop={1} width=\"100%\" justifyContent=\"flex-end\">\n <Text>\n <Text color={Colors.accent}>ENTER</Text>\n <Text dimColor> submit</Text>\n </Text>\n </Box>\n </Box>\n );\n }\n};\n","/**\n * Capability for MCP clients whose editor CLI has its own login command\n * (`claude mcp login`, `codex mcp login`). The editor owns the OAuth token and\n * its refresh, and its login command requires a real terminal — so the wizard\n * never runs it, it surfaces the exact command for the user to run.\n */\nexport interface LoginCapable {\n /** The editor's login command (e.g. `claude mcp login posthog`), or null when unusable right now (CLI absent). */\n loginCommand(local?: boolean): string | null;\n /** The login command when the server comes from the editor's plugin (e.g. `plugin:posthog:posthog`), or null when unusable. */\n pluginLoginCommand?(): string | null;\n}\n\nexport function isLoginCapable<T>(client: T): client is T & LoginCapable {\n return (\n typeof client === 'object' && client !== null && 'loginCommand' in client\n );\n}\n","/**\n * Capability for MCP clients that are connected by opening a hosted page in\n * the browser rather than writing a local config or running a CLI install.\n *\n * Mirrors the PluginCapable pattern in plugin-client.ts: the client carries the\n * URL and instruction text (product knowledge); the TUI renders whatever the\n * capability surfaces (generic machinery).\n */\n\nexport interface BrowserFinishable {\n /** URL the user opens to finish connecting (also shown as copy-paste fallback). */\n connectorUrl: string;\n /** One-line instruction shown after the page opens. */\n finishInstruction: string;\n}\n\nexport function isBrowserFinishable<T>(c: T): c is T & BrowserFinishable {\n return (\n typeof c === 'object' &&\n c !== null &&\n 'connectorUrl' in c &&\n 'finishInstruction' in c\n );\n}\n","/**\n * McpInstaller — service layer between McpScreen and MCP business logic.\n *\n * Decouples the screen from step internals. Testable, swappable,\n * no dynamic imports in React components.\n */\n\nimport {\n getSupportedClients,\n removeMCPServer,\n getInstalledClients,\n getSupportedPluginClients,\n installPlugins as runPluginInstall,\n} from '@steps/add-mcp-server-to-clients/index';\nimport { ALL_FEATURE_VALUES } from '@steps/add-mcp-server-to-clients/defaults';\nimport {\n McpClientStatus,\n namesWithStatus,\n redactSecrets,\n toClientResult,\n type McpClientResult,\n} from '@steps/add-mcp-server-to-clients/results';\nimport { isPluginCapable } from '@steps/add-mcp-server-to-clients/plugin-client';\nimport { isLoginCapable } from '@steps/add-mcp-server-to-clients/login-client';\nimport { isBrowserFinishable } from '@steps/add-mcp-server-to-clients/browser-client';\nimport { logToFile } from '@utils/debug';\nimport { analytics } from '@utils/analytics';\n\nexport interface McpClientInfo {\n name: string;\n supportsPlugin: boolean;\n /** True when the plugin already ships the posthog MCP server (no direct entry needed). */\n pluginBundlesMcp: boolean;\n /**\n * Set for clients connected by opening a hosted page in the browser. The\n * Done screen renders this so the user knows to finish setup in the browser.\n */\n finish?: { url: string; instruction: string };\n /** The editor's own login command (e.g. `claude mcp login posthog`), the one manual step left. */\n loginCommand?: string;\n /** Same, for the plugin-provided server (e.g. `claude mcp login plugin:posthog:posthog`). */\n pluginLoginCommand?: string;\n}\n\nexport { McpClientStatus };\nexport type { McpClientResult };\n\nexport interface McpInstaller {\n /** Detect which MCP-capable editors are available on this machine. */\n detectClients(): Promise<McpClientInfo[]>;\n\n /**\n * Install the PostHog MCP server to the given clients. Returns one result per\n * client — including the ones that were already installed and the ones that\n * failed, so the screen can say which happened and why.\n */\n install(\n clientNames: string[],\n features?: string[],\n apiKey?: string,\n ): Promise<McpClientResult[]>;\n\n /**\n * Remove the PostHog MCP server from every client that has it. Returns one\n * result per client so a failed removal isn't reported as a success.\n */\n remove(local?: boolean): Promise<McpClientResult[]>;\n\n /** Install the PostHog AI plugin to supported clients. Best-effort: failures do not affect MCP outcome. */\n installPlugins(clientNames: string[]): Promise<McpClientResult[]>;\n}\n\n/**\n * Production McpInstaller backed by real MCP client detection and installation.\n */\nexport function createMcpInstaller(): McpInstaller {\n // Cache the raw MCPClient objects so install() can reference them by name\n let cachedClients: Array<{ name: string; raw: unknown }> = [];\n\n return {\n async detectClients(): Promise<McpClientInfo[]> {\n const supported = await getSupportedClients();\n cachedClients = supported.map((c) => ({ name: c.name, raw: c }));\n return supported.map((c) => ({\n name: c.name,\n supportsPlugin: isPluginCapable(c) && c.supportsPlugin(),\n pluginBundlesMcp: isPluginCapable(c) && c.pluginBundlesMcpServer(),\n finish: isBrowserFinishable(c)\n ? { url: c.connectorUrl, instruction: c.finishInstruction }\n : undefined,\n loginCommand: (isLoginCapable(c) && c.loginCommand(false)) || undefined,\n pluginLoginCommand:\n (isLoginCapable(c) && c.pluginLoginCommand?.()) || undefined,\n }));\n },\n\n async install(\n clientNames: string[],\n features?: string[],\n apiKey?: string,\n ): Promise<McpClientResult[]> {\n const resolvedFeatures = features ?? [...ALL_FEATURE_VALUES];\n const toInstall = cachedClients\n .filter((c) => clientNames.includes(c.name))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((c) => c.raw as any);\n\n if (toInstall.length === 0) {\n logToFile(\n `[McpInstaller] No clients matched. clientNames=${JSON.stringify(\n clientNames,\n )}, cached=${JSON.stringify(cachedClients.map((c) => c.name))}`,\n );\n return [];\n }\n\n const results: McpClientResult[] = [];\n for (const client of toInstall) {\n const name = client.name as string;\n try {\n const result = await client.addServer(\n apiKey,\n resolvedFeatures,\n false,\n );\n results.push(toClientResult(name, result));\n if (!result?.success) {\n // redactSecrets, not the raw reason: the CLIs we shell out to echo\n // the Authorization header back in their error output.\n logToFile(\n `[McpInstaller] addServer returned success=false for ${name}: ${redactSecrets(\n result?.reason ?? 'no reason given',\n )}`,\n );\n }\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n logToFile(\n `[McpInstaller] addServer threw for ${name}: ${redactSecrets(\n reason,\n )}`,\n );\n results.push(toClientResult(name, { success: false, reason }));\n }\n }\n return results;\n },\n\n async remove(local?: boolean): Promise<McpClientResult[]> {\n // `local` was dropped here, so `mcp remove --local` looked at (and\n // reported on) the wrong server name.\n const installed = await getInstalledClients(local);\n if (installed.length === 0) return [];\n return removeMCPServer(installed, local);\n },\n\n async installPlugins(clientNames: string[]): Promise<McpClientResult[]> {\n const rawClients = cachedClients\n .filter((c) => clientNames.includes(c.name))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((c) => c.raw as any);\n\n const pluginClients = getSupportedPluginClients(rawClients);\n const results = await runPluginInstall(pluginClients);\n\n const already = namesWithStatus(results, McpClientStatus.Unchanged);\n analytics.wizardCapture('mcp plugins installed', {\n // `clients` keeps its original meaning — every client that ended up with\n // the plugin — so existing insights don't dip when a re-run reports\n // already-installed instead of a fresh write.\n clients: [\n ...namesWithStatus(results, McpClientStatus.Changed),\n ...already,\n ],\n already_installed: already,\n attempted: pluginClients.map((c) => c.name),\n });\n\n return results;\n },\n };\n}\n","/**\n * McpSuggestedPromptsServices — service layer between\n * McpSuggestedPromptsScreen and the network. Decouples the screen from\n * OAuth and the streaming-agent run so the playground can inject mocks\n * (skip login, canned streaming responses) without a special-case\n * branch in the screen itself.\n *\n * Mirrors the McpInstaller pattern: thin interface, production factory\n * that wires the real implementation, no dynamic imports in the React\n * tree.\n */\n\nimport type { Credentials } from '@lib/wizard-session';\nimport { getOrAskForProjectData } from '@utils/setup-utils';\nimport { Program } from '@lib/programs/program-registry';\nimport type { WizardStore } from '@ui/tui/store';\nimport type { ApiUser } from '@lib/api';\nimport {\n probeProjectData as runProbe,\n type ProjectDataProfile,\n} from '@lib/mcp-project-profile';\nimport { seedDemoEvents as runSeed } from '@lib/mcp-seed-events';\n\n/**\n * Discriminated union covering every kind of streamed event the screen\n * needs to render. Production yields these from Claude SDK messages;\n * the playground yields them from canned scripts.\n */\nexport type AgentChunk =\n | { kind: 'text'; text: string }\n /** `command` carries CLI mode's exec command string (`call <tool> …`) so the\n * screen can recover the inner tool for context-aware follow-ups. */\n | { kind: 'tool-call'; toolName: string; detail: string; command?: string }\n | { kind: 'tool-result'; toolName: string; detail: string }\n | { kind: 'error'; text: string }\n /** Stream completed. `sessionId` is the SDK session ID of the just-\n * completed turn; pass it back as `resumeSessionId` on a follow-up\n * call to continue the conversation with full history. */\n | { kind: 'done'; sessionId?: string };\n\nexport interface McpSuggestedPromptsServices {\n /**\n * Kicks off the OAuth dance. Production wires this to\n * `getOrAskForProjectData`; the playground returns canned values\n * after a fake delay.\n *\n * While the promise is pending, the implementation is expected to set\n * `session.loginUrl` (via `store.setLoginUrl`) so the screen can\n * render the URL inline. Mocks may set/clear this URL too if they\n * want to exercise the spinner + URL layout.\n */\n performLogin(): Promise<{\n credentials: Credentials;\n roleAtOrganization: string | null;\n user: ApiUser | null;\n }>;\n\n /**\n * Run a prompt against Claude with the PostHog MCP server available\n * for tool use. Yields chunks as the agent streams. Caller is\n * responsible for honoring the abort signal — implementations should\n * also short-circuit when `signal.aborted` becomes true.\n *\n * In production this calls the Claude Agent SDK's `query()` with the\n * user's OAuth token as the MCP Bearer. In the playground, the demo\n * provides canned scripts.\n */\n runPromptStreaming(args: {\n prompt: string;\n credentials: Credentials;\n signal: AbortSignal;\n /** When set, resume the named SDK session so the agent sees the\n * earlier turns as context. Used by follow-up picks; omitted on\n * the first prompt and after `[p]` restarts the conversation. */\n resumeSessionId?: string;\n }): AsyncIterable<AgentChunk>;\n\n /**\n * Scout the project after auth: a cheap, best-effort probe of event\n * volume, the project's real event names, and which products have data.\n * Drives the data-aware picker so the tutorial never offers a prompt\n * that hits an empty result. Always resolves (degraded profile on\n * failure) — never throws, never blocks the tutorial.\n */\n probeProjectData(credentials: Credentials): Promise<ProjectDataProfile>;\n\n /**\n * Send a small, backdated demo dataset to an empty project so the read\n * quests have something to show. Resolves with the seeded profile;\n * rejects if the send fails so the screen can fall back to the\n * write-only empty path.\n */\n seedDemoEvents(args: {\n credentials: Credentials;\n baseProfile: ProjectDataProfile;\n signal: AbortSignal;\n }): Promise<ProjectDataProfile>;\n}\n\n/**\n * Production services. The `runPromptStreaming` implementation lives\n * in a separate module so the heavy SDK import is only paid when\n * actually invoked.\n */\nexport function createMcpSuggestedPromptsServices(\n store: WizardStore,\n): McpSuggestedPromptsServices {\n return {\n performLogin: async () => {\n const result = await getOrAskForProjectData({\n signup: false,\n ci: false,\n apiKey: undefined,\n projectId: undefined,\n email: undefined,\n region: undefined,\n baseUrl: store.session.baseUrl,\n // Widens the OAuth scope grant: base `WIZARD_OAUTH_SCOPES` plus\n // read on every product surface (flags, experiments, surveys,\n // replays, errors, web/LLM analytics, cohorts, persons) plus\n // annotation read/write. Persistence writes (dashboard, insight,\n // notebook) come for free from the base set. See\n // `src/lib/oauth/program-scopes.ts`.\n programId: Program.McpTutorial,\n });\n return {\n credentials: {\n accessToken: result.accessToken,\n projectApiKey: result.projectApiKey,\n host: result.host,\n projectId: result.projectId,\n },\n roleAtOrganization: result.roleAtOrganization,\n user: result.user,\n };\n },\n\n runPromptStreaming: (args) =>\n runProductionPromptStreaming({\n ...args,\n // Gateway cost attribution. Only the id crosses here; the rest of the\n // trace tags are built where the headers are, keeping the agent module\n // out of the TUI's startup graph.\n programId: store.analyticsProgramId,\n integration: store.session.integration ?? undefined,\n }),\n\n probeProjectData: (credentials) =>\n runProbe({\n accessToken: credentials.accessToken,\n projectId: credentials.projectId,\n apiHost: credentials.host.apiHost,\n }),\n\n seedDemoEvents: ({ credentials, baseProfile, signal }) =>\n runSeed({\n projectApiKey: credentials.projectApiKey,\n apiHost: credentials.host.apiHost,\n baseProfile,\n signal,\n }),\n };\n}\n\nasync function* runProductionPromptStreaming(args: {\n prompt: string;\n credentials: Credentials;\n signal: AbortSignal;\n resumeSessionId?: string;\n programId?: string;\n integration?: string;\n}): AsyncIterable<AgentChunk> {\n // Defer the SDK import to call time — the playground never hits\n // this path (it overrides the whole service object), so demo\n // sessions don't pay the SDK load cost.\n const { runMcpPromptViaSdk } = await import(\n '@lib/agent/mcp-prompt-streaming'\n );\n yield* runMcpPromptViaSdk(args);\n}\n","/**\n * ScreenId registry — maps screen names to React components.\n *\n * Adding a new screen:\n * 1. Create the component in screens/ (or screens/<program>/).\n * 2. Add a `ScreenId` enum entry in screen-sequences.ts.\n * 3. Add an entry here.\n * 4. Reference the screen by name in the program's `steps` array.\n */\n\nimport type { ReactNode } from 'react';\nimport type { WizardStore } from './store.js';\nimport { ScreenId, Overlay, type ScreenName } from './router.js';\n\nimport { HealthCheckScreen } from './screens/health/HealthCheckScreen.js';\nimport { DoctorIntroScreen } from './screens/doctor/DoctorIntroScreen.js';\nimport { DoctorReportScreen } from './screens/doctor/DoctorReportScreen.js';\nimport { SettingsOverrideScreen } from './screens/SettingsOverrideScreen.js';\nimport { ManagedSettingsScreen } from './screens/ManagedSettingsScreen.js';\nimport { PortConflictScreen } from './screens/PortConflictScreen.js';\nimport { TaskNoticeScreen } from './screens/TaskNoticeScreen.js';\nimport { ManualAuthCodeScreen } from './screens/ManualAuthCodeScreen.js';\nimport { PostHogIntegrationIntroScreen } from './screens/PostHogIntegrationIntroScreen.js';\nimport { RevenueIntroScreen } from './screens/RevenueIntroScreen.js';\nimport { WarehouseIntroScreen } from './screens/WarehouseIntroScreen.js';\nimport { MigrationIntroScreen } from './screens/MigrationIntroScreen.js';\nimport { SourceMapsIntroScreen } from './screens/SourceMapsIntroScreen.js';\nimport { SourceMapsDetectScreen } from './screens/SourceMapsDetectScreen.js';\nimport { SourceMapsOutroScreen } from './screens/SourceMapsOutroScreen.js';\nimport { AgentSkillIntroScreen } from './screens/AgentSkillIntroScreen.js';\nimport { AiObservabilityIntroScreen } from './screens/AiObservabilityIntroScreen.js';\nimport { MetricsIntroScreen } from './screens/MetricsIntroScreen.js';\nimport { SelfDrivingIntroScreen } from './screens/SelfDrivingIntroScreen.js';\nimport { SelfDrivingIntegrationCheckScreen } from './screens/SelfDrivingIntegrationCheckScreen.js';\nimport { SelfDrivingIntegrationDetectScreen } from './screens/SelfDrivingIntegrationDetectScreen.js';\nimport { SelfDrivingHandoffScreen } from './screens/SelfDrivingHandoffScreen.js';\nimport { SelfDrivingGitHubScreen } from '@ui/tui/screens/SelfDrivingGitHubScreen';\nimport { AuditIntroScreen } from './screens/audit/AuditIntroScreen.js';\nimport { AuditRunScreen } from './screens/audit/AuditRunScreen.js';\nimport { AuditOutroScreen } from './screens/audit/AuditOutroScreen.js';\nimport { SetupScreen } from './screens/SetupScreen.js';\nimport { AuthScreen } from './screens/AuthScreen.js';\nimport { AiOptInRequiredScreen } from './screens/AiOptInRequiredScreen.js';\nimport { RunScreen } from './screens/RunScreen.js';\nimport { McpScreen } from './screens/McpScreen.js';\nimport { McpSuggestedPromptsScreen } from './screens/McpSuggestedPromptsScreen.js';\nimport { SlackConnectScreen } from './screens/SlackConnectScreen.js';\nimport { KeepSkillsScreen } from './screens/KeepSkillsScreen.js';\nimport { OutroScreen } from './screens/OutroScreen.js';\nimport { ExitScreen } from './screens/ExitScreen.js';\nimport { AuthErrorScreen } from './screens/AuthErrorScreen.js';\nimport { SessionTimeoutScreen } from './screens/SessionTimeoutScreen.js';\nimport { WizardAskScreen } from './screens/WizardAskScreen.js';\nimport { createMcpInstaller } from './services/mcp-installer.js';\nimport type { McpInstaller } from './services/mcp-installer.js';\nimport { createMcpSuggestedPromptsServices } from './services/mcp-suggested-prompts-services.js';\nimport type { McpSuggestedPromptsServices } from './services/mcp-suggested-prompts-services.js';\n\nexport interface ScreenServices {\n mcpInstaller: McpInstaller;\n mcpSuggestedPromptsServices: McpSuggestedPromptsServices;\n}\n\nexport function createServices(store: WizardStore): ScreenServices {\n return {\n mcpInstaller: createMcpInstaller(),\n mcpSuggestedPromptsServices: createMcpSuggestedPromptsServices(store),\n };\n}\n\nexport function createScreens(\n store: WizardStore,\n services: ScreenServices,\n): Record<ScreenName, ReactNode> {\n return {\n // Overlays\n [Overlay.SettingsOverride]: <SettingsOverrideScreen store={store} />,\n [Overlay.ManagedSettings]: <ManagedSettingsScreen store={store} />,\n [Overlay.PortConflict]: <PortConflictScreen store={store} />,\n [Overlay.TaskNotice]: <TaskNoticeScreen store={store} />,\n [Overlay.ManualAuthCode]: <ManualAuthCodeScreen store={store} />,\n [Overlay.AuthError]: <AuthErrorScreen store={store} />,\n [Overlay.SessionTimeout]: <SessionTimeoutScreen store={store} />,\n [Overlay.WizardAsk]: <WizardAskScreen store={store} />,\n\n // Wizard flow\n [ScreenId.Intro]: <PostHogIntegrationIntroScreen store={store} />,\n [ScreenId.RevenueIntro]: <RevenueIntroScreen store={store} />,\n [ScreenId.WarehouseIntro]: <WarehouseIntroScreen store={store} />,\n [ScreenId.SourceMapsIntro]: <SourceMapsIntroScreen store={store} />,\n [ScreenId.SourceMapsDetect]: <SourceMapsDetectScreen store={store} />,\n [ScreenId.SourceMapsOutro]: <SourceMapsOutroScreen store={store} />,\n [ScreenId.MigrationIntro]: <MigrationIntroScreen store={store} />,\n [ScreenId.AgentSkillIntro]: <AgentSkillIntroScreen store={store} />,\n [ScreenId.AiObservabilityIntro]: (\n <AiObservabilityIntroScreen store={store} />\n ),\n [ScreenId.MetricsIntro]: <MetricsIntroScreen store={store} />,\n [ScreenId.SelfDrivingIntro]: <SelfDrivingIntroScreen store={store} />,\n [ScreenId.SelfDrivingIntegrationCheck]: (\n <SelfDrivingIntegrationCheckScreen store={store} />\n ),\n [ScreenId.SelfDrivingIntegrationDetect]: (\n <SelfDrivingIntegrationDetectScreen store={store} />\n ),\n [ScreenId.SelfDrivingHandoff]: <SelfDrivingHandoffScreen store={store} />,\n [ScreenId.SelfDrivingGithub]: <SelfDrivingGitHubScreen store={store} />,\n [ScreenId.AuditIntro]: <AuditIntroScreen store={store} />,\n [ScreenId.AuditRun]: <AuditRunScreen store={store} />,\n [ScreenId.AuditOutro]: <AuditOutroScreen store={store} />,\n [ScreenId.HealthCheck]: <HealthCheckScreen store={store} />,\n [ScreenId.DoctorIntro]: <DoctorIntroScreen store={store} />,\n [ScreenId.DoctorReport]: <DoctorReportScreen store={store} />,\n [ScreenId.Setup]: <SetupScreen store={store} />,\n [ScreenId.Auth]: <AuthScreen store={store} />,\n [ScreenId.AiOptIn]: <AiOptInRequiredScreen store={store} />,\n [ScreenId.Run]: <RunScreen store={store} />,\n [ScreenId.Mcp]: (\n <McpScreen store={store} installer={services.mcpInstaller} />\n ),\n [ScreenId.McpSuggestedPrompts]: (\n <McpSuggestedPromptsScreen\n store={store}\n services={services.mcpSuggestedPromptsServices}\n />\n ),\n [ScreenId.SlackConnect]: <SlackConnectScreen store={store} />,\n [ScreenId.KeepSkills]: <KeepSkillsScreen store={store} />,\n [ScreenId.Outro]: <OutroScreen store={store} />,\n [ScreenId.Exit]: <ExitScreen />,\n\n // Standalone MCP flows\n [ScreenId.McpAdd]: (\n <McpScreen store={store} installer={services.mcpInstaller} />\n ),\n [ScreenId.McpRemove]: (\n <McpScreen\n store={store}\n installer={services.mcpInstaller}\n mode=\"remove\"\n />\n ),\n };\n}\n","import { useMemo } from 'react';\nimport { ScreenContainer } from './primitives/index.js';\nimport type { WizardStore } from './store.js';\nimport { createScreens, createServices } from './screen-registry.js';\n\ninterface AppProps {\n store: WizardStore;\n}\n\nexport const App = ({ store }: AppProps) => {\n const services = useMemo(() => createServices(store), [store]);\n const screens = useMemo(\n () => createScreens(store, services),\n [store, services],\n );\n\n return <ScreenContainer store={store} screens={screens} />;\n};\n","/**\n * exit-line.ts — builds the text printed to the MAIN terminal buffer after the\n * wizard leaves the alternate screen on exit.\n *\n * The TUI renders in the alternate screen buffer, which is torn down on exit —\n * everything the wizard drew (including the outro screen) is wiped. This line,\n * printed AFTER releaseTerminal(), is the only output that survives into the\n * user's scrollback. So the coding-agent handoff prompt is echoed here, on its\n * own plain line (no border, no bullets), which is what a terminal can\n * triple-click-select cleanly.\n *\n * Kept free of `ink`/`@inkjs/ui` imports so it stays a pure, unit-testable\n * function (start-tui.ts itself pulls in the whole render tree).\n */\n\nimport { totalTokenCount, type WizardStore } from './store.js';\nimport { OutroKind } from '@lib/wizard-session';\nimport { formatTokenCount, formatCostUsd } from '@lib/agent/token-pricing';\n\nconst RESET_ATTRS = '\\x1b[0m';\nconst GREEN = '\\x1b[32m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\n\n/**\n * Mirrors the hidden Ctrl+T HUD's tally into post-exit scrollback — but only\n * when the HUD is actually visible at exit (`store.tokenHudVisible`, which\n * defaults on in dev/test and off in production; `useDismissOnAnyKey`\n * already keeps Ctrl+T from also dismissing the outro screen underneath\n * it). A production run where the user never toggled it on shouldn't have a\n * cost number appear from nowhere once the TUI tears down. `null` when the\n * HUD is hidden, or the run never produced any usage (e.g. non-agent\n * programs).\n */\nfunction tokenCostLine(store: WizardStore): string | null {\n if (!store.tokenHudVisible) return null;\n const usage = store.tokenUsage;\n if (totalTokenCount(usage) === 0) return null;\n\n const label = usage.costIsFinal ? 'Final cost' : 'Cost (estimate)';\n return (\n `${DIM}${label}: ${formatCostUsd(usage.costUsd)}` +\n ` (in ${formatTokenCount(usage.inputTokens)}` +\n ` · out ${formatTokenCount(usage.outputTokens)}` +\n ` · cache read ${formatTokenCount(usage.cacheReadTokens)}` +\n ` · cache write ${formatTokenCount(\n usage.cacheCreationTokens,\n )})${RESET_ATTRS}`\n );\n}\n\n/**\n * The one manual step the wizard can't do itself: the editor's own MCP login.\n * Echoed into scrollback like the handoff prompt — command on its own plain\n * line so a terminal can triple-click-select it.\n */\nfunction mcpLoginBlock(store: WizardStore): string | null {\n const commands = store.session.mcpLoginCommands;\n if (!commands || commands.length === 0) return null;\n return (\n `${GREEN}${BOLD}\\u2714 Authenticate to finish (opens your browser):${RESET_ATTRS}\\n` +\n commands.join('\\n')\n );\n}\n\nexport function getExitLine(store: WizardStore): string {\n const outro = store.session.outroData;\n const label = store.session.programLabel ?? 'Wizard';\n const costLine = tokenCostLine(store);\n const loginBlock = mcpLoginBlock(store);\n\n if (outro?.kind === OutroKind.Success) {\n const message = outro.message ?? `${label} completed successfully.`;\n const reportSuffix =\n outro.reportFile && !message.includes(outro.reportFile)\n ? ` Check ./${outro.reportFile} for details.`\n : '';\n const headline = `${GREEN}${BOLD}✔${RESET_ATTRS} ${message}${reportSuffix}`;\n\n const parts = [headline];\n\n // The alt-screen outro is wiped on exit, so a program's primary\n // next-action link (e.g. the Self-driving inbox) only survives in\n // scrollback if echoed here. URL on its own line → clean triple-click.\n if (outro.primaryLink) {\n parts.push(\n `${DIM}${outro.primaryLink.label}:${RESET_ATTRS}\\n${outro.primaryLink.url}`,\n );\n }\n\n if (outro.nextSteps) {\n const bullets = outro.nextSteps.items\n .map((item) => `${DIM} • ${item}${RESET_ATTRS}`)\n .join('\\n');\n parts.push(`${DIM}${outro.nextSteps.heading}${RESET_ATTRS}\\n${bullets}`);\n }\n\n if (outro.handoffPrompt) {\n parts.push(\n `${DIM}Hand this to your coding agent to finish up (triple-click to select):${RESET_ATTRS}\\n` +\n outro.handoffPrompt,\n );\n }\n\n if (loginBlock) parts.push(loginBlock);\n if (costLine) parts.push(costLine);\n\n return parts.join('\\n\\n');\n }\n\n const parts = loginBlock\n ? [loginBlock]\n : [`${DIM}${label} exited.${RESET_ATTRS}`];\n if (costLine) parts.push(costLine);\n return parts.join('\\n\\n');\n}\n","/**\n * start-tui.ts — Sets up the Ink TUI renderer and InkUI.\n *\n * Renders in the terminal's alternate screen buffer so the wizard\n * doesn't pollute scrollback history. On exit, the previous terminal\n * content is restored and a single exit summary line is printed.\n */\n\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { WizardStore, Program, type ProgramId } from './store.js';\nimport { InkUI } from './ink-ui.js';\nimport { setUI } from '@ui/index';\nimport { App } from './App.js';\nimport { enterDarkTerminal, releaseTerminal } from './terminal.js';\nimport { analytics } from '@utils/analytics';\nimport { logToFile } from '@utils/debug';\nimport { getExitLine } from './exit-line.js';\n\nexport { releaseTerminal };\n\nexport function startTUI(\n version: string,\n program: ProgramId = Program.PostHogIntegration,\n): {\n unmount: () => void;\n store: WizardStore;\n waitForSetup: () => Promise<void>;\n} {\n enterDarkTerminal();\n\n const store = new WizardStore(program);\n store.version = version;\n\n const inkUI = new InkUI(store);\n setUI(inkUI);\n\n const { unmount: inkUnmount, waitUntilExit } = render(\n createElement(App, { store }),\n );\n\n analytics.setTag('program_id', program);\n // The launch marker — the first event of every TUI run, captured under\n // the run's anonymous id and merged into the user once they log in.\n analytics.wizardCapture('started', { program_id: program });\n\n // Fire the program steps' init work (e.g. the health-check pre-flight)\n // now that the screens are rendering — store construction alone must\n // not trigger it.\n store.runInitHooks();\n\n // Tearing down raw mode with a TTY read still pending surfaces a\n // benign 'read EIO' on stdin (macOS); without a handler Node treats\n // it as an uncaught exception and prints a stack over the exit line.\n process.stdin.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code !== 'EIO') throw err;\n });\n\n // On exit: unmount Ink, leave alt screen (restores previous content),\n // then print exit summary line into the main buffer.\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n // Timestamp the teardown — everything printed into the alt screen dies here.\n logToFile(\n `[start-tui] unmounting TUI, leaving alt screen (exitCode=${\n process.exitCode ?? 'unset'\n })`,\n );\n inkUnmount();\n releaseTerminal();\n process.stdout.write(getExitLine(store) + '\\n');\n };\n process.on('exit', cleanup);\n\n // Ink unmounts itself on ctrl+c (exitOnCtrlC) but that alone doesn't\n // end the process — background handles (e.g. the OAuth callback\n // server) keep the event loop alive, leaving a zombie wizard with no\n // UI. Follow the app teardown with a real exit.\n void waitUntilExit().then(async () => {\n // `cleaned` still false here means Ink tore itself down (ctrl+c) rather\n // than a runner-driven exit — flush the terminal analytics event before\n // the process dies, or interrupted runs vanish from the funnel entirely.\n // shutdown() is a no-op when a runner already reported a real status.\n const interrupted = !cleaned;\n cleanup();\n if (interrupted) {\n try {\n await analytics.shutdown('cancelled');\n } catch {\n /* never block exit on a flush failure */\n }\n }\n process.exit(process.exitCode ?? 0);\n });\n\n return {\n unmount: cleanup,\n store,\n waitForSetup: () => store.getGate('intro'),\n };\n}\n"],"mappings":"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"}
|